react-doctor 0.8.1-dev.c9f2c4b → 0.8.1-dev.cd9ca68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +289 -42
- package/dist/index.d.ts +27 -0
- package/dist/index.js +283 -38
- package/dist/lsp.js +283 -38
- package/package.json +3 -3
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
|
-
vite: "vite",
|
|
33431
|
-
"react-scripts": "cra",
|
|
33432
33430
|
"@remix-run/react": "remix",
|
|
33433
33431
|
gatsby: "gatsby",
|
|
33432
|
+
vite: "vite",
|
|
33433
|
+
"react-scripts": "cra",
|
|
33434
33434
|
expo: "expo",
|
|
33435
33435
|
"react-native": "react-native"
|
|
33436
33436
|
};
|
|
@@ -33957,19 +33957,6 @@ 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
|
-
};
|
|
33973
33960
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33974
33961
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33975
33962
|
const catalogName = extractCatalogName(version);
|
|
@@ -34172,7 +34159,60 @@ const listWorkspacePackages = (rootDirectory) => {
|
|
|
34172
34159
|
}
|
|
34173
34160
|
return packages;
|
|
34174
34161
|
};
|
|
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
|
+
};
|
|
34175
34211
|
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";
|
|
34176
34216
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
34177
34217
|
const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
|
|
34178
34218
|
const dependencyDeclaration = getDependencyDeclaration({
|
|
@@ -34191,7 +34231,26 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
|
|
|
34191
34231
|
if (nextMajor === null) return false;
|
|
34192
34232
|
return nextMajor < currentMajor;
|
|
34193
34233
|
};
|
|
34194
|
-
const
|
|
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) => {
|
|
34195
34254
|
if (facts.expo.version === null) {
|
|
34196
34255
|
const spec = getDependencySpec(packageJson, "expo");
|
|
34197
34256
|
if (spec !== null) facts.expo = {
|
|
@@ -34213,13 +34272,74 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
|
|
|
34213
34272
|
sourceDirectory: directory
|
|
34214
34273
|
};
|
|
34215
34274
|
}
|
|
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
|
+
}
|
|
34216
34305
|
if (facts.reanimatedVersion === null) {
|
|
34217
34306
|
const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
|
|
34218
34307
|
if (spec !== null) facts.reanimatedVersion = spec;
|
|
34219
34308
|
}
|
|
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);
|
|
34220
34322
|
facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
|
|
34221
34323
|
facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
|
|
34222
34324
|
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
|
+
}
|
|
34223
34343
|
};
|
|
34224
34344
|
const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
|
|
34225
34345
|
const facts = {
|
|
@@ -34239,12 +34359,31 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34239
34359
|
version: null,
|
|
34240
34360
|
sourceDirectory: null
|
|
34241
34361
|
},
|
|
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,
|
|
34242
34378
|
hasReactNativeAwarePackage: false,
|
|
34243
34379
|
hasReanimatedAwarePackage: false,
|
|
34244
34380
|
hasSsrDependency: false,
|
|
34381
|
+
hasRemotionDependency: false,
|
|
34382
|
+
hasUnknownRemotionVersion: false,
|
|
34383
|
+
remotionVersion: null,
|
|
34245
34384
|
reanimatedVersion: null
|
|
34246
34385
|
};
|
|
34247
|
-
evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
|
|
34386
|
+
evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
|
|
34248
34387
|
let isReactGroupSettled = !collectReactGroup;
|
|
34249
34388
|
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
34250
34389
|
for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
|
|
@@ -34253,7 +34392,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34253
34392
|
if (visitedDirectories.has(workspaceDirectory)) continue;
|
|
34254
34393
|
visitedDirectories.add(workspaceDirectory);
|
|
34255
34394
|
const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
|
|
34256
|
-
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
|
|
34395
|
+
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
|
|
34257
34396
|
const info = extractDependencyInfo(workspacePackageJson);
|
|
34258
34397
|
if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
|
|
34259
34398
|
if (isReactGroupSettled) continue;
|
|
@@ -34477,11 +34616,27 @@ const discoverProjectWithoutPackageJson = (directory) => {
|
|
|
34477
34616
|
tailwindVersion: null,
|
|
34478
34617
|
zodVersion: null,
|
|
34479
34618
|
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,
|
|
34480
34627
|
framework: "unknown",
|
|
34481
34628
|
hasTypeScript: hasOwnTsConfig,
|
|
34482
34629
|
hasReactCompiler: false,
|
|
34483
34630
|
hasReactCompilerLintPlugin: false,
|
|
34484
34631
|
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,
|
|
34485
34640
|
hasSsrDependency: false,
|
|
34486
34641
|
preactVersion: null,
|
|
34487
34642
|
preactMajorVersion: null,
|
|
@@ -34580,6 +34735,12 @@ const discoverProject = (directory) => {
|
|
|
34580
34735
|
packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
|
|
34581
34736
|
version: workspaceFacts.shopifyFlashList.version
|
|
34582
34737
|
}) : null;
|
|
34738
|
+
const zustandVersion = resolveCatalogBackedDependencyVersion({
|
|
34739
|
+
rootDirectory: directory,
|
|
34740
|
+
rootPackageJson: packageJson,
|
|
34741
|
+
packageName: "zustand",
|
|
34742
|
+
version: workspaceFacts.zustand.version
|
|
34743
|
+
});
|
|
34583
34744
|
const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
|
|
34584
34745
|
const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
|
|
34585
34746
|
const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
|
|
@@ -34588,7 +34749,21 @@ const discoverProject = (directory) => {
|
|
|
34588
34749
|
packageName: "next",
|
|
34589
34750
|
version: workspaceFacts.next.version
|
|
34590
34751
|
}) : 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
|
+
});
|
|
34591
34764
|
const preactVersion = getPreactVersion(packageJson);
|
|
34765
|
+
const remotionVersion = workspaceFacts.remotionVersion;
|
|
34766
|
+
const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
|
|
34592
34767
|
const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
|
|
34593
34768
|
const projectInfo = {
|
|
34594
34769
|
rootDirectory: directory,
|
|
@@ -34598,11 +34773,27 @@ const discoverProject = (directory) => {
|
|
|
34598
34773
|
tailwindVersion,
|
|
34599
34774
|
zodVersion,
|
|
34600
34775
|
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),
|
|
34601
34784
|
framework,
|
|
34602
34785
|
hasTypeScript,
|
|
34603
34786
|
hasReactCompiler: detectReactCompiler(directory, packageJson),
|
|
34604
34787
|
hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
|
|
34605
|
-
hasTanStackQuery:
|
|
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),
|
|
34606
34797
|
hasSsrDependency: workspaceFacts.hasSsrDependency,
|
|
34607
34798
|
preactVersion,
|
|
34608
34799
|
preactMajorVersion: parseReactMajor(preactVersion),
|
|
@@ -34836,7 +35027,6 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
|
|
|
34836
35027
|
"react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
|
|
34837
35028
|
"react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
|
|
34838
35029
|
"react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
|
|
34839
|
-
"react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
|
|
34840
35030
|
"react/jsx-no-undef": "react-doctor/jsx-no-undef",
|
|
34841
35031
|
"react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
|
|
34842
35032
|
"react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
|
|
@@ -37049,9 +37239,25 @@ const BABEL_CONFIG_FILE_NAMES = [
|
|
|
37049
37239
|
".babelrc.json"
|
|
37050
37240
|
];
|
|
37051
37241
|
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}['"]`);
|
|
37052
37246
|
const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
|
|
37053
37247
|
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"));
|
|
37054
37258
|
const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
37259
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
37260
|
+
const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
|
|
37055
37261
|
for (const fileName of BABEL_CONFIG_FILE_NAMES) {
|
|
37056
37262
|
const filePath = Path.join(rootDirectory, fileName);
|
|
37057
37263
|
if (!isFile(filePath)) continue;
|
|
@@ -37061,7 +37267,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
37061
37267
|
} catch {
|
|
37062
37268
|
continue;
|
|
37063
37269
|
}
|
|
37064
|
-
if (
|
|
37270
|
+
if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
|
|
37065
37271
|
filePath: fileName,
|
|
37066
37272
|
rule: "rn-no-metro-babel-preset",
|
|
37067
37273
|
severity: "error",
|
|
@@ -37084,12 +37290,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
|
|
|
37084
37290
|
return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
|
|
37085
37291
|
};
|
|
37086
37292
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
37087
|
-
const DEPENDENCY_SECTIONS = [
|
|
37088
|
-
"dependencies",
|
|
37089
|
-
"devDependencies",
|
|
37090
|
-
"peerDependencies",
|
|
37091
|
-
"optionalDependencies"
|
|
37092
|
-
];
|
|
37093
37293
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
37094
37294
|
"19.0": {
|
|
37095
37295
|
rceFixedVersion: "19.0.1",
|
|
@@ -37136,20 +37336,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
|
|
|
37136
37336
|
for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
|
|
37137
37337
|
return [...directories];
|
|
37138
37338
|
};
|
|
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
|
-
};
|
|
37146
37339
|
const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
|
|
37147
37340
|
const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
|
|
37148
37341
|
if (isFile(manifestPath)) {
|
|
37149
37342
|
const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
|
|
37150
37343
|
if (installedVersion !== null) return installedVersion;
|
|
37151
37344
|
}
|
|
37152
|
-
const candidateSpecs = [
|
|
37345
|
+
const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
|
|
37153
37346
|
for (const spec of candidateSpecs) {
|
|
37154
37347
|
const pinnedVersion = spec === null ? null : import_semver.valid(spec);
|
|
37155
37348
|
if (pinnedVersion !== null) return pinnedVersion;
|
|
@@ -37817,6 +38010,7 @@ const buildCapabilities = (project) => {
|
|
|
37817
38010
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
37818
38011
|
if (project.isStaticExport) capabilities.add("nextjs:static-export");
|
|
37819
38012
|
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
|
|
38013
|
+
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
|
|
37820
38014
|
addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
|
|
37821
38015
|
if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
|
|
37822
38016
|
major: 19,
|
|
@@ -37829,9 +38023,30 @@ const buildCapabilities = (project) => {
|
|
|
37829
38023
|
})) capabilities.add("tailwind:3.4");
|
|
37830
38024
|
if (project.zodVersion !== null) capabilities.add("zod");
|
|
37831
38025
|
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);
|
|
37832
38035
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
37833
38036
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
37834
|
-
if (project.hasTanStackQuery) capabilities.add("tanstack-query");
|
|
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
|
+
}
|
|
37835
38050
|
if (project.hasTypeScript) capabilities.add("typescript");
|
|
37836
38051
|
if (project.preactVersion !== null) capabilities.add("preact");
|
|
37837
38052
|
addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
|
|
@@ -40100,6 +40315,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
40100
40315
|
}
|
|
40101
40316
|
};
|
|
40102
40317
|
};
|
|
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
|
+
};
|
|
40103
40331
|
const bundledRequire = createRequire(import.meta.url);
|
|
40104
40332
|
const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
|
|
40105
40333
|
const resolveChildNodeVersion = (nodeBinaryPath) => {
|
|
@@ -40123,6 +40351,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
|
|
|
40123
40351
|
"oxlint-plugin-react-doctor/package.json",
|
|
40124
40352
|
"eslint-plugin-react-hooks/package.json"
|
|
40125
40353
|
];
|
|
40354
|
+
const resolvePluginFingerprint = () => {
|
|
40355
|
+
try {
|
|
40356
|
+
return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
|
|
40357
|
+
} catch {
|
|
40358
|
+
return "unresolved";
|
|
40359
|
+
}
|
|
40360
|
+
};
|
|
40126
40361
|
const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
40127
40362
|
const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
|
|
40128
40363
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
|
|
@@ -40132,6 +40367,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
|
40132
40367
|
} catch {
|
|
40133
40368
|
versions.push(`${specifier}=missing`);
|
|
40134
40369
|
}
|
|
40370
|
+
versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
|
|
40135
40371
|
return versions;
|
|
40136
40372
|
};
|
|
40137
40373
|
const esmRequire = createRequire(import.meta.url);
|
|
@@ -40825,12 +41061,17 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
|
|
|
40825
41061
|
const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
|
|
40826
41062
|
const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
|
|
40827
41063
|
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`.";
|
|
40828
41065
|
const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
|
|
40829
41066
|
const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
|
|
40830
41067
|
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
40831
41068
|
if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
|
|
40832
41069
|
return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
|
|
40833
41070
|
};
|
|
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
|
+
};
|
|
40834
41075
|
const PLUGIN_CATEGORY_MAP = {
|
|
40835
41076
|
react: "Bugs",
|
|
40836
41077
|
"react-hooks": "Bugs",
|
|
@@ -40888,6 +41129,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
|
|
|
40888
41129
|
message: REACT_ERROR_BOUNDARY_MESSAGE,
|
|
40889
41130
|
help: reasonDetail || help
|
|
40890
41131
|
};
|
|
41132
|
+
if (rule === "set-state-in-effect") return {
|
|
41133
|
+
message: buildSetStateInEffectMessage(reasonSummary.trim()),
|
|
41134
|
+
help: reasonDetail || help
|
|
41135
|
+
};
|
|
40891
41136
|
return {
|
|
40892
41137
|
message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
|
|
40893
41138
|
help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
|
|
@@ -45448,5 +45693,5 @@ const startLanguageServer = () => {
|
|
|
45448
45693
|
};
|
|
45449
45694
|
//#endregion
|
|
45450
45695
|
export { startLanguageServer };
|
|
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]="
|
|
45452
|
-
//# debugId=
|
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.8.1-dev.
|
|
3
|
+
"version": "0.8.1-dev.cd9ca68",
|
|
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
|
-
"
|
|
69
|
-
"
|
|
68
|
+
"deslop-js": "0.8.1",
|
|
69
|
+
"oxlint-plugin-react-doctor": "0.8.1-dev.cd9ca68"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/babel__code-frame": "^7.27.0",
|