react-doctor 0.1.5 → 0.1.6
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 +54 -24
- package/dist/eslint-plugin.js +1 -1
- package/dist/index.js +82 -24
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -39,10 +39,18 @@ const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
|
39
39
|
const OXLINT_NODE_REQUIREMENT = "^20.19.0 || >=22.12.0";
|
|
40
40
|
const GIT_SHOW_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
41
41
|
const IGNORED_DIRECTORIES = new Set([
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
".git",
|
|
43
|
+
".next",
|
|
44
|
+
".nuxt",
|
|
45
|
+
".output",
|
|
46
|
+
".svelte-kit",
|
|
47
|
+
".turbo",
|
|
44
48
|
"build",
|
|
45
|
-
"coverage"
|
|
49
|
+
"coverage",
|
|
50
|
+
"dist",
|
|
51
|
+
"node_modules",
|
|
52
|
+
"out",
|
|
53
|
+
"storybook-static"
|
|
46
54
|
]);
|
|
47
55
|
const CANONICAL_GITHUB_URL = "https://github.com/millionco/react-doctor";
|
|
48
56
|
const SKILL_NAME = "react-doctor";
|
|
@@ -1455,36 +1463,58 @@ const hasReactDependency = (packageJson) => {
|
|
|
1455
1463
|
const allDependencies = collectAllDependencies(packageJson);
|
|
1456
1464
|
return Object.keys(allDependencies).some((packageName) => REACT_DEPENDENCY_NAMES.has(packageName));
|
|
1457
1465
|
};
|
|
1458
|
-
const
|
|
1459
|
-
if (!fs.existsSync(rootDirectory) || !fs.statSync(rootDirectory).isDirectory()) return [];
|
|
1466
|
+
const toReactWorkspacePackages = (directories) => {
|
|
1460
1467
|
const packages = [];
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
const rootPackageJson = readPackageJson(rootPackageJsonPath);
|
|
1464
|
-
if (hasReactDependency(rootPackageJson)) {
|
|
1465
|
-
const name = rootPackageJson.name ?? path.basename(rootDirectory);
|
|
1466
|
-
packages.push({
|
|
1467
|
-
name,
|
|
1468
|
-
directory: rootDirectory
|
|
1469
|
-
});
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
const entries = fs.readdirSync(rootDirectory, { withFileTypes: true });
|
|
1473
|
-
for (const entry of entries) {
|
|
1474
|
-
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
1475
|
-
const subdirectory = path.join(rootDirectory, entry.name);
|
|
1476
|
-
const packageJsonPath = path.join(subdirectory, "package.json");
|
|
1468
|
+
for (const directory of directories) {
|
|
1469
|
+
const packageJsonPath = path.join(directory, "package.json");
|
|
1477
1470
|
if (!isFile(packageJsonPath)) continue;
|
|
1478
1471
|
const packageJson = readPackageJson(packageJsonPath);
|
|
1479
1472
|
if (!hasReactDependency(packageJson)) continue;
|
|
1480
|
-
const name = packageJson.name ??
|
|
1473
|
+
const name = packageJson.name ?? path.basename(directory);
|
|
1481
1474
|
packages.push({
|
|
1482
1475
|
name,
|
|
1483
|
-
directory
|
|
1476
|
+
directory
|
|
1484
1477
|
});
|
|
1485
1478
|
}
|
|
1486
1479
|
return packages;
|
|
1487
1480
|
};
|
|
1481
|
+
const listManifestWorkspacePackages = (rootDirectory) => {
|
|
1482
|
+
if (isFile(path.join(rootDirectory, "package.json"))) return listWorkspacePackages(rootDirectory);
|
|
1483
|
+
const patterns = parsePnpmWorkspacePatterns(rootDirectory);
|
|
1484
|
+
const nxPatterns = patterns.length > 0 ? [] : getNxWorkspaceDirectories(rootDirectory);
|
|
1485
|
+
return toReactWorkspacePackages((patterns.length > 0 ? patterns : nxPatterns).flatMap((pattern) => resolveWorkspaceDirectories(rootDirectory, pattern)));
|
|
1486
|
+
};
|
|
1487
|
+
const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
1488
|
+
const packages = [];
|
|
1489
|
+
const pendingDirectories = [rootDirectory];
|
|
1490
|
+
while (pendingDirectories.length > 0) {
|
|
1491
|
+
const currentDirectory = pendingDirectories.shift();
|
|
1492
|
+
if (!currentDirectory) continue;
|
|
1493
|
+
const packageJsonPath = path.join(currentDirectory, "package.json");
|
|
1494
|
+
if (isFile(packageJsonPath)) {
|
|
1495
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
1496
|
+
if (hasReactDependency(packageJson)) {
|
|
1497
|
+
const name = packageJson.name ?? path.basename(currentDirectory);
|
|
1498
|
+
packages.push({
|
|
1499
|
+
name,
|
|
1500
|
+
directory: currentDirectory
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
const entries = fs.readdirSync(currentDirectory, { withFileTypes: true }).toSorted((firstEntry, secondEntry) => firstEntry.name.localeCompare(secondEntry.name));
|
|
1505
|
+
for (const entry of entries) {
|
|
1506
|
+
if (!entry.isDirectory() || entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
1507
|
+
pendingDirectories.push(path.join(currentDirectory, entry.name));
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
return packages;
|
|
1511
|
+
};
|
|
1512
|
+
const discoverReactSubprojects = (rootDirectory) => {
|
|
1513
|
+
if (!fs.existsSync(rootDirectory) || !fs.statSync(rootDirectory).isDirectory()) return [];
|
|
1514
|
+
const manifestPackages = listManifestWorkspacePackages(rootDirectory);
|
|
1515
|
+
if (manifestPackages.length > 0) return manifestPackages;
|
|
1516
|
+
return discoverReactSubprojectsByFilesystem(rootDirectory);
|
|
1517
|
+
};
|
|
1488
1518
|
const listWorkspacePackages = (rootDirectory) => {
|
|
1489
1519
|
const packageJsonPath = path.join(rootDirectory, "package.json");
|
|
1490
1520
|
if (!isFile(packageJsonPath)) return [];
|
|
@@ -4252,7 +4282,7 @@ const promptProjectSelection = async (workspacePackages, rootDirectory) => {
|
|
|
4252
4282
|
};
|
|
4253
4283
|
//#endregion
|
|
4254
4284
|
//#region src/cli.ts
|
|
4255
|
-
const VERSION = "0.1.
|
|
4285
|
+
const VERSION = "0.1.6";
|
|
4256
4286
|
const VALID_FAIL_ON_LEVELS = new Set([
|
|
4257
4287
|
"error",
|
|
4258
4288
|
"warning",
|
package/dist/eslint-plugin.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -28,10 +28,18 @@ const KNIP_CONFIG_LOCATIONS = [
|
|
|
28
28
|
];
|
|
29
29
|
const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
30
30
|
const IGNORED_DIRECTORIES = new Set([
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
".git",
|
|
32
|
+
".next",
|
|
33
|
+
".nuxt",
|
|
34
|
+
".output",
|
|
35
|
+
".svelte-kit",
|
|
36
|
+
".turbo",
|
|
33
37
|
"build",
|
|
34
|
-
"coverage"
|
|
38
|
+
"coverage",
|
|
39
|
+
"dist",
|
|
40
|
+
"node_modules",
|
|
41
|
+
"out",
|
|
42
|
+
"storybook-static"
|
|
35
43
|
]);
|
|
36
44
|
const PROXY_OUTPUT_MAX_BYTES = 50 * 1024 * 1024;
|
|
37
45
|
const buildNoReactDependencyError = (directory) => `No React dependency found in ${directory}/package.json. Add "react" to dependencies (or peerDependencies) and re-run.`;
|
|
@@ -969,36 +977,86 @@ const hasReactDependency = (packageJson) => {
|
|
|
969
977
|
const allDependencies = collectAllDependencies(packageJson);
|
|
970
978
|
return Object.keys(allDependencies).some((packageName) => REACT_DEPENDENCY_NAMES.has(packageName));
|
|
971
979
|
};
|
|
972
|
-
const
|
|
973
|
-
if (!fs.existsSync(rootDirectory) || !fs.statSync(rootDirectory).isDirectory()) return [];
|
|
980
|
+
const toReactWorkspacePackages = (directories) => {
|
|
974
981
|
const packages = [];
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
const rootPackageJson = readPackageJson(rootPackageJsonPath);
|
|
978
|
-
if (hasReactDependency(rootPackageJson)) {
|
|
979
|
-
const name = rootPackageJson.name ?? path.basename(rootDirectory);
|
|
980
|
-
packages.push({
|
|
981
|
-
name,
|
|
982
|
-
directory: rootDirectory
|
|
983
|
-
});
|
|
984
|
-
}
|
|
985
|
-
}
|
|
986
|
-
const entries = fs.readdirSync(rootDirectory, { withFileTypes: true });
|
|
987
|
-
for (const entry of entries) {
|
|
988
|
-
if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
989
|
-
const subdirectory = path.join(rootDirectory, entry.name);
|
|
990
|
-
const packageJsonPath = path.join(subdirectory, "package.json");
|
|
982
|
+
for (const directory of directories) {
|
|
983
|
+
const packageJsonPath = path.join(directory, "package.json");
|
|
991
984
|
if (!isFile(packageJsonPath)) continue;
|
|
992
985
|
const packageJson = readPackageJson(packageJsonPath);
|
|
993
986
|
if (!hasReactDependency(packageJson)) continue;
|
|
994
|
-
const name = packageJson.name ??
|
|
987
|
+
const name = packageJson.name ?? path.basename(directory);
|
|
995
988
|
packages.push({
|
|
996
989
|
name,
|
|
997
|
-
directory
|
|
990
|
+
directory
|
|
998
991
|
});
|
|
999
992
|
}
|
|
1000
993
|
return packages;
|
|
1001
994
|
};
|
|
995
|
+
const listManifestWorkspacePackages = (rootDirectory) => {
|
|
996
|
+
if (isFile(path.join(rootDirectory, "package.json"))) return listWorkspacePackages(rootDirectory);
|
|
997
|
+
const patterns = parsePnpmWorkspacePatterns(rootDirectory);
|
|
998
|
+
const nxPatterns = patterns.length > 0 ? [] : getNxWorkspaceDirectories(rootDirectory);
|
|
999
|
+
return toReactWorkspacePackages((patterns.length > 0 ? patterns : nxPatterns).flatMap((pattern) => resolveWorkspaceDirectories(rootDirectory, pattern)));
|
|
1000
|
+
};
|
|
1001
|
+
const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
1002
|
+
const packages = [];
|
|
1003
|
+
const pendingDirectories = [rootDirectory];
|
|
1004
|
+
while (pendingDirectories.length > 0) {
|
|
1005
|
+
const currentDirectory = pendingDirectories.shift();
|
|
1006
|
+
if (!currentDirectory) continue;
|
|
1007
|
+
const packageJsonPath = path.join(currentDirectory, "package.json");
|
|
1008
|
+
if (isFile(packageJsonPath)) {
|
|
1009
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
1010
|
+
if (hasReactDependency(packageJson)) {
|
|
1011
|
+
const name = packageJson.name ?? path.basename(currentDirectory);
|
|
1012
|
+
packages.push({
|
|
1013
|
+
name,
|
|
1014
|
+
directory: currentDirectory
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
const entries = fs.readdirSync(currentDirectory, { withFileTypes: true }).toSorted((firstEntry, secondEntry) => firstEntry.name.localeCompare(secondEntry.name));
|
|
1019
|
+
for (const entry of entries) {
|
|
1020
|
+
if (!entry.isDirectory() || entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
1021
|
+
pendingDirectories.push(path.join(currentDirectory, entry.name));
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
return packages;
|
|
1025
|
+
};
|
|
1026
|
+
const discoverReactSubprojects = (rootDirectory) => {
|
|
1027
|
+
if (!fs.existsSync(rootDirectory) || !fs.statSync(rootDirectory).isDirectory()) return [];
|
|
1028
|
+
const manifestPackages = listManifestWorkspacePackages(rootDirectory);
|
|
1029
|
+
if (manifestPackages.length > 0) return manifestPackages;
|
|
1030
|
+
return discoverReactSubprojectsByFilesystem(rootDirectory);
|
|
1031
|
+
};
|
|
1032
|
+
const listWorkspacePackages = (rootDirectory) => {
|
|
1033
|
+
const packageJsonPath = path.join(rootDirectory, "package.json");
|
|
1034
|
+
if (!isFile(packageJsonPath)) return [];
|
|
1035
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
1036
|
+
const patterns = getWorkspacePatterns(rootDirectory, packageJson);
|
|
1037
|
+
if (patterns.length === 0) return [];
|
|
1038
|
+
const packages = [];
|
|
1039
|
+
if (hasReactDependency(packageJson)) {
|
|
1040
|
+
const rootName = packageJson.name ?? path.basename(rootDirectory);
|
|
1041
|
+
packages.push({
|
|
1042
|
+
name: rootName,
|
|
1043
|
+
directory: rootDirectory
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
for (const pattern of patterns) {
|
|
1047
|
+
const directories = resolveWorkspaceDirectories(rootDirectory, pattern);
|
|
1048
|
+
for (const workspaceDirectory of directories) {
|
|
1049
|
+
const workspacePackageJson = readPackageJson(path.join(workspaceDirectory, "package.json"));
|
|
1050
|
+
if (!hasReactDependency(workspacePackageJson)) continue;
|
|
1051
|
+
const name = workspacePackageJson.name ?? path.basename(workspaceDirectory);
|
|
1052
|
+
packages.push({
|
|
1053
|
+
name,
|
|
1054
|
+
directory: workspaceDirectory
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
return packages;
|
|
1059
|
+
};
|
|
1002
1060
|
const hasCompilerPackage = (packageJson) => {
|
|
1003
1061
|
const allDependencies = collectAllDependencies(packageJson);
|
|
1004
1062
|
return Object.keys(allDependencies).some((packageName) => REACT_COMPILER_PACKAGES.has(packageName));
|
|
@@ -1660,7 +1718,7 @@ const resolveDiagnoseTarget = (directory) => {
|
|
|
1660
1718
|
const reactSubprojects = discoverReactSubprojects(directory);
|
|
1661
1719
|
if (reactSubprojects.length === 0) return null;
|
|
1662
1720
|
if (reactSubprojects.length === 1) return reactSubprojects[0].directory;
|
|
1663
|
-
throw new AmbiguousProjectError(directory, reactSubprojects.map((subproject) => path.relative(directory, subproject.directory)));
|
|
1721
|
+
throw new AmbiguousProjectError(directory, reactSubprojects.map((subproject) => path.relative(directory, subproject.directory)).toSorted());
|
|
1664
1722
|
};
|
|
1665
1723
|
//#endregion
|
|
1666
1724
|
//#region src/utils/resolve-lint-include-paths.ts
|
package/package.json
CHANGED