react-doctor 0.8.1-dev.cc2d168 → 0.8.1-dev.d970055

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]="81bdc95e-12f2-565f-a05c-7b8a60a98f81")}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]="c24708ed-97a3-59cc-81f7-4cf277ab29f2")}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";
@@ -37317,10 +37317,6 @@ const listWorkspacePackages = (rootDirectory) => {
37317
37317
  return packages;
37318
37318
  };
37319
37319
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
37320
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
37321
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
37322
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
37323
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
37324
37320
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
37325
37321
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
37326
37322
  const dependencyDeclaration = getDependencyDeclaration({
@@ -37339,18 +37335,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
37339
37335
  if (nextMajor === null) return false;
37340
37336
  return nextMajor < currentMajor;
37341
37337
  };
37342
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
37343
- if (currentFact.version === null) return true;
37344
- if (nextFact.version === null) return false;
37345
- const currentMajor = getLowestDependencyMajor(currentFact.version);
37346
- const nextMajor = getLowestDependencyMajor(nextFact.version);
37347
- if (currentMajor === null) return false;
37348
- if (nextMajor === null) return true;
37349
- if (currentMajor > latestSupportedMajor) return false;
37350
- if (nextMajor > latestSupportedMajor) return true;
37351
- return nextMajor < currentMajor;
37352
- };
37353
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
37338
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
37354
37339
  if (facts.expo.version === null) {
37355
37340
  const spec = getDependencySpec(packageJson, "expo");
37356
37341
  if (spec !== null) facts.expo = {
@@ -37372,65 +37357,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
37372
37357
  sourceDirectory: directory
37373
37358
  };
37374
37359
  }
37375
- const mobxSpec = getDependencySpec(packageJson, "mobx");
37376
- if (mobxSpec !== null) {
37377
- const nextMobxFact = {
37378
- version: resolveCatalogBackedDependencyVersion({
37379
- rootDirectory: directory,
37380
- rootPackageJson: packageJson,
37381
- packageName: "mobx",
37382
- version: mobxSpec
37383
- }),
37384
- sourceDirectory: directory
37385
- };
37386
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
37387
- }
37388
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
37389
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
37390
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
37391
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
37392
- const zustandSpec = getDependencySpec(packageJson, "zustand");
37393
- if (zustandSpec !== null) {
37394
- const nextZustandFact = {
37395
- version: resolveCatalogBackedDependencyVersion({
37396
- rootDirectory: directory,
37397
- rootPackageJson: packageJson,
37398
- packageName: "zustand",
37399
- version: zustandSpec
37400
- }),
37401
- sourceDirectory: directory
37402
- };
37403
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
37404
- }
37405
37360
  if (facts.reanimatedVersion === null) {
37406
37361
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
37407
37362
  if (spec !== null) facts.reanimatedVersion = spec;
37408
37363
  }
37409
- if (facts.valtioVersion === null) {
37410
- const spec = getDependencySpec(packageJson, "valtio");
37411
- if (spec !== null) facts.valtioVersion = spec;
37412
- }
37413
37364
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
37414
37365
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
37415
37366
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
37416
- const remotionSpec = getDependencySpec(packageJson, "remotion");
37417
- if (remotionSpec !== null) {
37418
- facts.hasRemotionDependency = true;
37419
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
37420
- rootDirectory,
37421
- rootPackageJson,
37422
- packageName: "remotion",
37423
- version: remotionSpec
37424
- });
37425
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
37426
- if (remotionMajorVersion === null) {
37427
- facts.hasUnknownRemotionVersion = true;
37428
- facts.remotionVersion = null;
37429
- } else if (!facts.hasUnknownRemotionVersion) {
37430
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
37431
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
37432
- }
37433
- }
37434
37367
  };
37435
37368
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
37436
37369
  const facts = {
@@ -37450,28 +37383,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
37450
37383
  version: null,
37451
37384
  sourceDirectory: null
37452
37385
  },
37453
- valtioVersion: null,
37454
- mobx: {
37455
- version: null,
37456
- sourceDirectory: null
37457
- },
37458
- hasMobxReact: false,
37459
- hasMobxReactLite: false,
37460
- hasMobxStateTree: false,
37461
- hasMobxReactObserver: false,
37462
- zustand: {
37463
- version: null,
37464
- sourceDirectory: null
37465
- },
37466
37386
  hasReactNativeAwarePackage: false,
37467
37387
  hasReanimatedAwarePackage: false,
37468
37388
  hasSsrDependency: false,
37469
- hasRemotionDependency: false,
37470
- hasUnknownRemotionVersion: false,
37471
- remotionVersion: null,
37472
37389
  reanimatedVersion: null
37473
37390
  };
37474
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
37391
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
37475
37392
  let isReactGroupSettled = !collectReactGroup;
37476
37393
  const visitedDirectories = /* @__PURE__ */ new Set();
37477
37394
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -37480,7 +37397,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
37480
37397
  if (visitedDirectories.has(workspaceDirectory)) continue;
37481
37398
  visitedDirectories.add(workspaceDirectory);
37482
37399
  const workspacePackageJson = readPackageJson$1(Path.join(workspaceDirectory, "package.json"));
37483
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
37400
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
37484
37401
  const info = extractDependencyInfo(workspacePackageJson);
37485
37402
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
37486
37403
  if (isReactGroupSettled) continue;
@@ -37701,24 +37618,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
37701
37618
  tailwindVersion: null,
37702
37619
  zodVersion: null,
37703
37620
  zodMajorVersion: null,
37704
- mobxVersion: null,
37705
- mobxMajorVersion: null,
37706
- hasMobxReact: false,
37707
- hasMobxReactLite: false,
37708
- hasMobxStateTree: false,
37709
- hasMobxReactObserver: false,
37710
- zustandVersion: null,
37711
- zustandMajorVersion: null,
37712
37621
  framework: "unknown",
37713
37622
  hasTypeScript: hasOwnTsConfig,
37714
37623
  hasReactCompiler: false,
37715
37624
  hasReactCompilerLintPlugin: false,
37716
37625
  hasTanStackQuery: false,
37717
- valtioVersion: null,
37718
- valtioMajorVersion: null,
37719
- hasRemotion: false,
37720
- remotionVersion: null,
37721
- remotionMajorVersion: null,
37722
37626
  hasSsrDependency: false,
37723
37627
  preactVersion: null,
37724
37628
  preactMajorVersion: null,
@@ -37817,12 +37721,6 @@ const discoverProject = (directory) => {
37817
37721
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
37818
37722
  version: workspaceFacts.shopifyFlashList.version
37819
37723
  }) : null;
37820
- const zustandVersion = resolveCatalogBackedDependencyVersion({
37821
- rootDirectory: directory,
37822
- rootPackageJson: packageJson,
37823
- packageName: "zustand",
37824
- version: workspaceFacts.zustand.version
37825
- });
37826
37724
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
37827
37725
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
37828
37726
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -37831,20 +37729,7 @@ const discoverProject = (directory) => {
37831
37729
  packageName: "next",
37832
37730
  version: workspaceFacts.next.version
37833
37731
  }) : null;
37834
- const valtioVersion = resolveCatalogBackedDependencyVersion({
37835
- rootDirectory: directory,
37836
- rootPackageJson: packageJson,
37837
- packageName: "valtio",
37838
- version: workspaceFacts.valtioVersion
37839
- });
37840
- const mobxVersion = resolveCatalogBackedDependencyVersion({
37841
- rootDirectory: directory,
37842
- rootPackageJson: packageJson,
37843
- packageName: "mobx",
37844
- version: workspaceFacts.mobx.version
37845
- });
37846
37732
  const preactVersion = getPreactVersion(packageJson);
37847
- const remotionVersion = workspaceFacts.remotionVersion;
37848
37733
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
37849
37734
  const projectInfo = {
37850
37735
  rootDirectory: directory,
@@ -37854,24 +37739,11 @@ const discoverProject = (directory) => {
37854
37739
  tailwindVersion,
37855
37740
  zodVersion,
37856
37741
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
37857
- mobxVersion,
37858
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
37859
- hasMobxReact: workspaceFacts.hasMobxReact,
37860
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
37861
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
37862
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
37863
- zustandVersion,
37864
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
37865
37742
  framework,
37866
37743
  hasTypeScript,
37867
37744
  hasReactCompiler: detectReactCompiler(directory, packageJson),
37868
37745
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
37869
37746
  hasTanStackQuery: hasTanStackQuery(packageJson),
37870
- valtioVersion,
37871
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
37872
- hasRemotion: workspaceFacts.hasRemotionDependency,
37873
- remotionVersion,
37874
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
37875
37747
  hasSsrDependency: workspaceFacts.hasSsrDependency,
37876
37748
  preactVersion,
37877
37749
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -38105,6 +37977,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
38105
37977
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
38106
37978
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
38107
37979
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
37980
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
38108
37981
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
38109
37982
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
38110
37983
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -40426,25 +40299,9 @@ const BABEL_CONFIG_FILE_NAMES = [
40426
40299
  ".babelrc.json"
40427
40300
  ];
40428
40301
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
40429
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
40430
- const REACT_NATIVE_PACKAGE = "react-native";
40431
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
40432
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
40433
40302
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
40434
40303
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
40435
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
40436
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
40437
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson$1(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
40438
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
40439
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
40440
- if (normalizedVersionRange === null) return false;
40441
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
40442
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
40443
- };
40444
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
40445
40304
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
40446
- const packageJson = readPackageJson$1(Path.join(rootDirectory, "package.json"));
40447
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
40448
40305
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
40449
40306
  const filePath = Path.join(rootDirectory, fileName);
40450
40307
  if (!isFile(filePath)) continue;
@@ -40454,7 +40311,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
40454
40311
  } catch {
40455
40312
  continue;
40456
40313
  }
40457
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
40314
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
40458
40315
  filePath: fileName,
40459
40316
  rule: "rn-no-metro-babel-preset",
40460
40317
  severity: "error",
@@ -40477,6 +40334,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
40477
40334
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
40478
40335
  };
40479
40336
  const RULE_KEY = "no-vulnerable-react-server-components";
40337
+ const DEPENDENCY_SECTIONS = [
40338
+ "dependencies",
40339
+ "devDependencies",
40340
+ "peerDependencies",
40341
+ "optionalDependencies"
40342
+ ];
40480
40343
  const REACT_RSC_ADVISORIES_BY_MINOR = {
40481
40344
  "19.0": {
40482
40345
  rceFixedVersion: "19.0.1",
@@ -40523,13 +40386,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
40523
40386
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
40524
40387
  return [...directories];
40525
40388
  };
40389
+ const readDeclaredSpec = (packageJson, packageName) => {
40390
+ for (const section of DEPENDENCY_SECTIONS) {
40391
+ const spec = packageJson[section]?.[packageName];
40392
+ if (typeof spec === "string") return spec;
40393
+ }
40394
+ return null;
40395
+ };
40526
40396
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
40527
40397
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
40528
40398
  if (isFile(manifestPath)) {
40529
40399
  const installedVersion = import_semver.valid(readPackageJson$1(manifestPath).version ?? null);
40530
40400
  if (installedVersion !== null) return installedVersion;
40531
40401
  }
40532
- const candidateSpecs = [getDependencySpec(readPackageJson$1(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
40402
+ const candidateSpecs = [readDeclaredSpec(readPackageJson$1(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
40533
40403
  for (const spec of candidateSpecs) {
40534
40404
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
40535
40405
  if (pinnedVersion !== null) return pinnedVersion;
@@ -41209,24 +41079,9 @@ const buildCapabilities = (project) => {
41209
41079
  })) capabilities.add("tailwind:3.4");
41210
41080
  if (project.zodVersion !== null) capabilities.add("zod");
41211
41081
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
41212
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
41213
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
41214
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
41215
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
41216
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
41217
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
41218
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
41219
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
41220
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
41221
41082
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
41222
41083
  if (project.hasReactCompiler) capabilities.add("react-compiler");
41223
41084
  if (project.hasTanStackQuery) capabilities.add("tanstack-query");
41224
- if (project.valtioVersion !== null) capabilities.add("valtio");
41225
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
41226
- if (project.hasRemotion) {
41227
- capabilities.add("remotion");
41228
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
41229
- }
41230
41085
  if (project.hasTypeScript) capabilities.add("typescript");
41231
41086
  if (project.preactVersion !== null) capabilities.add("preact");
41232
41087
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -44236,17 +44091,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
44236
44091
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
44237
44092
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
44238
44093
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
44239
- const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
44240
44094
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
44241
44095
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
44242
44096
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
44243
44097
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
44244
44098
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
44245
44099
  };
44246
- const buildSetStateInEffectMessage = (reasonSummary) => {
44247
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
44248
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
44249
- };
44250
44100
  const PLUGIN_CATEGORY_MAP = {
44251
44101
  react: "Bugs",
44252
44102
  "react-hooks": "Bugs",
@@ -44304,10 +44154,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
44304
44154
  message: REACT_ERROR_BOUNDARY_MESSAGE,
44305
44155
  help: reasonDetail || help
44306
44156
  };
44307
- if (rule === "set-state-in-effect") return {
44308
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
44309
- help: reasonDetail || help
44310
- };
44311
44157
  return {
44312
44158
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
44313
44159
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -47510,7 +47356,7 @@ const makeNoopConsole = () => ({
47510
47356
  });
47511
47357
  //#endregion
47512
47358
  //#region src/cli/utils/version.ts
47513
- const VERSION = "0.8.1-dev.cc2d168";
47359
+ const VERSION = "0.8.1-dev.d970055";
47514
47360
  //#endregion
47515
47361
  //#region src/cli/utils/json-mode.ts
47516
47362
  let context = null;
@@ -47862,13 +47708,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
47862
47708
  * uploads source-map artifacts under, so stack frames symbolicate. Honors the
47863
47709
  * standard `SENTRY_RELEASE` override.
47864
47710
  */
47865
- const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.cc2d168`;
47711
+ const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.1-dev.d970055`;
47866
47712
  /**
47867
47713
  * Deployment environment shown in Sentry's environment filter. Defaults to
47868
47714
  * `production` for tagged releases and `development` for dev/unbuilt versions,
47869
47715
  * overridable via the standard `SENTRY_ENVIRONMENT` env var.
47870
47716
  */
47871
- const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.cc2d168") ? "development" : "production");
47717
+ const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.1-dev.d970055") ? "development" : "production");
47872
47718
  /**
47873
47719
  * Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
47874
47720
  * (set to `0` to disable tracing) and falls back to
@@ -66548,4 +66394,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
66548
66394
  export {};
66549
66395
 
66550
66396
  //# sourceMappingURL=cli.js.map
66551
- //# debugId=81bdc95e-12f2-565f-a05c-7b8a60a98f81
66397
+ //# debugId=c24708ed-97a3-59cc-81f7-4cf277ab29f2
package/dist/index.d.ts CHANGED
@@ -9543,35 +9543,11 @@ interface ProjectInfo {
9543
9543
  zodVersion: string | null;
9544
9544
  /** Parsed major from `zodVersion`, or `null` when absent/unparseable. Mirrors `reactMajorVersion`. */
9545
9545
  zodMajorVersion: number | null;
9546
- /** Declared MobX core version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
9547
- mobxVersion?: string | null;
9548
- /** Parsed major from `mobxVersion`, or `null` when absent/unparseable. */
9549
- mobxMajorVersion?: number | null;
9550
- hasMobxReact?: boolean;
9551
- hasMobxReactLite?: boolean;
9552
- hasMobxStateTree?: boolean;
9553
- hasMobxReactObserver?: boolean;
9554
- /** Declared Zustand version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
9555
- zustandVersion?: string | null;
9556
- /** Parsed major from `zustandVersion`, or `null` when absent/unparseable. */
9557
- zustandMajorVersion?: number | null;
9558
9546
  framework: Framework;
9559
9547
  hasTypeScript: boolean;
9560
9548
  hasReactCompiler: boolean;
9561
9549
  hasReactCompilerLintPlugin?: boolean;
9562
9550
  hasTanStackQuery: boolean;
9563
- hasRemotion?: boolean;
9564
- remotionVersion?: string | null;
9565
- remotionMajorVersion?: number | null;
9566
- /**
9567
- * The declared `valtio` version spec, or `null` when no package in the
9568
- * analyzed project declares Valtio. `useSnapshot` has kept the same
9569
- * render-read contract across Valtio 1 and 2, so presence alone drives the
9570
- * `valtio` capability and its parsed major-version ladder.
9571
- */
9572
- valtioVersion: string | null;
9573
- /** Parsed major from `valtioVersion`, or `null` when absent/unparseable. */
9574
- valtioMajorVersion: number | null;
9575
9551
  /**
9576
9552
  * `true` when the project or a workspace declares a Vite-based SSR runtime
9577
9553
  * such as React Router's Node adapter, Vike, or vite-plugin-ssr.
package/dist/index.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]="6aa1c6e1-8fcc-50d4-a076-3e864425bdc5")}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]="f645a3f8-ff1c-5f09-a174-8281db00eaa4")}catch(e){}}();
3
3
  import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
@@ -34121,10 +34121,6 @@ const listWorkspacePackages = (rootDirectory) => {
34121
34121
  return packages;
34122
34122
  };
34123
34123
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34124
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34125
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34126
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34127
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34128
34124
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34129
34125
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34130
34126
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34143,18 +34139,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34143
34139
  if (nextMajor === null) return false;
34144
34140
  return nextMajor < currentMajor;
34145
34141
  };
34146
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34147
- if (currentFact.version === null) return true;
34148
- if (nextFact.version === null) return false;
34149
- const currentMajor = getLowestDependencyMajor(currentFact.version);
34150
- const nextMajor = getLowestDependencyMajor(nextFact.version);
34151
- if (currentMajor === null) return false;
34152
- if (nextMajor === null) return true;
34153
- if (currentMajor > latestSupportedMajor) return false;
34154
- if (nextMajor > latestSupportedMajor) return true;
34155
- return nextMajor < currentMajor;
34156
- };
34157
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34142
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
34158
34143
  if (facts.expo.version === null) {
34159
34144
  const spec = getDependencySpec(packageJson, "expo");
34160
34145
  if (spec !== null) facts.expo = {
@@ -34176,65 +34161,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
34176
34161
  sourceDirectory: directory
34177
34162
  };
34178
34163
  }
34179
- const mobxSpec = getDependencySpec(packageJson, "mobx");
34180
- if (mobxSpec !== null) {
34181
- const nextMobxFact = {
34182
- version: resolveCatalogBackedDependencyVersion({
34183
- rootDirectory: directory,
34184
- rootPackageJson: packageJson,
34185
- packageName: "mobx",
34186
- version: mobxSpec
34187
- }),
34188
- sourceDirectory: directory
34189
- };
34190
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
34191
- }
34192
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
34193
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
34194
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34195
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34196
- const zustandSpec = getDependencySpec(packageJson, "zustand");
34197
- if (zustandSpec !== null) {
34198
- const nextZustandFact = {
34199
- version: resolveCatalogBackedDependencyVersion({
34200
- rootDirectory: directory,
34201
- rootPackageJson: packageJson,
34202
- packageName: "zustand",
34203
- version: zustandSpec
34204
- }),
34205
- sourceDirectory: directory
34206
- };
34207
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34208
- }
34209
34164
  if (facts.reanimatedVersion === null) {
34210
34165
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34211
34166
  if (spec !== null) facts.reanimatedVersion = spec;
34212
34167
  }
34213
- if (facts.valtioVersion === null) {
34214
- const spec = getDependencySpec(packageJson, "valtio");
34215
- if (spec !== null) facts.valtioVersion = spec;
34216
- }
34217
34168
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34218
34169
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34219
34170
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34220
- const remotionSpec = getDependencySpec(packageJson, "remotion");
34221
- if (remotionSpec !== null) {
34222
- facts.hasRemotionDependency = true;
34223
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34224
- rootDirectory,
34225
- rootPackageJson,
34226
- packageName: "remotion",
34227
- version: remotionSpec
34228
- });
34229
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34230
- if (remotionMajorVersion === null) {
34231
- facts.hasUnknownRemotionVersion = true;
34232
- facts.remotionVersion = null;
34233
- } else if (!facts.hasUnknownRemotionVersion) {
34234
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34235
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34236
- }
34237
- }
34238
34171
  };
34239
34172
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34240
34173
  const facts = {
@@ -34254,28 +34187,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34254
34187
  version: null,
34255
34188
  sourceDirectory: null
34256
34189
  },
34257
- valtioVersion: null,
34258
- mobx: {
34259
- version: null,
34260
- sourceDirectory: null
34261
- },
34262
- hasMobxReact: false,
34263
- hasMobxReactLite: false,
34264
- hasMobxStateTree: false,
34265
- hasMobxReactObserver: false,
34266
- zustand: {
34267
- version: null,
34268
- sourceDirectory: null
34269
- },
34270
34190
  hasReactNativeAwarePackage: false,
34271
34191
  hasReanimatedAwarePackage: false,
34272
34192
  hasSsrDependency: false,
34273
- hasRemotionDependency: false,
34274
- hasUnknownRemotionVersion: false,
34275
- remotionVersion: null,
34276
34193
  reanimatedVersion: null
34277
34194
  };
34278
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34195
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34279
34196
  let isReactGroupSettled = !collectReactGroup;
34280
34197
  const visitedDirectories = /* @__PURE__ */ new Set();
34281
34198
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34284,7 +34201,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34284
34201
  if (visitedDirectories.has(workspaceDirectory)) continue;
34285
34202
  visitedDirectories.add(workspaceDirectory);
34286
34203
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34287
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34204
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34288
34205
  const info = extractDependencyInfo(workspacePackageJson);
34289
34206
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34290
34207
  if (isReactGroupSettled) continue;
@@ -34508,24 +34425,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
34508
34425
  tailwindVersion: null,
34509
34426
  zodVersion: null,
34510
34427
  zodMajorVersion: null,
34511
- mobxVersion: null,
34512
- mobxMajorVersion: null,
34513
- hasMobxReact: false,
34514
- hasMobxReactLite: false,
34515
- hasMobxStateTree: false,
34516
- hasMobxReactObserver: false,
34517
- zustandVersion: null,
34518
- zustandMajorVersion: null,
34519
34428
  framework: "unknown",
34520
34429
  hasTypeScript: hasOwnTsConfig,
34521
34430
  hasReactCompiler: false,
34522
34431
  hasReactCompilerLintPlugin: false,
34523
34432
  hasTanStackQuery: false,
34524
- valtioVersion: null,
34525
- valtioMajorVersion: null,
34526
- hasRemotion: false,
34527
- remotionVersion: null,
34528
- remotionMajorVersion: null,
34529
34433
  hasSsrDependency: false,
34530
34434
  preactVersion: null,
34531
34435
  preactMajorVersion: null,
@@ -34624,12 +34528,6 @@ const discoverProject = (directory) => {
34624
34528
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34625
34529
  version: workspaceFacts.shopifyFlashList.version
34626
34530
  }) : null;
34627
- const zustandVersion = resolveCatalogBackedDependencyVersion({
34628
- rootDirectory: directory,
34629
- rootPackageJson: packageJson,
34630
- packageName: "zustand",
34631
- version: workspaceFacts.zustand.version
34632
- });
34633
34531
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34634
34532
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34635
34533
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34638,20 +34536,7 @@ const discoverProject = (directory) => {
34638
34536
  packageName: "next",
34639
34537
  version: workspaceFacts.next.version
34640
34538
  }) : null;
34641
- const valtioVersion = resolveCatalogBackedDependencyVersion({
34642
- rootDirectory: directory,
34643
- rootPackageJson: packageJson,
34644
- packageName: "valtio",
34645
- version: workspaceFacts.valtioVersion
34646
- });
34647
- const mobxVersion = resolveCatalogBackedDependencyVersion({
34648
- rootDirectory: directory,
34649
- rootPackageJson: packageJson,
34650
- packageName: "mobx",
34651
- version: workspaceFacts.mobx.version
34652
- });
34653
34539
  const preactVersion = getPreactVersion(packageJson);
34654
- const remotionVersion = workspaceFacts.remotionVersion;
34655
34540
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34656
34541
  const projectInfo = {
34657
34542
  rootDirectory: directory,
@@ -34661,24 +34546,11 @@ const discoverProject = (directory) => {
34661
34546
  tailwindVersion,
34662
34547
  zodVersion,
34663
34548
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34664
- mobxVersion,
34665
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
34666
- hasMobxReact: workspaceFacts.hasMobxReact,
34667
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34668
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34669
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34670
- zustandVersion,
34671
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34672
34549
  framework,
34673
34550
  hasTypeScript,
34674
34551
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34675
34552
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34676
34553
  hasTanStackQuery: hasTanStackQuery(packageJson),
34677
- valtioVersion,
34678
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34679
- hasRemotion: workspaceFacts.hasRemotionDependency,
34680
- remotionVersion,
34681
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34682
34554
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34683
34555
  preactVersion,
34684
34556
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -34912,6 +34784,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
34912
34784
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
34913
34785
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
34914
34786
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
34787
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
34915
34788
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
34916
34789
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
34917
34790
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -37198,25 +37071,9 @@ const BABEL_CONFIG_FILE_NAMES = [
37198
37071
  ".babelrc.json"
37199
37072
  ];
37200
37073
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37201
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37202
- const REACT_NATIVE_PACKAGE = "react-native";
37203
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37204
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37205
37074
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37206
37075
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37207
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37208
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37209
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37210
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37211
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37212
- if (normalizedVersionRange === null) return false;
37213
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37214
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37215
- };
37216
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37217
37076
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37218
- const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37219
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37220
37077
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37221
37078
  const filePath = Path.join(rootDirectory, fileName);
37222
37079
  if (!isFile(filePath)) continue;
@@ -37226,7 +37083,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37226
37083
  } catch {
37227
37084
  continue;
37228
37085
  }
37229
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37086
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37230
37087
  filePath: fileName,
37231
37088
  rule: "rn-no-metro-babel-preset",
37232
37089
  severity: "error",
@@ -37249,6 +37106,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
37249
37106
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37250
37107
  };
37251
37108
  const RULE_KEY = "no-vulnerable-react-server-components";
37109
+ const DEPENDENCY_SECTIONS = [
37110
+ "dependencies",
37111
+ "devDependencies",
37112
+ "peerDependencies",
37113
+ "optionalDependencies"
37114
+ ];
37252
37115
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37253
37116
  "19.0": {
37254
37117
  rceFixedVersion: "19.0.1",
@@ -37295,13 +37158,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37295
37158
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37296
37159
  return [...directories];
37297
37160
  };
37161
+ const readDeclaredSpec = (packageJson, packageName) => {
37162
+ for (const section of DEPENDENCY_SECTIONS) {
37163
+ const spec = packageJson[section]?.[packageName];
37164
+ if (typeof spec === "string") return spec;
37165
+ }
37166
+ return null;
37167
+ };
37298
37168
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37299
37169
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37300
37170
  if (isFile(manifestPath)) {
37301
37171
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37302
37172
  if (installedVersion !== null) return installedVersion;
37303
37173
  }
37304
- const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37174
+ const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37305
37175
  for (const spec of candidateSpecs) {
37306
37176
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37307
37177
  if (pinnedVersion !== null) return pinnedVersion;
@@ -37981,24 +37851,9 @@ const buildCapabilities = (project) => {
37981
37851
  })) capabilities.add("tailwind:3.4");
37982
37852
  if (project.zodVersion !== null) capabilities.add("zod");
37983
37853
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
37984
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
37985
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
37986
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
37987
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
37988
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
37989
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
37990
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
37991
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
37992
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
37993
37854
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
37994
37855
  if (project.hasReactCompiler) capabilities.add("react-compiler");
37995
37856
  if (project.hasTanStackQuery) capabilities.add("tanstack-query");
37996
- if (project.valtioVersion !== null) capabilities.add("valtio");
37997
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
37998
- if (project.hasRemotion) {
37999
- capabilities.add("remotion");
38000
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
38001
- }
38002
37857
  if (project.hasTypeScript) capabilities.add("typescript");
38003
37858
  if (project.preactVersion !== null) capabilities.add("preact");
38004
37859
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -40992,17 +40847,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
40992
40847
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
40993
40848
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
40994
40849
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
40995
- const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
40996
40850
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
40997
40851
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
40998
40852
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
40999
40853
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
41000
40854
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
41001
40855
  };
41002
- const buildSetStateInEffectMessage = (reasonSummary) => {
41003
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
41004
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
41005
- };
41006
40856
  const PLUGIN_CATEGORY_MAP = {
41007
40857
  react: "Bugs",
41008
40858
  "react-hooks": "Bugs",
@@ -41060,10 +40910,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
41060
40910
  message: REACT_ERROR_BOUNDARY_MESSAGE,
41061
40911
  help: reasonDetail || help
41062
40912
  };
41063
- if (rule === "set-state-in-effect") return {
41064
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
41065
- help: reasonDetail || help
41066
- };
41067
40913
  return {
41068
40914
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
41069
40915
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -43982,4 +43828,4 @@ const toJsonReport = (result, options) => buildJsonReport({
43982
43828
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
43983
43829
 
43984
43830
  //# sourceMappingURL=index.js.map
43985
- //# debugId=6aa1c6e1-8fcc-50d4-a076-3e864425bdc5
43831
+ //# debugId=f645a3f8-ff1c-5f09-a174-8281db00eaa4
package/dist/lsp.js CHANGED
@@ -34173,10 +34173,6 @@ const listWorkspacePackages = (rootDirectory) => {
34173
34173
  return packages;
34174
34174
  };
34175
34175
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34176
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34177
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34178
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34179
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34180
34176
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34181
34177
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34182
34178
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34195,18 +34191,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34195
34191
  if (nextMajor === null) return false;
34196
34192
  return nextMajor < currentMajor;
34197
34193
  };
34198
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34199
- if (currentFact.version === null) return true;
34200
- if (nextFact.version === null) return false;
34201
- const currentMajor = getLowestDependencyMajor(currentFact.version);
34202
- const nextMajor = getLowestDependencyMajor(nextFact.version);
34203
- if (currentMajor === null) return false;
34204
- if (nextMajor === null) return true;
34205
- if (currentMajor > latestSupportedMajor) return false;
34206
- if (nextMajor > latestSupportedMajor) return true;
34207
- return nextMajor < currentMajor;
34208
- };
34209
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34194
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
34210
34195
  if (facts.expo.version === null) {
34211
34196
  const spec = getDependencySpec(packageJson, "expo");
34212
34197
  if (spec !== null) facts.expo = {
@@ -34228,65 +34213,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
34228
34213
  sourceDirectory: directory
34229
34214
  };
34230
34215
  }
34231
- const mobxSpec = getDependencySpec(packageJson, "mobx");
34232
- if (mobxSpec !== null) {
34233
- const nextMobxFact = {
34234
- version: resolveCatalogBackedDependencyVersion({
34235
- rootDirectory: directory,
34236
- rootPackageJson: packageJson,
34237
- packageName: "mobx",
34238
- version: mobxSpec
34239
- }),
34240
- sourceDirectory: directory
34241
- };
34242
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
34243
- }
34244
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
34245
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
34246
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34247
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34248
- const zustandSpec = getDependencySpec(packageJson, "zustand");
34249
- if (zustandSpec !== null) {
34250
- const nextZustandFact = {
34251
- version: resolveCatalogBackedDependencyVersion({
34252
- rootDirectory: directory,
34253
- rootPackageJson: packageJson,
34254
- packageName: "zustand",
34255
- version: zustandSpec
34256
- }),
34257
- sourceDirectory: directory
34258
- };
34259
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34260
- }
34261
34216
  if (facts.reanimatedVersion === null) {
34262
34217
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34263
34218
  if (spec !== null) facts.reanimatedVersion = spec;
34264
34219
  }
34265
- if (facts.valtioVersion === null) {
34266
- const spec = getDependencySpec(packageJson, "valtio");
34267
- if (spec !== null) facts.valtioVersion = spec;
34268
- }
34269
34220
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34270
34221
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34271
34222
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34272
- const remotionSpec = getDependencySpec(packageJson, "remotion");
34273
- if (remotionSpec !== null) {
34274
- facts.hasRemotionDependency = true;
34275
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34276
- rootDirectory,
34277
- rootPackageJson,
34278
- packageName: "remotion",
34279
- version: remotionSpec
34280
- });
34281
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34282
- if (remotionMajorVersion === null) {
34283
- facts.hasUnknownRemotionVersion = true;
34284
- facts.remotionVersion = null;
34285
- } else if (!facts.hasUnknownRemotionVersion) {
34286
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34287
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34288
- }
34289
- }
34290
34223
  };
34291
34224
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34292
34225
  const facts = {
@@ -34306,28 +34239,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34306
34239
  version: null,
34307
34240
  sourceDirectory: null
34308
34241
  },
34309
- valtioVersion: null,
34310
- mobx: {
34311
- version: null,
34312
- sourceDirectory: null
34313
- },
34314
- hasMobxReact: false,
34315
- hasMobxReactLite: false,
34316
- hasMobxStateTree: false,
34317
- hasMobxReactObserver: false,
34318
- zustand: {
34319
- version: null,
34320
- sourceDirectory: null
34321
- },
34322
34242
  hasReactNativeAwarePackage: false,
34323
34243
  hasReanimatedAwarePackage: false,
34324
34244
  hasSsrDependency: false,
34325
- hasRemotionDependency: false,
34326
- hasUnknownRemotionVersion: false,
34327
- remotionVersion: null,
34328
34245
  reanimatedVersion: null
34329
34246
  };
34330
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34247
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34331
34248
  let isReactGroupSettled = !collectReactGroup;
34332
34249
  const visitedDirectories = /* @__PURE__ */ new Set();
34333
34250
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34336,7 +34253,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34336
34253
  if (visitedDirectories.has(workspaceDirectory)) continue;
34337
34254
  visitedDirectories.add(workspaceDirectory);
34338
34255
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34339
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34256
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34340
34257
  const info = extractDependencyInfo(workspacePackageJson);
34341
34258
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34342
34259
  if (isReactGroupSettled) continue;
@@ -34560,24 +34477,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
34560
34477
  tailwindVersion: null,
34561
34478
  zodVersion: null,
34562
34479
  zodMajorVersion: null,
34563
- mobxVersion: null,
34564
- mobxMajorVersion: null,
34565
- hasMobxReact: false,
34566
- hasMobxReactLite: false,
34567
- hasMobxStateTree: false,
34568
- hasMobxReactObserver: false,
34569
- zustandVersion: null,
34570
- zustandMajorVersion: null,
34571
34480
  framework: "unknown",
34572
34481
  hasTypeScript: hasOwnTsConfig,
34573
34482
  hasReactCompiler: false,
34574
34483
  hasReactCompilerLintPlugin: false,
34575
34484
  hasTanStackQuery: false,
34576
- valtioVersion: null,
34577
- valtioMajorVersion: null,
34578
- hasRemotion: false,
34579
- remotionVersion: null,
34580
- remotionMajorVersion: null,
34581
34485
  hasSsrDependency: false,
34582
34486
  preactVersion: null,
34583
34487
  preactMajorVersion: null,
@@ -34676,12 +34580,6 @@ const discoverProject = (directory) => {
34676
34580
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34677
34581
  version: workspaceFacts.shopifyFlashList.version
34678
34582
  }) : null;
34679
- const zustandVersion = resolveCatalogBackedDependencyVersion({
34680
- rootDirectory: directory,
34681
- rootPackageJson: packageJson,
34682
- packageName: "zustand",
34683
- version: workspaceFacts.zustand.version
34684
- });
34685
34583
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34686
34584
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34687
34585
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34690,20 +34588,7 @@ const discoverProject = (directory) => {
34690
34588
  packageName: "next",
34691
34589
  version: workspaceFacts.next.version
34692
34590
  }) : null;
34693
- const valtioVersion = resolveCatalogBackedDependencyVersion({
34694
- rootDirectory: directory,
34695
- rootPackageJson: packageJson,
34696
- packageName: "valtio",
34697
- version: workspaceFacts.valtioVersion
34698
- });
34699
- const mobxVersion = resolveCatalogBackedDependencyVersion({
34700
- rootDirectory: directory,
34701
- rootPackageJson: packageJson,
34702
- packageName: "mobx",
34703
- version: workspaceFacts.mobx.version
34704
- });
34705
34591
  const preactVersion = getPreactVersion(packageJson);
34706
- const remotionVersion = workspaceFacts.remotionVersion;
34707
34592
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34708
34593
  const projectInfo = {
34709
34594
  rootDirectory: directory,
@@ -34713,24 +34598,11 @@ const discoverProject = (directory) => {
34713
34598
  tailwindVersion,
34714
34599
  zodVersion,
34715
34600
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34716
- mobxVersion,
34717
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
34718
- hasMobxReact: workspaceFacts.hasMobxReact,
34719
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34720
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34721
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34722
- zustandVersion,
34723
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34724
34601
  framework,
34725
34602
  hasTypeScript,
34726
34603
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34727
34604
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34728
34605
  hasTanStackQuery: hasTanStackQuery(packageJson),
34729
- valtioVersion,
34730
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34731
- hasRemotion: workspaceFacts.hasRemotionDependency,
34732
- remotionVersion,
34733
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34734
34606
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34735
34607
  preactVersion,
34736
34608
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -34964,6 +34836,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
34964
34836
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
34965
34837
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
34966
34838
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
34839
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
34967
34840
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
34968
34841
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
34969
34842
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -37176,25 +37049,9 @@ const BABEL_CONFIG_FILE_NAMES = [
37176
37049
  ".babelrc.json"
37177
37050
  ];
37178
37051
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37179
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37180
- const REACT_NATIVE_PACKAGE = "react-native";
37181
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37182
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37183
37052
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37184
37053
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37185
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37186
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37187
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37188
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37189
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37190
- if (normalizedVersionRange === null) return false;
37191
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37192
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37193
- };
37194
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37195
37054
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37196
- const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37197
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37198
37055
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37199
37056
  const filePath = Path.join(rootDirectory, fileName);
37200
37057
  if (!isFile(filePath)) continue;
@@ -37204,7 +37061,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37204
37061
  } catch {
37205
37062
  continue;
37206
37063
  }
37207
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37064
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37208
37065
  filePath: fileName,
37209
37066
  rule: "rn-no-metro-babel-preset",
37210
37067
  severity: "error",
@@ -37227,6 +37084,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
37227
37084
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37228
37085
  };
37229
37086
  const RULE_KEY = "no-vulnerable-react-server-components";
37087
+ const DEPENDENCY_SECTIONS = [
37088
+ "dependencies",
37089
+ "devDependencies",
37090
+ "peerDependencies",
37091
+ "optionalDependencies"
37092
+ ];
37230
37093
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37231
37094
  "19.0": {
37232
37095
  rceFixedVersion: "19.0.1",
@@ -37273,13 +37136,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37273
37136
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37274
37137
  return [...directories];
37275
37138
  };
37139
+ const readDeclaredSpec = (packageJson, packageName) => {
37140
+ for (const section of DEPENDENCY_SECTIONS) {
37141
+ const spec = packageJson[section]?.[packageName];
37142
+ if (typeof spec === "string") return spec;
37143
+ }
37144
+ return null;
37145
+ };
37276
37146
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37277
37147
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37278
37148
  if (isFile(manifestPath)) {
37279
37149
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37280
37150
  if (installedVersion !== null) return installedVersion;
37281
37151
  }
37282
- const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37152
+ const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37283
37153
  for (const spec of candidateSpecs) {
37284
37154
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37285
37155
  if (pinnedVersion !== null) return pinnedVersion;
@@ -37959,24 +37829,9 @@ const buildCapabilities = (project) => {
37959
37829
  })) capabilities.add("tailwind:3.4");
37960
37830
  if (project.zodVersion !== null) capabilities.add("zod");
37961
37831
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
37962
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
37963
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
37964
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
37965
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
37966
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
37967
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
37968
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
37969
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
37970
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
37971
37832
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
37972
37833
  if (project.hasReactCompiler) capabilities.add("react-compiler");
37973
37834
  if (project.hasTanStackQuery) capabilities.add("tanstack-query");
37974
- if (project.valtioVersion !== null) capabilities.add("valtio");
37975
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
37976
- if (project.hasRemotion) {
37977
- capabilities.add("remotion");
37978
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
37979
- }
37980
37835
  if (project.hasTypeScript) capabilities.add("typescript");
37981
37836
  if (project.preactVersion !== null) capabilities.add("preact");
37982
37837
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -40970,17 +40825,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
40970
40825
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
40971
40826
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
40972
40827
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
40973
- const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
40974
40828
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
40975
40829
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
40976
40830
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
40977
40831
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
40978
40832
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
40979
40833
  };
40980
- const buildSetStateInEffectMessage = (reasonSummary) => {
40981
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
40982
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
40983
- };
40984
40834
  const PLUGIN_CATEGORY_MAP = {
40985
40835
  react: "Bugs",
40986
40836
  "react-hooks": "Bugs",
@@ -41038,10 +40888,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
41038
40888
  message: REACT_ERROR_BOUNDARY_MESSAGE,
41039
40889
  help: reasonDetail || help
41040
40890
  };
41041
- if (rule === "set-state-in-effect") return {
41042
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
41043
- help: reasonDetail || help
41044
- };
41045
40891
  return {
41046
40892
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
41047
40893
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -45602,5 +45448,5 @@ const startLanguageServer = () => {
45602
45448
  };
45603
45449
  //#endregion
45604
45450
  export { startLanguageServer };
45605
- !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]="f2369b82-a22a-50e5-b71b-2ceb30eaee9f")}catch(e){}}();
45606
- //# debugId=f2369b82-a22a-50e5-b71b-2ceb30eaee9f
45451
+ !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]="4fa679df-c187-5989-bc8a-a96791a6f02c")}catch(e){}}();
45452
+ //# debugId=4fa679df-c187-5989-bc8a-a96791a6f02c
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.8.1-dev.cc2d168",
3
+ "version": "0.8.1-dev.d970055",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -65,8 +65,8 @@
65
65
  "vscode-languageserver-textdocument": "^1.0.12",
66
66
  "vscode-uri": "^3.1.0",
67
67
  "yaml": "^2.9.0",
68
- "deslop-js": "0.8.1",
69
- "oxlint-plugin-react-doctor": "0.8.1-dev.cc2d168"
68
+ "oxlint-plugin-react-doctor": "0.8.1-dev.d970055",
69
+ "deslop-js": "0.8.1"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/babel__code-frame": "^7.27.0",
@@ -74,8 +74,8 @@
74
74
  "@xterm/headless": "^6.0.0",
75
75
  "commander": "^14.0.3",
76
76
  "ora": "^9.4.0",
77
- "@react-doctor/core": "0.8.1",
78
77
  "@react-doctor/api": "0.8.1",
78
+ "@react-doctor/core": "0.8.1",
79
79
  "@react-doctor/language-server": "0.8.1"
80
80
  },
81
81
  "engines": {