react-doctor 0.9.1-dev.8534d86 → 0.9.1-dev.b1b62db

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/dist/cli.js +279 -19
  2. package/dist/index.js +275 -15
  3. package/dist/lsp.js +275 -15
  4. package/package.json +4 -4
package/dist/lsp.js CHANGED
@@ -62342,7 +62342,7 @@ const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json")
62342
62342
  const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
62343
62343
  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");
62344
62344
  const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
62345
- const getRequireModuleSpecifier = (expression) => {
62345
+ const getRequireModuleSpecifier$1 = (expression) => {
62346
62346
  if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
62347
62347
  const moduleSpecifier = expression.arguments[0];
62348
62348
  return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
@@ -62386,21 +62386,21 @@ const getImportBinding = (sourceFile, bindingName) => {
62386
62386
  for (const declaration of statement.declarationList.declarations) {
62387
62387
  if (!declaration.initializer) continue;
62388
62388
  if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
62389
- const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
62389
+ const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
62390
62390
  if (directModuleSpecifier) return {
62391
62391
  moduleSpecifier: directModuleSpecifier,
62392
62392
  exportName: "default",
62393
62393
  isNamespace: true
62394
62394
  };
62395
- if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
62396
- moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
62395
+ if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
62396
+ moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
62397
62397
  exportName: declaration.initializer.name.text,
62398
62398
  isNamespace: false
62399
62399
  };
62400
62400
  }
62401
62401
  if (!ts.isObjectBindingPattern(declaration.name)) continue;
62402
62402
  const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
62403
- const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
62403
+ const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
62404
62404
  if (bindingElement && moduleSpecifier) return {
62405
62405
  moduleSpecifier,
62406
62406
  exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
@@ -62771,7 +62771,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
62771
62771
  if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
62772
62772
  const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
62773
62773
  if (propertyName === null) return null;
62774
- const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
62774
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
62775
62775
  if (requiredModuleSpecifier !== null) {
62776
62776
  if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
62777
62777
  if (!requiredModuleSpecifier.startsWith(".")) return null;
@@ -62833,7 +62833,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62833
62833
  if (ts.isCallExpression(node)) {
62834
62834
  const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
62835
62835
  if (callTargetResult !== null) return callTargetResult;
62836
- const directModuleSpecifier = getRequireModuleSpecifier(node);
62836
+ const directModuleSpecifier = getRequireModuleSpecifier$1(node);
62837
62837
  const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
62838
62838
  if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
62839
62839
  if (directModuleSpecifier && !isRequireShadowed) {
@@ -62855,7 +62855,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
62855
62855
  return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
62856
62856
  }
62857
62857
  if (ts.isPropertyAccessExpression(node)) {
62858
- const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
62858
+ const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
62859
62859
  if (requiredModuleSpecifier) {
62860
62860
  if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
62861
62861
  if (requiredModuleSpecifier.startsWith(".")) {
@@ -66166,7 +66166,7 @@ const warn = (message) => {
66166
66166
  runSync(warn$1(message));
66167
66167
  };
66168
66168
  const CONFIG_BASENAME = "doctor.config";
66169
- const CONFIG_EXTENSIONS = [
66169
+ const CONFIG_EXTENSIONS$1 = [
66170
66170
  "ts",
66171
66171
  "mts",
66172
66172
  "cts",
@@ -66270,7 +66270,7 @@ const loadLegacyConfig = (directory) => {
66270
66270
  };
66271
66271
  const loadConfigFromDirectory = async (directory) => {
66272
66272
  let sawBrokenConfigFile = false;
66273
- for (const extension of CONFIG_EXTENSIONS) {
66273
+ for (const extension of CONFIG_EXTENSIONS$1) {
66274
66274
  const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
66275
66275
  if (!isFile(filePath)) continue;
66276
66276
  const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
@@ -70029,7 +70029,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
70029
70029
  const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
70030
70030
  const normalizeConfigForHash = (config) => {
70031
70031
  const clone = JSON.parse(JSON.stringify(config));
70032
- if (clone?.settings?.["react-doctor"]) clone.settings["react-doctor"].rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
70032
+ if (clone?.settings?.["react-doctor"]) {
70033
+ const reactDoctorSettings = clone.settings["react-doctor"];
70034
+ reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
70035
+ if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
70036
+ }
70033
70037
  if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
70034
70038
  return clone;
70035
70039
  };
@@ -70188,13 +70192,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
70188
70192
  }
70189
70193
  return enabled;
70190
70194
  };
70191
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
70195
+ 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 }) => {
70192
70196
  const hasIncludedTags = includedTags.size > 0;
70193
70197
  const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
70194
70198
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
70195
70199
  const jsPlugins = [];
70196
70200
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
70197
70201
  const capabilities = getCapabilities(project);
70202
+ const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
70198
70203
  const enabledReactDoctorRules = {};
70199
70204
  for (const registryEntry of REACT_DOCTOR_RULES) {
70200
70205
  const rule = reactDoctorPlugin.rules[registryEntry.id];
@@ -70240,8 +70245,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
70240
70245
  jsPlugins: [...jsPlugins, pluginPath],
70241
70246
  settings: { "react-doctor": {
70242
70247
  framework: project.framework,
70243
- rootDirectory: resolveSettingsRootDirectory(project.rootDirectory),
70248
+ rootDirectory: settingsRootDirectory,
70244
70249
  capabilities: [...capabilities].sort(),
70250
+ ...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
70251
+ ...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
70252
+ unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
70253
+ unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
70254
+ directory: scope.directory,
70255
+ names: [...scope.names]
70256
+ }))
70257
+ } : {},
70245
70258
  ...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
70246
70259
  ...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
70247
70260
  } },
@@ -70252,6 +70265,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
70252
70265
  }
70253
70266
  };
70254
70267
  };
70268
+ const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
70269
+ const CONFIG_BASENAMES = [
70270
+ "astro.config",
70271
+ "esbuild.config",
70272
+ "rollup.config",
70273
+ "rolldown.config",
70274
+ "rspack.config",
70275
+ "vite.config",
70276
+ "webpack.config"
70277
+ ];
70278
+ const CONFIG_EXTENSIONS = [
70279
+ ".cjs",
70280
+ ".cts",
70281
+ ".js",
70282
+ ".mjs",
70283
+ ".mts",
70284
+ ".ts"
70285
+ ];
70286
+ const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
70287
+ const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
70288
+ const SUPPORTED_GLOBAL_VALUES = new Set([
70289
+ true,
70290
+ false,
70291
+ "readable",
70292
+ "readonly",
70293
+ "writable",
70294
+ "writeable"
70295
+ ]);
70296
+ const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
70297
+ if (ts.isSpreadAssignment(property)) return false;
70298
+ const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
70299
+ return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
70300
+ }) ?? null;
70301
+ const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
70302
+ const getStaticPropertyAssignment = (objectExpression, propertyName) => {
70303
+ const property = getStaticProperty(objectExpression, propertyName);
70304
+ return property && ts.isPropertyAssignment(property) ? property : null;
70305
+ };
70306
+ const getRequireModuleSpecifier = (expression) => {
70307
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
70308
+ if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
70309
+ if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
70310
+ const moduleSpecifier = unwrappedExpression.arguments[0];
70311
+ return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
70312
+ };
70313
+ const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
70314
+ const unwrappedExpression = unwrapTypescriptExpression(expression);
70315
+ return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
70316
+ };
70317
+ 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");
70318
+ const isTopLevelExpression = (node) => {
70319
+ let ancestor = node.parent;
70320
+ while (ancestor && !ts.isSourceFile(ancestor)) {
70321
+ if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
70322
+ if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
70323
+ ancestor = ancestor.parent;
70324
+ }
70325
+ return false;
70326
+ };
70327
+ const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
70328
+ let ancestor = node.parent;
70329
+ let didFindConfigProperty = false;
70330
+ while (ancestor && !ts.isSourceFile(ancestor)) {
70331
+ 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;
70332
+ if (ts.isPropertyAssignment(ancestor)) {
70333
+ const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
70334
+ if (didFindConfigProperty || !isConfigProperty) return false;
70335
+ if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
70336
+ didFindConfigProperty = true;
70337
+ ancestor = ancestor.parent;
70338
+ continue;
70339
+ }
70340
+ if (didFindConfigProperty) {
70341
+ if (ts.isExportAssignment(ancestor)) return true;
70342
+ if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
70343
+ 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);
70344
+ 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;
70345
+ }
70346
+ ancestor = ancestor.parent;
70347
+ }
70348
+ return false;
70349
+ };
70350
+ const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
70351
+ const optionsExpression = callExpression.arguments[0];
70352
+ if (!optionsExpression) return null;
70353
+ const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
70354
+ if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
70355
+ if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
70356
+ if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
70357
+ const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
70358
+ if (!eslintrcProperty) return null;
70359
+ const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
70360
+ if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
70361
+ if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
70362
+ const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
70363
+ if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
70364
+ const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
70365
+ if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
70366
+ if (!ts.isPropertyAssignment(filepathProperty)) return null;
70367
+ const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
70368
+ return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
70369
+ };
70370
+ const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
70371
+ let sourceText;
70372
+ try {
70373
+ sourceText = NFS.readFileSync(configPath, "utf8");
70374
+ } catch {
70375
+ return {
70376
+ didFindActiveAutoImport: false,
70377
+ globalsPaths: []
70378
+ };
70379
+ }
70380
+ const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
70381
+ const autoImportBindings = /* @__PURE__ */ new Map();
70382
+ const esbuildBindings = /* @__PURE__ */ new Set();
70383
+ const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
70384
+ for (const statement of sourceFile.statements) {
70385
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
70386
+ const moduleSpecifier = statement.moduleSpecifier.text;
70387
+ if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
70388
+ const defaultBinding = statement.importClause?.name;
70389
+ if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
70390
+ }
70391
+ if (moduleSpecifier === "esbuild") {
70392
+ const defaultBinding = statement.importClause?.name;
70393
+ if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
70394
+ const namedBindings = statement.importClause?.namedBindings;
70395
+ if (namedBindings && ts.isNamedImports(namedBindings)) {
70396
+ for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
70397
+ }
70398
+ if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
70399
+ }
70400
+ }
70401
+ if (!ts.isVariableStatement(statement)) continue;
70402
+ for (const declaration of statement.declarationList.declarations) {
70403
+ if (!declaration.initializer) continue;
70404
+ const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
70405
+ const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
70406
+ if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
70407
+ if (moduleSpecifier === "esbuild") {
70408
+ if (declarationName) esbuildNamespaceBindings.add(declarationName);
70409
+ if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
70410
+ const importedName = bindingElement.propertyName ?? bindingElement.name;
70411
+ if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
70412
+ }
70413
+ }
70414
+ if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
70415
+ }
70416
+ }
70417
+ const globalsPaths = /* @__PURE__ */ new Set();
70418
+ let didFindActiveAutoImport = false;
70419
+ let didFindUnsafeActiveAutoImport = false;
70420
+ const visit = (node) => {
70421
+ if (ts.isCallExpression(node)) {
70422
+ const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
70423
+ if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
70424
+ if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
70425
+ didFindActiveAutoImport = true;
70426
+ const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
70427
+ if (globalsPath) globalsPaths.add(globalsPath);
70428
+ else didFindUnsafeActiveAutoImport = true;
70429
+ }
70430
+ }
70431
+ }
70432
+ ts.forEachChild(node, visit);
70433
+ };
70434
+ visit(sourceFile);
70435
+ return {
70436
+ didFindActiveAutoImport,
70437
+ globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
70438
+ };
70439
+ };
70440
+ const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
70441
+ const relativePath = Path.relative(rootDirectory, globalsPath);
70442
+ if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
70443
+ const parsed = failOpenReadJson(globalsPath, null);
70444
+ if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
70445
+ 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();
70446
+ };
70447
+ const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
70448
+ let currentDirectory = Path.dirname(absoluteFilePath);
70449
+ const visitedDirectories = [];
70450
+ while (true) {
70451
+ const cachedDirectory = cache.get(currentDirectory);
70452
+ if (cachedDirectory !== void 0) {
70453
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
70454
+ return cachedDirectory;
70455
+ }
70456
+ const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
70457
+ if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
70458
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
70459
+ return null;
70460
+ }
70461
+ visitedDirectories.push(currentDirectory);
70462
+ if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
70463
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
70464
+ return currentDirectory;
70465
+ }
70466
+ if (currentDirectory === rootDirectory) {
70467
+ for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
70468
+ return null;
70469
+ }
70470
+ currentDirectory = Path.dirname(currentDirectory);
70471
+ }
70472
+ };
70473
+ const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
70474
+ let directoryEntries;
70475
+ try {
70476
+ directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
70477
+ } catch {
70478
+ return [];
70479
+ }
70480
+ const configuredGlobalsPaths = [];
70481
+ for (const entry of directoryEntries) {
70482
+ if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
70483
+ const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
70484
+ if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
70485
+ }
70486
+ if (configuredGlobalsPaths.length === 0) return [];
70487
+ const globalsPaths = configuredGlobalsPaths[0];
70488
+ if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
70489
+ const names = /* @__PURE__ */ new Set();
70490
+ for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
70491
+ return [...names].sort();
70492
+ };
70493
+ const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
70494
+ const absoluteRootDirectory = Path.resolve(rootDirectory);
70495
+ const packageDirectoryCache = /* @__PURE__ */ new Map();
70496
+ const packageDirectories = /* @__PURE__ */ new Set();
70497
+ for (const candidateFile of candidateFiles) {
70498
+ const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
70499
+ if (packageDirectory) packageDirectories.add(packageDirectory);
70500
+ }
70501
+ const scopes = [...packageDirectories].map((packageDirectory) => ({
70502
+ directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
70503
+ names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
70504
+ })).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
70505
+ return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
70506
+ };
70255
70507
  const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
70256
70508
  const decodeFileDiagnostics = (raw) => {
70257
70509
  if (!Array.isArray(raw)) return null;
@@ -72245,6 +72497,8 @@ const reactHooksJsPluginDropNote = (error) => {
72245
72497
  const runOxlint = async (options) => {
72246
72498
  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;
72247
72499
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
72500
+ const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
72501
+ let unpluginAutoImportGlobalScopes = [];
72248
72502
  const severityControls = buildRuleSeverityControls(userConfig);
72249
72503
  validateRuleRegistration();
72250
72504
  resetManifestCaches();
@@ -72293,6 +72547,10 @@ const runOxlint = async (options) => {
72293
72547
  await yieldToEventLoop();
72294
72548
  const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
72295
72549
  const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
72550
+ unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
72551
+ rootDirectory,
72552
+ candidateFiles
72553
+ });
72296
72554
  const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
72297
72555
  const lintFiles = preparedHtmlSources.lintFiles;
72298
72556
  const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
@@ -72308,6 +72566,8 @@ const runOxlint = async (options) => {
72308
72566
  ignoredTags,
72309
72567
  includedTags,
72310
72568
  includeTagDefaults,
72569
+ runtimeGlobals,
72570
+ unpluginAutoImportGlobalScopes,
72311
72571
  serverAuthFunctionNames,
72312
72572
  severityControls,
72313
72573
  userPlugins,
@@ -76112,5 +76372,5 @@ const startLanguageServer = () => {
76112
76372
  };
76113
76373
  //#endregion
76114
76374
  export { startLanguageServer };
76115
- !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]="8f4550d9-ab09-5b95-8e16-28b534d81552")}catch(e){}}();
76116
- //# debugId=8f4550d9-ab09-5b95-8e16-28b534d81552
76375
+ !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]="60b26f08-3459-56b1-938b-6a9bcdea7253")}catch(e){}}();
76376
+ //# debugId=60b26f08-3459-56b1-938b-6a9bcdea7253
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.9.1-dev.8534d86",
3
+ "version": "0.9.1-dev.b1b62db",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -70,7 +70,7 @@
70
70
  "vscode-uri": "^3.1.0",
71
71
  "yaml": "^2.9.0",
72
72
  "deslop-js": "0.9.1",
73
- "oxlint-plugin-react-doctor": "0.9.1-dev.8534d86"
73
+ "oxlint-plugin-react-doctor": "0.9.1-dev.b1b62db"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/babel__code-frame": "^7.27.0",
@@ -80,9 +80,9 @@
80
80
  "commander": "^14.0.3",
81
81
  "ink-testing-library": "^4.0.0",
82
82
  "ora": "^9.4.0",
83
- "@react-doctor/core": "0.9.1",
83
+ "@react-doctor/api": "0.9.1",
84
84
  "@react-doctor/language-server": "0.9.1",
85
- "@react-doctor/api": "0.9.1"
85
+ "@react-doctor/core": "0.9.1"
86
86
  },
87
87
  "engines": {
88
88
  "node": "^20.19.0 || >=22.13.0"