react-doctor 0.8.1-dev.21221c2 → 0.8.1-dev.284b4e4

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/lsp.js CHANGED
@@ -32883,44 +32883,6 @@ var AmbiguousProjectError = class extends Error {
32883
32883
  }
32884
32884
  };
32885
32885
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
32886
- const isErrnoException = (error) => error instanceof Error && "code" in error;
32887
- const IGNORABLE_READDIR_ERROR_CODES = new Set([
32888
- "EACCES",
32889
- "EPERM",
32890
- "ENOENT",
32891
- "ENOTDIR",
32892
- "EINVAL",
32893
- "ELOOP",
32894
- "ENAMETOOLONG"
32895
- ]);
32896
- const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
32897
- const readDirectoryEntries = (directoryPath) => {
32898
- try {
32899
- return NFS.readdirSync(directoryPath, { withFileTypes: true });
32900
- } catch (error) {
32901
- if (isIgnorableReaddirError(error)) return [];
32902
- throw error;
32903
- }
32904
- };
32905
- const isFile = (filePath) => {
32906
- try {
32907
- return NFS.statSync(filePath).isFile();
32908
- } catch {
32909
- return false;
32910
- }
32911
- };
32912
- const isDirectory = (directoryPath) => {
32913
- try {
32914
- return NFS.statSync(directoryPath).isDirectory();
32915
- } catch {
32916
- return false;
32917
- }
32918
- };
32919
- const isPlainObject = (value) => {
32920
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
32921
- const prototype = Object.getPrototypeOf(value);
32922
- return prototype === null || prototype === Object.prototype;
32923
- };
32924
32886
  const SOURCE_FILE_PATTERN = /\.(tsx?|jsx?|mts|mjs)$/;
32925
32887
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
32926
32888
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
@@ -33102,6 +33064,44 @@ const SUPPLY_CHAIN_OVERLAP_TIMEOUT_MS = 9e4;
33102
33064
  const SUPPLY_CHAIN_CACHE_TTL_MS = 864e5;
33103
33065
  const SUPPLY_CHAIN_CACHE_SUBDIR = "supply-chain";
33104
33066
  const SUPPLY_CHAIN_IGNORED_PACKAGES = new Set(["next"]);
33067
+ const isErrnoException = (error) => error instanceof Error && "code" in error;
33068
+ const IGNORABLE_READDIR_ERROR_CODES = new Set([
33069
+ "EACCES",
33070
+ "EPERM",
33071
+ "ENOENT",
33072
+ "ENOTDIR",
33073
+ "EINVAL",
33074
+ "ELOOP",
33075
+ "ENAMETOOLONG"
33076
+ ]);
33077
+ const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
33078
+ const readDirectoryEntries = (directoryPath) => {
33079
+ try {
33080
+ return NFS.readdirSync(directoryPath, { withFileTypes: true });
33081
+ } catch (error) {
33082
+ if (isIgnorableReaddirError(error)) return [];
33083
+ throw error;
33084
+ }
33085
+ };
33086
+ const isFile = (filePath) => {
33087
+ try {
33088
+ return NFS.statSync(filePath).isFile();
33089
+ } catch {
33090
+ return false;
33091
+ }
33092
+ };
33093
+ const isDirectory = (directoryPath) => {
33094
+ try {
33095
+ return NFS.statSync(directoryPath).isDirectory();
33096
+ } catch {
33097
+ return false;
33098
+ }
33099
+ };
33100
+ const isPlainObject = (value) => {
33101
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
33102
+ const prototype = Object.getPrototypeOf(value);
33103
+ return prototype === null || prototype === Object.prototype;
33104
+ };
33105
33105
  const lastSourceMappingUrl = (fileContent) => {
33106
33106
  const lastReference = [...fileContent.matchAll(/\/\/# sourceMappingURL=(\S+)/g)].at(-1);
33107
33107
  return lastReference ? lastReference[1] : null;
@@ -33427,10 +33427,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
33427
33427
  const FRAMEWORK_PACKAGES = {
33428
33428
  next: "nextjs",
33429
33429
  "@tanstack/react-start": "tanstack-start",
33430
- vite: "vite",
33431
- "react-scripts": "cra",
33432
33430
  "@remix-run/react": "remix",
33433
33431
  gatsby: "gatsby",
33432
+ vite: "vite",
33433
+ "react-scripts": "cra",
33434
33434
  expo: "expo",
33435
33435
  "react-native": "react-native"
33436
33436
  };
@@ -33454,11 +33454,17 @@ const NEXT_CONFIG_FILENAMES = [
33454
33454
  ];
33455
33455
  const BABEL_CONFIG_FILENAMES = [
33456
33456
  ".babelrc",
33457
+ ".babelrc.js",
33457
33458
  ".babelrc.json",
33459
+ ".babelrc.cjs",
33460
+ ".babelrc.mjs",
33461
+ ".babelrc.cts",
33458
33462
  "babel.config.js",
33459
33463
  "babel.config.json",
33460
33464
  "babel.config.cjs",
33461
- "babel.config.mjs"
33465
+ "babel.config.mjs",
33466
+ "babel.config.ts",
33467
+ "babel.config.cts"
33462
33468
  ];
33463
33469
  const VITE_CONFIG_FILENAMES = [
33464
33470
  "vite.config.js",
@@ -33470,12 +33476,28 @@ const VITE_CONFIG_FILENAMES = [
33470
33476
  "vitest.config.ts",
33471
33477
  "vitest.config.js"
33472
33478
  ];
33479
+ const RSBUILD_CONFIG_FILENAMES = [
33480
+ "rsbuild.config.ts",
33481
+ "rsbuild.config.js",
33482
+ "rsbuild.config.mts",
33483
+ "rsbuild.config.mjs",
33484
+ "rsbuild.config.cts",
33485
+ "rsbuild.config.cjs"
33486
+ ];
33487
+ const RSPACK_CONFIG_FILENAMES = [
33488
+ "rspack.config.ts",
33489
+ "rspack.config.js",
33490
+ "rspack.config.mts",
33491
+ "rspack.config.mjs",
33492
+ "rspack.config.cts",
33493
+ "rspack.config.cjs"
33494
+ ];
33473
33495
  const EXPO_APP_CONFIG_FILENAMES = [
33474
33496
  "app.json",
33475
33497
  "app.config.js",
33476
33498
  "app.config.ts"
33477
33499
  ];
33478
- const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|["']react-compiler["']/;
33500
+ const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|reactCompilerPreset\s*\(|["']react-compiler["']/;
33479
33501
  const REACT_COMPILER_ENABLED_FLAG_PATTERN = /["']?reactCompiler["']?\s*:\s*(?:true\b|\{)/;
33480
33502
  const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
33481
33503
  const hasCompilerPackage = (packageJson, compilerPackages) => {
@@ -33510,6 +33532,8 @@ const detectReactCompiler = (directory, packageJson) => {
33510
33532
  if (hasCompilerInConfigFiles(directory, NEXT_CONFIG_FILENAMES)) return true;
33511
33533
  if (hasCompilerInConfigFiles(directory, BABEL_CONFIG_FILENAMES)) return true;
33512
33534
  if (hasCompilerInConfigFiles(directory, VITE_CONFIG_FILENAMES)) return true;
33535
+ if (hasCompilerInConfigFiles(directory, RSBUILD_CONFIG_FILENAMES)) return true;
33536
+ if (hasCompilerInConfigFiles(directory, RSPACK_CONFIG_FILENAMES)) return true;
33513
33537
  if (hasCompilerInConfigFiles(directory, EXPO_APP_CONFIG_FILENAMES)) return true;
33514
33538
  return hasCompilerPackageInAncestors(directory, REACT_COMPILER_TRANSFORM_PACKAGES);
33515
33539
  };
@@ -33518,7 +33542,7 @@ const detectNextjsStaticExport = (directory) => NEXT_CONFIG_FILENAMES.some((file
33518
33542
  const filePath = Path.join(directory, filename);
33519
33543
  return isFile(filePath) && STATIC_EXPORT_OUTPUT_PATTERN.test(NFS.readFileSync(filePath, "utf-8"));
33520
33544
  });
33521
- const UNRESOLVABLE_PROTOCOL_VERSION = /^(?:file|git|github|https?|link|patch|portal|workspace|npm):/i;
33545
+ const UNRESOLVABLE_PROTOCOL_VERSION = /^(?:catalog|file|git|github|https?|link|patch|portal|workspace|npm):/i;
33522
33546
  const DIST_TAG_VERSION = /^[a-z][a-z0-9._-]*$/i;
33523
33547
  const WILDCARD_VERSION = /^[*xX](?:\.[*xX])*$/;
33524
33548
  const NPM_ALIAS_VERSION = /^npm:(?:@[^/]+\/[^@]+|[^@]+)@(.+)$/i;
@@ -33651,6 +33675,16 @@ const getLowestDependencyMajor = (version) => {
33651
33675
  }
33652
33676
  return lowestMajor;
33653
33677
  };
33678
+ const getDependencyMajorWithinSupportedRange = (version, latestSupportedMajor) => {
33679
+ const normalizedVersion = normalizeDependencyVersion(version);
33680
+ if (normalizedVersion === null) return null;
33681
+ const validRange = import_semver.validRange(normalizedVersion);
33682
+ if (validRange === null) return null;
33683
+ const minimumVersion = import_semver.minVersion(validRange);
33684
+ if (minimumVersion === null || minimumVersion.major > latestSupportedMajor) return null;
33685
+ if (import_semver.intersects(validRange, `>=${latestSupportedMajor + 1}.0.0`)) return null;
33686
+ return minimumVersion.major;
33687
+ };
33654
33688
  const isConcreteDependencyVersion = (version) => {
33655
33689
  const normalizedVersion = normalizeDependencyVersion(version);
33656
33690
  return normalizedVersion !== null && /\d/.test(normalizedVersion);
@@ -33694,9 +33728,18 @@ const parseReactMajorMinor = (reactVersion) => {
33694
33728
  };
33695
33729
  };
33696
33730
  const parseLowerBoundVersion = (versionSpec) => import_semver.validRange(versionSpec) !== null ? import_semver.minVersion(versionSpec) : import_semver.coerce(versionSpec);
33697
- const parseTailwindMajorMinor = (tailwindVersion) => {
33698
- if (typeof tailwindVersion !== "string") return null;
33699
- const trimmed = tailwindVersion.trim();
33731
+ const parseThreeRelease = (threeVersion) => {
33732
+ if (typeof threeVersion !== "string") return null;
33733
+ const normalizedVersion = normalizeDependencyVersion(threeVersion);
33734
+ if (normalizedVersion === null) return null;
33735
+ const lowerBound = parseLowerBoundVersion(normalizedVersion);
33736
+ if (lowerBound === null) return null;
33737
+ if (lowerBound.major > 0) return Number.MAX_SAFE_INTEGER;
33738
+ return lowerBound.minor > 0 ? lowerBound.minor : null;
33739
+ };
33740
+ const parseDependencyMajorMinor = (dependencyVersion) => {
33741
+ if (typeof dependencyVersion !== "string") return null;
33742
+ const trimmed = dependencyVersion.trim();
33700
33743
  if (trimmed.length === 0) return null;
33701
33744
  const lowerBound = parseLowerBoundVersion(trimmed);
33702
33745
  if (lowerBound === null || lowerBound.major <= 0) return null;
@@ -33705,6 +33748,7 @@ const parseTailwindMajorMinor = (tailwindVersion) => {
33705
33748
  minor: lowerBound.minor
33706
33749
  };
33707
33750
  };
33751
+ const parseTailwindMajorMinor = (tailwindVersion) => parseDependencyMajorMinor(tailwindVersion);
33708
33752
  const hasUpperBoundOnlyPeerRange = (range) => {
33709
33753
  if (typeof range !== "string") return false;
33710
33754
  const normalizedRange = normalizeDependencyVersion(range);
@@ -33726,7 +33770,7 @@ const resolveEffectiveReactMajor = (reactVersion, packageJson) => {
33726
33770
  if (peerFloor === null) return hasUpperBoundOnlyPeerRange(peerReactRange) ? null : installedReactMajor;
33727
33771
  return installedReactMajor !== null ? Math.min(installedReactMajor, peerFloor) : peerFloor;
33728
33772
  };
33729
- const isCatalogReference = (version) => version.startsWith("catalog:");
33773
+ const isCatalogReference = (version) => typeof version === "string" && version.startsWith("catalog:");
33730
33774
  const extractCatalogName = (version) => {
33731
33775
  if (!isCatalogReference(version)) return null;
33732
33776
  const name = version.slice(8).trim();
@@ -33876,6 +33920,12 @@ const TAILWIND_ZOD_SECTIONS = [
33876
33920
  "devDependencies",
33877
33921
  "peerDependencies"
33878
33922
  ];
33923
+ const DEPENDENCY_SPEC_SECTIONS = [
33924
+ "dependencies",
33925
+ "devDependencies",
33926
+ "peerDependencies",
33927
+ "optionalDependencies"
33928
+ ];
33879
33929
  const EMPTY_DEPENDENCY_INFO = {
33880
33930
  reactVersion: null,
33881
33931
  tailwindVersion: null,
@@ -33885,7 +33935,7 @@ const EMPTY_DEPENDENCY_INFO = {
33885
33935
  const pickConcreteVersion = (packageJson, packageName, sections) => {
33886
33936
  for (const section of sections) {
33887
33937
  const version = packageJson[section]?.[packageName];
33888
- if (version === void 0) continue;
33938
+ if (typeof version !== "string") continue;
33889
33939
  if (isCatalogReference(version)) return null;
33890
33940
  if (isConcreteDependencyVersion(version)) return version;
33891
33941
  }
@@ -33917,13 +33967,16 @@ const extractDependencyInfo = (packageJson) => {
33917
33967
  };
33918
33968
  };
33919
33969
  const getDependencySpec = (packageJson, packageName) => {
33920
- const spec = packageJson.dependencies?.[packageName] ?? packageJson.devDependencies?.[packageName] ?? packageJson.peerDependencies?.[packageName] ?? packageJson.optionalDependencies?.[packageName];
33921
- return typeof spec === "string" ? spec : null;
33970
+ for (const section of DEPENDENCY_SPEC_SECTIONS) {
33971
+ const spec = packageJson[section]?.[packageName];
33972
+ if (typeof spec === "string") return spec;
33973
+ }
33974
+ return null;
33922
33975
  };
33923
33976
  const getDependencyDeclaration = ({ packageJson, packageName, sections }) => {
33924
33977
  for (const section of sections) {
33925
33978
  const version = packageJson[section]?.[packageName];
33926
- if (version === void 0) continue;
33979
+ if (typeof version !== "string") continue;
33927
33980
  return {
33928
33981
  catalogReference: extractCatalogName(version) ?? null,
33929
33982
  hasDeclaration: true,
@@ -33957,24 +34010,15 @@ const getPreactVersion = (packageJson) => {
33957
34010
  ...packageJson.devDependencies
33958
34011
  }.preact ?? null;
33959
34012
  };
33960
- const TANSTACK_QUERY_PACKAGES = new Set([
33961
- "@tanstack/react-query",
33962
- "@tanstack/query-core",
33963
- "react-query"
33964
- ]);
33965
- const hasTanStackQuery = (packageJson) => {
33966
- const allDependencies = {
33967
- ...packageJson.peerDependencies,
33968
- ...packageJson.dependencies,
33969
- ...packageJson.devDependencies
33970
- };
33971
- return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
33972
- };
33973
- const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
34013
+ const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, sourceDirectory = rootDirectory, sourcePackageJson = rootPackageJson, version }) => {
33974
34014
  if (version === null || !isCatalogReference(version)) return version;
33975
34015
  const catalogName = extractCatalogName(version);
33976
- const resolvedLocalVersion = resolveCatalogVersion(rootPackageJson, packageName, rootDirectory, catalogName);
33977
- if (resolvedLocalVersion) return resolvedLocalVersion;
34016
+ const resolvedSourceVersion = resolveCatalogVersion(sourcePackageJson, packageName, sourceDirectory, catalogName);
34017
+ if (resolvedSourceVersion) return resolvedSourceVersion;
34018
+ if (sourceDirectory !== rootDirectory || sourcePackageJson !== rootPackageJson) {
34019
+ const resolvedRootVersion = resolveCatalogVersion(rootPackageJson, packageName, rootDirectory, catalogName);
34020
+ if (resolvedRootVersion) return resolvedRootVersion;
34021
+ }
33978
34022
  const monorepoRoot = findMonorepoRoot(rootDirectory);
33979
34023
  if (!monorepoRoot) return version;
33980
34024
  const monorepoPackageJsonPath = Path.join(monorepoRoot, "package.json");
@@ -34172,7 +34216,79 @@ const listWorkspacePackages = (rootDirectory) => {
34172
34216
  }
34173
34217
  return packages;
34174
34218
  };
34219
+ const PREFERRED_DEPENDENCY_SECTIONS = [
34220
+ "dependencies",
34221
+ "peerDependencies",
34222
+ "devDependencies"
34223
+ ];
34224
+ const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
34225
+ for (const packageName of packageNames) {
34226
+ const declaration = getDependencyDeclaration({
34227
+ packageJson,
34228
+ packageName,
34229
+ sections: PREFERRED_DEPENDENCY_SECTIONS
34230
+ });
34231
+ if (declaration.version !== null) return declaration.version;
34232
+ }
34233
+ return null;
34234
+ };
34235
+ const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
34236
+ const getTanStackQueryVersion = (packageJson) => {
34237
+ return getPreferredDependencyVersion({
34238
+ packageJson,
34239
+ packageNames: TANSTACK_REACT_QUERY_PACKAGES
34240
+ });
34241
+ };
34242
+ const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
34243
+ const getStyledComponentsVersion = (packageJson) => {
34244
+ return getPreferredDependencyVersion({
34245
+ packageJson,
34246
+ packageNames: STYLED_COMPONENTS_PACKAGES
34247
+ });
34248
+ };
34249
+ const I18N_PACKAGES = [
34250
+ "i18next",
34251
+ "react-i18next",
34252
+ "next-i18next",
34253
+ "react-intl",
34254
+ "next-intl",
34255
+ "use-intl",
34256
+ "@formatjs/intl",
34257
+ "@lingui/core",
34258
+ "@lingui/react",
34259
+ "typesafe-i18n",
34260
+ "@tolgee/react",
34261
+ "react-intl-universal"
34262
+ ];
34263
+ const hasI18nDependency = (packageJson) => {
34264
+ const allDependencies = {
34265
+ ...packageJson.peerDependencies,
34266
+ ...packageJson.dependencies,
34267
+ ...packageJson.devDependencies,
34268
+ ...packageJson.optionalDependencies
34269
+ };
34270
+ return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
34271
+ };
34175
34272
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34273
+ const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34274
+ const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34275
+ const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34276
+ const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34277
+ const REACT_THREE_FIBER_DEPENDENCY_NAMES = ["@react-three/fiber", "react-three-fiber"];
34278
+ const REACT_THREE_FIBER_SECTIONS = [
34279
+ "dependencies",
34280
+ "peerDependencies",
34281
+ "optionalDependencies",
34282
+ "devDependencies"
34283
+ ];
34284
+ const THREE_DEPENDENCY_SECTIONS = [
34285
+ "dependencies",
34286
+ "peerDependencies",
34287
+ "optionalDependencies",
34288
+ "devDependencies"
34289
+ ];
34290
+ const REACT_THREE_FIBER_ECOSYSTEM_DEPENDENCY_NAMES = [...REACT_THREE_FIBER_DEPENDENCY_NAMES, "@react-three/drei"];
34291
+ const THREE_DEPENDENCY_NAMES = [...REACT_THREE_FIBER_ECOSYSTEM_DEPENDENCY_NAMES, "three"];
34176
34292
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34177
34293
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34178
34294
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34183,7 +34299,7 @@ const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootD
34183
34299
  if (!dependencyDeclaration.hasDeclaration) return null;
34184
34300
  return concreteVersion ?? resolveCatalogVersion(workspacePackageJson, packageName, workspaceDirectory, dependencyDeclaration.catalogReference) ?? resolveCatalogVersion(rootPackageJson, packageName, rootDirectory, dependencyDeclaration.catalogReference);
34185
34301
  };
34186
- const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34302
+ const shouldReplaceWithLowerMajor = (currentVersion, nextVersion) => {
34187
34303
  if (!currentVersion) return true;
34188
34304
  const currentMajor = parseReactMajor(currentVersion);
34189
34305
  const nextMajor = parseReactMajor(nextVersion);
@@ -34191,7 +34307,62 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34191
34307
  if (nextMajor === null) return false;
34192
34308
  return nextMajor < currentMajor;
34193
34309
  };
34194
- const evaluateManifestFacts = (facts, packageJson, directory) => {
34310
+ const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34311
+ if (currentFact.version === null) return true;
34312
+ if (nextFact.version === null) return false;
34313
+ const currentMajor = getLowestDependencyMajor(currentFact.version);
34314
+ const nextMajor = getLowestDependencyMajor(nextFact.version);
34315
+ if (currentMajor === null) return false;
34316
+ if (nextMajor === null) return true;
34317
+ if (currentMajor > latestSupportedMajor) return false;
34318
+ if (nextMajor > latestSupportedMajor) return true;
34319
+ return nextMajor < currentMajor;
34320
+ };
34321
+ const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
34322
+ if (!currentVersion) return true;
34323
+ const currentMajor = getLowestDependencyMajor(currentVersion);
34324
+ const nextMajor = getLowestDependencyMajor(nextVersion);
34325
+ if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
34326
+ if (nextMajor === null) return currentMajor >= 6;
34327
+ return nextMajor < currentMajor;
34328
+ };
34329
+ const selectOldestDependencyVersion = (currentVersion, nextVersion) => {
34330
+ if (currentVersion === null || nextVersion === null) return null;
34331
+ const current = parseDependencyMajorMinor(currentVersion);
34332
+ const next = parseDependencyMajorMinor(nextVersion);
34333
+ if (current === null) return currentVersion;
34334
+ if (next === null) return nextVersion;
34335
+ if (next.major !== current.major) return next.major < current.major ? nextVersion : currentVersion;
34336
+ return next.minor < current.minor ? nextVersion : currentVersion;
34337
+ };
34338
+ const shouldReplaceMobxFact = (currentFact, nextFact) => {
34339
+ if (currentFact.sourceDirectory === null) return true;
34340
+ if (currentFact.version === null) return false;
34341
+ if (nextFact.version === null) return true;
34342
+ const currentMajor = getDependencyMajorWithinSupportedRange(currentFact.version, 6);
34343
+ const nextMajor = getDependencyMajorWithinSupportedRange(nextFact.version, 6);
34344
+ if (currentMajor === null) return false;
34345
+ if (nextMajor === null) return true;
34346
+ return selectOldestDependencyVersion(currentFact.version, nextFact.version) === nextFact.version;
34347
+ };
34348
+ const collectBindingVersion = (facts, packageJson, directory, packageName) => {
34349
+ const version = getDependencySpec(packageJson, packageName);
34350
+ if (version === null) return;
34351
+ const resolvedVersion = resolveCatalogBackedDependencyVersion({
34352
+ rootDirectory: directory,
34353
+ rootPackageJson: packageJson,
34354
+ packageName,
34355
+ version
34356
+ });
34357
+ if (packageName === MOBX_REACT_PACKAGE_NAME) {
34358
+ facts.mobxReactVersion = facts.hasMobxReact ? selectOldestDependencyVersion(facts.mobxReactVersion, resolvedVersion) : resolvedVersion;
34359
+ facts.hasMobxReact = true;
34360
+ return;
34361
+ }
34362
+ facts.mobxReactLiteVersion = facts.hasMobxReactLite ? selectOldestDependencyVersion(facts.mobxReactLiteVersion, resolvedVersion) : resolvedVersion;
34363
+ facts.hasMobxReactLite = true;
34364
+ };
34365
+ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34195
34366
  if (facts.expo.version === null) {
34196
34367
  const spec = getDependencySpec(packageJson, "expo");
34197
34368
  if (spec !== null) facts.expo = {
@@ -34213,13 +34384,113 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
34213
34384
  sourceDirectory: directory
34214
34385
  };
34215
34386
  }
34387
+ const mobxSpec = getDependencySpec(packageJson, "mobx");
34388
+ if (mobxSpec !== null) {
34389
+ const nextMobxFact = {
34390
+ version: resolveCatalogBackedDependencyVersion({
34391
+ rootDirectory: directory,
34392
+ rootPackageJson: packageJson,
34393
+ packageName: "mobx",
34394
+ version: mobxSpec
34395
+ }),
34396
+ sourceDirectory: directory
34397
+ };
34398
+ if (shouldReplaceMobxFact(facts.mobx, nextMobxFact)) facts.mobx = nextMobxFact;
34399
+ }
34400
+ collectBindingVersion(facts, packageJson, directory, MOBX_REACT_PACKAGE_NAME);
34401
+ collectBindingVersion(facts, packageJson, directory, MOBX_REACT_LITE_PACKAGE_NAME);
34402
+ facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34403
+ facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34404
+ const zustandSpec = getDependencySpec(packageJson, "zustand");
34405
+ if (zustandSpec !== null) {
34406
+ const nextZustandFact = {
34407
+ version: resolveCatalogBackedDependencyVersion({
34408
+ rootDirectory: directory,
34409
+ rootPackageJson: packageJson,
34410
+ packageName: "zustand",
34411
+ version: zustandSpec
34412
+ }),
34413
+ sourceDirectory: directory
34414
+ };
34415
+ if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34416
+ }
34216
34417
  if (facts.reanimatedVersion === null) {
34217
34418
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34218
34419
  if (spec !== null) facts.reanimatedVersion = spec;
34219
34420
  }
34421
+ if (facts.valtioVersion === null) {
34422
+ const spec = getDependencySpec(packageJson, "valtio");
34423
+ if (spec !== null) facts.valtioVersion = spec;
34424
+ }
34425
+ facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
34426
+ const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
34427
+ rootDirectory: directory,
34428
+ rootPackageJson: packageJson,
34429
+ packageName: "styled-components",
34430
+ version: getStyledComponentsVersion(packageJson)
34431
+ });
34432
+ if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
34433
+ facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
34434
+ for (const packageName of REACT_THREE_FIBER_DEPENDENCY_NAMES) {
34435
+ const version = resolveCatalogBackedDependencyVersion({
34436
+ rootDirectory,
34437
+ rootPackageJson,
34438
+ sourceDirectory: directory,
34439
+ sourcePackageJson: packageJson,
34440
+ packageName,
34441
+ version: getDependencyDeclaration({
34442
+ packageName,
34443
+ packageJson,
34444
+ sections: REACT_THREE_FIBER_SECTIONS
34445
+ }).version
34446
+ });
34447
+ if (version === null) continue;
34448
+ if (shouldReplaceWithLowerMajor(facts.reactThreeFiber.version, version)) facts.reactThreeFiber = {
34449
+ packageName,
34450
+ version,
34451
+ sourceDirectory: directory
34452
+ };
34453
+ }
34454
+ const threeVersion = resolveCatalogBackedDependencyVersion({
34455
+ rootDirectory,
34456
+ rootPackageJson,
34457
+ sourceDirectory: directory,
34458
+ sourcePackageJson: packageJson,
34459
+ packageName: "three",
34460
+ version: getDependencyDeclaration({
34461
+ packageName: "three",
34462
+ packageJson,
34463
+ sections: THREE_DEPENDENCY_SECTIONS
34464
+ }).version
34465
+ });
34466
+ if (threeVersion !== null) {
34467
+ const currentRelease = parseThreeRelease(facts.threeVersion);
34468
+ const nextRelease = parseThreeRelease(threeVersion);
34469
+ if (facts.threeVersion === null || nextRelease !== null && (currentRelease === null || nextRelease < currentRelease)) facts.threeVersion = threeVersion;
34470
+ }
34220
34471
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34221
34472
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34222
34473
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34474
+ const remotionSpec = getDependencySpec(packageJson, "remotion");
34475
+ if (remotionSpec !== null) {
34476
+ facts.hasRemotionDependency = true;
34477
+ const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34478
+ rootDirectory,
34479
+ rootPackageJson,
34480
+ packageName: "remotion",
34481
+ version: remotionSpec
34482
+ });
34483
+ const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34484
+ if (remotionMajorVersion === null) {
34485
+ facts.hasUnknownRemotionVersion = true;
34486
+ facts.remotionVersion = null;
34487
+ } else if (!facts.hasUnknownRemotionVersion) {
34488
+ const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34489
+ if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34490
+ }
34491
+ }
34492
+ facts.hasThree = facts.hasThree || THREE_DEPENDENCY_NAMES.some((dependencyName) => getDependencySpec(packageJson, dependencyName) !== null);
34493
+ facts.hasReactThreeFiber = facts.hasReactThreeFiber || REACT_THREE_FIBER_ECOSYSTEM_DEPENDENCY_NAMES.some((dependencyName) => getDependencySpec(packageJson, dependencyName) !== null);
34223
34494
  };
34224
34495
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34225
34496
  const facts = {
@@ -34239,12 +34510,41 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34239
34510
  version: null,
34240
34511
  sourceDirectory: null
34241
34512
  },
34513
+ valtioVersion: null,
34514
+ mobx: {
34515
+ version: null,
34516
+ sourceDirectory: null
34517
+ },
34518
+ hasMobxReact: false,
34519
+ mobxReactVersion: null,
34520
+ hasMobxReactLite: false,
34521
+ mobxReactLiteVersion: null,
34522
+ hasMobxStateTree: false,
34523
+ hasMobxReactObserver: false,
34524
+ zustand: {
34525
+ version: null,
34526
+ sourceDirectory: null
34527
+ },
34528
+ tanstackQueryVersion: null,
34529
+ styledComponentsVersion: null,
34530
+ hasI18nLibrary: false,
34242
34531
  hasReactNativeAwarePackage: false,
34243
34532
  hasReanimatedAwarePackage: false,
34244
34533
  hasSsrDependency: false,
34534
+ hasRemotionDependency: false,
34535
+ hasUnknownRemotionVersion: false,
34536
+ remotionVersion: null,
34537
+ hasThree: false,
34538
+ threeVersion: null,
34539
+ hasReactThreeFiber: false,
34540
+ reactThreeFiber: {
34541
+ packageName: null,
34542
+ version: null,
34543
+ sourceDirectory: null
34544
+ },
34245
34545
  reanimatedVersion: null
34246
34546
  };
34247
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34547
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34248
34548
  let isReactGroupSettled = !collectReactGroup;
34249
34549
  const visitedDirectories = /* @__PURE__ */ new Set();
34250
34550
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34253,7 +34553,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34253
34553
  if (visitedDirectories.has(workspaceDirectory)) continue;
34254
34554
  visitedDirectories.add(workspaceDirectory);
34255
34555
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34256
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34556
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34257
34557
  const info = extractDependencyInfo(workspacePackageJson);
34258
34558
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34259
34559
  if (isReactGroupSettled) continue;
@@ -34284,7 +34584,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34284
34584
  workspaceDirectory,
34285
34585
  workspacePackageJson
34286
34586
  });
34287
- if (reactVersion && shouldReplaceReactVersion(facts.reactVersion, reactVersion)) facts.reactVersion = reactVersion;
34587
+ if (reactVersion && shouldReplaceWithLowerMajor(facts.reactVersion, reactVersion)) facts.reactVersion = reactVersion;
34288
34588
  if (tailwindVersion && !facts.tailwindVersion) facts.tailwindVersion = tailwindVersion;
34289
34589
  if (zodVersion && !facts.zodVersion) facts.zodVersion = zodVersion;
34290
34590
  const settledReactMajor = parseReactMajor(facts.reactVersion);
@@ -34477,11 +34777,35 @@ const discoverProjectWithoutPackageJson = (directory) => {
34477
34777
  tailwindVersion: null,
34478
34778
  zodVersion: null,
34479
34779
  zodMajorVersion: null,
34780
+ mobxVersion: null,
34781
+ mobxMajorVersion: null,
34782
+ hasMobxReact: false,
34783
+ mobxReactVersion: null,
34784
+ hasMobxReactLite: false,
34785
+ mobxReactLiteVersion: null,
34786
+ hasMobxStateTree: false,
34787
+ hasMobxReactObserver: false,
34788
+ zustandVersion: null,
34789
+ zustandMajorVersion: null,
34480
34790
  framework: "unknown",
34481
34791
  hasTypeScript: hasOwnTsConfig,
34482
34792
  hasReactCompiler: false,
34483
34793
  hasReactCompilerLintPlugin: false,
34484
34794
  hasTanStackQuery: false,
34795
+ valtioVersion: null,
34796
+ valtioMajorVersion: null,
34797
+ hasRemotion: false,
34798
+ remotionVersion: null,
34799
+ remotionMajorVersion: null,
34800
+ hasI18nLibrary: false,
34801
+ tanstackQueryVersion: null,
34802
+ styledComponentsVersion: null,
34803
+ hasThree: false,
34804
+ threeVersion: null,
34805
+ threeRelease: null,
34806
+ hasReactThreeFiber: false,
34807
+ reactThreeFiberVersion: null,
34808
+ reactThreeFiberMajorVersion: null,
34485
34809
  hasSsrDependency: false,
34486
34810
  preactVersion: null,
34487
34811
  preactMajorVersion: null,
@@ -34580,6 +34904,12 @@ const discoverProject = (directory) => {
34580
34904
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34581
34905
  version: workspaceFacts.shopifyFlashList.version
34582
34906
  }) : null;
34907
+ const zustandVersion = resolveCatalogBackedDependencyVersion({
34908
+ rootDirectory: directory,
34909
+ rootPackageJson: packageJson,
34910
+ packageName: "zustand",
34911
+ version: workspaceFacts.zustand.version
34912
+ });
34583
34913
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34584
34914
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34585
34915
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34588,7 +34918,33 @@ const discoverProject = (directory) => {
34588
34918
  packageName: "next",
34589
34919
  version: workspaceFacts.next.version
34590
34920
  }) : null;
34921
+ const valtioVersion = resolveCatalogBackedDependencyVersion({
34922
+ rootDirectory: directory,
34923
+ rootPackageJson: packageJson,
34924
+ packageName: "valtio",
34925
+ version: workspaceFacts.valtioVersion
34926
+ });
34927
+ const mobxVersion = resolveCatalogBackedDependencyVersion({
34928
+ rootDirectory: directory,
34929
+ rootPackageJson: packageJson,
34930
+ packageName: "mobx",
34931
+ version: workspaceFacts.mobx.version
34932
+ });
34591
34933
  const preactVersion = getPreactVersion(packageJson);
34934
+ const remotionVersion = workspaceFacts.remotionVersion;
34935
+ const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
34936
+ const reactThreeFiberVersion = workspaceFacts.reactThreeFiber.packageName ? resolveCatalogBackedDependencyVersion({
34937
+ rootDirectory: directory,
34938
+ rootPackageJson: packageJson,
34939
+ packageName: workspaceFacts.reactThreeFiber.packageName,
34940
+ version: workspaceFacts.reactThreeFiber.version
34941
+ }) : null;
34942
+ const threeVersion = resolveCatalogBackedDependencyVersion({
34943
+ rootDirectory: directory,
34944
+ rootPackageJson: packageJson,
34945
+ packageName: "three",
34946
+ version: workspaceFacts.threeVersion
34947
+ });
34592
34948
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34593
34949
  const projectInfo = {
34594
34950
  rootDirectory: directory,
@@ -34598,11 +34954,35 @@ const discoverProject = (directory) => {
34598
34954
  tailwindVersion,
34599
34955
  zodVersion,
34600
34956
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34957
+ mobxVersion,
34958
+ mobxMajorVersion: mobxVersion === null ? null : getDependencyMajorWithinSupportedRange(mobxVersion, 6),
34959
+ hasMobxReact: workspaceFacts.hasMobxReact,
34960
+ mobxReactVersion: workspaceFacts.mobxReactVersion,
34961
+ hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34962
+ mobxReactLiteVersion: workspaceFacts.mobxReactLiteVersion,
34963
+ hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34964
+ hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34965
+ zustandVersion,
34966
+ zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34601
34967
  framework,
34602
34968
  hasTypeScript,
34603
34969
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34604
34970
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34605
- hasTanStackQuery: hasTanStackQuery(packageJson),
34971
+ hasTanStackQuery: tanstackQueryVersion !== null,
34972
+ hasI18nLibrary: workspaceFacts.hasI18nLibrary,
34973
+ tanstackQueryVersion,
34974
+ styledComponentsVersion: workspaceFacts.styledComponentsVersion,
34975
+ valtioVersion,
34976
+ valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34977
+ hasRemotion: workspaceFacts.hasRemotionDependency,
34978
+ remotionVersion,
34979
+ remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34980
+ hasThree: workspaceFacts.hasThree,
34981
+ threeVersion,
34982
+ threeRelease: parseThreeRelease(threeVersion),
34983
+ hasReactThreeFiber: workspaceFacts.hasReactThreeFiber,
34984
+ reactThreeFiberVersion,
34985
+ reactThreeFiberMajorVersion: reactThreeFiberVersion === null ? null : getLowestDependencyMajor(reactThreeFiberVersion),
34606
34986
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34607
34987
  preactVersion,
34608
34988
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -37048,9 +37428,25 @@ const BABEL_CONFIG_FILE_NAMES = [
37048
37428
  ".babelrc.json"
37049
37429
  ];
37050
37430
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37431
+ const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37432
+ const REACT_NATIVE_PACKAGE = "react-native";
37433
+ const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37434
+ const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37051
37435
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37052
37436
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37437
+ const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37438
+ const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37439
+ const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37440
+ if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37441
+ const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37442
+ if (normalizedVersionRange === null) return false;
37443
+ const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37444
+ return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37445
+ };
37446
+ const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37053
37447
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37448
+ const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37449
+ const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37054
37450
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37055
37451
  const filePath = Path.join(rootDirectory, fileName);
37056
37452
  if (!isFile(filePath)) continue;
@@ -37060,7 +37456,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37060
37456
  } catch {
37061
37457
  continue;
37062
37458
  }
37063
- if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37459
+ if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37064
37460
  filePath: fileName,
37065
37461
  rule: "rn-no-metro-babel-preset",
37066
37462
  severity: "error",
@@ -37083,12 +37479,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
37083
37479
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37084
37480
  };
37085
37481
  const RULE_KEY = "no-vulnerable-react-server-components";
37086
- const DEPENDENCY_SECTIONS = [
37087
- "dependencies",
37088
- "devDependencies",
37089
- "peerDependencies",
37090
- "optionalDependencies"
37091
- ];
37092
37482
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37093
37483
  "19.0": {
37094
37484
  rceFixedVersion: "19.0.1",
@@ -37135,20 +37525,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37135
37525
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37136
37526
  return [...directories];
37137
37527
  };
37138
- const readDeclaredSpec = (packageJson, packageName) => {
37139
- for (const section of DEPENDENCY_SECTIONS) {
37140
- const spec = packageJson[section]?.[packageName];
37141
- if (typeof spec === "string") return spec;
37142
- }
37143
- return null;
37144
- };
37145
37528
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37146
37529
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37147
37530
  if (isFile(manifestPath)) {
37148
37531
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37149
37532
  if (installedVersion !== null) return installedVersion;
37150
37533
  }
37151
- const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37534
+ const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37152
37535
  for (const spec of candidateSpecs) {
37153
37536
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37154
37537
  if (pinnedVersion !== null) return pinnedVersion;
@@ -37800,10 +38183,10 @@ const SSR_FRAMEWORKS = new Set([
37800
38183
  "gatsby",
37801
38184
  "tanstack-start"
37802
38185
  ]);
37803
- const addMajorLadder = (capabilities, name, major, earliest, latest) => {
37804
- if (major === null) return;
37805
- const cappedMajor = Math.min(major, latest);
37806
- for (let candidate = earliest; candidate <= cappedMajor; candidate += 1) capabilities.add(`${name}:${candidate}`);
38186
+ const addVersionCapabilityLadder = (capabilities, name, detectedVersion, earliest, latest) => {
38187
+ if (detectedVersion === null) return;
38188
+ const cappedVersion = Math.min(detectedVersion, latest);
38189
+ for (let candidate = earliest; candidate <= cappedVersion; candidate += 1) capabilities.add(`${name}:${candidate}`);
37807
38190
  };
37808
38191
  const buildCapabilities = (project) => {
37809
38192
  const capabilities = /* @__PURE__ */ new Set();
@@ -37816,24 +38199,77 @@ const buildCapabilities = (project) => {
37816
38199
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
37817
38200
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
37818
38201
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
37819
- addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
38202
+ if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
38203
+ addVersionCapabilityLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
37820
38204
  if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
37821
38205
  major: 19,
37822
38206
  minor: 2
37823
38207
  })) capabilities.add("react:19.2");
37824
- if (project.tailwindVersion !== null) capabilities.add("tailwind");
37825
- if (project.tailwindVersion !== null && isMajorMinorAtLeast(parseTailwindMajorMinor(project.tailwindVersion), {
37826
- major: 3,
37827
- minor: 4
37828
- })) capabilities.add("tailwind:3.4");
38208
+ if (project.tailwindVersion !== null) {
38209
+ capabilities.add("tailwind");
38210
+ const tailwindVersion = parseTailwindMajorMinor(project.tailwindVersion);
38211
+ if (isMajorMinorAtLeast(tailwindVersion, {
38212
+ major: 3,
38213
+ minor: 4
38214
+ })) capabilities.add("tailwind:3.4");
38215
+ if (tailwindVersion !== null && isMajorMinorAtLeast(tailwindVersion, {
38216
+ major: 4,
38217
+ minor: 0
38218
+ })) capabilities.add("tailwind:4");
38219
+ }
37829
38220
  if (project.zodVersion !== null) capabilities.add("zod");
37830
38221
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
38222
+ if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
38223
+ if (project.hasMobxReact === true) capabilities.add("mobx-react");
38224
+ if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
38225
+ if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
38226
+ const mobxReactVersion = parseDependencyMajorMinor(project.mobxReactVersion);
38227
+ const mobxReactLiteVersion = parseDependencyMajorMinor(project.mobxReactLiteVersion);
38228
+ const hasMobxReactObserverMemoGuard = mobxReactVersion !== null && isMajorMinorAtLeast(mobxReactVersion, {
38229
+ major: 7,
38230
+ minor: 3
38231
+ });
38232
+ const hasMobxReactLiteObserverMemoGuard = mobxReactLiteVersion !== null && isMajorMinorAtLeast(mobxReactLiteVersion, {
38233
+ major: 3,
38234
+ minor: 3
38235
+ });
38236
+ if (hasMobxReactObserverMemoGuard) capabilities.add("mobx-react-observer-memo-guard");
38237
+ if (hasMobxReactLiteObserverMemoGuard) capabilities.add("mobx-react-lite-observer-memo-guard");
38238
+ if (hasMobxReactObserverMemoGuard || hasMobxReactLiteObserverMemoGuard) capabilities.add("mobx-react-binding-observer-memo-guard");
38239
+ if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
38240
+ if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
38241
+ if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addVersionCapabilityLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
38242
+ const mobxVersion = parseDependencyMajorMinor(project.mobxVersion);
38243
+ if (project.mobxMajorVersion === 6 && mobxVersion !== null && isMajorMinorAtLeast(mobxVersion, {
38244
+ major: 6,
38245
+ minor: 10
38246
+ })) capabilities.add("mobx:6.10");
38247
+ if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
38248
+ if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
37831
38249
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
37832
38250
  if (project.hasReactCompiler) capabilities.add("react-compiler");
37833
- if (project.hasTanStackQuery) capabilities.add("tanstack-query");
38251
+ if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
38252
+ if (project.styledComponentsVersion) {
38253
+ capabilities.add("styled-components");
38254
+ const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
38255
+ if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
38256
+ }
38257
+ if (project.hasI18nLibrary) capabilities.add("i18n");
38258
+ if (project.valtioVersion !== null) capabilities.add("valtio");
38259
+ addVersionCapabilityLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
38260
+ if (project.hasRemotion) {
38261
+ capabilities.add("remotion");
38262
+ addVersionCapabilityLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
38263
+ }
38264
+ if (project.hasThree || project.hasReactThreeFiber) capabilities.add("three");
38265
+ addVersionCapabilityLadder(capabilities, "three", project.threeRelease ?? null, 145, 250);
38266
+ if (project.hasReactThreeFiber) {
38267
+ capabilities.add("r3f");
38268
+ addVersionCapabilityLadder(capabilities, "r3f", project.reactThreeFiberMajorVersion ?? null, 3, 10);
38269
+ }
37834
38270
  if (project.hasTypeScript) capabilities.add("typescript");
37835
38271
  if (project.preactVersion !== null) capabilities.add("preact");
37836
- addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
38272
+ addVersionCapabilityLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
37837
38273
  if (project.preactVersion !== null && project.reactVersion === null) capabilities.add("pure-preact");
37838
38274
  return capabilities;
37839
38275
  };
@@ -37845,7 +38281,7 @@ const getCapabilities = (project) => {
37845
38281
  capabilitiesByProject.set(project, capabilities);
37846
38282
  return capabilities;
37847
38283
  };
37848
- const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen) => {
38284
+ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen, includedTags) => {
37849
38285
  if (requires) {
37850
38286
  for (const capability of requires) if (!capabilities.has(capability)) return false;
37851
38287
  }
@@ -37856,20 +38292,29 @@ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhe
37856
38292
  if (tags) {
37857
38293
  for (const tag of tags) if (ignoredTags.has(tag)) return false;
37858
38294
  }
38295
+ if (includedTags && includedTags.size > 0) {
38296
+ if (!tags?.some((tag) => includedTags.has(tag))) return false;
38297
+ }
37859
38298
  return true;
37860
38299
  };
38300
+ const shouldEnableRuleByDefaultStatus = (options) => options.defaultEnabled !== false || options.hasExplicitOverride === true || options.includeTagDefaults && options.hasIncludedTags;
37861
38301
  const yieldToEventLoop = () => new Promise((resolve) => {
37862
38302
  setImmediate(resolve);
37863
38303
  });
37864
38304
  const createSecurityScanSession = (rootDirectory, options) => {
37865
38305
  const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
37866
38306
  const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
38307
+ const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
37867
38308
  const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
37868
38309
  const rule = entry.rule;
37869
38310
  const scan = rule.scan;
37870
38311
  if (typeof scan !== "function") return [];
37871
- if (rule.defaultEnabled === false) return [];
37872
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) return [];
38312
+ if (!shouldEnableRuleByDefaultStatus({
38313
+ defaultEnabled: rule.defaultEnabled,
38314
+ includeTagDefaults: options.includeTagDefaults === true,
38315
+ hasIncludedTags: includedTags.size > 0
38316
+ })) return [];
38317
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) return [];
37873
38318
  return [{
37874
38319
  entry,
37875
38320
  scan,
@@ -39855,8 +40300,9 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
39855
40300
  }
39856
40301
  return enabled;
39857
40302
  };
39858
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
39859
- const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
40303
+ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
40304
+ const hasIncludedTags = includedTags.size > 0;
40305
+ const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
39860
40306
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
39861
40307
  const jsPlugins = [];
39862
40308
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
@@ -39871,9 +40317,14 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
39871
40317
  if (rule.scan !== void 0) continue;
39872
40318
  if (customRulesOnly && registryEntry.originallyExternal) continue;
39873
40319
  if (rule.framework !== "global" && !rule.requires) continue;
39874
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) continue;
40320
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
39875
40321
  const explicitRuleOverride = resolveRuleSeverityOverride({ ruleKey: registryEntry.key }, severityControls);
39876
- if (rule.defaultEnabled === false && explicitRuleOverride === void 0) continue;
40322
+ if (!shouldEnableRuleByDefaultStatus({
40323
+ defaultEnabled: rule.defaultEnabled,
40324
+ includeTagDefaults,
40325
+ hasIncludedTags,
40326
+ hasExplicitOverride: explicitRuleOverride !== void 0
40327
+ })) continue;
39877
40328
  const severity = resolveRuleSeverityOverride({
39878
40329
  ruleKey: registryEntry.key,
39879
40330
  category: rule.category
@@ -39882,7 +40333,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
39882
40333
  enabledReactDoctorRules[registryEntry.key] = severity;
39883
40334
  }
39884
40335
  const userPluginRules = {};
39885
- if (ruleSelection !== "sidecar") for (const userPlugin of userPlugins) {
40336
+ if (ruleSelection !== "sidecar" && !hasIncludedTags) for (const userPlugin of userPlugins) {
39886
40337
  Object.assign(userPluginRules, buildUserPluginRules(userPlugin, severityControls));
39887
40338
  jsPlugins.push(userPlugin.entry);
39888
40339
  }
@@ -40099,6 +40550,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
40099
40550
  }
40100
40551
  };
40101
40552
  };
40553
+ const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
40554
+ const fingerprintFileContents = (filePath, fingerprintLength) => {
40555
+ const fileStats = NFS.statSync(filePath, { bigint: true });
40556
+ const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
40557
+ if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
40558
+ const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
40559
+ fingerprintCacheByFilePath.set(filePath, {
40560
+ fingerprint,
40561
+ modifiedTimeNanoseconds: fileStats.mtimeNs,
40562
+ sizeBytes: fileStats.size
40563
+ });
40564
+ return fingerprint;
40565
+ };
40102
40566
  const bundledRequire = createRequire(import.meta.url);
40103
40567
  const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
40104
40568
  const resolveChildNodeVersion = (nodeBinaryPath) => {
@@ -40122,6 +40586,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
40122
40586
  "oxlint-plugin-react-doctor/package.json",
40123
40587
  "eslint-plugin-react-hooks/package.json"
40124
40588
  ];
40589
+ const resolvePluginFingerprint = () => {
40590
+ try {
40591
+ return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
40592
+ } catch {
40593
+ return "unresolved";
40594
+ }
40595
+ };
40125
40596
  const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40126
40597
  const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
40127
40598
  for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
@@ -40131,6 +40602,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40131
40602
  } catch {
40132
40603
  versions.push(`${specifier}=missing`);
40133
40604
  }
40605
+ versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
40134
40606
  return versions;
40135
40607
  };
40136
40608
  const esmRequire = createRequire(import.meta.url);
@@ -41606,7 +42078,7 @@ const reactHooksJsPluginDropNote = (error) => {
41606
42078
  * 6. always restore disable directives + clean up the temp dir
41607
42079
  */
41608
42080
  const runOxlint = async (options) => {
41609
- const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
42081
+ 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;
41610
42082
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
41611
42083
  const severityControls = buildRuleSeverityControls(userConfig);
41612
42084
  validateRuleRegistration();
@@ -41620,13 +42092,15 @@ const runOxlint = async (options) => {
41620
42092
  }
41621
42093
  const pluginPath = resolvePluginPath();
41622
42094
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
41623
- const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
42095
+ const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
41624
42096
  const buildConfig = (overrides) => createOxlintConfig({
41625
42097
  pluginPath,
41626
42098
  project,
41627
42099
  customRulesOnly,
41628
42100
  extendsPaths: overrides.extendsPaths,
41629
42101
  ignoredTags,
42102
+ includedTags,
42103
+ includeTagDefaults,
41630
42104
  serverAuthFunctionNames,
41631
42105
  severityControls,
41632
42106
  userPlugins,
@@ -42015,6 +42489,8 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
42015
42489
  respectInlineDisables: input.respectInlineDisables,
42016
42490
  adoptExistingLintConfig: input.adoptExistingLintConfig,
42017
42491
  ignoredTags: input.ignoredTags,
42492
+ includedTags: input.includedTags,
42493
+ includeTagDefaults: input.includeTagDefaults,
42018
42494
  userConfig: input.userConfig ?? null,
42019
42495
  configSourceDirectory: input.configSourceDirectory,
42020
42496
  onPartialFailure: (reason) => {
@@ -42863,7 +43339,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
42863
43339
  const securityScanFailedRef = yield* make$13(false);
42864
43340
  const securityScanFiber = yield* forkChild(runCollect(applyPerElementPipeline(isDiffMode ? empty$4 : unwrap(tryPromise(() => checkSecurityScanCooperative(scanDirectory, {
42865
43341
  project,
42866
- ignoredTags: input.ignoredTags
43342
+ ignoredTags: input.ignoredTags,
43343
+ includedTags: input.includedTags,
43344
+ includeTagDefaults: input.includeTagDefaults
42867
43345
  })).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)), catch_$1(() => set(securityScanFailedRef, true).pipe(as(empty$4))))))).pipe(withSpan("SecurityScan.run")));
42868
43346
  const shouldRunSupplyChain = !isDiffMode || (input.supplyChainManifestChanged ?? false);
42869
43347
  const supplyChainOverlapTimeout = yield* SupplyChainOverlapTimeoutMs;
@@ -42954,6 +43432,8 @@ const runInspect = (input, hooks = {}) => gen(function* () {
42954
43432
  respectInlineDisables: input.respectInlineDisables,
42955
43433
  adoptExistingLintConfig: input.adoptExistingLintConfig,
42956
43434
  ignoredTags: input.ignoredTags,
43435
+ includedTags: input.includedTags,
43436
+ includeTagDefaults: input.includeTagDefaults,
42957
43437
  userConfig: resolvedConfig.config ?? void 0,
42958
43438
  configSourceDirectory: resolvedConfig.configSourceDirectory ?? void 0,
42959
43439
  onFileProgress: (scannedFileCount, totalFileCount) => {
@@ -45456,5 +45936,5 @@ const startLanguageServer = () => {
45456
45936
  };
45457
45937
  //#endregion
45458
45938
  export { startLanguageServer };
45459
- !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]="2e6fca06-4d93-5b9e-86fd-92bfb63393e0")}catch(e){}}();
45460
- //# debugId=2e6fca06-4d93-5b9e-86fd-92bfb63393e0
45939
+ !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]="7883c0f4-2c18-5701-a9f3-47a33baca988")}catch(e){}}();
45940
+ //# debugId=7883c0f4-2c18-5701-a9f3-47a33baca988