react-doctor 0.9.1-dev.54ba416 → 0.9.1-dev.7ee59d3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="082c13c1-ba8f-56d5-9944-c005ab0edc0e")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7f26fa62-fe0c-5ae0-bc9c-97a0deb50b43")}catch(e){}}();
3
3
  import { createRequire } from "node:module";
4
4
  import * as NodeChildProcess from "node:child_process";
5
5
  import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
@@ -64616,7 +64616,8 @@ var AmbiguousProjectError = class extends Error {
64616
64616
  }
64617
64617
  };
64618
64618
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
64619
- const SOURCE_FILE_PATTERN = /\.(tsx?|jsx?|mts|mjs)$/;
64619
+ const HTML_FILE_PATTERN = /\.html$/i;
64620
+ const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
64620
64621
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
64621
64622
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
64622
64623
  const MINIFIED_SNIFF_BYTES = 65536;
@@ -65482,10 +65483,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
65482
65483
  ]).find(isFile) ?? null;
65483
65484
  };
65484
65485
  const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json") || Path.basename(filePath) === ".babelrc" ? ts.parseJsonText(filePath, content) : ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
65485
- const getStaticPropertyName$1 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
65486
+ const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
65486
65487
  const isCommonJsConfigExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
65487
65488
  const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
65488
- const getRequireModuleSpecifier = (expression) => {
65489
+ const getRequireModuleSpecifier$1 = (expression) => {
65489
65490
  if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
65490
65491
  const moduleSpecifier = expression.arguments[0];
65491
65492
  return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
@@ -65498,7 +65499,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
65498
65499
  const namedBindings = importClause?.namedBindings;
65499
65500
  return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
65500
65501
  }
65501
- if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => ts.isIdentifier(declaration.name) && declaration.name.text === bindingName);
65502
+ if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
65502
65503
  return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
65503
65504
  });
65504
65505
  const getImportBinding = (sourceFile, bindingName) => {
@@ -65529,24 +65530,24 @@ const getImportBinding = (sourceFile, bindingName) => {
65529
65530
  for (const declaration of statement.declarationList.declarations) {
65530
65531
  if (!declaration.initializer) continue;
65531
65532
  if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
65532
- const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
65533
+ const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
65533
65534
  if (directModuleSpecifier) return {
65534
65535
  moduleSpecifier: directModuleSpecifier,
65535
65536
  exportName: "default",
65536
65537
  isNamespace: true
65537
65538
  };
65538
- if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
65539
- moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
65539
+ if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
65540
+ moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
65540
65541
  exportName: declaration.initializer.name.text,
65541
65542
  isNamespace: false
65542
65543
  };
65543
65544
  }
65544
65545
  if (!ts.isObjectBindingPattern(declaration.name)) continue;
65545
65546
  const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
65546
- const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
65547
+ const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
65547
65548
  if (bindingElement && moduleSpecifier) return {
65548
65549
  moduleSpecifier,
65549
- exportName: bindingElement.propertyName ? getStaticPropertyName$1(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
65550
+ exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
65550
65551
  isNamespace: false
65551
65552
  };
65552
65553
  }
@@ -65599,6 +65600,48 @@ const getScopedConfigBinding = (identifier) => {
65599
65600
  };
65600
65601
  };
65601
65602
  const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
65603
+ const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
65604
+ const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
65605
+ const isNodeCreateRequireCall = (node, analysis) => {
65606
+ if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
65607
+ if (!ts.isCallExpression(node)) return false;
65608
+ const target = node.expression;
65609
+ if (ts.isIdentifier(target)) {
65610
+ if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
65611
+ const importBinding = getImportBinding(analysis.sourceFile, target.text);
65612
+ return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
65613
+ }
65614
+ if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
65615
+ if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
65616
+ const createRequireReceiver = target.expression;
65617
+ if (ts.isCallExpression(createRequireReceiver)) {
65618
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
65619
+ if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
65620
+ const requireIdentifier = createRequireReceiver.expression;
65621
+ return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
65622
+ }
65623
+ if (!ts.isIdentifier(createRequireReceiver)) return false;
65624
+ if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
65625
+ const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
65626
+ return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
65627
+ };
65628
+ const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
65629
+ const [moduleSpecifierNode] = callExpression.arguments;
65630
+ if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
65631
+ const target = callExpression.expression;
65632
+ if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
65633
+ if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
65634
+ if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
65635
+ if (!ts.isIdentifier(target.expression)) return null;
65636
+ const resolverIdentifier = target.expression;
65637
+ if (analysis.localBindings.has(resolverIdentifier.text)) return null;
65638
+ const scopedBinding = getScopedConfigBinding(resolverIdentifier);
65639
+ const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
65640
+ const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
65641
+ if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
65642
+ if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
65643
+ return moduleSpecifierNode.text;
65644
+ };
65602
65645
  const getAssignedPropertyInitializer = (identifier, propertyName) => {
65603
65646
  let bindingScope = null;
65604
65647
  let currentNode = identifier;
@@ -65707,7 +65750,7 @@ const getReactCompilerFlagState = (expression, analysis) => {
65707
65750
  }
65708
65751
  if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
65709
65752
  for (const property of [...unwrappedExpression.properties].reverse()) {
65710
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
65753
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
65711
65754
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
65712
65755
  if (ts.isSpreadAssignment(property)) {
65713
65756
  const spreadState = getReactCompilerFlagState(property.expression, analysis);
@@ -65733,8 +65776,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
65733
65776
  }
65734
65777
  if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
65735
65778
  for (const property of [...resolvedExpression.properties].reverse()) {
65736
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === propertyName) return property.initializer;
65737
- if (ts.isMethodDeclaration(property) && getStaticPropertyName$1(property.name) === propertyName) return property;
65779
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
65780
+ if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
65738
65781
  if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
65739
65782
  if (ts.isSpreadAssignment(property)) {
65740
65783
  const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
@@ -65765,7 +65808,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
65765
65808
  return resolvedExpression.properties.some((property) => {
65766
65809
  if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
65767
65810
  if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
65768
- const staticPropertyName = getStaticPropertyName$1(property.name);
65811
+ const staticPropertyName = getStaticPropertyName$2(property.name);
65769
65812
  return staticPropertyName === null || staticPropertyName === propertyName;
65770
65813
  }
65771
65814
  return false;
@@ -65784,7 +65827,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
65784
65827
  continue;
65785
65828
  }
65786
65829
  if (ts.isExpressionStatement(statement) && isCommonJsConfigExportAssignment(statement.expression, sourceFile) && exportName !== "default" && ts.isObjectLiteralExpression(statement.expression.right)) for (const property of [...statement.expression.right.properties].reverse()) {
65787
- if (ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === exportName) {
65830
+ if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
65788
65831
  exportedNodes.push(property.initializer);
65789
65832
  break;
65790
65833
  }
@@ -65914,7 +65957,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
65914
65957
  if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
65915
65958
  const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
65916
65959
  if (propertyName === null) return null;
65917
- const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
65960
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
65918
65961
  if (requiredModuleSpecifier !== null) {
65919
65962
  if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
65920
65963
  if (!requiredModuleSpecifier.startsWith(".")) return null;
@@ -65943,10 +65986,10 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
65943
65986
  const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
65944
65987
  if (reactCompilerFlagState?.isEnabled) return true;
65945
65988
  for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
65946
- const propertyName = getStaticPropertyName$1(property.name);
65989
+ const propertyName = getStaticPropertyName$2(property.name);
65947
65990
  if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
65948
65991
  if (propertyName === "reactCompiler") continue;
65949
- if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$1(laterProperty.name) === propertyName)) continue;
65992
+ if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === propertyName)) continue;
65950
65993
  const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
65951
65994
  if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer) && property.initializer.text.startsWith(".")) {
65952
65995
  const extendedFilePath = resolveImportedConfigFile(analysis.filePath, property.initializer.text);
@@ -65956,12 +65999,12 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
65956
65999
  } else if (ts.isShorthandPropertyAssignment(property)) {
65957
66000
  if (excludedPropertyNames?.has(property.name.text)) continue;
65958
66001
  if (property.name.text === "reactCompiler") continue;
65959
- if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$1(laterProperty.name) === property.name.text)) continue;
66002
+ if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === property.name.text)) continue;
65960
66003
  const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
65961
66004
  if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
65962
66005
  } else if (ts.isSpreadAssignment(property)) {
65963
66006
  if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
65964
- if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$1(laterProperty.name) === "plugins" || getStaticPropertyName$1(laterProperty.name) === "presets"))) continue;
66007
+ if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$2(laterProperty.name) === "plugins" || getStaticPropertyName$2(laterProperty.name) === "presets"))) continue;
65965
66008
  if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
65966
66009
  }
65967
66010
  return false;
@@ -65974,9 +66017,11 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
65974
66017
  });
65975
66018
  }
65976
66019
  if (ts.isCallExpression(node)) {
66020
+ const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
66021
+ if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
65977
66022
  const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
65978
66023
  if (callTargetResult !== null) return callTargetResult;
65979
- const directModuleSpecifier = getRequireModuleSpecifier(node);
66024
+ const directModuleSpecifier = getRequireModuleSpecifier$1(node);
65980
66025
  const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
65981
66026
  if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
65982
66027
  if (directModuleSpecifier && !isRequireShadowed) {
@@ -65998,7 +66043,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
65998
66043
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
65999
66044
  }
66000
66045
  if (ts.isPropertyAccessExpression(node)) {
66001
- const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
66046
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
66002
66047
  if (requiredModuleSpecifier) {
66003
66048
  if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
66004
66049
  if (requiredModuleSpecifier.startsWith(".")) {
@@ -69335,7 +69380,7 @@ const warn = (message) => {
69335
69380
  runSync(warn$1(message));
69336
69381
  };
69337
69382
  const CONFIG_BASENAME = "doctor.config";
69338
- const CONFIG_EXTENSIONS = [
69383
+ const CONFIG_EXTENSIONS$1 = [
69339
69384
  "ts",
69340
69385
  "mts",
69341
69386
  "cts",
@@ -69439,7 +69484,7 @@ const loadLegacyConfig = (directory) => {
69439
69484
  };
69440
69485
  const loadConfigFromDirectory = async (directory) => {
69441
69486
  let sawBrokenConfigFile = false;
69442
- for (const extension of CONFIG_EXTENSIONS) {
69487
+ for (const extension of CONFIG_EXTENSIONS$1) {
69443
69488
  const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
69444
69489
  if (!isFile(filePath)) continue;
69445
69490
  const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
@@ -69498,7 +69543,7 @@ const loadConfigWithSource = (rootDirectory) => {
69498
69543
  return loadPromise;
69499
69544
  };
69500
69545
  const directoryHasCurrentConfig = (directory) => {
69501
- for (const extension of CONFIG_EXTENSIONS) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
69546
+ for (const extension of CONFIG_EXTENSIONS$1) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
69502
69547
  return readEmbeddedPackageJsonConfig(directory) !== null;
69503
69548
  };
69504
69549
  /**
@@ -70202,6 +70247,321 @@ const buildReactNativeDiagnostic = (input) => ({
70202
70247
  column: input.column ?? 0,
70203
70248
  category: input.category ?? "Correctness"
70204
70249
  });
70250
+ const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
70251
+ const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
70252
+ const RELEASE_STRING_MARKER = "__RD_RELEASE__";
70253
+ const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
70254
+ const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
70255
+ const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
70256
+ const stripGradleComments = (contents) => {
70257
+ let result = "";
70258
+ let index = 0;
70259
+ let quote = null;
70260
+ while (index < contents.length) {
70261
+ const character = contents[index];
70262
+ const nextCharacter = contents[index + 1];
70263
+ if (quote !== null) {
70264
+ result += character;
70265
+ if (character === "\\") {
70266
+ result += nextCharacter ?? "";
70267
+ index += 2;
70268
+ continue;
70269
+ }
70270
+ if (character === quote) quote = null;
70271
+ index += 1;
70272
+ continue;
70273
+ }
70274
+ if (character === "\"" || character === "'") {
70275
+ quote = character;
70276
+ result += character;
70277
+ index += 1;
70278
+ continue;
70279
+ }
70280
+ if (character === "/" && nextCharacter === "/") {
70281
+ while (index < contents.length && contents[index] !== "\n") {
70282
+ result += " ";
70283
+ index += 1;
70284
+ }
70285
+ continue;
70286
+ }
70287
+ if (character === "/" && nextCharacter === "*") {
70288
+ result += " ";
70289
+ index += 2;
70290
+ while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
70291
+ result += contents[index] === "\n" ? "\n" : " ";
70292
+ index += 1;
70293
+ }
70294
+ if (index < contents.length) {
70295
+ result += " ";
70296
+ index += 2;
70297
+ }
70298
+ continue;
70299
+ }
70300
+ result += character;
70301
+ index += 1;
70302
+ }
70303
+ return result;
70304
+ };
70305
+ const maskGradleStrings = (contents) => {
70306
+ let result = "";
70307
+ let index = 0;
70308
+ let quote = null;
70309
+ while (index < contents.length) {
70310
+ const character = contents[index];
70311
+ if (quote === null) {
70312
+ if (character === "\"" || character === "'") {
70313
+ quote = character;
70314
+ result += " ";
70315
+ } else result += character;
70316
+ index += 1;
70317
+ continue;
70318
+ }
70319
+ if (character === "\\") {
70320
+ result += " ";
70321
+ index += 2;
70322
+ continue;
70323
+ }
70324
+ if (character === quote) quote = null;
70325
+ result += character === "\n" ? "\n" : " ";
70326
+ index += 1;
70327
+ }
70328
+ return result;
70329
+ };
70330
+ const findBlockContents = (contents, pattern) => {
70331
+ const blocks = [];
70332
+ pattern.lastIndex = 0;
70333
+ let match = pattern.exec(contents);
70334
+ while (match !== null) {
70335
+ const openingBraceIndex = pattern.lastIndex - 1;
70336
+ let depth = 1;
70337
+ let index = openingBraceIndex + 1;
70338
+ let quote = null;
70339
+ while (index < contents.length && depth > 0) {
70340
+ const character = contents[index];
70341
+ if (quote !== null) {
70342
+ if (character === "\\") {
70343
+ index += 2;
70344
+ continue;
70345
+ }
70346
+ if (character === quote) quote = null;
70347
+ } else if (character === "\"" || character === "'") quote = character;
70348
+ else if (character === "{") depth += 1;
70349
+ else if (character === "}") depth -= 1;
70350
+ index += 1;
70351
+ }
70352
+ if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
70353
+ match = pattern.exec(contents);
70354
+ }
70355
+ return blocks;
70356
+ };
70357
+ const getFinalStaticBoolean = (contents, pattern) => {
70358
+ pattern.lastIndex = 0;
70359
+ let finalValue = null;
70360
+ let match = pattern.exec(contents);
70361
+ while (match !== null) {
70362
+ const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
70363
+ if (staticValue === "true") finalValue = true;
70364
+ else if (staticValue === "false") finalValue = false;
70365
+ else finalValue = null;
70366
+ match = pattern.exec(contents);
70367
+ }
70368
+ return finalValue;
70369
+ };
70370
+ const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
70371
+ const readAndroidReleaseShrinking = (rootDirectory) => {
70372
+ for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
70373
+ const filePath = Path.posix.join("android", "app", buildFileName);
70374
+ const absoluteFilePath = Path.join(rootDirectory, filePath);
70375
+ if (!isFile(absoluteFilePath)) continue;
70376
+ let contents;
70377
+ try {
70378
+ contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
70379
+ } catch {
70380
+ return null;
70381
+ }
70382
+ const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
70383
+ const [releaseBlock] = releaseBlocks;
70384
+ if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
70385
+ const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
70386
+ const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
70387
+ if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
70388
+ return {
70389
+ filePath,
70390
+ hasDisabledMinification,
70391
+ hasDisabledResourceShrinking
70392
+ };
70393
+ }
70394
+ return null;
70395
+ };
70396
+ const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
70397
+ const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
70398
+ if (releaseShrinking === null) return [];
70399
+ const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
70400
+ return [buildReactNativeDiagnostic({
70401
+ filePath: releaseShrinking.filePath,
70402
+ rule: "rn-android-release-shrinking-disabled",
70403
+ category: "Performance",
70404
+ message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
70405
+ help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
70406
+ })];
70407
+ };
70408
+ const getTypescriptScriptKind = (fileName) => {
70409
+ if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
70410
+ if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
70411
+ if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
70412
+ return ts.ScriptKind.JS;
70413
+ };
70414
+ const unwrapTypescriptExpression = (expression) => {
70415
+ let currentExpression = expression;
70416
+ while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
70417
+ return currentExpression;
70418
+ };
70419
+ const BABEL_CONFIG_FILE_NAMES$1 = [
70420
+ "babel.config.js",
70421
+ "babel.config.cjs",
70422
+ "babel.config.mjs",
70423
+ "babel.config.ts",
70424
+ "babel.config.cts",
70425
+ "babel.config.json",
70426
+ ".babelrc",
70427
+ ".babelrc.js",
70428
+ ".babelrc.cjs",
70429
+ ".babelrc.mjs",
70430
+ ".babelrc.cts",
70431
+ ".babelrc.json"
70432
+ ];
70433
+ const readUnknownPluginNames = (value) => {
70434
+ if (!Array.isArray(value)) return null;
70435
+ const pluginNames = [];
70436
+ for (const entry of value) {
70437
+ if (typeof entry === "string") {
70438
+ pluginNames.push(entry);
70439
+ continue;
70440
+ }
70441
+ if (Array.isArray(entry) && typeof entry[0] === "string") {
70442
+ pluginNames.push(entry[0]);
70443
+ continue;
70444
+ }
70445
+ return null;
70446
+ }
70447
+ return pluginNames;
70448
+ };
70449
+ const getStaticPropertyName$1 = (propertyName) => {
70450
+ if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
70451
+ return null;
70452
+ };
70453
+ const getStaticPluginName = (expression) => {
70454
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
70455
+ if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
70456
+ if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
70457
+ const pluginExpression = unwrappedExpression.elements[0];
70458
+ return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
70459
+ };
70460
+ const getPluginNamesFromObject = (objectExpression) => {
70461
+ if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
70462
+ const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
70463
+ if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
70464
+ const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
70465
+ if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
70466
+ const pluginNames = [];
70467
+ for (const element of pluginListExpression.elements) {
70468
+ if (ts.isSpreadElement(element)) return null;
70469
+ const pluginName = getStaticPluginName(element);
70470
+ if (pluginName === null) return null;
70471
+ pluginNames.push(pluginName);
70472
+ }
70473
+ return pluginNames;
70474
+ };
70475
+ const isModuleExports = (expression) => ts.isPropertyAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.name.text === "exports" || ts.isElementAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.argumentExpression !== void 0 && ts.isStringLiteralLike(expression.argumentExpression) && expression.argumentExpression.text === "exports";
70476
+ const getDirectExportedObject = (sourceFile) => {
70477
+ const exportedExpressions = [];
70478
+ for (const statement of sourceFile.statements) {
70479
+ if (ts.isExportAssignment(statement)) {
70480
+ exportedExpressions.push(statement.expression);
70481
+ continue;
70482
+ }
70483
+ if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
70484
+ }
70485
+ if (exportedExpressions.length !== 1) return null;
70486
+ const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
70487
+ return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
70488
+ };
70489
+ const parseConfigPluginNames = (filePath, contents) => {
70490
+ try {
70491
+ const parsedJson = JSON.parse(contents);
70492
+ return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
70493
+ } catch {
70494
+ if (ts.transpileModule(contents, {
70495
+ fileName: filePath,
70496
+ reportDiagnostics: true,
70497
+ compilerOptions: { allowJs: true }
70498
+ }).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
70499
+ const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
70500
+ return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
70501
+ }
70502
+ };
70503
+ const readStaticBabelPluginNames = (rootDirectory) => {
70504
+ for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
70505
+ const absoluteFilePath = Path.join(rootDirectory, fileName);
70506
+ if (!isFile(absoluteFilePath)) continue;
70507
+ try {
70508
+ return {
70509
+ filePath: fileName,
70510
+ pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
70511
+ };
70512
+ } catch {
70513
+ return {
70514
+ filePath: fileName,
70515
+ pluginNames: null
70516
+ };
70517
+ }
70518
+ }
70519
+ const packageJson = readPackageJson$1(Path.join(rootDirectory, "package.json"));
70520
+ if (!isPlainObject(packageJson.babel)) return null;
70521
+ return {
70522
+ filePath: "package.json",
70523
+ pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
70524
+ };
70525
+ };
70526
+ const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
70527
+ const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
70528
+ const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
70529
+ const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
70530
+ if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
70531
+ return [buildReactNativeDiagnostic({
70532
+ filePath,
70533
+ rule: "rn-react-compiler-plugin-first",
70534
+ category: "Performance",
70535
+ message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
70536
+ help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
70537
+ })];
70538
+ };
70539
+ const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
70540
+ const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
70541
+ if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
70542
+ const diagnostics = [];
70543
+ if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
70544
+ filePath,
70545
+ rule: "rn-reanimated-worklets-plugin-last",
70546
+ category: "Performance",
70547
+ message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
70548
+ help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
70549
+ }));
70550
+ const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
70551
+ if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
70552
+ filePath,
70553
+ rule: "rn-reanimated-worklets-plugin-last",
70554
+ category: "Performance",
70555
+ message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
70556
+ help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
70557
+ }));
70558
+ return diagnostics;
70559
+ };
70560
+ const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
70561
+ const babelPlugins = readStaticBabelPluginNames(rootDirectory);
70562
+ if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
70563
+ return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
70564
+ };
70205
70565
  const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
70206
70566
  const isBuilderBobLibrary = (packageJson) => {
70207
70567
  const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
@@ -70278,7 +70638,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
70278
70638
  const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
70279
70639
  const checkReactNativeProject = (rootDirectory, project) => {
70280
70640
  if (!isReactNativeProject(project)) return [];
70281
- return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
70641
+ return [
70642
+ ...checkReactNativeMetroBabelPreset(rootDirectory),
70643
+ ...checkReactNativeBabelPluginOrder(rootDirectory, project),
70644
+ ...checkReactNativeAndroidReleaseShrinking(rootDirectory),
70645
+ ...checkReactNativeLibraryDependencies(rootDirectory)
70646
+ ];
70282
70647
  };
70283
70648
  const RULE_KEY = "no-vulnerable-react-server-components";
70284
70649
  const REACT_RSC_ADVISORIES_BY_MINOR = {
@@ -70429,17 +70794,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
70429
70794
  }
70430
70795
  return diagnostics;
70431
70796
  };
70432
- const getTypescriptScriptKind = (fileName) => {
70433
- if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
70434
- if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
70435
- if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
70436
- return ts.ScriptKind.JS;
70437
- };
70438
- const unwrapTypescriptExpression = (expression) => {
70439
- let currentExpression = expression;
70440
- while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
70441
- return currentExpression;
70442
- };
70443
70797
  const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
70444
70798
  isAnimationFunction: false,
70445
70799
  isMotionComponent: false,
@@ -70995,7 +71349,11 @@ const buildCapabilities = (project) => {
70995
71349
  capabilities.add(project.framework);
70996
71350
  if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
70997
71351
  if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
70998
- if (project.expoVersion !== null) capabilities.add("expo");
71352
+ if (project.expoVersion !== null) {
71353
+ capabilities.add("expo");
71354
+ const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
71355
+ if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
71356
+ }
70999
71357
  if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
71000
71358
  if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
71001
71359
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
@@ -71059,6 +71417,11 @@ const buildCapabilities = (project) => {
71059
71417
  if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
71060
71418
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
71061
71419
  if (project.hasReactCompiler) capabilities.add("react-compiler");
71420
+ if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
71421
+ capabilities.add("reanimated");
71422
+ const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
71423
+ if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
71424
+ }
71062
71425
  if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
71063
71426
  if (project.styledComponentsVersion) {
71064
71427
  capabilities.add("styled-components");
@@ -72972,7 +73335,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
72972
73335
  const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
72973
73336
  const normalizeConfigForHash = (config) => {
72974
73337
  const clone = JSON.parse(JSON.stringify(config));
72975
- if (clone?.settings?.["react-doctor"]) clone.settings["react-doctor"].rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
73338
+ if (clone?.settings?.["react-doctor"]) {
73339
+ const reactDoctorSettings = clone.settings["react-doctor"];
73340
+ reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
73341
+ if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
73342
+ }
72976
73343
  if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
72977
73344
  return clone;
72978
73345
  };
@@ -73131,13 +73498,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
73131
73498
  }
73132
73499
  return enabled;
73133
73500
  };
73134
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
73501
+ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, runtimeGlobals, unpluginAutoImportGlobalScopes, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
73135
73502
  const hasIncludedTags = includedTags.size > 0;
73136
73503
  const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
73137
73504
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
73138
73505
  const jsPlugins = [];
73139
73506
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
73140
73507
  const capabilities = getCapabilities(project);
73508
+ const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
73141
73509
  const enabledReactDoctorRules = {};
73142
73510
  for (const registryEntry of REACT_DOCTOR_RULES) {
73143
73511
  const rule = reactDoctorPlugin.rules[registryEntry.id];
@@ -73183,8 +73551,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
73183
73551
  jsPlugins: [...jsPlugins, pluginPath],
73184
73552
  settings: { "react-doctor": {
73185
73553
  framework: project.framework,
73186
- rootDirectory: resolveSettingsRootDirectory(project.rootDirectory),
73554
+ rootDirectory: settingsRootDirectory,
73187
73555
  capabilities: [...capabilities].sort(),
73556
+ ...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
73557
+ ...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
73558
+ unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
73559
+ unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
73560
+ directory: scope.directory,
73561
+ names: [...scope.names]
73562
+ }))
73563
+ } : {},
73188
73564
  ...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
73189
73565
  ...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
73190
73566
  } },
@@ -73195,6 +73571,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
73195
73571
  }
73196
73572
  };
73197
73573
  };
73574
+ const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
73575
+ const CONFIG_BASENAMES = [
73576
+ "astro.config",
73577
+ "esbuild.config",
73578
+ "rollup.config",
73579
+ "rolldown.config",
73580
+ "rspack.config",
73581
+ "vite.config",
73582
+ "webpack.config"
73583
+ ];
73584
+ const CONFIG_EXTENSIONS = [
73585
+ ".cjs",
73586
+ ".cts",
73587
+ ".js",
73588
+ ".mjs",
73589
+ ".mts",
73590
+ ".ts"
73591
+ ];
73592
+ const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
73593
+ const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
73594
+ const SUPPORTED_GLOBAL_VALUES = new Set([
73595
+ true,
73596
+ false,
73597
+ "readable",
73598
+ "readonly",
73599
+ "writable",
73600
+ "writeable"
73601
+ ]);
73602
+ const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
73603
+ if (ts.isSpreadAssignment(property)) return false;
73604
+ const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
73605
+ return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
73606
+ }) ?? null;
73607
+ const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
73608
+ const getStaticPropertyAssignment = (objectExpression, propertyName) => {
73609
+ const property = getStaticProperty(objectExpression, propertyName);
73610
+ return property && ts.isPropertyAssignment(property) ? property : null;
73611
+ };
73612
+ const getRequireModuleSpecifier = (expression) => {
73613
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
73614
+ if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
73615
+ if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
73616
+ const moduleSpecifier = unwrappedExpression.arguments[0];
73617
+ return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
73618
+ };
73619
+ const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
73620
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
73621
+ return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
73622
+ };
73623
+ const isCommonJsExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
73624
+ const isTopLevelExpression = (node) => {
73625
+ let ancestor = node.parent;
73626
+ while (ancestor && !ts.isSourceFile(ancestor)) {
73627
+ if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
73628
+ if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
73629
+ ancestor = ancestor.parent;
73630
+ }
73631
+ return false;
73632
+ };
73633
+ const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
73634
+ let ancestor = node.parent;
73635
+ let didFindConfigProperty = false;
73636
+ while (ancestor && !ts.isSourceFile(ancestor)) {
73637
+ if (!didFindConfigProperty && !ts.isArrayLiteralExpression(ancestor) && !ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isPropertyAssignment(ancestor)) return false;
73638
+ if (ts.isPropertyAssignment(ancestor)) {
73639
+ const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
73640
+ if (didFindConfigProperty || !isConfigProperty) return false;
73641
+ if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
73642
+ didFindConfigProperty = true;
73643
+ ancestor = ancestor.parent;
73644
+ continue;
73645
+ }
73646
+ if (didFindConfigProperty) {
73647
+ if (ts.isExportAssignment(ancestor)) return true;
73648
+ if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
73649
+ if (propertyName === "plugins" && ts.isCallExpression(ancestor) && (ts.isIdentifier(ancestor.expression) ? esbuildBindings.has(ancestor.expression.text) : ts.isPropertyAccessExpression(ancestor.expression) && ancestor.expression.name.text === "build" && (ts.isIdentifier(ancestor.expression.expression) && esbuildNamespaceBindings.has(ancestor.expression.expression.text) || getRequireModuleSpecifier(ancestor.expression.expression) === "esbuild"))) return isTopLevelExpression(ancestor);
73650
+ if (!(ts.isObjectLiteralExpression(ancestor) || ts.isParenthesizedExpression(ancestor) || ts.isAsExpression(ancestor) || ts.isSatisfiesExpression(ancestor) || ts.isNonNullExpression(ancestor) || ts.isTypeAssertionExpression(ancestor) || ts.isCallExpression(ancestor) && ts.isIdentifier(ancestor.expression) && ancestor.expression.text === "defineConfig")) return false;
73651
+ }
73652
+ ancestor = ancestor.parent;
73653
+ }
73654
+ return false;
73655
+ };
73656
+ const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
73657
+ const optionsExpression = callExpression.arguments[0];
73658
+ if (!optionsExpression) return null;
73659
+ const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
73660
+ if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
73661
+ if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
73662
+ if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
73663
+ const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
73664
+ if (!eslintrcProperty) return null;
73665
+ const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
73666
+ if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
73667
+ if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
73668
+ const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
73669
+ if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
73670
+ const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
73671
+ if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
73672
+ if (!ts.isPropertyAssignment(filepathProperty)) return null;
73673
+ const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
73674
+ return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
73675
+ };
73676
+ const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
73677
+ let sourceText;
73678
+ try {
73679
+ sourceText = NFS.readFileSync(configPath, "utf8");
73680
+ } catch {
73681
+ return {
73682
+ didFindActiveAutoImport: false,
73683
+ globalsPaths: []
73684
+ };
73685
+ }
73686
+ const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
73687
+ const autoImportBindings = /* @__PURE__ */ new Map();
73688
+ const esbuildBindings = /* @__PURE__ */ new Set();
73689
+ const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
73690
+ for (const statement of sourceFile.statements) {
73691
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
73692
+ const moduleSpecifier = statement.moduleSpecifier.text;
73693
+ if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
73694
+ const defaultBinding = statement.importClause?.name;
73695
+ if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
73696
+ }
73697
+ if (moduleSpecifier === "esbuild") {
73698
+ const defaultBinding = statement.importClause?.name;
73699
+ if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
73700
+ const namedBindings = statement.importClause?.namedBindings;
73701
+ if (namedBindings && ts.isNamedImports(namedBindings)) {
73702
+ for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
73703
+ }
73704
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
73705
+ }
73706
+ }
73707
+ if (!ts.isVariableStatement(statement)) continue;
73708
+ for (const declaration of statement.declarationList.declarations) {
73709
+ if (!declaration.initializer) continue;
73710
+ const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
73711
+ const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
73712
+ if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
73713
+ if (moduleSpecifier === "esbuild") {
73714
+ if (declarationName) esbuildNamespaceBindings.add(declarationName);
73715
+ if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
73716
+ const importedName = bindingElement.propertyName ?? bindingElement.name;
73717
+ if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
73718
+ }
73719
+ }
73720
+ if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
73721
+ }
73722
+ }
73723
+ const globalsPaths = /* @__PURE__ */ new Set();
73724
+ let didFindActiveAutoImport = false;
73725
+ let didFindUnsafeActiveAutoImport = false;
73726
+ const visit = (node) => {
73727
+ if (ts.isCallExpression(node)) {
73728
+ const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
73729
+ if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
73730
+ if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
73731
+ didFindActiveAutoImport = true;
73732
+ const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
73733
+ if (globalsPath) globalsPaths.add(globalsPath);
73734
+ else didFindUnsafeActiveAutoImport = true;
73735
+ }
73736
+ }
73737
+ }
73738
+ ts.forEachChild(node, visit);
73739
+ };
73740
+ visit(sourceFile);
73741
+ return {
73742
+ didFindActiveAutoImport,
73743
+ globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
73744
+ };
73745
+ };
73746
+ const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
73747
+ const relativePath = Path.relative(rootDirectory, globalsPath);
73748
+ if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
73749
+ const parsed = failOpenReadJson(globalsPath, null);
73750
+ if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
73751
+ return Object.entries(parsed.globals).filter((entry) => entry[0].length > 0 && (typeof entry[1] === "boolean" || typeof entry[1] === "string") && SUPPORTED_GLOBAL_VALUES.has(entry[1])).map(([name]) => name).sort();
73752
+ };
73753
+ const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
73754
+ let currentDirectory = Path.dirname(absoluteFilePath);
73755
+ const visitedDirectories = [];
73756
+ while (true) {
73757
+ const cachedDirectory = cache.get(currentDirectory);
73758
+ if (cachedDirectory !== void 0) {
73759
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
73760
+ return cachedDirectory;
73761
+ }
73762
+ const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
73763
+ if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
73764
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
73765
+ return null;
73766
+ }
73767
+ visitedDirectories.push(currentDirectory);
73768
+ if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
73769
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
73770
+ return currentDirectory;
73771
+ }
73772
+ if (currentDirectory === rootDirectory) {
73773
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
73774
+ return null;
73775
+ }
73776
+ currentDirectory = Path.dirname(currentDirectory);
73777
+ }
73778
+ };
73779
+ const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
73780
+ let directoryEntries;
73781
+ try {
73782
+ directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
73783
+ } catch {
73784
+ return [];
73785
+ }
73786
+ const configuredGlobalsPaths = [];
73787
+ for (const entry of directoryEntries) {
73788
+ if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
73789
+ const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
73790
+ if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
73791
+ }
73792
+ if (configuredGlobalsPaths.length === 0) return [];
73793
+ const globalsPaths = configuredGlobalsPaths[0];
73794
+ if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
73795
+ const names = /* @__PURE__ */ new Set();
73796
+ for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
73797
+ return [...names].sort();
73798
+ };
73799
+ const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
73800
+ const absoluteRootDirectory = Path.resolve(rootDirectory);
73801
+ const packageDirectoryCache = /* @__PURE__ */ new Map();
73802
+ const packageDirectories = /* @__PURE__ */ new Set();
73803
+ for (const candidateFile of candidateFiles) {
73804
+ const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
73805
+ if (packageDirectory) packageDirectories.add(packageDirectory);
73806
+ }
73807
+ const scopes = [...packageDirectories].map((packageDirectory) => ({
73808
+ directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
73809
+ names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
73810
+ })).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
73811
+ return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
73812
+ };
73198
73813
  const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
73199
73814
  const decodeFileDiagnostics = (raw) => {
73200
73815
  if (!Array.isArray(raw)) return null;
@@ -73517,6 +74132,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
73517
74132
  if (!help) return REANIMATED_SHARED_VALUE_HINT;
73518
74133
  return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
73519
74134
  };
74135
+ const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
74136
+ const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
74137
+ let lineStartOffset = boundedOffset;
74138
+ while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
74139
+ return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
74140
+ };
73520
74141
  const REDACTED_PLACEHOLDER = "<redacted>";
73521
74142
  const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
73522
74143
  const KNOWN_SECRET_RULES = [
@@ -74232,7 +74853,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
74232
74853
  * with empty text still carry a useful jump target, so they're kept
74233
74854
  * with a neutral message.
74234
74855
  */
74235
- const buildRelatedLocations = (labels, filePath) => {
74856
+ const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
74236
74857
  if (labels.length <= 1) return [];
74237
74858
  const related = [];
74238
74859
  for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
@@ -74240,8 +74861,8 @@ const buildRelatedLocations = (labels, filePath) => {
74240
74861
  if (!label?.span) continue;
74241
74862
  related.push({
74242
74863
  filePath,
74243
- line: label.span.line ?? 0,
74244
- column: label.span.column ?? 0,
74864
+ line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
74865
+ column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
74245
74866
  offset: label.span.offset,
74246
74867
  length: label.span.length,
74247
74868
  message: label.label ?? ""
@@ -74261,7 +74882,7 @@ const isOxlintOutput = (value) => isRecord$1(value) && Array.isArray(value.diagn
74261
74882
  * to the first `{`. Raises `OxlintOutputUnparseable` when the
74262
74883
  * stdout isn't valid JSON or doesn't carry a `diagnostics` array.
74263
74884
  */
74264
- const parseOxlintOutput = (stdout, project, rootDirectory) => {
74885
+ const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
74265
74886
  if (!stdout) return [];
74266
74887
  const jsonStart = stdout.indexOf("{");
74267
74888
  const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
@@ -74278,8 +74899,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
74278
74899
  const sourceBufferCache = /* @__PURE__ */ new Map();
74279
74900
  const sourceLinesCache = /* @__PURE__ */ new Map();
74280
74901
  const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
74902
+ const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
74903
+ const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
74281
74904
  const readSourceBuffer = (filename) => {
74282
- const absolutePath = resolveAbsolutePath(filename);
74905
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
74283
74906
  const cached = sourceBufferCache.get(absolutePath);
74284
74907
  if (cached !== void 0) return cached;
74285
74908
  let sourceBuffer;
@@ -74292,7 +74915,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
74292
74915
  return sourceBuffer;
74293
74916
  };
74294
74917
  const readSourceLines = (filename) => {
74295
- const absolutePath = resolveAbsolutePath(filename);
74918
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
74296
74919
  const cached = sourceLinesCache.get(absolutePath);
74297
74920
  if (cached !== void 0) return cached;
74298
74921
  const sourceBuffer = readSourceBuffer(filename);
@@ -74301,27 +74924,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
74301
74924
  return sourceLines;
74302
74925
  };
74303
74926
  const isMinifiedDiagnosticFile = (filename) => {
74304
- const absolutePath = resolveAbsolutePath(filename);
74927
+ const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
74305
74928
  const cached = minifiedFileCache.get(absolutePath);
74306
74929
  if (cached !== void 0) return cached;
74307
74930
  const minified = isMinifiedSource(absolutePath);
74308
74931
  minifiedFileCache.set(absolutePath, minified);
74309
74932
  return minified;
74310
74933
  };
74311
- return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
74934
+ return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
74312
74935
  const { plugin, rule } = parseRuleCode(diagnostic.code);
74313
74936
  const primaryLabel = diagnostic.labels[0];
74314
74937
  const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
74315
- const normalizedFilePath = diagnostic.filename.replaceAll("\\", "/");
74938
+ const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
74939
+ const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
74316
74940
  const primarySpan = primaryLabel?.span;
74317
74941
  const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
74318
- const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
74942
+ const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
74319
74943
  const category = resolveDiagnosticCategory(plugin, rule);
74320
74944
  const matchByOccurrence = resolveMatchByOccurrence(rule, category);
74321
74945
  const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
74322
- const primaryLineIndex = primarySpan ? primarySpan.line - 1 : -1;
74946
+ const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
74947
+ const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
74948
+ const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
74323
74949
  const primaryLine = sourceLines?.[primaryLineIndex];
74324
- const primaryColumnIndex = primarySpan ? primarySpan.column - 1 : -1;
74950
+ const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
74325
74951
  const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
74326
74952
  const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
74327
74953
  const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
@@ -74334,8 +74960,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
74334
74960
  message: cleaned.message,
74335
74961
  help: cleaned.help,
74336
74962
  url: diagnostic.url,
74337
- line: primarySpan?.line ?? 0,
74338
- column: primarySpan?.column ?? 0,
74963
+ line: primaryLineNumber,
74964
+ column: primaryColumnNumber,
74339
74965
  ...primarySpan ? {
74340
74966
  offset: primarySpan.offset,
74341
74967
  length: primarySpan.length,
@@ -74523,7 +75149,11 @@ const isParallelismRelatedSpawnError = (error) => {
74523
75149
  * loop with a slimmer config in that case.
74524
75150
  */
74525
75151
  const spawnLintBatches = async (input) => {
74526
- const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
75152
+ const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
75153
+ const resolveSourcePath = (filePath) => {
75154
+ const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
75155
+ return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
75156
+ };
74527
75157
  const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
74528
75158
  let rescueDeadlineEpochMs;
74529
75159
  const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
@@ -74543,7 +75173,7 @@ const spawnLintBatches = async (input) => {
74543
75173
  }
74544
75174
  const batchArgs = [...baseArgs, ...batch];
74545
75175
  try {
74546
- return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
75176
+ return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
74547
75177
  } catch (error) {
74548
75178
  if (!isSplittableReactDoctorError(error)) throw error;
74549
75179
  if (isPastDeadline()) {
@@ -74649,10 +75279,12 @@ const spawnLintBatches = async (input) => {
74649
75279
  onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
74650
75280
  };
74651
75281
  const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
74652
- reportSkippedFiles(droppedFiles, (fileListPreview) => `${droppedFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
74653
- reportSkippedFiles(outcome.deadlineSkippedFiles, (fileListPreview) => `${outcome.deadlineSkippedFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
75282
+ const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
75283
+ const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
75284
+ reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
75285
+ reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
74654
75286
  const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
74655
- input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
75287
+ input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
74656
75288
  return dedupeDiagnostics(diagnostics);
74657
75289
  };
74658
75290
  let didValidate = false;
@@ -74751,6 +75383,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
74751
75383
  }
74752
75384
  return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
74753
75385
  };
75386
+ const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
75387
+ const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
75388
+ const COMMENT_OPEN = "<!--";
75389
+ const COMMENT_CLOSE = "-->";
75390
+ const FRONTMATTER_FENCE = "---";
75391
+ const SCRIPT_TAG_NAME = "script";
75392
+ const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
75393
+ const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
75394
+ const TEMPLATE_TAG_NAME = "template";
75395
+ const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
75396
+ const JAVASCRIPT_MIME_TYPES = new Set([
75397
+ "application/ecmascript",
75398
+ "application/javascript",
75399
+ "application/x-ecmascript",
75400
+ "application/x-javascript",
75401
+ "text/ecmascript",
75402
+ "text/javascript",
75403
+ "text/javascript1.0",
75404
+ "text/javascript1.1",
75405
+ "text/javascript1.2",
75406
+ "text/javascript1.3",
75407
+ "text/javascript1.4",
75408
+ "text/javascript1.5",
75409
+ "text/jscript",
75410
+ "text/livescript",
75411
+ "text/x-ecmascript",
75412
+ "text/x-javascript"
75413
+ ]);
75414
+ const RAW_TEXT_TAG_NAMES = new Set([
75415
+ "iframe",
75416
+ "noembed",
75417
+ "noframes",
75418
+ "noscript",
75419
+ "style",
75420
+ "textarea",
75421
+ "title",
75422
+ "xmp"
75423
+ ]);
75424
+ const PLAINTEXT_TAG_NAME = "plaintext";
75425
+ const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
75426
+ const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
75427
+ const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
75428
+ const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
75429
+ const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
75430
+ const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
75431
+ const TAB_UTF8_BYTE = " ".charCodeAt(0);
75432
+ const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
75433
+ const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
75434
+ const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
75435
+ if (startByte + expected.length > sourceBuffer.length) return false;
75436
+ for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
75437
+ const sourceByte = sourceBuffer[startByte + expectedIndex];
75438
+ if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
75439
+ }
75440
+ return true;
75441
+ };
75442
+ const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
75443
+ const isPotentialTagStart = (byte) => {
75444
+ if (byte === void 0) return false;
75445
+ return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
75446
+ };
75447
+ const findLineEnd = (sourceBuffer, lineStartByte) => {
75448
+ let byteIndex = lineStartByte;
75449
+ while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
75450
+ return byteIndex;
75451
+ };
75452
+ const findNextLineStart = (sourceBuffer, lineStartByte) => {
75453
+ const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
75454
+ if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
75455
+ return Math.min(lineEndByte + 1, sourceBuffer.length);
75456
+ };
75457
+ const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
75458
+ if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
75459
+ const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
75460
+ for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
75461
+ return true;
75462
+ };
75463
+ const findFrontmatterEnd = (sourceBuffer) => {
75464
+ if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
75465
+ const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
75466
+ let lineStartByte = findNextLineStart(sourceBuffer, 0);
75467
+ while (lineStartByte < sourceBuffer.length) {
75468
+ if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
75469
+ lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
75470
+ }
75471
+ return openingFenceEndByte;
75472
+ };
75473
+ const maskByteRange = (maskedBuffer, startByte, endByte) => {
75474
+ for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
75475
+ const byte = maskedBuffer[byteIndex];
75476
+ if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
75477
+ }
75478
+ };
75479
+ const readStartTagName = (sourceBuffer, tagStartByte) => {
75480
+ const firstNameByte = sourceBuffer[tagStartByte + 1];
75481
+ if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
75482
+ let nameEndByte = tagStartByte + 2;
75483
+ while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
75484
+ return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
75485
+ };
75486
+ const findTagEnd = (sourceBuffer, startByte) => {
75487
+ let quoteByte = null;
75488
+ for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
75489
+ const byte = sourceBuffer[byteIndex];
75490
+ if (quoteByte !== null) {
75491
+ if (byte === quoteByte) quoteByte = null;
75492
+ continue;
75493
+ }
75494
+ if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
75495
+ quoteByte = byte;
75496
+ continue;
75497
+ }
75498
+ if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
75499
+ }
75500
+ return sourceBuffer.length;
75501
+ };
75502
+ const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
75503
+ let byteIndex = attributesStartByte;
75504
+ let hasSource = false;
75505
+ let language = null;
75506
+ let scriptType = null;
75507
+ while (byteIndex < tagEndByte) {
75508
+ while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
75509
+ const attributeNameStartByte = byteIndex;
75510
+ while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
75511
+ const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
75512
+ while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
75513
+ let attributeValue = "";
75514
+ if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
75515
+ byteIndex++;
75516
+ while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
75517
+ const quoteByte = sourceBuffer[byteIndex];
75518
+ if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
75519
+ const valueStartByte = byteIndex + 1;
75520
+ byteIndex = valueStartByte;
75521
+ while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
75522
+ attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
75523
+ if (byteIndex < tagEndByte) byteIndex++;
75524
+ } else {
75525
+ const valueStartByte = byteIndex;
75526
+ while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
75527
+ attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
75528
+ }
75529
+ }
75530
+ if (attributeName === "src") hasSource = true;
75531
+ else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
75532
+ else if (attributeName === "language" && language === null) language = attributeValue;
75533
+ }
75534
+ return {
75535
+ hasSource,
75536
+ language,
75537
+ type: scriptType
75538
+ };
75539
+ };
75540
+ const isExecutableScript = (attributes) => {
75541
+ if (attributes.hasSource) return false;
75542
+ const type = attributes.type?.trim().toLowerCase() ?? "";
75543
+ if (type !== "") {
75544
+ const mimeType = type.split(";")[0]?.trim() ?? "";
75545
+ return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
75546
+ }
75547
+ const language = attributes.language?.trim().toLowerCase() ?? "";
75548
+ return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
75549
+ };
75550
+ const findElementClose = (sourceBuffer, startByte, tagName) => {
75551
+ const closeTagStart = `</${tagName}`;
75552
+ for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) if (sourceBuffer[byteIndex] === TAG_OPEN_UTF8_BYTE && matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, closeTagStart) && isTagBoundary(sourceBuffer[byteIndex + closeTagStart.length])) return byteIndex;
75553
+ return sourceBuffer.length;
75554
+ };
75555
+ const prepareHtmlScriptSource = (sourceBuffer) => {
75556
+ const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
75557
+ let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
75558
+ if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
75559
+ const executableScriptBodies = [];
75560
+ let byteIndex = frontmatterEndByte;
75561
+ let templateDepth = 0;
75562
+ while (byteIndex < sourceBuffer.length) {
75563
+ if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
75564
+ byteIndex++;
75565
+ continue;
75566
+ }
75567
+ if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
75568
+ const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
75569
+ byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
75570
+ continue;
75571
+ }
75572
+ if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
75573
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
75574
+ if (templateDepth > 0) templateDepth--;
75575
+ byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
75576
+ continue;
75577
+ }
75578
+ if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
75579
+ if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
75580
+ byteIndex++;
75581
+ continue;
75582
+ }
75583
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
75584
+ const tagName = readStartTagName(sourceBuffer, byteIndex);
75585
+ if (tagName === PLAINTEXT_TAG_NAME) break;
75586
+ if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
75587
+ if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
75588
+ const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
75589
+ if (closeTagStartByte === sourceBuffer.length) break;
75590
+ const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
75591
+ byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
75592
+ continue;
75593
+ }
75594
+ byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
75595
+ continue;
75596
+ }
75597
+ const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
75598
+ if (tagEndByte === sourceBuffer.length) break;
75599
+ const bodyStartByte = tagEndByte + 1;
75600
+ const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
75601
+ const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
75602
+ if (attributes.hasSource || templateDepth > 0) {
75603
+ maskedBuffer ??= Buffer.from(sourceBuffer);
75604
+ maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
75605
+ } else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
75606
+ if (bodyEndByte === sourceBuffer.length) break;
75607
+ const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
75608
+ byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
75609
+ }
75610
+ return {
75611
+ executableScriptBodies,
75612
+ lintBuffer: maskedBuffer ?? sourceBuffer
75613
+ };
75614
+ };
75615
+ const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
75616
+ const lintFiles = [];
75617
+ const sourcePathByLintPath = /* @__PURE__ */ new Map();
75618
+ const sizeByLintPath = /* @__PURE__ */ new Map();
75619
+ const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
75620
+ let htmlFileIndex = 0;
75621
+ let hasThreeModuleImport = false;
75622
+ for (const candidateFile of candidateFiles) {
75623
+ if (!HTML_FILE_PATTERN.test(candidateFile)) {
75624
+ lintFiles.push(candidateFile);
75625
+ continue;
75626
+ }
75627
+ const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
75628
+ const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
75629
+ const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
75630
+ if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
75631
+ const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
75632
+ NFS.writeFileSync(lintPath, lintBuffer);
75633
+ lintFiles.push(lintPath);
75634
+ sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
75635
+ sizeByLintPath.set(lintPath, sourceBuffer.length);
75636
+ hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
75637
+ htmlFileIndex++;
75638
+ }
75639
+ return {
75640
+ lintFiles,
75641
+ sourcePathByLintPath,
75642
+ sizeByLintPath,
75643
+ hasThreeModuleImport
75644
+ };
75645
+ };
74754
75646
  /**
74755
75647
  * Atomically (re)writes the generated oxlintrc.json. Used twice in
74756
75648
  * the runner: once for the primary scan, once for the
@@ -74911,6 +75803,8 @@ const reactHooksJsPluginDropNote = (error) => {
74911
75803
  const runOxlint = async (options) => {
74912
75804
  const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
74913
75805
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
75806
+ const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
75807
+ let unpluginAutoImportGlobalScopes = [];
74914
75808
  const severityControls = buildRuleSeverityControls(userConfig);
74915
75809
  validateRuleRegistration();
74916
75810
  resetManifestCaches();
@@ -74924,21 +75818,6 @@ const runOxlint = async (options) => {
74924
75818
  const pluginPath = resolvePluginPath();
74925
75819
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
74926
75820
  const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
74927
- const buildConfig = (overrides) => createOxlintConfig({
74928
- pluginPath,
74929
- project,
74930
- customRulesOnly,
74931
- extendsPaths: overrides.extendsPaths,
74932
- ignoredTags,
74933
- includedTags,
74934
- includeTagDefaults,
74935
- serverAuthFunctionNames,
74936
- severityControls,
74937
- userPlugins,
74938
- disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
74939
- ruleSelection: overrides.ruleSelection,
74940
- sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
74941
- });
74942
75821
  const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
74943
75822
  const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
74944
75823
  const configPath = Path.join(configDirectory, "oxlintrc.json");
@@ -74974,7 +75853,36 @@ const runOxlint = async (options) => {
74974
75853
  await yieldToEventLoop();
74975
75854
  const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
74976
75855
  const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
75856
+ unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
75857
+ rootDirectory,
75858
+ candidateFiles
75859
+ });
75860
+ const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
75861
+ const lintFiles = preparedHtmlSources.lintFiles;
75862
+ const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
75863
+ const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
75864
+ ...project,
75865
+ hasThree: true
75866
+ } : project;
75867
+ const buildConfig = (overrides) => createOxlintConfig({
75868
+ pluginPath,
75869
+ project: lintProject,
75870
+ customRulesOnly,
75871
+ extendsPaths: overrides.extendsPaths,
75872
+ ignoredTags,
75873
+ includedTags,
75874
+ includeTagDefaults,
75875
+ runtimeGlobals,
75876
+ unpluginAutoImportGlobalScopes,
75877
+ serverAuthFunctionNames,
75878
+ severityControls,
75879
+ userPlugins,
75880
+ disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
75881
+ ruleSelection: overrides.ruleSelection,
75882
+ sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
75883
+ });
74977
75884
  const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
75885
+ if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
74978
75886
  const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
74979
75887
  baseArgs: passBaseArgs,
74980
75888
  files: passFiles,
@@ -75003,7 +75911,8 @@ const runOxlint = async (options) => {
75003
75911
  fileBatches: passFileBatches,
75004
75912
  rootDirectory,
75005
75913
  nodeBinaryPath,
75006
- project,
75914
+ project: lintProject,
75915
+ sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
75007
75916
  onPartialFailure: reportPartialFailure,
75008
75917
  onAnalyzedFiles: (filePaths) => {
75009
75918
  analyzedFiles = filePaths;
@@ -75038,7 +75947,7 @@ const runOxlint = async (options) => {
75038
75947
  };
75039
75948
  }
75040
75949
  };
75041
- if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
75950
+ if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
75042
75951
  const rulesetHash = computeRulesetHash({
75043
75952
  config: buildConfig({
75044
75953
  extendsPaths: [],
@@ -75196,14 +76105,15 @@ const runOxlint = async (options) => {
75196
76105
  ]);
75197
76106
  }
75198
76107
  const baseArgs = makeBaseArgs(configPath);
75199
- const fileBatches = buildFileBatches(baseArgs, candidateFiles);
76108
+ const fileBatches = buildFileBatches(baseArgs, lintFiles);
75200
76109
  let analyzedFiles = [];
75201
76110
  const runBatches = () => spawnLintBatches({
75202
76111
  baseArgs,
75203
76112
  fileBatches,
75204
76113
  rootDirectory,
75205
76114
  nodeBinaryPath,
75206
- project,
76115
+ project: lintProject,
76116
+ sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
75207
76117
  onPartialFailure,
75208
76118
  onAnalyzedFiles: (filePaths) => {
75209
76119
  analyzedFiles = filePaths;
@@ -77410,7 +78320,7 @@ const makeNoopConsole = () => ({
77410
78320
  });
77411
78321
  //#endregion
77412
78322
  //#region src/cli/utils/version.ts
77413
- const VERSION = "0.9.1-dev.54ba416";
78323
+ const VERSION = "0.9.1-dev.7ee59d3";
77414
78324
  //#endregion
77415
78325
  //#region src/cli/utils/json-mode.ts
77416
78326
  let context = null;
@@ -77768,13 +78678,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
77768
78678
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
77769
78679
  * standard `SENTRY_RELEASE` override.
77770
78680
  */
77771
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.54ba416`;
78681
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.7ee59d3`;
77772
78682
  /**
77773
78683
  * Deployment environment shown in Sentry's environment filter. Defaults to
77774
78684
  * `production` for tagged releases and `development` for dev/unbuilt versions,
77775
78685
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
77776
78686
  */
77777
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.54ba416") ? "development" : "production");
78687
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.7ee59d3") ? "development" : "production");
77778
78688
  /**
77779
78689
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
77780
78690
  * (set to `0` to disable tracing) and falls back to
@@ -90439,6 +91349,7 @@ const buildScanAttributes = (input) => {
90439
91349
  rulesDisabled: ruleKeys.filter((key) => ruleOverrides[key] === "off").length,
90440
91350
  fileCount: input.result?.scannedFileCount ?? null,
90441
91351
  nonJsxFileCount: input.result?.analyzedFiles?.filter((filePath) => !JSX_FILE_PATTERN.test(filePath)).length ?? null,
91352
+ htmlFileCount: input.result?.analyzedFiles?.filter((filePath) => HTML_FILE_PATTERN.test(filePath)).length ?? null,
90442
91353
  multilineDiagnosticCount: input.result?.diagnostics.filter((diagnostic) => (diagnostic.endLine ?? diagnostic.line) > diagnostic.line).length ?? null
90443
91354
  });
90444
91355
  };
@@ -96492,7 +97403,7 @@ ${highlighter.dim("Learn more:")}
96492
97403
  ${highlighter.info(CI_URL)}
96493
97404
  `;
96494
97405
  const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
96495
- const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
97406
+ const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
96496
97407
  program.action(inspectAction);
96497
97408
  program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
96498
97409
  program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
@@ -96572,4 +97483,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
96572
97483
  export { toForwardSlashes as A, highlighter as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, isCiEnvironment as F, sync as G, mergeReactDoctorConfigs as H, DIAGNOSTIC_CATEGORY_BUCKETS as I, void_ as K, Progress as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_DETAIL_WIDTH_FRACTION as P, Reporter as R, hasLintHardFailure as S, formatFixRecipeLine as T, resolveScanTarget as U, mapWithConcurrency as V, runPromise as W, canAnimateOnboarding as _, resolveCliInspectOptions as a, buildCodeFrame as b, detectLaunchableAgents as c, launchCliAgent as d, isShareOptedOut as f, doctorFace as g, easeOutCubic as h, selectProjects as i, findNearestPackageDirectory as j, recordCount as k, CLI_AGENT_BINARIES as l, printFooter as m, shouldFailScanGate as n, countUniqueScannedFiles as o, inspect as p, succeed$3 as q, discoverWorkspacePackages as r, setUpGitHubActions as s, exitGracefully as t, copyToClipboard as u, computeProjectedScore as v, buildSortedRuleGroups as w, buildNoScoreMessage as x, formatElapsedTime as y, getCategoryImpact as z };
96573
97484
 
96574
97485
  //# sourceMappingURL=cli.js.map
96575
- //# debugId=082c13c1-ba8f-56d5-9944-c005ab0edc0e
97486
+ //# debugId=7f26fa62-fe0c-5ae0-bc9c-97a0deb50b43