react-doctor 0.8.1-dev.a667b45 → 0.8.1-dev.af33723

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/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]="14f17993-c8fc-5c43-a518-2b2055f5d836")}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]="d6c84ba6-2fee-56d3-ba17-e8408ecdedc5")}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";
@@ -32854,44 +32854,6 @@ var AmbiguousProjectError = class extends Error {
32854
32854
  }
32855
32855
  };
32856
32856
  const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
32857
- const isErrnoException = (error) => error instanceof Error && "code" in error;
32858
- const IGNORABLE_READDIR_ERROR_CODES = new Set([
32859
- "EACCES",
32860
- "EPERM",
32861
- "ENOENT",
32862
- "ENOTDIR",
32863
- "EINVAL",
32864
- "ELOOP",
32865
- "ENAMETOOLONG"
32866
- ]);
32867
- const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
32868
- const readDirectoryEntries = (directoryPath) => {
32869
- try {
32870
- return NFS.readdirSync(directoryPath, { withFileTypes: true });
32871
- } catch (error) {
32872
- if (isIgnorableReaddirError(error)) return [];
32873
- throw error;
32874
- }
32875
- };
32876
- const isFile = (filePath) => {
32877
- try {
32878
- return NFS.statSync(filePath).isFile();
32879
- } catch {
32880
- return false;
32881
- }
32882
- };
32883
- const isDirectory = (directoryPath) => {
32884
- try {
32885
- return NFS.statSync(directoryPath).isDirectory();
32886
- } catch {
32887
- return false;
32888
- }
32889
- };
32890
- const isPlainObject = (value) => {
32891
- if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
32892
- const prototype = Object.getPrototypeOf(value);
32893
- return prototype === null || prototype === Object.prototype;
32894
- };
32895
32857
  const SOURCE_FILE_PATTERN = /\.(tsx?|jsx?|mts|mjs)$/;
32896
32858
  const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
32897
32859
  const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
@@ -33050,6 +33012,44 @@ const SUPPLY_CHAIN_OVERLAP_TIMEOUT_MS = 9e4;
33050
33012
  const SUPPLY_CHAIN_CACHE_TTL_MS = 864e5;
33051
33013
  const SUPPLY_CHAIN_CACHE_SUBDIR = "supply-chain";
33052
33014
  const SUPPLY_CHAIN_IGNORED_PACKAGES = new Set(["next"]);
33015
+ const isErrnoException = (error) => error instanceof Error && "code" in error;
33016
+ const IGNORABLE_READDIR_ERROR_CODES = new Set([
33017
+ "EACCES",
33018
+ "EPERM",
33019
+ "ENOENT",
33020
+ "ENOTDIR",
33021
+ "EINVAL",
33022
+ "ELOOP",
33023
+ "ENAMETOOLONG"
33024
+ ]);
33025
+ const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
33026
+ const readDirectoryEntries = (directoryPath) => {
33027
+ try {
33028
+ return NFS.readdirSync(directoryPath, { withFileTypes: true });
33029
+ } catch (error) {
33030
+ if (isIgnorableReaddirError(error)) return [];
33031
+ throw error;
33032
+ }
33033
+ };
33034
+ const isFile = (filePath) => {
33035
+ try {
33036
+ return NFS.statSync(filePath).isFile();
33037
+ } catch {
33038
+ return false;
33039
+ }
33040
+ };
33041
+ const isDirectory = (directoryPath) => {
33042
+ try {
33043
+ return NFS.statSync(directoryPath).isDirectory();
33044
+ } catch {
33045
+ return false;
33046
+ }
33047
+ };
33048
+ const isPlainObject = (value) => {
33049
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
33050
+ const prototype = Object.getPrototypeOf(value);
33051
+ return prototype === null || prototype === Object.prototype;
33052
+ };
33053
33053
  const lastSourceMappingUrl = (fileContent) => {
33054
33054
  const lastReference = [...fileContent.matchAll(/\/\/# sourceMappingURL=(\S+)/g)].at(-1);
33055
33055
  return lastReference ? lastReference[1] : null;
@@ -33375,10 +33375,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
33375
33375
  const FRAMEWORK_PACKAGES = {
33376
33376
  next: "nextjs",
33377
33377
  "@tanstack/react-start": "tanstack-start",
33378
- vite: "vite",
33379
- "react-scripts": "cra",
33380
33378
  "@remix-run/react": "remix",
33381
33379
  gatsby: "gatsby",
33380
+ vite: "vite",
33381
+ "react-scripts": "cra",
33382
33382
  expo: "expo",
33383
33383
  "react-native": "react-native"
33384
33384
  };
@@ -33402,11 +33402,17 @@ const NEXT_CONFIG_FILENAMES = [
33402
33402
  ];
33403
33403
  const BABEL_CONFIG_FILENAMES = [
33404
33404
  ".babelrc",
33405
+ ".babelrc.js",
33405
33406
  ".babelrc.json",
33407
+ ".babelrc.cjs",
33408
+ ".babelrc.mjs",
33409
+ ".babelrc.cts",
33406
33410
  "babel.config.js",
33407
33411
  "babel.config.json",
33408
33412
  "babel.config.cjs",
33409
- "babel.config.mjs"
33413
+ "babel.config.mjs",
33414
+ "babel.config.ts",
33415
+ "babel.config.cts"
33410
33416
  ];
33411
33417
  const VITE_CONFIG_FILENAMES = [
33412
33418
  "vite.config.js",
@@ -33418,12 +33424,28 @@ const VITE_CONFIG_FILENAMES = [
33418
33424
  "vitest.config.ts",
33419
33425
  "vitest.config.js"
33420
33426
  ];
33427
+ const RSBUILD_CONFIG_FILENAMES = [
33428
+ "rsbuild.config.ts",
33429
+ "rsbuild.config.js",
33430
+ "rsbuild.config.mts",
33431
+ "rsbuild.config.mjs",
33432
+ "rsbuild.config.cts",
33433
+ "rsbuild.config.cjs"
33434
+ ];
33435
+ const RSPACK_CONFIG_FILENAMES = [
33436
+ "rspack.config.ts",
33437
+ "rspack.config.js",
33438
+ "rspack.config.mts",
33439
+ "rspack.config.mjs",
33440
+ "rspack.config.cts",
33441
+ "rspack.config.cjs"
33442
+ ];
33421
33443
  const EXPO_APP_CONFIG_FILENAMES = [
33422
33444
  "app.json",
33423
33445
  "app.config.js",
33424
33446
  "app.config.ts"
33425
33447
  ];
33426
- const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|["']react-compiler["']/;
33448
+ const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|reactCompilerPreset\s*\(|["']react-compiler["']/;
33427
33449
  const REACT_COMPILER_ENABLED_FLAG_PATTERN = /["']?reactCompiler["']?\s*:\s*(?:true\b|\{)/;
33428
33450
  const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
33429
33451
  const hasCompilerPackage = (packageJson, compilerPackages) => {
@@ -33458,6 +33480,8 @@ const detectReactCompiler = (directory, packageJson) => {
33458
33480
  if (hasCompilerInConfigFiles(directory, NEXT_CONFIG_FILENAMES)) return true;
33459
33481
  if (hasCompilerInConfigFiles(directory, BABEL_CONFIG_FILENAMES)) return true;
33460
33482
  if (hasCompilerInConfigFiles(directory, VITE_CONFIG_FILENAMES)) return true;
33483
+ if (hasCompilerInConfigFiles(directory, RSBUILD_CONFIG_FILENAMES)) return true;
33484
+ if (hasCompilerInConfigFiles(directory, RSPACK_CONFIG_FILENAMES)) return true;
33461
33485
  if (hasCompilerInConfigFiles(directory, EXPO_APP_CONFIG_FILENAMES)) return true;
33462
33486
  return hasCompilerPackageInAncestors(directory, REACT_COMPILER_TRANSFORM_PACKAGES);
33463
33487
  };
@@ -33599,6 +33623,16 @@ const getLowestDependencyMajor = (version) => {
33599
33623
  }
33600
33624
  return lowestMajor;
33601
33625
  };
33626
+ const getDependencyMajorWithinSupportedRange = (version, latestSupportedMajor) => {
33627
+ const normalizedVersion = normalizeDependencyVersion(version);
33628
+ if (normalizedVersion === null) return null;
33629
+ const validRange = import_semver.validRange(normalizedVersion);
33630
+ if (validRange === null) return null;
33631
+ const minimumVersion = import_semver.minVersion(validRange);
33632
+ if (minimumVersion === null || minimumVersion.major > latestSupportedMajor) return null;
33633
+ if (import_semver.intersects(validRange, `>=${latestSupportedMajor + 1}.0.0`)) return null;
33634
+ return minimumVersion.major;
33635
+ };
33602
33636
  const isConcreteDependencyVersion = (version) => {
33603
33637
  const normalizedVersion = normalizeDependencyVersion(version);
33604
33638
  return normalizedVersion !== null && /\d/.test(normalizedVersion);
@@ -33642,9 +33676,9 @@ const parseReactMajorMinor = (reactVersion) => {
33642
33676
  };
33643
33677
  };
33644
33678
  const parseLowerBoundVersion = (versionSpec) => import_semver.validRange(versionSpec) !== null ? import_semver.minVersion(versionSpec) : import_semver.coerce(versionSpec);
33645
- const parseTailwindMajorMinor = (tailwindVersion) => {
33646
- if (typeof tailwindVersion !== "string") return null;
33647
- const trimmed = tailwindVersion.trim();
33679
+ const parseDependencyMajorMinor = (dependencyVersion) => {
33680
+ if (typeof dependencyVersion !== "string") return null;
33681
+ const trimmed = dependencyVersion.trim();
33648
33682
  if (trimmed.length === 0) return null;
33649
33683
  const lowerBound = parseLowerBoundVersion(trimmed);
33650
33684
  if (lowerBound === null || lowerBound.major <= 0) return null;
@@ -33653,6 +33687,7 @@ const parseTailwindMajorMinor = (tailwindVersion) => {
33653
33687
  minor: lowerBound.minor
33654
33688
  };
33655
33689
  };
33690
+ const parseTailwindMajorMinor = (tailwindVersion) => parseDependencyMajorMinor(tailwindVersion);
33656
33691
  const hasUpperBoundOnlyPeerRange = (range) => {
33657
33692
  if (typeof range !== "string") return false;
33658
33693
  const normalizedRange = normalizeDependencyVersion(range);
@@ -33905,19 +33940,6 @@ const getPreactVersion = (packageJson) => {
33905
33940
  ...packageJson.devDependencies
33906
33941
  }.preact ?? null;
33907
33942
  };
33908
- const TANSTACK_QUERY_PACKAGES = new Set([
33909
- "@tanstack/react-query",
33910
- "@tanstack/query-core",
33911
- "react-query"
33912
- ]);
33913
- const hasTanStackQuery = (packageJson) => {
33914
- const allDependencies = {
33915
- ...packageJson.peerDependencies,
33916
- ...packageJson.dependencies,
33917
- ...packageJson.devDependencies
33918
- };
33919
- return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
33920
- };
33921
33943
  const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
33922
33944
  if (version === null || !isCatalogReference(version)) return version;
33923
33945
  const catalogName = extractCatalogName(version);
@@ -34120,7 +34142,60 @@ const listWorkspacePackages = (rootDirectory) => {
34120
34142
  }
34121
34143
  return packages;
34122
34144
  };
34145
+ const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
34146
+ const allDependencies = {
34147
+ ...packageJson.devDependencies,
34148
+ ...packageJson.peerDependencies,
34149
+ ...packageJson.dependencies
34150
+ };
34151
+ for (const packageName of packageNames) {
34152
+ const version = allDependencies[packageName];
34153
+ if (version !== void 0) return version;
34154
+ }
34155
+ return null;
34156
+ };
34157
+ const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
34158
+ const getTanStackQueryVersion = (packageJson) => {
34159
+ return getPreferredDependencyVersion({
34160
+ packageJson,
34161
+ packageNames: TANSTACK_REACT_QUERY_PACKAGES
34162
+ });
34163
+ };
34164
+ const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
34165
+ const getStyledComponentsVersion = (packageJson) => {
34166
+ return getPreferredDependencyVersion({
34167
+ packageJson,
34168
+ packageNames: STYLED_COMPONENTS_PACKAGES
34169
+ });
34170
+ };
34171
+ const I18N_PACKAGES = [
34172
+ "i18next",
34173
+ "react-i18next",
34174
+ "next-i18next",
34175
+ "react-intl",
34176
+ "next-intl",
34177
+ "use-intl",
34178
+ "@formatjs/intl",
34179
+ "@lingui/core",
34180
+ "@lingui/react",
34181
+ "typesafe-i18n",
34182
+ "@tolgee/react",
34183
+ "react-intl-universal"
34184
+ ];
34185
+ const hasI18nDependency = (packageJson) => {
34186
+ const allDependencies = {
34187
+ ...packageJson.peerDependencies,
34188
+ ...packageJson.dependencies,
34189
+ ...packageJson.devDependencies,
34190
+ ...packageJson.optionalDependencies
34191
+ };
34192
+ return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
34193
+ };
34123
34194
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34195
+ const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34196
+ const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34197
+ const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34198
+ const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34124
34199
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34125
34200
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34126
34201
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34139,7 +34214,62 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34139
34214
  if (nextMajor === null) return false;
34140
34215
  return nextMajor < currentMajor;
34141
34216
  };
34142
- const evaluateManifestFacts = (facts, packageJson, directory) => {
34217
+ const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34218
+ if (currentFact.version === null) return true;
34219
+ if (nextFact.version === null) return false;
34220
+ const currentMajor = getLowestDependencyMajor(currentFact.version);
34221
+ const nextMajor = getLowestDependencyMajor(nextFact.version);
34222
+ if (currentMajor === null) return false;
34223
+ if (nextMajor === null) return true;
34224
+ if (currentMajor > latestSupportedMajor) return false;
34225
+ if (nextMajor > latestSupportedMajor) return true;
34226
+ return nextMajor < currentMajor;
34227
+ };
34228
+ const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
34229
+ if (!currentVersion) return true;
34230
+ const currentMajor = getLowestDependencyMajor(currentVersion);
34231
+ const nextMajor = getLowestDependencyMajor(nextVersion);
34232
+ if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
34233
+ if (nextMajor === null) return currentMajor >= 6;
34234
+ return nextMajor < currentMajor;
34235
+ };
34236
+ const selectOldestDependencyVersion = (currentVersion, nextVersion) => {
34237
+ if (currentVersion === null || nextVersion === null) return null;
34238
+ const current = parseDependencyMajorMinor(currentVersion);
34239
+ const next = parseDependencyMajorMinor(nextVersion);
34240
+ if (current === null) return currentVersion;
34241
+ if (next === null) return nextVersion;
34242
+ if (next.major !== current.major) return next.major < current.major ? nextVersion : currentVersion;
34243
+ return next.minor < current.minor ? nextVersion : currentVersion;
34244
+ };
34245
+ const shouldReplaceMobxFact = (currentFact, nextFact) => {
34246
+ if (currentFact.sourceDirectory === null) return true;
34247
+ if (currentFact.version === null) return false;
34248
+ if (nextFact.version === null) return true;
34249
+ const currentMajor = getDependencyMajorWithinSupportedRange(currentFact.version, 6);
34250
+ const nextMajor = getDependencyMajorWithinSupportedRange(nextFact.version, 6);
34251
+ if (currentMajor === null) return false;
34252
+ if (nextMajor === null) return true;
34253
+ return selectOldestDependencyVersion(currentFact.version, nextFact.version) === nextFact.version;
34254
+ };
34255
+ const collectBindingVersion = (facts, packageJson, directory, packageName) => {
34256
+ const version = getDependencySpec(packageJson, packageName);
34257
+ if (version === null) return;
34258
+ const resolvedVersion = resolveCatalogBackedDependencyVersion({
34259
+ rootDirectory: directory,
34260
+ rootPackageJson: packageJson,
34261
+ packageName,
34262
+ version
34263
+ });
34264
+ if (packageName === MOBX_REACT_PACKAGE_NAME) {
34265
+ facts.mobxReactVersion = facts.hasMobxReact ? selectOldestDependencyVersion(facts.mobxReactVersion, resolvedVersion) : resolvedVersion;
34266
+ facts.hasMobxReact = true;
34267
+ return;
34268
+ }
34269
+ facts.mobxReactLiteVersion = facts.hasMobxReactLite ? selectOldestDependencyVersion(facts.mobxReactLiteVersion, resolvedVersion) : resolvedVersion;
34270
+ facts.hasMobxReactLite = true;
34271
+ };
34272
+ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34143
34273
  if (facts.expo.version === null) {
34144
34274
  const spec = getDependencySpec(packageJson, "expo");
34145
34275
  if (spec !== null) facts.expo = {
@@ -34161,13 +34291,74 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
34161
34291
  sourceDirectory: directory
34162
34292
  };
34163
34293
  }
34294
+ const mobxSpec = getDependencySpec(packageJson, "mobx");
34295
+ if (mobxSpec !== null) {
34296
+ const nextMobxFact = {
34297
+ version: resolveCatalogBackedDependencyVersion({
34298
+ rootDirectory: directory,
34299
+ rootPackageJson: packageJson,
34300
+ packageName: "mobx",
34301
+ version: mobxSpec
34302
+ }),
34303
+ sourceDirectory: directory
34304
+ };
34305
+ if (shouldReplaceMobxFact(facts.mobx, nextMobxFact)) facts.mobx = nextMobxFact;
34306
+ }
34307
+ collectBindingVersion(facts, packageJson, directory, MOBX_REACT_PACKAGE_NAME);
34308
+ collectBindingVersion(facts, packageJson, directory, MOBX_REACT_LITE_PACKAGE_NAME);
34309
+ facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34310
+ facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34311
+ const zustandSpec = getDependencySpec(packageJson, "zustand");
34312
+ if (zustandSpec !== null) {
34313
+ const nextZustandFact = {
34314
+ version: resolveCatalogBackedDependencyVersion({
34315
+ rootDirectory: directory,
34316
+ rootPackageJson: packageJson,
34317
+ packageName: "zustand",
34318
+ version: zustandSpec
34319
+ }),
34320
+ sourceDirectory: directory
34321
+ };
34322
+ if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34323
+ }
34164
34324
  if (facts.reanimatedVersion === null) {
34165
34325
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34166
34326
  if (spec !== null) facts.reanimatedVersion = spec;
34167
34327
  }
34328
+ if (facts.valtioVersion === null) {
34329
+ const spec = getDependencySpec(packageJson, "valtio");
34330
+ if (spec !== null) facts.valtioVersion = spec;
34331
+ }
34332
+ facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
34333
+ const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
34334
+ rootDirectory: directory,
34335
+ rootPackageJson: packageJson,
34336
+ packageName: "styled-components",
34337
+ version: getStyledComponentsVersion(packageJson)
34338
+ });
34339
+ if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
34340
+ facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
34168
34341
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34169
34342
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34170
34343
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34344
+ const remotionSpec = getDependencySpec(packageJson, "remotion");
34345
+ if (remotionSpec !== null) {
34346
+ facts.hasRemotionDependency = true;
34347
+ const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34348
+ rootDirectory,
34349
+ rootPackageJson,
34350
+ packageName: "remotion",
34351
+ version: remotionSpec
34352
+ });
34353
+ const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34354
+ if (remotionMajorVersion === null) {
34355
+ facts.hasUnknownRemotionVersion = true;
34356
+ facts.remotionVersion = null;
34357
+ } else if (!facts.hasUnknownRemotionVersion) {
34358
+ const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34359
+ if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34360
+ }
34361
+ }
34171
34362
  };
34172
34363
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34173
34364
  const facts = {
@@ -34187,12 +34378,33 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34187
34378
  version: null,
34188
34379
  sourceDirectory: null
34189
34380
  },
34381
+ valtioVersion: null,
34382
+ mobx: {
34383
+ version: null,
34384
+ sourceDirectory: null
34385
+ },
34386
+ hasMobxReact: false,
34387
+ mobxReactVersion: null,
34388
+ hasMobxReactLite: false,
34389
+ mobxReactLiteVersion: null,
34390
+ hasMobxStateTree: false,
34391
+ hasMobxReactObserver: false,
34392
+ zustand: {
34393
+ version: null,
34394
+ sourceDirectory: null
34395
+ },
34396
+ tanstackQueryVersion: null,
34397
+ styledComponentsVersion: null,
34398
+ hasI18nLibrary: false,
34190
34399
  hasReactNativeAwarePackage: false,
34191
34400
  hasReanimatedAwarePackage: false,
34192
34401
  hasSsrDependency: false,
34402
+ hasRemotionDependency: false,
34403
+ hasUnknownRemotionVersion: false,
34404
+ remotionVersion: null,
34193
34405
  reanimatedVersion: null
34194
34406
  };
34195
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34407
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34196
34408
  let isReactGroupSettled = !collectReactGroup;
34197
34409
  const visitedDirectories = /* @__PURE__ */ new Set();
34198
34410
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34201,7 +34413,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34201
34413
  if (visitedDirectories.has(workspaceDirectory)) continue;
34202
34414
  visitedDirectories.add(workspaceDirectory);
34203
34415
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34204
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34416
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34205
34417
  const info = extractDependencyInfo(workspacePackageJson);
34206
34418
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34207
34419
  if (isReactGroupSettled) continue;
@@ -34425,11 +34637,29 @@ const discoverProjectWithoutPackageJson = (directory) => {
34425
34637
  tailwindVersion: null,
34426
34638
  zodVersion: null,
34427
34639
  zodMajorVersion: null,
34640
+ mobxVersion: null,
34641
+ mobxMajorVersion: null,
34642
+ hasMobxReact: false,
34643
+ mobxReactVersion: null,
34644
+ hasMobxReactLite: false,
34645
+ mobxReactLiteVersion: null,
34646
+ hasMobxStateTree: false,
34647
+ hasMobxReactObserver: false,
34648
+ zustandVersion: null,
34649
+ zustandMajorVersion: null,
34428
34650
  framework: "unknown",
34429
34651
  hasTypeScript: hasOwnTsConfig,
34430
34652
  hasReactCompiler: false,
34431
34653
  hasReactCompilerLintPlugin: false,
34432
34654
  hasTanStackQuery: false,
34655
+ valtioVersion: null,
34656
+ valtioMajorVersion: null,
34657
+ hasRemotion: false,
34658
+ remotionVersion: null,
34659
+ remotionMajorVersion: null,
34660
+ hasI18nLibrary: false,
34661
+ tanstackQueryVersion: null,
34662
+ styledComponentsVersion: null,
34433
34663
  hasSsrDependency: false,
34434
34664
  preactVersion: null,
34435
34665
  preactMajorVersion: null,
@@ -34528,6 +34758,12 @@ const discoverProject = (directory) => {
34528
34758
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34529
34759
  version: workspaceFacts.shopifyFlashList.version
34530
34760
  }) : null;
34761
+ const zustandVersion = resolveCatalogBackedDependencyVersion({
34762
+ rootDirectory: directory,
34763
+ rootPackageJson: packageJson,
34764
+ packageName: "zustand",
34765
+ version: workspaceFacts.zustand.version
34766
+ });
34531
34767
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34532
34768
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34533
34769
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34536,7 +34772,21 @@ const discoverProject = (directory) => {
34536
34772
  packageName: "next",
34537
34773
  version: workspaceFacts.next.version
34538
34774
  }) : null;
34775
+ const valtioVersion = resolveCatalogBackedDependencyVersion({
34776
+ rootDirectory: directory,
34777
+ rootPackageJson: packageJson,
34778
+ packageName: "valtio",
34779
+ version: workspaceFacts.valtioVersion
34780
+ });
34781
+ const mobxVersion = resolveCatalogBackedDependencyVersion({
34782
+ rootDirectory: directory,
34783
+ rootPackageJson: packageJson,
34784
+ packageName: "mobx",
34785
+ version: workspaceFacts.mobx.version
34786
+ });
34539
34787
  const preactVersion = getPreactVersion(packageJson);
34788
+ const remotionVersion = workspaceFacts.remotionVersion;
34789
+ const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
34540
34790
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34541
34791
  const projectInfo = {
34542
34792
  rootDirectory: directory,
@@ -34546,11 +34796,29 @@ const discoverProject = (directory) => {
34546
34796
  tailwindVersion,
34547
34797
  zodVersion,
34548
34798
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34799
+ mobxVersion,
34800
+ mobxMajorVersion: mobxVersion === null ? null : getDependencyMajorWithinSupportedRange(mobxVersion, 6),
34801
+ hasMobxReact: workspaceFacts.hasMobxReact,
34802
+ mobxReactVersion: workspaceFacts.mobxReactVersion,
34803
+ hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34804
+ mobxReactLiteVersion: workspaceFacts.mobxReactLiteVersion,
34805
+ hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34806
+ hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34807
+ zustandVersion,
34808
+ zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34549
34809
  framework,
34550
34810
  hasTypeScript,
34551
34811
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34552
34812
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34553
- hasTanStackQuery: hasTanStackQuery(packageJson),
34813
+ hasTanStackQuery: tanstackQueryVersion !== null,
34814
+ hasI18nLibrary: workspaceFacts.hasI18nLibrary,
34815
+ tanstackQueryVersion,
34816
+ styledComponentsVersion: workspaceFacts.styledComponentsVersion,
34817
+ valtioVersion,
34818
+ valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34819
+ hasRemotion: workspaceFacts.hasRemotionDependency,
34820
+ remotionVersion,
34821
+ remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34554
34822
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34555
34823
  preactVersion,
34556
34824
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -34784,7 +35052,6 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
34784
35052
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
34785
35053
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
34786
35054
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
34787
- "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
34788
35055
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
34789
35056
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
34790
35057
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -37071,9 +37338,25 @@ const BABEL_CONFIG_FILE_NAMES = [
37071
37338
  ".babelrc.json"
37072
37339
  ];
37073
37340
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37341
+ const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37342
+ const REACT_NATIVE_PACKAGE = "react-native";
37343
+ const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37344
+ const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37074
37345
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37075
37346
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37347
+ const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37348
+ const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37349
+ const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37350
+ if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37351
+ const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37352
+ if (normalizedVersionRange === null) return false;
37353
+ const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37354
+ return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37355
+ };
37356
+ const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37076
37357
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37358
+ const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37359
+ const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37077
37360
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37078
37361
  const filePath = Path.join(rootDirectory, fileName);
37079
37362
  if (!isFile(filePath)) continue;
@@ -37083,7 +37366,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37083
37366
  } catch {
37084
37367
  continue;
37085
37368
  }
37086
- if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37369
+ if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37087
37370
  filePath: fileName,
37088
37371
  rule: "rn-no-metro-babel-preset",
37089
37372
  severity: "error",
@@ -37106,12 +37389,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
37106
37389
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37107
37390
  };
37108
37391
  const RULE_KEY = "no-vulnerable-react-server-components";
37109
- const DEPENDENCY_SECTIONS = [
37110
- "dependencies",
37111
- "devDependencies",
37112
- "peerDependencies",
37113
- "optionalDependencies"
37114
- ];
37115
37392
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37116
37393
  "19.0": {
37117
37394
  rceFixedVersion: "19.0.1",
@@ -37158,20 +37435,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37158
37435
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37159
37436
  return [...directories];
37160
37437
  };
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
- };
37168
37438
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37169
37439
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37170
37440
  if (isFile(manifestPath)) {
37171
37441
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37172
37442
  if (installedVersion !== null) return installedVersion;
37173
37443
  }
37174
- const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37444
+ const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37175
37445
  for (const spec of candidateSpecs) {
37176
37446
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37177
37447
  if (pinnedVersion !== null) return pinnedVersion;
@@ -37839,21 +38109,68 @@ const buildCapabilities = (project) => {
37839
38109
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
37840
38110
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
37841
38111
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
38112
+ if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
37842
38113
  addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
37843
38114
  if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
37844
38115
  major: 19,
37845
38116
  minor: 2
37846
38117
  })) capabilities.add("react:19.2");
37847
- if (project.tailwindVersion !== null) capabilities.add("tailwind");
37848
- if (project.tailwindVersion !== null && isMajorMinorAtLeast(parseTailwindMajorMinor(project.tailwindVersion), {
37849
- major: 3,
37850
- minor: 4
37851
- })) capabilities.add("tailwind:3.4");
38118
+ if (project.tailwindVersion !== null) {
38119
+ capabilities.add("tailwind");
38120
+ const tailwindVersion = parseTailwindMajorMinor(project.tailwindVersion);
38121
+ if (isMajorMinorAtLeast(tailwindVersion, {
38122
+ major: 3,
38123
+ minor: 4
38124
+ })) capabilities.add("tailwind:3.4");
38125
+ if (tailwindVersion !== null && isMajorMinorAtLeast(tailwindVersion, {
38126
+ major: 4,
38127
+ minor: 0
38128
+ })) capabilities.add("tailwind:4");
38129
+ }
37852
38130
  if (project.zodVersion !== null) capabilities.add("zod");
37853
38131
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
38132
+ if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
38133
+ if (project.hasMobxReact === true) capabilities.add("mobx-react");
38134
+ if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
38135
+ if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
38136
+ const mobxReactVersion = parseDependencyMajorMinor(project.mobxReactVersion);
38137
+ const mobxReactLiteVersion = parseDependencyMajorMinor(project.mobxReactLiteVersion);
38138
+ const hasMobxReactObserverMemoGuard = mobxReactVersion !== null && isMajorMinorAtLeast(mobxReactVersion, {
38139
+ major: 7,
38140
+ minor: 3
38141
+ });
38142
+ const hasMobxReactLiteObserverMemoGuard = mobxReactLiteVersion !== null && isMajorMinorAtLeast(mobxReactLiteVersion, {
38143
+ major: 3,
38144
+ minor: 3
38145
+ });
38146
+ if (hasMobxReactObserverMemoGuard) capabilities.add("mobx-react-observer-memo-guard");
38147
+ if (hasMobxReactLiteObserverMemoGuard) capabilities.add("mobx-react-lite-observer-memo-guard");
38148
+ if (hasMobxReactObserverMemoGuard || hasMobxReactLiteObserverMemoGuard) capabilities.add("mobx-react-binding-observer-memo-guard");
38149
+ if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
38150
+ if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
38151
+ if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
38152
+ const mobxVersion = parseDependencyMajorMinor(project.mobxVersion);
38153
+ if (project.mobxMajorVersion === 6 && mobxVersion !== null && isMajorMinorAtLeast(mobxVersion, {
38154
+ major: 6,
38155
+ minor: 10
38156
+ })) capabilities.add("mobx:6.10");
38157
+ if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
38158
+ if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
37854
38159
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
37855
38160
  if (project.hasReactCompiler) capabilities.add("react-compiler");
37856
- if (project.hasTanStackQuery) capabilities.add("tanstack-query");
38161
+ if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
38162
+ if (project.styledComponentsVersion) {
38163
+ capabilities.add("styled-components");
38164
+ const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
38165
+ if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
38166
+ }
38167
+ if (project.hasI18nLibrary) capabilities.add("i18n");
38168
+ if (project.valtioVersion !== null) capabilities.add("valtio");
38169
+ addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
38170
+ if (project.hasRemotion) {
38171
+ capabilities.add("remotion");
38172
+ addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
38173
+ }
37857
38174
  if (project.hasTypeScript) capabilities.add("typescript");
37858
38175
  if (project.preactVersion !== null) capabilities.add("preact");
37859
38176
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -37868,7 +38185,7 @@ const getCapabilities = (project) => {
37868
38185
  capabilitiesByProject.set(project, capabilities);
37869
38186
  return capabilities;
37870
38187
  };
37871
- const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen) => {
38188
+ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen, includedTags) => {
37872
38189
  if (requires) {
37873
38190
  for (const capability of requires) if (!capabilities.has(capability)) return false;
37874
38191
  }
@@ -37879,20 +38196,29 @@ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhe
37879
38196
  if (tags) {
37880
38197
  for (const tag of tags) if (ignoredTags.has(tag)) return false;
37881
38198
  }
38199
+ if (includedTags && includedTags.size > 0) {
38200
+ if (!tags?.some((tag) => includedTags.has(tag))) return false;
38201
+ }
37882
38202
  return true;
37883
38203
  };
38204
+ const shouldEnableRuleByDefaultStatus = (options) => options.defaultEnabled !== false || options.hasExplicitOverride === true || options.includeTagDefaults && options.hasIncludedTags;
37884
38205
  const yieldToEventLoop = () => new Promise((resolve) => {
37885
38206
  setImmediate(resolve);
37886
38207
  });
37887
38208
  const createSecurityScanSession = (rootDirectory, options) => {
37888
38209
  const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
37889
38210
  const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
38211
+ const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
37890
38212
  const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
37891
38213
  const rule = entry.rule;
37892
38214
  const scan = rule.scan;
37893
38215
  if (typeof scan !== "function") return [];
37894
- if (rule.defaultEnabled === false) return [];
37895
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) return [];
38216
+ if (!shouldEnableRuleByDefaultStatus({
38217
+ defaultEnabled: rule.defaultEnabled,
38218
+ includeTagDefaults: options.includeTagDefaults === true,
38219
+ hasIncludedTags: includedTags.size > 0
38220
+ })) return [];
38221
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) return [];
37896
38222
  return [{
37897
38223
  entry,
37898
38224
  scan,
@@ -39878,8 +40204,9 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
39878
40204
  }
39879
40205
  return enabled;
39880
40206
  };
39881
- const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
39882
- const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
40207
+ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
40208
+ const hasIncludedTags = includedTags.size > 0;
40209
+ const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
39883
40210
  const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
39884
40211
  const jsPlugins = [];
39885
40212
  if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
@@ -39894,9 +40221,14 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
39894
40221
  if (rule.scan !== void 0) continue;
39895
40222
  if (customRulesOnly && registryEntry.originallyExternal) continue;
39896
40223
  if (rule.framework !== "global" && !rule.requires) continue;
39897
- if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) continue;
40224
+ if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
39898
40225
  const explicitRuleOverride = resolveRuleSeverityOverride({ ruleKey: registryEntry.key }, severityControls);
39899
- if (rule.defaultEnabled === false && explicitRuleOverride === void 0) continue;
40226
+ if (!shouldEnableRuleByDefaultStatus({
40227
+ defaultEnabled: rule.defaultEnabled,
40228
+ includeTagDefaults,
40229
+ hasIncludedTags,
40230
+ hasExplicitOverride: explicitRuleOverride !== void 0
40231
+ })) continue;
39900
40232
  const severity = resolveRuleSeverityOverride({
39901
40233
  ruleKey: registryEntry.key,
39902
40234
  category: rule.category
@@ -39905,7 +40237,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
39905
40237
  enabledReactDoctorRules[registryEntry.key] = severity;
39906
40238
  }
39907
40239
  const userPluginRules = {};
39908
- if (ruleSelection !== "sidecar") for (const userPlugin of userPlugins) {
40240
+ if (ruleSelection !== "sidecar" && !hasIncludedTags) for (const userPlugin of userPlugins) {
39909
40241
  Object.assign(userPluginRules, buildUserPluginRules(userPlugin, severityControls));
39910
40242
  jsPlugins.push(userPlugin.entry);
39911
40243
  }
@@ -40122,6 +40454,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
40122
40454
  }
40123
40455
  };
40124
40456
  };
40457
+ const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
40458
+ const fingerprintFileContents = (filePath, fingerprintLength) => {
40459
+ const fileStats = NFS.statSync(filePath, { bigint: true });
40460
+ const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
40461
+ if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
40462
+ const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
40463
+ fingerprintCacheByFilePath.set(filePath, {
40464
+ fingerprint,
40465
+ modifiedTimeNanoseconds: fileStats.mtimeNs,
40466
+ sizeBytes: fileStats.size
40467
+ });
40468
+ return fingerprint;
40469
+ };
40125
40470
  const bundledRequire = createRequire(import.meta.url);
40126
40471
  const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
40127
40472
  const resolveChildNodeVersion = (nodeBinaryPath) => {
@@ -40145,6 +40490,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
40145
40490
  "oxlint-plugin-react-doctor/package.json",
40146
40491
  "eslint-plugin-react-hooks/package.json"
40147
40492
  ];
40493
+ const resolvePluginFingerprint = () => {
40494
+ try {
40495
+ return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
40496
+ } catch {
40497
+ return "unresolved";
40498
+ }
40499
+ };
40148
40500
  const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40149
40501
  const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
40150
40502
  for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
@@ -40154,6 +40506,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40154
40506
  } catch {
40155
40507
  versions.push(`${specifier}=missing`);
40156
40508
  }
40509
+ versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
40157
40510
  return versions;
40158
40511
  };
40159
40512
  const esmRequire = createRequire(import.meta.url);
@@ -41629,7 +41982,7 @@ const reactHooksJsPluginDropNote = (error) => {
41629
41982
  * 6. always restore disable directives + clean up the temp dir
41630
41983
  */
41631
41984
  const runOxlint = async (options) => {
41632
- 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;
41985
+ 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;
41633
41986
  const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
41634
41987
  const severityControls = buildRuleSeverityControls(userConfig);
41635
41988
  validateRuleRegistration();
@@ -41643,13 +41996,15 @@ const runOxlint = async (options) => {
41643
41996
  }
41644
41997
  const pluginPath = resolvePluginPath();
41645
41998
  const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
41646
- const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
41999
+ const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
41647
42000
  const buildConfig = (overrides) => createOxlintConfig({
41648
42001
  pluginPath,
41649
42002
  project,
41650
42003
  customRulesOnly,
41651
42004
  extendsPaths: overrides.extendsPaths,
41652
42005
  ignoredTags,
42006
+ includedTags,
42007
+ includeTagDefaults,
41653
42008
  serverAuthFunctionNames,
41654
42009
  severityControls,
41655
42010
  userPlugins,
@@ -42038,6 +42393,8 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
42038
42393
  respectInlineDisables: input.respectInlineDisables,
42039
42394
  adoptExistingLintConfig: input.adoptExistingLintConfig,
42040
42395
  ignoredTags: input.ignoredTags,
42396
+ includedTags: input.includedTags,
42397
+ includeTagDefaults: input.includeTagDefaults,
42041
42398
  userConfig: input.userConfig ?? null,
42042
42399
  configSourceDirectory: input.configSourceDirectory,
42043
42400
  onPartialFailure: (reason) => {
@@ -42886,7 +43243,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
42886
43243
  const securityScanFailedRef = yield* make$13(false);
42887
43244
  const securityScanFiber = yield* forkChild(runCollect(applyPerElementPipeline(isDiffMode ? empty$4 : unwrap(tryPromise(() => checkSecurityScanCooperative(scanDirectory, {
42888
43245
  project,
42889
- ignoredTags: input.ignoredTags
43246
+ ignoredTags: input.ignoredTags,
43247
+ includedTags: input.includedTags,
43248
+ includeTagDefaults: input.includeTagDefaults
42890
43249
  })).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)), catch_$1(() => set(securityScanFailedRef, true).pipe(as(empty$4))))))).pipe(withSpan("SecurityScan.run")));
42891
43250
  const shouldRunSupplyChain = !isDiffMode || (input.supplyChainManifestChanged ?? false);
42892
43251
  const supplyChainOverlapTimeout = yield* SupplyChainOverlapTimeoutMs;
@@ -42977,6 +43336,8 @@ const runInspect = (input, hooks = {}) => gen(function* () {
42977
43336
  respectInlineDisables: input.respectInlineDisables,
42978
43337
  adoptExistingLintConfig: input.adoptExistingLintConfig,
42979
43338
  ignoredTags: input.ignoredTags,
43339
+ includedTags: input.includedTags,
43340
+ includeTagDefaults: input.includeTagDefaults,
42980
43341
  userConfig: resolvedConfig.config ?? void 0,
42981
43342
  configSourceDirectory: resolvedConfig.configSourceDirectory ?? void 0,
42982
43343
  onFileProgress: (scannedFileCount, totalFileCount) => {
@@ -43837,4 +44198,4 @@ const toJsonReport = (result, options) => buildJsonReport({
43837
44198
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
43838
44199
 
43839
44200
  //# sourceMappingURL=index.js.map
43840
- //# debugId=14f17993-c8fc-5c43-a518-2b2055f5d836
44201
+ //# debugId=d6c84ba6-2fee-56d3-ba17-e8408ecdedc5