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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lsp.js CHANGED
@@ -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
- "@remix-run/react": "remix",
33431
- gatsby: "gatsby",
33432
33430
  vite: "vite",
33433
33431
  "react-scripts": "cra",
33432
+ "@remix-run/react": "remix",
33433
+ gatsby: "gatsby",
33434
33434
  expo: "expo",
33435
33435
  "react-native": "react-native"
33436
33436
  };
@@ -33957,6 +33957,19 @@ const getPreactVersion = (packageJson) => {
33957
33957
  ...packageJson.devDependencies
33958
33958
  }.preact ?? null;
33959
33959
  };
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
+ };
33960
33973
  const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
33961
33974
  if (version === null || !isCatalogReference(version)) return version;
33962
33975
  const catalogName = extractCatalogName(version);
@@ -34159,60 +34172,7 @@ const listWorkspacePackages = (rootDirectory) => {
34159
34172
  }
34160
34173
  return packages;
34161
34174
  };
34162
- const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
34163
- const allDependencies = {
34164
- ...packageJson.devDependencies,
34165
- ...packageJson.peerDependencies,
34166
- ...packageJson.dependencies
34167
- };
34168
- for (const packageName of packageNames) {
34169
- const version = allDependencies[packageName];
34170
- if (version !== void 0) return version;
34171
- }
34172
- return null;
34173
- };
34174
- const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
34175
- const getTanStackQueryVersion = (packageJson) => {
34176
- return getPreferredDependencyVersion({
34177
- packageJson,
34178
- packageNames: TANSTACK_REACT_QUERY_PACKAGES
34179
- });
34180
- };
34181
- const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
34182
- const getStyledComponentsVersion = (packageJson) => {
34183
- return getPreferredDependencyVersion({
34184
- packageJson,
34185
- packageNames: STYLED_COMPONENTS_PACKAGES
34186
- });
34187
- };
34188
- const I18N_PACKAGES = [
34189
- "i18next",
34190
- "react-i18next",
34191
- "next-i18next",
34192
- "react-intl",
34193
- "next-intl",
34194
- "use-intl",
34195
- "@formatjs/intl",
34196
- "@lingui/core",
34197
- "@lingui/react",
34198
- "typesafe-i18n",
34199
- "@tolgee/react",
34200
- "react-intl-universal"
34201
- ];
34202
- const hasI18nDependency = (packageJson) => {
34203
- const allDependencies = {
34204
- ...packageJson.peerDependencies,
34205
- ...packageJson.dependencies,
34206
- ...packageJson.devDependencies,
34207
- ...packageJson.optionalDependencies
34208
- };
34209
- return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
34210
- };
34211
34175
  const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
34212
- const MOBX_REACT_PACKAGE_NAME = "mobx-react";
34213
- const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
34214
- const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
34215
- const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
34216
34176
  const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
34217
34177
  const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
34218
34178
  const dependencyDeclaration = getDependencyDeclaration({
@@ -34231,26 +34191,7 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
34231
34191
  if (nextMajor === null) return false;
34232
34192
  return nextMajor < currentMajor;
34233
34193
  };
34234
- const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
34235
- if (currentFact.version === null) return true;
34236
- if (nextFact.version === null) return false;
34237
- const currentMajor = getLowestDependencyMajor(currentFact.version);
34238
- const nextMajor = getLowestDependencyMajor(nextFact.version);
34239
- if (currentMajor === null) return false;
34240
- if (nextMajor === null) return true;
34241
- if (currentMajor > latestSupportedMajor) return false;
34242
- if (nextMajor > latestSupportedMajor) return true;
34243
- return nextMajor < currentMajor;
34244
- };
34245
- const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
34246
- if (!currentVersion) return true;
34247
- const currentMajor = getLowestDependencyMajor(currentVersion);
34248
- const nextMajor = getLowestDependencyMajor(nextVersion);
34249
- if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
34250
- if (nextMajor === null) return currentMajor >= 6;
34251
- return nextMajor < currentMajor;
34252
- };
34253
- const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
34194
+ const evaluateManifestFacts = (facts, packageJson, directory) => {
34254
34195
  if (facts.expo.version === null) {
34255
34196
  const spec = getDependencySpec(packageJson, "expo");
34256
34197
  if (spec !== null) facts.expo = {
@@ -34272,74 +34213,13 @@ const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, roo
34272
34213
  sourceDirectory: directory
34273
34214
  };
34274
34215
  }
34275
- const mobxSpec = getDependencySpec(packageJson, "mobx");
34276
- if (mobxSpec !== null) {
34277
- const nextMobxFact = {
34278
- version: resolveCatalogBackedDependencyVersion({
34279
- rootDirectory: directory,
34280
- rootPackageJson: packageJson,
34281
- packageName: "mobx",
34282
- version: mobxSpec
34283
- }),
34284
- sourceDirectory: directory
34285
- };
34286
- if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
34287
- }
34288
- facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
34289
- facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
34290
- facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
34291
- facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
34292
- const zustandSpec = getDependencySpec(packageJson, "zustand");
34293
- if (zustandSpec !== null) {
34294
- const nextZustandFact = {
34295
- version: resolveCatalogBackedDependencyVersion({
34296
- rootDirectory: directory,
34297
- rootPackageJson: packageJson,
34298
- packageName: "zustand",
34299
- version: zustandSpec
34300
- }),
34301
- sourceDirectory: directory
34302
- };
34303
- if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
34304
- }
34305
34216
  if (facts.reanimatedVersion === null) {
34306
34217
  const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
34307
34218
  if (spec !== null) facts.reanimatedVersion = spec;
34308
34219
  }
34309
- if (facts.valtioVersion === null) {
34310
- const spec = getDependencySpec(packageJson, "valtio");
34311
- if (spec !== null) facts.valtioVersion = spec;
34312
- }
34313
- facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
34314
- const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
34315
- rootDirectory: directory,
34316
- rootPackageJson: packageJson,
34317
- packageName: "styled-components",
34318
- version: getStyledComponentsVersion(packageJson)
34319
- });
34320
- if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
34321
- facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
34322
34220
  facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
34323
34221
  facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
34324
34222
  facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
34325
- const remotionSpec = getDependencySpec(packageJson, "remotion");
34326
- if (remotionSpec !== null) {
34327
- facts.hasRemotionDependency = true;
34328
- const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
34329
- rootDirectory,
34330
- rootPackageJson,
34331
- packageName: "remotion",
34332
- version: remotionSpec
34333
- });
34334
- const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
34335
- if (remotionMajorVersion === null) {
34336
- facts.hasUnknownRemotionVersion = true;
34337
- facts.remotionVersion = null;
34338
- } else if (!facts.hasUnknownRemotionVersion) {
34339
- const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
34340
- if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
34341
- }
34342
- }
34343
34223
  };
34344
34224
  const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
34345
34225
  const facts = {
@@ -34359,31 +34239,12 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34359
34239
  version: null,
34360
34240
  sourceDirectory: null
34361
34241
  },
34362
- valtioVersion: null,
34363
- mobx: {
34364
- version: null,
34365
- sourceDirectory: null
34366
- },
34367
- hasMobxReact: false,
34368
- hasMobxReactLite: false,
34369
- hasMobxStateTree: false,
34370
- hasMobxReactObserver: false,
34371
- zustand: {
34372
- version: null,
34373
- sourceDirectory: null
34374
- },
34375
- tanstackQueryVersion: null,
34376
- styledComponentsVersion: null,
34377
- hasI18nLibrary: false,
34378
34242
  hasReactNativeAwarePackage: false,
34379
34243
  hasReanimatedAwarePackage: false,
34380
34244
  hasSsrDependency: false,
34381
- hasRemotionDependency: false,
34382
- hasUnknownRemotionVersion: false,
34383
- remotionVersion: null,
34384
34245
  reanimatedVersion: null
34385
34246
  };
34386
- evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
34247
+ evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
34387
34248
  let isReactGroupSettled = !collectReactGroup;
34388
34249
  const visitedDirectories = /* @__PURE__ */ new Set();
34389
34250
  for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
@@ -34392,7 +34253,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
34392
34253
  if (visitedDirectories.has(workspaceDirectory)) continue;
34393
34254
  visitedDirectories.add(workspaceDirectory);
34394
34255
  const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
34395
- evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
34256
+ evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
34396
34257
  const info = extractDependencyInfo(workspacePackageJson);
34397
34258
  if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
34398
34259
  if (isReactGroupSettled) continue;
@@ -34616,27 +34477,11 @@ const discoverProjectWithoutPackageJson = (directory) => {
34616
34477
  tailwindVersion: null,
34617
34478
  zodVersion: null,
34618
34479
  zodMajorVersion: null,
34619
- mobxVersion: null,
34620
- mobxMajorVersion: null,
34621
- hasMobxReact: false,
34622
- hasMobxReactLite: false,
34623
- hasMobxStateTree: false,
34624
- hasMobxReactObserver: false,
34625
- zustandVersion: null,
34626
- zustandMajorVersion: null,
34627
34480
  framework: "unknown",
34628
34481
  hasTypeScript: hasOwnTsConfig,
34629
34482
  hasReactCompiler: false,
34630
34483
  hasReactCompilerLintPlugin: false,
34631
34484
  hasTanStackQuery: false,
34632
- valtioVersion: null,
34633
- valtioMajorVersion: null,
34634
- hasRemotion: false,
34635
- remotionVersion: null,
34636
- remotionMajorVersion: null,
34637
- hasI18nLibrary: false,
34638
- tanstackQueryVersion: null,
34639
- styledComponentsVersion: null,
34640
34485
  hasSsrDependency: false,
34641
34486
  preactVersion: null,
34642
34487
  preactMajorVersion: null,
@@ -34735,12 +34580,6 @@ const discoverProject = (directory) => {
34735
34580
  packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
34736
34581
  version: workspaceFacts.shopifyFlashList.version
34737
34582
  }) : null;
34738
- const zustandVersion = resolveCatalogBackedDependencyVersion({
34739
- rootDirectory: directory,
34740
- rootPackageJson: packageJson,
34741
- packageName: "zustand",
34742
- version: workspaceFacts.zustand.version
34743
- });
34744
34583
  const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
34745
34584
  const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
34746
34585
  const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
@@ -34749,21 +34588,7 @@ const discoverProject = (directory) => {
34749
34588
  packageName: "next",
34750
34589
  version: workspaceFacts.next.version
34751
34590
  }) : null;
34752
- const valtioVersion = resolveCatalogBackedDependencyVersion({
34753
- rootDirectory: directory,
34754
- rootPackageJson: packageJson,
34755
- packageName: "valtio",
34756
- version: workspaceFacts.valtioVersion
34757
- });
34758
- const mobxVersion = resolveCatalogBackedDependencyVersion({
34759
- rootDirectory: directory,
34760
- rootPackageJson: packageJson,
34761
- packageName: "mobx",
34762
- version: workspaceFacts.mobx.version
34763
- });
34764
34591
  const preactVersion = getPreactVersion(packageJson);
34765
- const remotionVersion = workspaceFacts.remotionVersion;
34766
- const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
34767
34592
  const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
34768
34593
  const projectInfo = {
34769
34594
  rootDirectory: directory,
@@ -34773,27 +34598,11 @@ const discoverProject = (directory) => {
34773
34598
  tailwindVersion,
34774
34599
  zodVersion,
34775
34600
  zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
34776
- mobxVersion,
34777
- mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
34778
- hasMobxReact: workspaceFacts.hasMobxReact,
34779
- hasMobxReactLite: workspaceFacts.hasMobxReactLite,
34780
- hasMobxStateTree: workspaceFacts.hasMobxStateTree,
34781
- hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
34782
- zustandVersion,
34783
- zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
34784
34601
  framework,
34785
34602
  hasTypeScript,
34786
34603
  hasReactCompiler: detectReactCompiler(directory, packageJson),
34787
34604
  hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
34788
- hasTanStackQuery: tanstackQueryVersion !== null,
34789
- hasI18nLibrary: workspaceFacts.hasI18nLibrary,
34790
- tanstackQueryVersion,
34791
- styledComponentsVersion: workspaceFacts.styledComponentsVersion,
34792
- valtioVersion,
34793
- valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
34794
- hasRemotion: workspaceFacts.hasRemotionDependency,
34795
- remotionVersion,
34796
- remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
34605
+ hasTanStackQuery: hasTanStackQuery(packageJson),
34797
34606
  hasSsrDependency: workspaceFacts.hasSsrDependency,
34798
34607
  preactVersion,
34799
34608
  preactMajorVersion: parseReactMajor(preactVersion),
@@ -35027,6 +34836,7 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
35027
34836
  "react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
35028
34837
  "react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
35029
34838
  "react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
34839
+ "react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
35030
34840
  "react/jsx-no-undef": "react-doctor/jsx-no-undef",
35031
34841
  "react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
35032
34842
  "react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
@@ -37239,25 +37049,9 @@ const BABEL_CONFIG_FILE_NAMES = [
37239
37049
  ".babelrc.json"
37240
37050
  ];
37241
37051
  const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
37242
- const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
37243
- const REACT_NATIVE_PACKAGE = "react-native";
37244
- const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
37245
- const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
37246
37052
  const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
37247
37053
  const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
37248
- const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
37249
- const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
37250
- const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
37251
- if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
37252
- const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
37253
- if (normalizedVersionRange === null) return false;
37254
- const minimumVersion = import_semver.minVersion(normalizedVersionRange);
37255
- return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
37256
- };
37257
- const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
37258
37054
  const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37259
- const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
37260
- const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
37261
37055
  for (const fileName of BABEL_CONFIG_FILE_NAMES) {
37262
37056
  const filePath = Path.join(rootDirectory, fileName);
37263
37057
  if (!isFile(filePath)) continue;
@@ -37267,7 +37061,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
37267
37061
  } catch {
37268
37062
  continue;
37269
37063
  }
37270
- if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
37064
+ if (contents.includes(LEGACY_PRESET_SPEC)) return [buildReactNativeDiagnostic({
37271
37065
  filePath: fileName,
37272
37066
  rule: "rn-no-metro-babel-preset",
37273
37067
  severity: "error",
@@ -37290,6 +37084,12 @@ const checkReactNativeProject = (rootDirectory, project) => {
37290
37084
  return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
37291
37085
  };
37292
37086
  const RULE_KEY = "no-vulnerable-react-server-components";
37087
+ const DEPENDENCY_SECTIONS = [
37088
+ "dependencies",
37089
+ "devDependencies",
37090
+ "peerDependencies",
37091
+ "optionalDependencies"
37092
+ ];
37293
37093
  const REACT_RSC_ADVISORIES_BY_MINOR = {
37294
37094
  "19.0": {
37295
37095
  rceFixedVersion: "19.0.1",
@@ -37336,13 +37136,20 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
37336
37136
  for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
37337
37137
  return [...directories];
37338
37138
  };
37139
+ const readDeclaredSpec = (packageJson, packageName) => {
37140
+ for (const section of DEPENDENCY_SECTIONS) {
37141
+ const spec = packageJson[section]?.[packageName];
37142
+ if (typeof spec === "string") return spec;
37143
+ }
37144
+ return null;
37145
+ };
37339
37146
  const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
37340
37147
  const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
37341
37148
  if (isFile(manifestPath)) {
37342
37149
  const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
37343
37150
  if (installedVersion !== null) return installedVersion;
37344
37151
  }
37345
- const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37152
+ const candidateSpecs = [readDeclaredSpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
37346
37153
  for (const spec of candidateSpecs) {
37347
37154
  const pinnedVersion = spec === null ? null : import_semver.valid(spec);
37348
37155
  if (pinnedVersion !== null) return pinnedVersion;
@@ -38010,7 +37817,6 @@ const buildCapabilities = (project) => {
38010
37817
  if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
38011
37818
  if (project.isStaticExport) capabilities.add("nextjs:static-export");
38012
37819
  if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
38013
- if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
38014
37820
  addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
38015
37821
  if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
38016
37822
  major: 19,
@@ -38023,30 +37829,9 @@ const buildCapabilities = (project) => {
38023
37829
  })) capabilities.add("tailwind:3.4");
38024
37830
  if (project.zodVersion !== null) capabilities.add("zod");
38025
37831
  if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
38026
- if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
38027
- if (project.hasMobxReact === true) capabilities.add("mobx-react");
38028
- if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
38029
- if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
38030
- if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
38031
- if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
38032
- if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
38033
- if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
38034
- if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
38035
37832
  if (project.isPreES2023Target) capabilities.add("pre-es2023");
38036
37833
  if (project.hasReactCompiler) capabilities.add("react-compiler");
38037
- if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
38038
- if (project.styledComponentsVersion) {
38039
- capabilities.add("styled-components");
38040
- const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
38041
- if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
38042
- }
38043
- if (project.hasI18nLibrary) capabilities.add("i18n");
38044
- if (project.valtioVersion !== null) capabilities.add("valtio");
38045
- addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
38046
- if (project.hasRemotion) {
38047
- capabilities.add("remotion");
38048
- addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
38049
- }
37834
+ if (project.hasTanStackQuery) capabilities.add("tanstack-query");
38050
37835
  if (project.hasTypeScript) capabilities.add("typescript");
38051
37836
  if (project.preactVersion !== null) capabilities.add("preact");
38052
37837
  addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
@@ -40315,19 +40100,6 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
40315
40100
  }
40316
40101
  };
40317
40102
  };
40318
- const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
40319
- const fingerprintFileContents = (filePath, fingerprintLength) => {
40320
- const fileStats = NFS.statSync(filePath, { bigint: true });
40321
- const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
40322
- if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
40323
- const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
40324
- fingerprintCacheByFilePath.set(filePath, {
40325
- fingerprint,
40326
- modifiedTimeNanoseconds: fileStats.mtimeNs,
40327
- sizeBytes: fileStats.size
40328
- });
40329
- return fingerprint;
40330
- };
40331
40103
  const bundledRequire = createRequire(import.meta.url);
40332
40104
  const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
40333
40105
  const resolveChildNodeVersion = (nodeBinaryPath) => {
@@ -40351,13 +40123,6 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
40351
40123
  "oxlint-plugin-react-doctor/package.json",
40352
40124
  "eslint-plugin-react-hooks/package.json"
40353
40125
  ];
40354
- const resolvePluginFingerprint = () => {
40355
- try {
40356
- return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
40357
- } catch {
40358
- return "unresolved";
40359
- }
40360
- };
40361
40126
  const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40362
40127
  const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
40363
40128
  for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
@@ -40367,7 +40132,6 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
40367
40132
  } catch {
40368
40133
  versions.push(`${specifier}=missing`);
40369
40134
  }
40370
- versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
40371
40135
  return versions;
40372
40136
  };
40373
40137
  const esmRequire = createRequire(import.meta.url);
@@ -41061,17 +40825,12 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
41061
40825
  const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
41062
40826
  const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
41063
40827
  const REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION = "It's how the library works, not a bug in your code. Memoize values you pass from it into other memoized components, or suppress it with `// react-doctor-disable-next-line react-hooks-js/incompatible-library`.";
41064
- 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`.";
41065
40828
  const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
41066
40829
  const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
41067
40830
  const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
41068
40831
  if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
41069
40832
  return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
41070
40833
  };
41071
- const buildSetStateInEffectMessage = (reasonSummary) => {
41072
- const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
41073
- return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
41074
- };
41075
40834
  const PLUGIN_CATEGORY_MAP = {
41076
40835
  react: "Bugs",
41077
40836
  "react-hooks": "Bugs",
@@ -41129,10 +40888,6 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
41129
40888
  message: REACT_ERROR_BOUNDARY_MESSAGE,
41130
40889
  help: reasonDetail || help
41131
40890
  };
41132
- if (rule === "set-state-in-effect") return {
41133
- message: buildSetStateInEffectMessage(reasonSummary.trim()),
41134
- help: reasonDetail || help
41135
- };
41136
40891
  return {
41137
40892
  message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
41138
40893
  help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
@@ -45693,5 +45448,5 @@ const startLanguageServer = () => {
45693
45448
  };
45694
45449
  //#endregion
45695
45450
  export { startLanguageServer };
45696
- !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]="9a23503e-e7cd-5df6-a9fe-39a2baf287bc")}catch(e){}}();
45697
- //# debugId=9a23503e-e7cd-5df6-a9fe-39a2baf287bc
45451
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4fa679df-c187-5989-bc8a-a96791a6f02c")}catch(e){}}();
45452
+ //# debugId=4fa679df-c187-5989-bc8a-a96791a6f02c
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-doctor",
3
- "version": "0.8.1-dev.cd9ca68",
3
+ "version": "0.8.1-dev.d970055",
4
4
  "description": "Your agent writes bad React. This catches it",
5
5
  "keywords": [
6
6
  "accessibility",
@@ -65,8 +65,8 @@
65
65
  "vscode-languageserver-textdocument": "^1.0.12",
66
66
  "vscode-uri": "^3.1.0",
67
67
  "yaml": "^2.9.0",
68
- "deslop-js": "0.8.1",
69
- "oxlint-plugin-react-doctor": "0.8.1-dev.cd9ca68"
68
+ "oxlint-plugin-react-doctor": "0.8.1-dev.d970055",
69
+ "deslop-js": "0.8.1"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/babel__code-frame": "^7.27.0",
@@ -75,8 +75,8 @@
75
75
  "commander": "^14.0.3",
76
76
  "ora": "^9.4.0",
77
77
  "@react-doctor/api": "0.8.1",
78
- "@react-doctor/language-server": "0.8.1",
79
- "@react-doctor/core": "0.8.1"
78
+ "@react-doctor/core": "0.8.1",
79
+ "@react-doctor/language-server": "0.8.1"
80
80
  },
81
81
  "engines": {
82
82
  "node": "^20.19.0 || >=22.13.0"