react-doctor 0.8.1-dev.6fcd9c9 → 0.8.1-dev.7818922

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.d.ts CHANGED
@@ -9030,12 +9030,11 @@ interface Diagnostic {
9030
9030
  * Set when the finding's identity is the flagged element itself (a missing
9031
9031
  * attribute, a wrong element) rather than the flagged line's text — every
9032
9032
  * Accessibility-category finding, plus rules that opt in via their
9033
- * `matchByOccurrence` metadata flag. After strict evidence matching,
9034
- * `computeDiagnosticDelta` may match these by same-file `(plugin/rule,
9035
- * message)` occurrence count, so reformatting the flagged element doesn't
9036
- * reclassify a pre-existing finding as new. Resolved at diagnostic creation,
9037
- * where rule metadata is available. Absent means diagnosed-source-sensitive
9038
- * matching (the default).
9033
+ * `matchByOccurrence` metadata flag. `computeDiagnosticDelta` matches these
9034
+ * by `(filePath, plugin/rule)` occurrence count, so reformatting the flagged
9035
+ * line doesn't reclassify a pre-existing finding as new. Resolved at
9036
+ * diagnostic creation, where rule metadata is available. Absent means
9037
+ * line-text-sensitive matching (the default).
9039
9038
  */
9040
9039
  matchByOccurrence?: boolean;
9041
9040
  /**
@@ -9543,35 +9542,11 @@ interface ProjectInfo {
9543
9542
  zodVersion: string | null;
9544
9543
  /** Parsed major from `zodVersion`, or `null` when absent/unparseable. Mirrors `reactMajorVersion`. */
9545
9544
  zodMajorVersion: number | null;
9546
- /** Declared MobX core version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
9547
- mobxVersion?: string | null;
9548
- /** Parsed major from `mobxVersion`, or `null` when absent/unparseable. */
9549
- mobxMajorVersion?: number | null;
9550
- hasMobxReact?: boolean;
9551
- hasMobxReactLite?: boolean;
9552
- hasMobxStateTree?: boolean;
9553
- hasMobxReactObserver?: boolean;
9554
- /** Declared Zustand version spec. Optional so existing `ProjectInfo` consumers remain source-compatible. */
9555
- zustandVersion?: string | null;
9556
- /** Parsed major from `zustandVersion`, or `null` when absent/unparseable. */
9557
- zustandMajorVersion?: number | null;
9558
9545
  framework: Framework;
9559
9546
  hasTypeScript: boolean;
9560
9547
  hasReactCompiler: boolean;
9561
9548
  hasReactCompilerLintPlugin?: boolean;
9562
9549
  hasTanStackQuery: boolean;
9563
- hasRemotion?: boolean;
9564
- remotionVersion?: string | null;
9565
- remotionMajorVersion?: number | null;
9566
- /**
9567
- * The declared `valtio` version spec, or `null` when no package in the
9568
- * analyzed project declares Valtio. `useSnapshot` has kept the same
9569
- * render-read contract across Valtio 1 and 2, so presence alone drives the
9570
- * `valtio` capability and its parsed major-version ladder.
9571
- */
9572
- valtioVersion: string | null;
9573
- /** Parsed major from `valtioVersion`, or `null` when absent/unparseable. */
9574
- valtioMajorVersion: number | null;
9575
9550
  /**
9576
9551
  * `true` when the project or a workspace declares a Vite-based SSR runtime
9577
9552
  * such as React Router's Node adapter, Vike, or vite-plugin-ssr.
@@ -9872,8 +9847,7 @@ interface InspectResult {
9872
9847
  baselineDelta?: {
9873
9848
  /** The commit the base content was read from (resolved merge-base). */baseRef: string; /** Findings present at base but gone at head — resolved by the change. */
9874
9849
  fixedCount: number; /** Total findings at base (over the same files), for context. */
9875
- baseTotalCount: number; /** Pre-existing findings matched after moving to a different file. */
9876
- crossFileMatchCount?: number;
9850
+ baseTotalCount: number;
9877
9851
  };
9878
9852
  }
9879
9853
  /**
@@ -10289,7 +10263,15 @@ declare const buildJsonReport: (input: BuildJsonReportInput) => JsonReportV3$1;
10289
10263
  * `GitBaseBranchMissing`) as clean user errors instead of crashes.
10290
10264
  */
10291
10265
  declare const getDiffInfo: (directory: string, explicitBaseBranch?: string, includeUntracked?: boolean) => Promise<DiffInfo | null>;
10292
- declare const filterSourceFiles: (filePaths: ReadonlyArray<string>) => string[];
10266
+ declare const filterSourceFiles: (filePaths: string[]) => string[];
10267
+ /**
10268
+ * Programmatic façade over `Git.changedLineRanges` (the `lines` scope). Diffs
10269
+ * `files` with `--unified=0` against `baseRef` (or the index when `cached`),
10270
+ * returning per-file changed line ranges relative to `directory`. Returns
10271
+ * `null` when the ranges can't be computed (git unavailable / unsafe ref /
10272
+ * non-zero exit) so the caller degrades to file-level scope; an empty array
10273
+ * means git succeeded but the files added no lines.
10274
+ */
10293
10275
  //#endregion
10294
10276
  //#region src/summarize-diagnostics.d.ts
10295
10277
  declare const summarizeDiagnostics: (diagnostics: Diagnostic[], worstScore?: number | null, worstScoreLabel?: string | null) => JsonReportSummary; //#endregion
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6aa1c6e1-8fcc-50d4-a076-3e864425bdc5")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3121a4e4-8a4a-55ea-ade8-47d0bf576a2f")}catch(e){}}();
3
3
  import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
4
4
  import { createRequire } from "node:module";
5
5
  import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
@@ -34121,10 +34121,6 @@ const listWorkspacePackages = (rootDirectory) => {
34121
34121
  return packages;
34122
34122
  };
34123
34123
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34124
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34125
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34126
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34127
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34128
34124
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34129
34125
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34130
34126
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34143,18 +34139,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34143
34139
  if (nextMajor === null) return false;
34144
34140
  return nextMajor < currentMajor;
34145
34141
  };
34146
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34147
- if (currentFact.version === null) return true;
34148
- if (nextFact.version === null) return false;
34149
- const currentMajor = getLowestDependencyMajor(currentFact.version);
34150
- const nextMajor = getLowestDependencyMajor(nextFact.version);
34151
- if (currentMajor === null) return false;
34152
- if (nextMajor === null) return true;
34153
- if (currentMajor > latestSupportedMajor) return false;
34154
- if (nextMajor > latestSupportedMajor) return true;
34155
- return nextMajor < currentMajor;
34156
- };
34157
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34142
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
34158
34143
  if (facts.expo.version === null) {
34159
34144
  const spec = getDependencySpec(packageJson, "expo");
34160
34145
  if (spec !== null) facts.expo = {
@@ -34176,65 +34161,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
34176
34161
  sourceDirectory: directory
34177
34162
  };
34178
34163
  }
34179
- const mobxSpec = getDependencySpec(packageJson, "mobx");
34180
- if (mobxSpec !== null) {
34181
- const nextMobxFact = {
34182
- version: resolveCatalogBackedDependencyVersion({
34183
- rootDirectory: directory,
34184
- rootPackageJson: packageJson,
34185
- packageName: "mobx",
34186
- version: mobxSpec
34187
- }),
34188
- sourceDirectory: directory
34189
- };
34190
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
34191
- }
34192
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
34193
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
34194
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34195
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34196
- const zustandSpec = getDependencySpec(packageJson, "zustand");
34197
- if (zustandSpec !== null) {
34198
- const nextZustandFact = {
34199
- version: resolveCatalogBackedDependencyVersion({
34200
- rootDirectory: directory,
34201
- rootPackageJson: packageJson,
34202
- packageName: "zustand",
34203
- version: zustandSpec
34204
- }),
34205
- sourceDirectory: directory
34206
- };
34207
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34208
- }
34209
34164
  if (facts.reanimatedVersion === null) {
34210
34165
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34211
34166
  if (spec !== null) facts.reanimatedVersion = spec;
34212
34167
  }
34213
- if (facts.valtioVersion === null) {
34214
- const spec = getDependencySpec(packageJson, "valtio");
34215
- if (spec !== null) facts.valtioVersion = spec;
34216
- }
34217
34168
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34218
34169
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34219
34170
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34220
- const remotionSpec = getDependencySpec(packageJson, "remotion");
34221
- if (remotionSpec !== null) {
34222
- facts.hasRemotionDependency = true;
34223
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34224
- rootDirectory,
34225
- rootPackageJson,
34226
- packageName: "remotion",
34227
- version: remotionSpec
34228
- });
34229
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34230
- if (remotionMajorVersion === null) {
34231
- facts.hasUnknownRemotionVersion = true;
34232
- facts.remotionVersion = null;
34233
- } else if (!facts.hasUnknownRemotionVersion) {
34234
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34235
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34236
- }
34237
- }
34238
34171
  };
34239
34172
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34240
34173
  const facts = {
@@ -34254,28 +34187,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34254
34187
  version: null,
34255
34188
  sourceDirectory: null
34256
34189
  },
34257
- valtioVersion: null,
34258
- mobx: {
34259
- version: null,
34260
- sourceDirectory: null
34261
- },
34262
- hasMobxReact: false,
34263
- hasMobxReactLite: false,
34264
- hasMobxStateTree: false,
34265
- hasMobxReactObserver: false,
34266
- zustand: {
34267
- version: null,
34268
- sourceDirectory: null
34269
- },
34270
34190
  hasReactNativeAwarePackage: false,
34271
34191
  hasReanimatedAwarePackage: false,
34272
34192
  hasSsrDependency: false,
34273
- hasRemotionDependency: false,
34274
- hasUnknownRemotionVersion: false,
34275
- remotionVersion: null,
34276
34193
  reanimatedVersion: null
34277
34194
  };
34278
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34195
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34279
34196
  let isReactGroupSettled = !collectReactGroup;
34280
34197
  const visitedDirectories = /* @__PURE__ */ new Set();
34281
34198
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34284,7 +34201,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34284
34201
  if (visitedDirectories.has(workspaceDirectory)) continue;
34285
34202
  visitedDirectories.add(workspaceDirectory);
34286
34203
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34287
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34204
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34288
34205
  const info = extractDependencyInfo(workspacePackageJson);
34289
34206
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34290
34207
  if (isReactGroupSettled) continue;
@@ -34508,24 +34425,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
34508
34425
  tailwindVersion: null,
34509
34426
  zodVersion: null,
34510
34427
  zodMajorVersion: null,
34511
- mobxVersion: null,
34512
- mobxMajorVersion: null,
34513
- hasMobxReact: false,
34514
- hasMobxReactLite: false,
34515
- hasMobxStateTree: false,
34516
- hasMobxReactObserver: false,
34517
- zustandVersion: null,
34518
- zustandMajorVersion: null,
34519
34428
  framework: "unknown",
34520
34429
  hasTypeScript: hasOwnTsConfig,
34521
34430
  hasReactCompiler: false,
34522
34431
  hasReactCompilerLintPlugin: false,
34523
34432
  hasTanStackQuery: false,
34524
- valtioVersion: null,
34525
- valtioMajorVersion: null,
34526
- hasRemotion: false,
34527
- remotionVersion: null,
34528
- remotionMajorVersion: null,
34529
34433
  hasSsrDependency: false,
34530
34434
  preactVersion: null,
34531
34435
  preactMajorVersion: null,
@@ -34624,12 +34528,6 @@ const discoverProject = (directory) => {
34624
34528
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34625
34529
  version: workspaceFacts.shopifyFlashList.version
34626
34530
  }) : null;
34627
- const zustandVersion = resolveCatalogBackedDependencyVersion({
34628
- rootDirectory: directory,
34629
- rootPackageJson: packageJson,
34630
- packageName: "zustand",
34631
- version: workspaceFacts.zustand.version
34632
- });
34633
34531
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34634
34532
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34635
34533
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34638,20 +34536,7 @@ const discoverProject = (directory) => {
34638
34536
  packageName: "next",
34639
34537
  version: workspaceFacts.next.version
34640
34538
  }) : null;
34641
- const valtioVersion = resolveCatalogBackedDependencyVersion({
34642
- rootDirectory: directory,
34643
- rootPackageJson: packageJson,
34644
- packageName: "valtio",
34645
- version: workspaceFacts.valtioVersion
34646
- });
34647
- const mobxVersion = resolveCatalogBackedDependencyVersion({
34648
- rootDirectory: directory,
34649
- rootPackageJson: packageJson,
34650
- packageName: "mobx",
34651
- version: workspaceFacts.mobx.version
34652
- });
34653
34539
  const preactVersion = getPreactVersion(packageJson);
34654
- const remotionVersion = workspaceFacts.remotionVersion;
34655
34540
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34656
34541
  const projectInfo = {
34657
34542
  rootDirectory: directory,
@@ -34661,24 +34546,11 @@ const discoverProject = (directory) => {
34661
34546
  tailwindVersion,
34662
34547
  zodVersion,
34663
34548
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34664
- mobxVersion,
34665
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
34666
- hasMobxReact: workspaceFacts.hasMobxReact,
34667
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34668
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34669
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34670
- zustandVersion,
34671
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34672
34549
  framework,
34673
34550
  hasTypeScript,
34674
34551
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34675
34552
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34676
34553
  hasTanStackQuery: hasTanStackQuery(packageJson),
34677
- valtioVersion,
34678
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34679
- hasRemotion: workspaceFacts.hasRemotionDependency,
34680
- remotionVersion,
34681
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34682
34554
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34683
34555
  preactVersion,
34684
34556
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -34912,6 +34784,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
34912
34784
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
34913
34785
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
34914
34786
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
34787
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
34915
34788
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
34916
34789
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
34917
34790
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -37198,25 +37071,9 @@ const BABEL_CONFIG_FILE_NAMES = [
37198
37071
  ".babelrc.json"
37199
37072
  ];
37200
37073
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37201
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37202
- const REACT_NATIVE_PACKAGE = "react-native";
37203
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37204
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37205
37074
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37206
37075
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37207
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37208
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37209
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37210
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37211
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37212
- if (normalizedVersionRange === null) return false;
37213
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37214
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37215
- };
37216
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37217
37076
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37218
- const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37219
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37220
37077
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37221
37078
  const filePath = Path.join(rootDirectory, fileName);
37222
37079
  if (!isFile(filePath)) continue;
@@ -37226,7 +37083,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37226
37083
  } catch {
37227
37084
  continue;
37228
37085
  }
37229
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37086
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37230
37087
  filePath: fileName,
37231
37088
  rule: "rn-no-metro-babel-preset",
37232
37089
  severity: "error",
@@ -37249,6 +37106,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
37249
37106
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37250
37107
  };
37251
37108
  const RULE_KEY = "no-vulnerable-react-server-components";
37109
+ const DEPENDENCY_SECTIONS = [
37110
+ "dependencies",
37111
+ "devDependencies",
37112
+ "peerDependencies",
37113
+ "optionalDependencies"
37114
+ ];
37252
37115
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37253
37116
  "19.0": {
37254
37117
  rceFixedVersion: "19.0.1",
@@ -37295,13 +37158,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37295
37158
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37296
37159
  return [...directories];
37297
37160
  };
37161
+ const readDeclaredSpec = (packageJson, packageName) => {
37162
+ for (const section of DEPENDENCY_SECTIONS) {
37163
+ const spec = packageJson[section]?.[packageName];
37164
+ if (typeof spec === "string") return spec;
37165
+ }
37166
+ return null;
37167
+ };
37298
37168
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37299
37169
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37300
37170
  if (isFile(manifestPath)) {
37301
37171
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37302
37172
  if (installedVersion !== null) return installedVersion;
37303
37173
  }
37304
- const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37174
+ const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37305
37175
  for (const spec of candidateSpecs) {
37306
37176
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37307
37177
  if (pinnedVersion !== null) return pinnedVersion;
@@ -37981,24 +37851,9 @@ const buildCapabilities = (project) => {
37981
37851
  })) capabilities.add("tailwind:3.4");
37982
37852
  if (project.zodVersion !== null) capabilities.add("zod");
37983
37853
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
37984
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
37985
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
37986
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
37987
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
37988
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
37989
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
37990
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
37991
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
37992
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
37993
37854
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
37994
37855
  if (project.hasReactCompiler) capabilities.add("react-compiler");
37995
37856
  if (project.hasTanStackQuery) capabilities.add("tanstack-query");
37996
- if (project.valtioVersion !== null) capabilities.add("valtio");
37997
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
37998
- if (project.hasRemotion) {
37999
- capabilities.add("remotion");
38000
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
38001
- }
38002
37857
  if (project.hasTypeScript) capabilities.add("typescript");
38003
37858
  if (project.preactVersion !== null) capabilities.add("preact");
38004
37859
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -39235,35 +39090,6 @@ const parseGithubViewerPermission = (stdout) => {
39235
39090
  return /^[A-Z_]+$/.test(value) ? value.toLowerCase() : null;
39236
39091
  };
39237
39092
  const splitNullSeparated = (value) => value.split("\0").filter((entry) => entry.length > 0);
39238
- const parseBaselineDiffPlan = (value) => {
39239
- const entries = splitNullSeparated(value);
39240
- const baseFiles = /* @__PURE__ */ new Set();
39241
- const headFiles = /* @__PURE__ */ new Set();
39242
- for (let entryIndex = 0; entryIndex < entries.length; entryIndex += 2) {
39243
- const status = entries[entryIndex];
39244
- const filePath = entries[entryIndex + 1];
39245
- if (status === void 0 || filePath === void 0 || status.length !== 1) return null;
39246
- if (status === "A") {
39247
- headFiles.add(filePath);
39248
- continue;
39249
- }
39250
- if (status === "D") {
39251
- baseFiles.add(filePath);
39252
- continue;
39253
- }
39254
- if (status === "M" || status === "T") {
39255
- baseFiles.add(filePath);
39256
- headFiles.add(filePath);
39257
- continue;
39258
- }
39259
- return null;
39260
- }
39261
- return {
39262
- baseFiles: [...baseFiles],
39263
- headFiles: [...headFiles],
39264
- untrackedFiles: []
39265
- };
39266
- };
39267
39093
  const UNTRACKED_FILE_LAST_LINE = Number.MAX_SAFE_INTEGER;
39268
39094
  /**
39269
39095
  * `Git` wraps every `git`-via-subprocess call react-doctor makes
@@ -39466,45 +39292,6 @@ var Git = class Git extends Service()("react-doctor/Git") {
39466
39292
  githubViewerPermission,
39467
39293
  branchExists,
39468
39294
  mergeBase,
39469
- baselineDiffPlan: (input) => {
39470
- if (!isSafeGitRevision(input.ref)) return succeed$2(null);
39471
- return gen(function* () {
39472
- const unmerged = yield* runGit(input.directory, [
39473
- "diff",
39474
- "--no-ext-diff",
39475
- "-z",
39476
- "--name-only",
39477
- "--diff-filter=U",
39478
- "--relative"
39479
- ]);
39480
- if (unmerged.status !== 0 || unmerged.stdout.length > 0) return null;
39481
- const result = yield* runGit(input.directory, [
39482
- "diff",
39483
- "--no-ext-diff",
39484
- "--no-textconv",
39485
- "--no-renames",
39486
- "-z",
39487
- "--name-status",
39488
- "--relative",
39489
- input.ref
39490
- ]);
39491
- if (result.status !== 0) return null;
39492
- const plan = parseBaselineDiffPlan(result.stdout);
39493
- if (plan === null) return null;
39494
- const untracked = yield* runGit(input.directory, [
39495
- "ls-files",
39496
- "--others",
39497
- "--exclude-standard",
39498
- "-z"
39499
- ]);
39500
- if (untracked.status !== 0) return null;
39501
- return {
39502
- baseFiles: plan.baseFiles,
39503
- headFiles: plan.headFiles,
39504
- untrackedFiles: splitNullSeparated(untracked.stdout)
39505
- };
39506
- }).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.baselineDiffPlan"));
39507
- },
39508
39295
  diffSelection: ({ directory, explicitBaseBranch, includeUntracked = false }) => gen(function* () {
39509
39296
  if (explicitBaseBranch !== void 0 && explicitBaseBranch.trim().length === 0) return yield* fail$4(new ReactDoctorError({ reason: new GitBaseBranchInvalid({ detail: "Diff base branch cannot be empty." }) }));
39510
39297
  if (explicitBaseBranch !== void 0) {
@@ -39654,7 +39441,6 @@ var Git = class Git extends Service()("react-doctor/Git") {
39654
39441
  githubViewerPermission: () => succeed$2(snapshot.githubViewerPermission ?? null),
39655
39442
  branchExists: (_directory, branch) => succeed$2(snapshot.branchExists?.get(branch) ?? false),
39656
39443
  mergeBase: ({ ref }) => succeed$2(snapshot.mergeBase?.get(ref) ?? null),
39657
- baselineDiffPlan: () => succeed$2(snapshot.baselineDiffPlan ?? null),
39658
39444
  diffSelection: () => succeed$2(snapshot.diffSelection ?? null),
39659
39445
  stagedFilePaths: () => succeed$2(snapshot.stagedFiles ?? []),
39660
39446
  showStagedContent: (_directory, relativePath) => succeed$2(snapshot.stagedContent?.get(relativePath) ?? null),
@@ -40992,17 +40778,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
40992
40778
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
40993
40779
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
40994
40780
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
40995
- const SET_STATE_IN_EFFECT_ACTION = "Prefer deriving or initializing the value before render. If the effect must read a browser API after mount, treat this as advisory or suppress it with `// react-doctor-disable-next-line react-hooks-js/set-state-in-effect`.";
40996
40781
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
40997
40782
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
40998
40783
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
40999
40784
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
41000
40785
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
41001
40786
  };
41002
- const buildSetStateInEffectMessage = (reasonSummary) => {
41003
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
41004
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
41005
- };
41006
40787
  const PLUGIN_CATEGORY_MAP = {
41007
40788
  react: "Bugs",
41008
40789
  "react-hooks": "Bugs",
@@ -41060,10 +40841,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
41060
40841
  message: REACT_ERROR_BOUNDARY_MESSAGE,
41061
40842
  help: reasonDetail || help
41062
40843
  };
41063
- if (rule === "set-state-in-effect") return {
41064
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
41065
- help: reasonDetail || help
41066
- };
41067
40844
  return {
41068
40845
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
41069
40846
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -43389,19 +43166,12 @@ const isPathInsideDirectory = (childAbsolutePath, parentAbsolutePath) => {
43389
43166
  */
43390
43167
  const materializeSourceTree = (input) => gen(function* () {
43391
43168
  const materializedFiles = [];
43392
- const unmaterializedFiles = [];
43393
43169
  const resolvedTempDirectory = path.resolve(input.tempDirectory);
43394
43170
  for (const relativePath of input.files) {
43395
43171
  const content = yield* input.readContent(relativePath).pipe(orElseSucceed(() => null));
43396
- if (content === null) {
43397
- unmaterializedFiles.push(relativePath);
43398
- continue;
43399
- }
43172
+ if (content === null) continue;
43400
43173
  const candidateTargetPath = path.resolve(resolvedTempDirectory, relativePath);
43401
- if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory)) {
43402
- unmaterializedFiles.push(relativePath);
43403
- continue;
43404
- }
43174
+ if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory)) continue;
43405
43175
  yield* sync(() => {
43406
43176
  fs.mkdirSync(path.dirname(candidateTargetPath), { recursive: true });
43407
43177
  fs.writeFileSync(candidateTargetPath, content);
@@ -43418,7 +43188,6 @@ const materializeSourceTree = (input) => gen(function* () {
43418
43188
  return {
43419
43189
  tempDirectory: input.tempDirectory,
43420
43190
  materializedFiles,
43421
- unmaterializedFiles,
43422
43191
  cleanup: () => {
43423
43192
  try {
43424
43193
  fs.rmSync(input.tempDirectory, {
@@ -43982,4 +43751,4 @@ const toJsonReport = (result, options) => buildJsonReport({
43982
43751
  export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
43983
43752
 
43984
43753
  //# sourceMappingURL=index.js.map
43985
- //# debugId=6aa1c6e1-8fcc-50d4-a076-3e864425bdc5
43754
+ //# debugId=3121a4e4-8a4a-55ea-ade8-47d0bf576a2f