react-doctor 0.2.0-beta.6 → 0.2.1
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/README.md +6 -6
- package/dist/cli.js +302 -55
- package/dist/index.d.ts +2 -1
- package/dist/index.js +292 -54
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -447,16 +447,16 @@ Top React codebases scanned by React Doctor, ranked by score. Updated automatica
|
|
|
447
447
|
<!-- prettier-ignore -->
|
|
448
448
|
| # | Repo | Score |
|
|
449
449
|
| -- | ---- | ----: |
|
|
450
|
-
| 1 | [executor](https://github.com/RhysSullivan/executor) |
|
|
450
|
+
| 1 | [executor](https://github.com/RhysSullivan/executor) | 96 |
|
|
451
451
|
| 2 | [nodejs.org](https://github.com/nodejs/nodejs.org) | 86 |
|
|
452
|
-
| 3 | [tldraw](https://github.com/tldraw/tldraw) |
|
|
453
|
-
| 4 | [t3code](https://github.com/pingdotgg/t3code) |
|
|
452
|
+
| 3 | [tldraw](https://github.com/tldraw/tldraw) | 71 |
|
|
453
|
+
| 4 | [t3code](https://github.com/pingdotgg/t3code) | 69 |
|
|
454
454
|
| 5 | [better-auth](https://github.com/better-auth/better-auth) | 64 |
|
|
455
|
-
| 6 | [
|
|
456
|
-
| 7 | [
|
|
455
|
+
| 6 | [mastra](https://github.com/mastra-ai/mastra) | 63 |
|
|
456
|
+
| 7 | [excalidraw](https://github.com/excalidraw/excalidraw) | 62 |
|
|
457
457
|
| 8 | [payload](https://github.com/payloadcms/payload) | 60 |
|
|
458
458
|
| 9 | [typebot](https://github.com/baptisteArno/typebot.io) | 57 |
|
|
459
|
-
| 10 | [
|
|
459
|
+
| 10 | [medusajs/admin](https://github.com/medusajs/medusa) | 56 |
|
|
460
460
|
|
|
461
461
|
<!-- LEADERBOARD:END -->
|
|
462
462
|
|
package/dist/cli.js
CHANGED
|
@@ -34,7 +34,6 @@ var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(
|
|
|
34
34
|
value: mod,
|
|
35
35
|
enumerable: true
|
|
36
36
|
}) : target, mod));
|
|
37
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
38
37
|
//#endregion
|
|
39
38
|
//#region ../types/dist/index.js
|
|
40
39
|
const REACT_NATIVE_DEPENDENCY_NAMES = new Set([
|
|
@@ -102,12 +101,31 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
102
101
|
"out",
|
|
103
102
|
"storybook-static"
|
|
104
103
|
]);
|
|
104
|
+
const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
105
|
+
"EACCES",
|
|
106
|
+
"EPERM",
|
|
107
|
+
"ENOENT",
|
|
108
|
+
"ENOTDIR"
|
|
109
|
+
]);
|
|
110
|
+
const isIgnorableReaddirError = (error) => {
|
|
111
|
+
if (typeof error !== "object" || error === null) return false;
|
|
112
|
+
const errorCode = error.code;
|
|
113
|
+
return typeof errorCode === "string" && IGNORABLE_READDIR_ERROR_CODES.has(errorCode);
|
|
114
|
+
};
|
|
115
|
+
const readDirectoryEntries = (directoryPath) => {
|
|
116
|
+
try {
|
|
117
|
+
return fs.readdirSync(directoryPath, { withFileTypes: true });
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (isIgnorableReaddirError(error)) return [];
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
105
123
|
const countSourceFilesViaFilesystem = (rootDirectory) => {
|
|
106
124
|
let count = 0;
|
|
107
125
|
const stack = [rootDirectory];
|
|
108
126
|
while (stack.length > 0) {
|
|
109
127
|
const currentDirectory = stack.pop();
|
|
110
|
-
const entries =
|
|
128
|
+
const entries = readDirectoryEntries(currentDirectory);
|
|
111
129
|
for (const entry of entries) {
|
|
112
130
|
if (entry.isDirectory()) {
|
|
113
131
|
if (!entry.name.startsWith(".") && !IGNORED_DIRECTORIES.has(entry.name)) stack.push(path.join(currentDirectory, entry.name));
|
|
@@ -142,7 +160,7 @@ const readPackageJsonUncached = (packageJsonPath) => {
|
|
|
142
160
|
if (error instanceof SyntaxError) return {};
|
|
143
161
|
if (error instanceof Error && "code" in error) {
|
|
144
162
|
const { code } = error;
|
|
145
|
-
if (code === "EISDIR" || code === "EACCES") return {};
|
|
163
|
+
if (code === "EISDIR" || code === "EACCES" || code === "EPERM" || code === "ENOENT") return {};
|
|
146
164
|
}
|
|
147
165
|
throw error;
|
|
148
166
|
}
|
|
@@ -513,6 +531,13 @@ const getDependencyDeclaration = ({ packageJson, packageName, sections }) => {
|
|
|
513
531
|
version: null
|
|
514
532
|
};
|
|
515
533
|
};
|
|
534
|
+
const isDirectory = (directoryPath) => {
|
|
535
|
+
try {
|
|
536
|
+
return fs.statSync(directoryPath).isDirectory();
|
|
537
|
+
} catch {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
};
|
|
516
541
|
const NX_PROJECT_DISCOVERY_DIRS = [
|
|
517
542
|
"apps",
|
|
518
543
|
"libs",
|
|
@@ -523,8 +548,8 @@ const getNxWorkspaceDirectories = (rootDirectory) => {
|
|
|
523
548
|
const collected = [];
|
|
524
549
|
for (const candidate of NX_PROJECT_DISCOVERY_DIRS) {
|
|
525
550
|
const candidatePath = path.join(rootDirectory, candidate);
|
|
526
|
-
if (!
|
|
527
|
-
for (const entry of
|
|
551
|
+
if (!isDirectory(candidatePath)) continue;
|
|
552
|
+
for (const entry of readDirectoryEntries(candidatePath)) {
|
|
528
553
|
if (!entry.isDirectory()) continue;
|
|
529
554
|
const projectDirectory = path.join(candidatePath, entry.name);
|
|
530
555
|
if (isFile(path.join(projectDirectory, "project.json")) || isFile(path.join(projectDirectory, "package.json"))) collected.push(`${candidate}/${entry.name}`);
|
|
@@ -566,17 +591,17 @@ const resolveWorkspaceDirectories = (rootDirectory, pattern) => {
|
|
|
566
591
|
const cleanPattern = pattern.replace(/["']/g, "").replace(/\/\*\*$/, "/*");
|
|
567
592
|
if (!cleanPattern.includes("*")) {
|
|
568
593
|
const directoryPath = path.join(rootDirectory, cleanPattern);
|
|
569
|
-
if (
|
|
594
|
+
if (isDirectory(directoryPath) && isFile(path.join(directoryPath, "package.json"))) return [directoryPath];
|
|
570
595
|
return [];
|
|
571
596
|
}
|
|
572
597
|
const wildcardIndex = cleanPattern.indexOf("*");
|
|
573
598
|
const baseDirectory = path.join(rootDirectory, cleanPattern.slice(0, wildcardIndex));
|
|
574
599
|
const suffixAfterWildcard = cleanPattern.slice(wildcardIndex + 1);
|
|
575
|
-
if (!
|
|
600
|
+
if (!isDirectory(baseDirectory)) return [];
|
|
576
601
|
const resolved = [];
|
|
577
|
-
for (const entry of
|
|
578
|
-
const entryPath = path.join(baseDirectory, entry, suffixAfterWildcard);
|
|
579
|
-
if (
|
|
602
|
+
for (const entry of readDirectoryEntries(baseDirectory)) {
|
|
603
|
+
const entryPath = path.join(baseDirectory, entry.name, suffixAfterWildcard);
|
|
604
|
+
if (isDirectory(entryPath) && isFile(path.join(entryPath, "package.json"))) resolved.push(entryPath);
|
|
580
605
|
}
|
|
581
606
|
return resolved;
|
|
582
607
|
};
|
|
@@ -821,7 +846,7 @@ const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
|
821
846
|
});
|
|
822
847
|
}
|
|
823
848
|
}
|
|
824
|
-
const entries =
|
|
849
|
+
const entries = readDirectoryEntries(currentDirectory).toSorted((firstEntry, secondEntry) => firstEntry.name.localeCompare(secondEntry.name));
|
|
825
850
|
for (const entry of entries) {
|
|
826
851
|
if (!entry.isDirectory() || entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
827
852
|
pendingDirectories.push(path.join(currentDirectory, entry.name));
|
|
@@ -830,7 +855,7 @@ const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
|
830
855
|
return packages;
|
|
831
856
|
};
|
|
832
857
|
const discoverReactSubprojects = (rootDirectory) => {
|
|
833
|
-
if (!
|
|
858
|
+
if (!isDirectory(rootDirectory)) return [];
|
|
834
859
|
const manifestPackages = listManifestWorkspacePackages(rootDirectory);
|
|
835
860
|
if (manifestPackages.length > 0) return manifestPackages;
|
|
836
861
|
return discoverReactSubprojectsByFilesystem(rootDirectory);
|
|
@@ -938,11 +963,11 @@ const isTailwindAtLeast = (detected, required) => {
|
|
|
938
963
|
return detected.minor >= required.minor;
|
|
939
964
|
};
|
|
940
965
|
//#endregion
|
|
941
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
966
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
|
|
942
967
|
var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
943
|
-
const path$3 = __require("path");
|
|
944
968
|
const WIN_SLASH = "\\\\/";
|
|
945
969
|
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
|
|
970
|
+
const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
|
|
946
971
|
/**
|
|
947
972
|
* Posix glob regex
|
|
948
973
|
*/
|
|
@@ -970,7 +995,8 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
970
995
|
NO_DOTS_SLASH: `(?!${DOTS_SLASH})`,
|
|
971
996
|
QMARK_NO_DOT: `[^.${SLASH_LITERAL}]`,
|
|
972
997
|
STAR: `${QMARK}*?`,
|
|
973
|
-
START_ANCHOR
|
|
998
|
+
START_ANCHOR,
|
|
999
|
+
SEP: "/"
|
|
974
1000
|
};
|
|
975
1001
|
/**
|
|
976
1002
|
* Windows glob regex
|
|
@@ -987,11 +1013,14 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
987
1013
|
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
|
|
988
1014
|
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
|
|
989
1015
|
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
|
|
990
|
-
END_ANCHOR: `(?:[${WIN_SLASH}]|$)
|
|
1016
|
+
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
|
|
1017
|
+
SEP: "\\"
|
|
991
1018
|
};
|
|
992
1019
|
module.exports = {
|
|
1020
|
+
DEFAULT_MAX_EXTGLOB_RECURSION,
|
|
993
1021
|
MAX_LENGTH: 1024 * 64,
|
|
994
1022
|
POSIX_REGEX_SOURCE: {
|
|
1023
|
+
__proto__: null,
|
|
995
1024
|
alnum: "a-zA-Z0-9",
|
|
996
1025
|
alpha: "a-zA-Z",
|
|
997
1026
|
ascii: "\\x00-\\x7F",
|
|
@@ -1014,6 +1043,7 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1014
1043
|
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
|
|
1015
1044
|
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
|
|
1016
1045
|
REPLACEMENTS: {
|
|
1046
|
+
__proto__: null,
|
|
1017
1047
|
"***": "*",
|
|
1018
1048
|
"**/**": "**",
|
|
1019
1049
|
"**/**/**": "**"
|
|
@@ -1061,7 +1091,6 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1061
1091
|
CHAR_UNDERSCORE: 95,
|
|
1062
1092
|
CHAR_VERTICAL_LINE: 124,
|
|
1063
1093
|
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
|
|
1064
|
-
SEP: path$3.sep,
|
|
1065
1094
|
/**
|
|
1066
1095
|
* Create EXTGLOB_CHARS
|
|
1067
1096
|
*/
|
|
@@ -1103,30 +1132,27 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1103
1132
|
};
|
|
1104
1133
|
}));
|
|
1105
1134
|
//#endregion
|
|
1106
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1135
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/utils.js
|
|
1107
1136
|
var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
1108
|
-
const path$2 = __require("path");
|
|
1109
|
-
const win32 = process.platform === "win32";
|
|
1110
1137
|
const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
|
|
1111
1138
|
exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
|
|
1112
1139
|
exports.hasRegexChars = (str) => REGEX_SPECIAL_CHARS.test(str);
|
|
1113
1140
|
exports.isRegexChar = (str) => str.length === 1 && exports.hasRegexChars(str);
|
|
1114
1141
|
exports.escapeRegex = (str) => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
|
|
1115
1142
|
exports.toPosixSlashes = (str) => str.replace(REGEX_BACKSLASH, "/");
|
|
1143
|
+
exports.isWindows = () => {
|
|
1144
|
+
if (typeof navigator !== "undefined" && navigator.platform) {
|
|
1145
|
+
const platform = navigator.platform.toLowerCase();
|
|
1146
|
+
return platform === "win32" || platform === "windows";
|
|
1147
|
+
}
|
|
1148
|
+
if (typeof process !== "undefined" && process.platform) return process.platform === "win32";
|
|
1149
|
+
return false;
|
|
1150
|
+
};
|
|
1116
1151
|
exports.removeBackslashes = (str) => {
|
|
1117
1152
|
return str.replace(REGEX_REMOVE_BACKSLASH, (match) => {
|
|
1118
1153
|
return match === "\\" ? "" : match;
|
|
1119
1154
|
});
|
|
1120
1155
|
};
|
|
1121
|
-
exports.supportsLookbehinds = () => {
|
|
1122
|
-
const segs = process.version.slice(1).split(".").map(Number);
|
|
1123
|
-
if (segs.length === 3 && segs[0] >= 9 || segs[0] === 8 && segs[1] >= 10) return true;
|
|
1124
|
-
return false;
|
|
1125
|
-
};
|
|
1126
|
-
exports.isWindows = (options) => {
|
|
1127
|
-
if (options && typeof options.windows === "boolean") return options.windows;
|
|
1128
|
-
return win32 === true || path$2.sep === "\\";
|
|
1129
|
-
};
|
|
1130
1156
|
exports.escapeLast = (input, char, lastIdx) => {
|
|
1131
1157
|
const idx = input.lastIndexOf(char, lastIdx);
|
|
1132
1158
|
if (idx === -1) return input;
|
|
@@ -1146,9 +1172,15 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
|
1146
1172
|
if (state.negated === true) output = `(?:^(?!${output}).*$)`;
|
|
1147
1173
|
return output;
|
|
1148
1174
|
};
|
|
1175
|
+
exports.basename = (path, { windows } = {}) => {
|
|
1176
|
+
const segs = path.split(windows ? /[\\/]/ : "/");
|
|
1177
|
+
const last = segs[segs.length - 1];
|
|
1178
|
+
if (last === "") return segs[segs.length - 2];
|
|
1179
|
+
return last;
|
|
1180
|
+
};
|
|
1149
1181
|
}));
|
|
1150
1182
|
//#endregion
|
|
1151
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1183
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/scan.js
|
|
1152
1184
|
var require_scan = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
1153
1185
|
const utils = require_utils();
|
|
1154
1186
|
const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
|
|
@@ -1435,7 +1467,7 @@ var require_scan = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1435
1467
|
module.exports = scan;
|
|
1436
1468
|
}));
|
|
1437
1469
|
//#endregion
|
|
1438
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1470
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js
|
|
1439
1471
|
var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
1440
1472
|
const constants = require_constants();
|
|
1441
1473
|
const utils = require_utils();
|
|
@@ -1463,6 +1495,177 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1463
1495
|
const syntaxError = (type, char) => {
|
|
1464
1496
|
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
|
|
1465
1497
|
};
|
|
1498
|
+
const splitTopLevel = (input) => {
|
|
1499
|
+
const parts = [];
|
|
1500
|
+
let bracket = 0;
|
|
1501
|
+
let paren = 0;
|
|
1502
|
+
let quote = 0;
|
|
1503
|
+
let value = "";
|
|
1504
|
+
let escaped = false;
|
|
1505
|
+
for (const ch of input) {
|
|
1506
|
+
if (escaped === true) {
|
|
1507
|
+
value += ch;
|
|
1508
|
+
escaped = false;
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1511
|
+
if (ch === "\\") {
|
|
1512
|
+
value += ch;
|
|
1513
|
+
escaped = true;
|
|
1514
|
+
continue;
|
|
1515
|
+
}
|
|
1516
|
+
if (ch === "\"") {
|
|
1517
|
+
quote = quote === 1 ? 0 : 1;
|
|
1518
|
+
value += ch;
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
if (quote === 0) {
|
|
1522
|
+
if (ch === "[") bracket++;
|
|
1523
|
+
else if (ch === "]" && bracket > 0) bracket--;
|
|
1524
|
+
else if (bracket === 0) {
|
|
1525
|
+
if (ch === "(") paren++;
|
|
1526
|
+
else if (ch === ")" && paren > 0) paren--;
|
|
1527
|
+
else if (ch === "|" && paren === 0) {
|
|
1528
|
+
parts.push(value);
|
|
1529
|
+
value = "";
|
|
1530
|
+
continue;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
value += ch;
|
|
1535
|
+
}
|
|
1536
|
+
parts.push(value);
|
|
1537
|
+
return parts;
|
|
1538
|
+
};
|
|
1539
|
+
const isPlainBranch = (branch) => {
|
|
1540
|
+
let escaped = false;
|
|
1541
|
+
for (const ch of branch) {
|
|
1542
|
+
if (escaped === true) {
|
|
1543
|
+
escaped = false;
|
|
1544
|
+
continue;
|
|
1545
|
+
}
|
|
1546
|
+
if (ch === "\\") {
|
|
1547
|
+
escaped = true;
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
if (/[?*+@!()[\]{}]/.test(ch)) return false;
|
|
1551
|
+
}
|
|
1552
|
+
return true;
|
|
1553
|
+
};
|
|
1554
|
+
const normalizeSimpleBranch = (branch) => {
|
|
1555
|
+
let value = branch.trim();
|
|
1556
|
+
let changed = true;
|
|
1557
|
+
while (changed === true) {
|
|
1558
|
+
changed = false;
|
|
1559
|
+
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
|
|
1560
|
+
value = value.slice(2, -1);
|
|
1561
|
+
changed = true;
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
if (!isPlainBranch(value)) return;
|
|
1565
|
+
return value.replace(/\\(.)/g, "$1");
|
|
1566
|
+
};
|
|
1567
|
+
const hasRepeatedCharPrefixOverlap = (branches) => {
|
|
1568
|
+
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
|
|
1569
|
+
for (let i = 0; i < values.length; i++) for (let j = i + 1; j < values.length; j++) {
|
|
1570
|
+
const a = values[i];
|
|
1571
|
+
const b = values[j];
|
|
1572
|
+
const char = a[0];
|
|
1573
|
+
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) continue;
|
|
1574
|
+
if (a === b || a.startsWith(b) || b.startsWith(a)) return true;
|
|
1575
|
+
}
|
|
1576
|
+
return false;
|
|
1577
|
+
};
|
|
1578
|
+
const parseRepeatedExtglob = (pattern, requireEnd = true) => {
|
|
1579
|
+
if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") return;
|
|
1580
|
+
let bracket = 0;
|
|
1581
|
+
let paren = 0;
|
|
1582
|
+
let quote = 0;
|
|
1583
|
+
let escaped = false;
|
|
1584
|
+
for (let i = 1; i < pattern.length; i++) {
|
|
1585
|
+
const ch = pattern[i];
|
|
1586
|
+
if (escaped === true) {
|
|
1587
|
+
escaped = false;
|
|
1588
|
+
continue;
|
|
1589
|
+
}
|
|
1590
|
+
if (ch === "\\") {
|
|
1591
|
+
escaped = true;
|
|
1592
|
+
continue;
|
|
1593
|
+
}
|
|
1594
|
+
if (ch === "\"") {
|
|
1595
|
+
quote = quote === 1 ? 0 : 1;
|
|
1596
|
+
continue;
|
|
1597
|
+
}
|
|
1598
|
+
if (quote === 1) continue;
|
|
1599
|
+
if (ch === "[") {
|
|
1600
|
+
bracket++;
|
|
1601
|
+
continue;
|
|
1602
|
+
}
|
|
1603
|
+
if (ch === "]" && bracket > 0) {
|
|
1604
|
+
bracket--;
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1607
|
+
if (bracket > 0) continue;
|
|
1608
|
+
if (ch === "(") {
|
|
1609
|
+
paren++;
|
|
1610
|
+
continue;
|
|
1611
|
+
}
|
|
1612
|
+
if (ch === ")") {
|
|
1613
|
+
paren--;
|
|
1614
|
+
if (paren === 0) {
|
|
1615
|
+
if (requireEnd === true && i !== pattern.length - 1) return;
|
|
1616
|
+
return {
|
|
1617
|
+
type: pattern[0],
|
|
1618
|
+
body: pattern.slice(2, i),
|
|
1619
|
+
end: i
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
};
|
|
1625
|
+
const getStarExtglobSequenceOutput = (pattern) => {
|
|
1626
|
+
let index = 0;
|
|
1627
|
+
const chars = [];
|
|
1628
|
+
while (index < pattern.length) {
|
|
1629
|
+
const match = parseRepeatedExtglob(pattern.slice(index), false);
|
|
1630
|
+
if (!match || match.type !== "*") return;
|
|
1631
|
+
const branches = splitTopLevel(match.body).map((branch) => branch.trim());
|
|
1632
|
+
if (branches.length !== 1) return;
|
|
1633
|
+
const branch = normalizeSimpleBranch(branches[0]);
|
|
1634
|
+
if (!branch || branch.length !== 1) return;
|
|
1635
|
+
chars.push(branch);
|
|
1636
|
+
index += match.end + 1;
|
|
1637
|
+
}
|
|
1638
|
+
if (chars.length < 1) return;
|
|
1639
|
+
return `${chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`}*`;
|
|
1640
|
+
};
|
|
1641
|
+
const repeatedExtglobRecursion = (pattern) => {
|
|
1642
|
+
let depth = 0;
|
|
1643
|
+
let value = pattern.trim();
|
|
1644
|
+
let match = parseRepeatedExtglob(value);
|
|
1645
|
+
while (match) {
|
|
1646
|
+
depth++;
|
|
1647
|
+
value = match.body.trim();
|
|
1648
|
+
match = parseRepeatedExtglob(value);
|
|
1649
|
+
}
|
|
1650
|
+
return depth;
|
|
1651
|
+
};
|
|
1652
|
+
const analyzeRepeatedExtglob = (body, options) => {
|
|
1653
|
+
if (options.maxExtglobRecursion === false) return { risky: false };
|
|
1654
|
+
const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
|
|
1655
|
+
const branches = splitTopLevel(body).map((branch) => branch.trim());
|
|
1656
|
+
if (branches.length > 1) {
|
|
1657
|
+
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) return { risky: true };
|
|
1658
|
+
}
|
|
1659
|
+
for (const branch of branches) {
|
|
1660
|
+
const safeOutput = getStarExtglobSequenceOutput(branch);
|
|
1661
|
+
if (safeOutput) return {
|
|
1662
|
+
risky: true,
|
|
1663
|
+
safeOutput
|
|
1664
|
+
};
|
|
1665
|
+
if (repeatedExtglobRecursion(branch) > max) return { risky: true };
|
|
1666
|
+
}
|
|
1667
|
+
return { risky: false };
|
|
1668
|
+
};
|
|
1466
1669
|
/**
|
|
1467
1670
|
* Parse the given input string.
|
|
1468
1671
|
* @param {String} input
|
|
@@ -1483,8 +1686,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1483
1686
|
};
|
|
1484
1687
|
const tokens = [bos];
|
|
1485
1688
|
const capture = opts.capture ? "" : "?:";
|
|
1486
|
-
const
|
|
1487
|
-
const PLATFORM_CHARS = constants.globChars(win32);
|
|
1689
|
+
const PLATFORM_CHARS = constants.globChars(opts.windows);
|
|
1488
1690
|
const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
|
|
1489
1691
|
const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS;
|
|
1490
1692
|
const globstar = (opts) => {
|
|
@@ -1576,8 +1778,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1576
1778
|
if (extglobs.length && tok.type !== "paren") extglobs[extglobs.length - 1].inner += tok.value;
|
|
1577
1779
|
if (tok.value || tok.output) append(tok);
|
|
1578
1780
|
if (prev && prev.type === "text" && tok.type === "text") {
|
|
1781
|
+
prev.output = (prev.output || prev.value) + tok.value;
|
|
1579
1782
|
prev.value += tok.value;
|
|
1580
|
-
prev.output = (prev.output || "") + tok.value;
|
|
1581
1783
|
return;
|
|
1582
1784
|
}
|
|
1583
1785
|
tok.prev = prev;
|
|
@@ -1593,6 +1795,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1593
1795
|
token.prev = prev;
|
|
1594
1796
|
token.parens = state.parens;
|
|
1595
1797
|
token.output = state.output;
|
|
1798
|
+
token.startIndex = state.index;
|
|
1799
|
+
token.tokensIndex = tokens.length;
|
|
1596
1800
|
const output = (opts.capture ? "(" : "") + token.open;
|
|
1597
1801
|
increment("parens");
|
|
1598
1802
|
push({
|
|
@@ -1609,6 +1813,30 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1609
1813
|
extglobs.push(token);
|
|
1610
1814
|
};
|
|
1611
1815
|
const extglobClose = (token) => {
|
|
1816
|
+
const literal = input.slice(token.startIndex, state.index + 1);
|
|
1817
|
+
const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
|
|
1818
|
+
if ((token.type === "plus" || token.type === "star") && analysis.risky) {
|
|
1819
|
+
const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
|
|
1820
|
+
const open = tokens[token.tokensIndex];
|
|
1821
|
+
open.type = "text";
|
|
1822
|
+
open.value = literal;
|
|
1823
|
+
open.output = safeOutput || utils.escapeRegex(literal);
|
|
1824
|
+
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
|
|
1825
|
+
tokens[i].value = "";
|
|
1826
|
+
tokens[i].output = "";
|
|
1827
|
+
delete tokens[i].suffix;
|
|
1828
|
+
}
|
|
1829
|
+
state.output = token.output + open.output;
|
|
1830
|
+
state.backtrack = true;
|
|
1831
|
+
push({
|
|
1832
|
+
type: "paren",
|
|
1833
|
+
extglob: true,
|
|
1834
|
+
value,
|
|
1835
|
+
output: ""
|
|
1836
|
+
});
|
|
1837
|
+
decrement("parens");
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1612
1840
|
let output = token.close + (opts.capture ? ")" : "");
|
|
1613
1841
|
let rest;
|
|
1614
1842
|
if (token.type === "negate") {
|
|
@@ -1967,7 +2195,6 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1967
2195
|
if (prev && prev.type === "paren") {
|
|
1968
2196
|
const next = peek();
|
|
1969
2197
|
let output = value;
|
|
1970
|
-
if (next === "<" && !utils.supportsLookbehinds()) throw new Error("Node.js v10 or higher is required for regex lookbehinds");
|
|
1971
2198
|
if (prev.value === "(" && !/[!=<:]/.test(next) || next === "<" && !/<([!=]|\w+>)/.test(remaining())) output = `\\${value}`;
|
|
1972
2199
|
push({
|
|
1973
2200
|
type: "text",
|
|
@@ -2255,8 +2482,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
2255
2482
|
const len = input.length;
|
|
2256
2483
|
if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
|
|
2257
2484
|
input = REPLACEMENTS[input] || input;
|
|
2258
|
-
const
|
|
2259
|
-
const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants.globChars(win32);
|
|
2485
|
+
const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants.globChars(opts.windows);
|
|
2260
2486
|
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
2261
2487
|
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
2262
2488
|
const capture = opts.capture ? "" : "?:";
|
|
@@ -2296,9 +2522,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
2296
2522
|
module.exports = parse;
|
|
2297
2523
|
}));
|
|
2298
2524
|
//#endregion
|
|
2299
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
2525
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/picomatch.js
|
|
2300
2526
|
var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
2301
|
-
const path$1 = __require("path");
|
|
2302
2527
|
const scan = require_scan();
|
|
2303
2528
|
const parse = require_parse();
|
|
2304
2529
|
const utils = require_utils();
|
|
@@ -2340,7 +2565,7 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2340
2565
|
const isState = isObject(glob) && glob.tokens && glob.input;
|
|
2341
2566
|
if (glob === "" || typeof glob !== "string" && !isState) throw new TypeError("Expected pattern to be a non-empty string");
|
|
2342
2567
|
const opts = options || {};
|
|
2343
|
-
const posix =
|
|
2568
|
+
const posix = opts.windows;
|
|
2344
2569
|
const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
|
|
2345
2570
|
const state = regex.state;
|
|
2346
2571
|
delete regex.state;
|
|
@@ -2436,8 +2661,8 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2436
2661
|
* @return {Boolean}
|
|
2437
2662
|
* @api public
|
|
2438
2663
|
*/
|
|
2439
|
-
picomatch.matchBase = (input, glob, options
|
|
2440
|
-
return (glob instanceof RegExp ? glob : picomatch.makeRe(glob, options)).test(
|
|
2664
|
+
picomatch.matchBase = (input, glob, options) => {
|
|
2665
|
+
return (glob instanceof RegExp ? glob : picomatch.makeRe(glob, options)).test(utils.basename(input));
|
|
2441
2666
|
};
|
|
2442
2667
|
/**
|
|
2443
2668
|
* Returns true if **any** of the given glob `patterns` match the specified `string`.
|
|
@@ -2507,6 +2732,14 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2507
2732
|
* Compile a regular expression from the `state` object returned by the
|
|
2508
2733
|
* [parse()](#parse) method.
|
|
2509
2734
|
*
|
|
2735
|
+
* ```js
|
|
2736
|
+
* const picomatch = require('picomatch');
|
|
2737
|
+
* const state = picomatch.parse('*.js');
|
|
2738
|
+
* // picomatch.compileRe(state[, options]);
|
|
2739
|
+
*
|
|
2740
|
+
* console.log(picomatch.compileRe(state));
|
|
2741
|
+
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
|
2742
|
+
* ```
|
|
2510
2743
|
* @param {Object} `state`
|
|
2511
2744
|
* @param {Object} `options`
|
|
2512
2745
|
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
|
|
@@ -2530,10 +2763,10 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2530
2763
|
*
|
|
2531
2764
|
* ```js
|
|
2532
2765
|
* const picomatch = require('picomatch');
|
|
2533
|
-
*
|
|
2534
|
-
* // picomatch.compileRe(state[, options]);
|
|
2766
|
+
* // picomatch.makeRe(state[, options]);
|
|
2535
2767
|
*
|
|
2536
|
-
*
|
|
2768
|
+
* const result = picomatch.makeRe('*.js');
|
|
2769
|
+
* console.log(result);
|
|
2537
2770
|
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
|
2538
2771
|
* ```
|
|
2539
2772
|
* @param {String} `state` The object returned from the `.parse` method.
|
|
@@ -2591,7 +2824,17 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2591
2824
|
//#endregion
|
|
2592
2825
|
//#region ../core/dist/index.js
|
|
2593
2826
|
var import_picomatch = /* @__PURE__ */ __toESM$1((/* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
2594
|
-
|
|
2827
|
+
const pico = require_picomatch$1();
|
|
2828
|
+
const utils = require_utils();
|
|
2829
|
+
function picomatch(glob, options, returnState = false) {
|
|
2830
|
+
if (options && (options.windows === null || options.windows === void 0)) options = {
|
|
2831
|
+
...options,
|
|
2832
|
+
windows: utils.isWindows()
|
|
2833
|
+
};
|
|
2834
|
+
return pico(glob, options, returnState);
|
|
2835
|
+
}
|
|
2836
|
+
Object.assign(picomatch, pico);
|
|
2837
|
+
module.exports = picomatch;
|
|
2595
2838
|
})))(), 1);
|
|
2596
2839
|
var __create = Object.create;
|
|
2597
2840
|
var __defProp = Object.defineProperty;
|
|
@@ -2618,6 +2861,7 @@ const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
|
|
|
2618
2861
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
2619
2862
|
const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
2620
2863
|
const SHARE_BASE_URL = "https://www.react.doctor/share";
|
|
2864
|
+
const REACT_REVIEW_URL = "https://react.review";
|
|
2621
2865
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
2622
2866
|
const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
|
|
2623
2867
|
const ADOPTABLE_LINT_CONFIG_FILENAMES = [".oxlintrc.json", ".eslintrc.json"];
|
|
@@ -4071,12 +4315,7 @@ const findFilesWithDisableDirectivesViaFilesystem = (rootDirectory, includePaths
|
|
|
4071
4315
|
while (stack.length > 0) {
|
|
4072
4316
|
const current = stack.pop();
|
|
4073
4317
|
if (current === void 0) continue;
|
|
4074
|
-
|
|
4075
|
-
try {
|
|
4076
|
-
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
4077
|
-
} catch {
|
|
4078
|
-
continue;
|
|
4079
|
-
}
|
|
4318
|
+
const entries = readDirectoryEntries(current);
|
|
4080
4319
|
for (const entry of entries) {
|
|
4081
4320
|
if (entry.isDirectory()) {
|
|
4082
4321
|
if (entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
@@ -4208,7 +4447,7 @@ const resolveConfigRootDir = (config, configSourceDirectory) => {
|
|
|
4208
4447
|
if (trimmedRootDir.length === 0) return null;
|
|
4209
4448
|
const resolvedRootDir = path.isAbsolute(trimmedRootDir) ? trimmedRootDir : path.resolve(configSourceDirectory, trimmedRootDir);
|
|
4210
4449
|
if (resolvedRootDir === configSourceDirectory) return null;
|
|
4211
|
-
if (!
|
|
4450
|
+
if (!isDirectory(resolvedRootDir)) {
|
|
4212
4451
|
logger.warn(`react-doctor config "rootDir" points to "${rawRootDir}" (resolved to ${resolvedRootDir}), which is not a directory. Ignoring.`);
|
|
4213
4452
|
return null;
|
|
4214
4453
|
}
|
|
@@ -4234,7 +4473,7 @@ const listSourceFilesViaFilesystem = (rootDirectory) => {
|
|
|
4234
4473
|
const stack = [rootDirectory];
|
|
4235
4474
|
while (stack.length > 0) {
|
|
4236
4475
|
const currentDirectory = stack.pop();
|
|
4237
|
-
const entries =
|
|
4476
|
+
const entries = readDirectoryEntries(currentDirectory);
|
|
4238
4477
|
for (const entry of entries) {
|
|
4239
4478
|
const absolutePath = path.join(currentDirectory, entry.name);
|
|
4240
4479
|
if (entry.isDirectory()) {
|
|
@@ -5356,6 +5595,12 @@ const printNoScoreHeader = (noScoreMessage) => {
|
|
|
5356
5595
|
logger.log(` ${highlighter.gray(noScoreMessage)}`);
|
|
5357
5596
|
logger.break();
|
|
5358
5597
|
};
|
|
5598
|
+
const printReactReviewCta = () => {
|
|
5599
|
+
logger.log(` ${highlighter.bold("→ Catch these issues on every PR:")} ${highlighter.info(REACT_REVIEW_URL)}`);
|
|
5600
|
+
logger.log(` ${highlighter.dim("React Review is a GitHub App built on React Doctor, and it runs on each pull request,")}`);
|
|
5601
|
+
logger.log(` ${highlighter.dim("posts new issues as inline review comments, and tracks your team's score over time.")}`);
|
|
5602
|
+
logger.break();
|
|
5603
|
+
};
|
|
5359
5604
|
//#endregion
|
|
5360
5605
|
//#region src/cli/utils/write-diagnostics-directory.ts
|
|
5361
5606
|
const writeDiagnosticsDirectory = (diagnostics) => {
|
|
@@ -5404,6 +5649,8 @@ const printSummary = (diagnostics, elapsedMilliseconds, scoreResult, projectName
|
|
|
5404
5649
|
logger.break();
|
|
5405
5650
|
const shareUrl = buildShareUrl(diagnostics, scoreResult, projectName);
|
|
5406
5651
|
logger.log(` ${highlighter.bold("→ Share your results:")} ${highlighter.info(shareUrl)}`);
|
|
5652
|
+
logger.break();
|
|
5653
|
+
printReactReviewCta();
|
|
5407
5654
|
}
|
|
5408
5655
|
};
|
|
5409
5656
|
//#endregion
|
|
@@ -5751,7 +5998,7 @@ const CI_ENVIRONMENT_VARIABLES = [
|
|
|
5751
5998
|
const isCiEnvironment = () => CI_ENVIRONMENT_VARIABLES.some((envVariable) => Boolean(process.env[envVariable])) || process.env.CI === "true";
|
|
5752
5999
|
//#endregion
|
|
5753
6000
|
//#region src/cli/utils/version.ts
|
|
5754
|
-
const VERSION = "0.2.
|
|
6001
|
+
const VERSION = "0.2.1";
|
|
5755
6002
|
//#endregion
|
|
5756
6003
|
//#region src/cli/utils/json-mode.ts
|
|
5757
6004
|
let context = null;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
1
2
|
//#region ../types/dist/index.d.ts
|
|
2
3
|
//#region src/config.d.ts
|
|
3
4
|
type FailOnLevel = "error" | "warning" | "none";
|
|
@@ -401,7 +402,7 @@ declare class AmbiguousProjectError extends ReactDoctorError {
|
|
|
401
402
|
constructor(directory: string, candidates: readonly string[], options?: ErrorOptions);
|
|
402
403
|
}
|
|
403
404
|
declare const isReactDoctorError: (value: unknown) => value is ReactDoctorError; //#endregion
|
|
404
|
-
//#region src/utils/is-
|
|
405
|
+
//#region src/utils/is-directory.d.ts
|
|
405
406
|
//#endregion
|
|
406
407
|
//#region ../core/dist/index.d.ts
|
|
407
408
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,6 @@ var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(
|
|
|
27
27
|
value: mod,
|
|
28
28
|
enumerable: true
|
|
29
29
|
}) : target, mod));
|
|
30
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
31
30
|
//#endregion
|
|
32
31
|
//#region ../types/dist/index.js
|
|
33
32
|
const REACT_NATIVE_DEPENDENCY_NAMES = new Set([
|
|
@@ -114,12 +113,31 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
114
113
|
"out",
|
|
115
114
|
"storybook-static"
|
|
116
115
|
]);
|
|
116
|
+
const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
117
|
+
"EACCES",
|
|
118
|
+
"EPERM",
|
|
119
|
+
"ENOENT",
|
|
120
|
+
"ENOTDIR"
|
|
121
|
+
]);
|
|
122
|
+
const isIgnorableReaddirError = (error) => {
|
|
123
|
+
if (typeof error !== "object" || error === null) return false;
|
|
124
|
+
const errorCode = error.code;
|
|
125
|
+
return typeof errorCode === "string" && IGNORABLE_READDIR_ERROR_CODES.has(errorCode);
|
|
126
|
+
};
|
|
127
|
+
const readDirectoryEntries = (directoryPath) => {
|
|
128
|
+
try {
|
|
129
|
+
return fs.readdirSync(directoryPath, { withFileTypes: true });
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (isIgnorableReaddirError(error)) return [];
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
117
135
|
const countSourceFilesViaFilesystem = (rootDirectory) => {
|
|
118
136
|
let count = 0;
|
|
119
137
|
const stack = [rootDirectory];
|
|
120
138
|
while (stack.length > 0) {
|
|
121
139
|
const currentDirectory = stack.pop();
|
|
122
|
-
const entries =
|
|
140
|
+
const entries = readDirectoryEntries(currentDirectory);
|
|
123
141
|
for (const entry of entries) {
|
|
124
142
|
if (entry.isDirectory()) {
|
|
125
143
|
if (!entry.name.startsWith(".") && !IGNORED_DIRECTORIES.has(entry.name)) stack.push(path.join(currentDirectory, entry.name));
|
|
@@ -157,7 +175,7 @@ const readPackageJsonUncached = (packageJsonPath) => {
|
|
|
157
175
|
if (error instanceof SyntaxError) return {};
|
|
158
176
|
if (error instanceof Error && "code" in error) {
|
|
159
177
|
const { code } = error;
|
|
160
|
-
if (code === "EISDIR" || code === "EACCES") return {};
|
|
178
|
+
if (code === "EISDIR" || code === "EACCES" || code === "EPERM" || code === "ENOENT") return {};
|
|
161
179
|
}
|
|
162
180
|
throw error;
|
|
163
181
|
}
|
|
@@ -528,6 +546,13 @@ const getDependencyDeclaration = ({ packageJson, packageName, sections }) => {
|
|
|
528
546
|
version: null
|
|
529
547
|
};
|
|
530
548
|
};
|
|
549
|
+
const isDirectory = (directoryPath) => {
|
|
550
|
+
try {
|
|
551
|
+
return fs.statSync(directoryPath).isDirectory();
|
|
552
|
+
} catch {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
};
|
|
531
556
|
const NX_PROJECT_DISCOVERY_DIRS = [
|
|
532
557
|
"apps",
|
|
533
558
|
"libs",
|
|
@@ -538,8 +563,8 @@ const getNxWorkspaceDirectories = (rootDirectory) => {
|
|
|
538
563
|
const collected = [];
|
|
539
564
|
for (const candidate of NX_PROJECT_DISCOVERY_DIRS) {
|
|
540
565
|
const candidatePath = path.join(rootDirectory, candidate);
|
|
541
|
-
if (!
|
|
542
|
-
for (const entry of
|
|
566
|
+
if (!isDirectory(candidatePath)) continue;
|
|
567
|
+
for (const entry of readDirectoryEntries(candidatePath)) {
|
|
543
568
|
if (!entry.isDirectory()) continue;
|
|
544
569
|
const projectDirectory = path.join(candidatePath, entry.name);
|
|
545
570
|
if (isFile(path.join(projectDirectory, "project.json")) || isFile(path.join(projectDirectory, "package.json"))) collected.push(`${candidate}/${entry.name}`);
|
|
@@ -581,17 +606,17 @@ const resolveWorkspaceDirectories = (rootDirectory, pattern) => {
|
|
|
581
606
|
const cleanPattern = pattern.replace(/["']/g, "").replace(/\/\*\*$/, "/*");
|
|
582
607
|
if (!cleanPattern.includes("*")) {
|
|
583
608
|
const directoryPath = path.join(rootDirectory, cleanPattern);
|
|
584
|
-
if (
|
|
609
|
+
if (isDirectory(directoryPath) && isFile(path.join(directoryPath, "package.json"))) return [directoryPath];
|
|
585
610
|
return [];
|
|
586
611
|
}
|
|
587
612
|
const wildcardIndex = cleanPattern.indexOf("*");
|
|
588
613
|
const baseDirectory = path.join(rootDirectory, cleanPattern.slice(0, wildcardIndex));
|
|
589
614
|
const suffixAfterWildcard = cleanPattern.slice(wildcardIndex + 1);
|
|
590
|
-
if (!
|
|
615
|
+
if (!isDirectory(baseDirectory)) return [];
|
|
591
616
|
const resolved = [];
|
|
592
|
-
for (const entry of
|
|
593
|
-
const entryPath = path.join(baseDirectory, entry, suffixAfterWildcard);
|
|
594
|
-
if (
|
|
617
|
+
for (const entry of readDirectoryEntries(baseDirectory)) {
|
|
618
|
+
const entryPath = path.join(baseDirectory, entry.name, suffixAfterWildcard);
|
|
619
|
+
if (isDirectory(entryPath) && isFile(path.join(entryPath, "package.json"))) resolved.push(entryPath);
|
|
595
620
|
}
|
|
596
621
|
return resolved;
|
|
597
622
|
};
|
|
@@ -836,7 +861,7 @@ const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
|
836
861
|
});
|
|
837
862
|
}
|
|
838
863
|
}
|
|
839
|
-
const entries =
|
|
864
|
+
const entries = readDirectoryEntries(currentDirectory).toSorted((firstEntry, secondEntry) => firstEntry.name.localeCompare(secondEntry.name));
|
|
840
865
|
for (const entry of entries) {
|
|
841
866
|
if (!entry.isDirectory() || entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
842
867
|
pendingDirectories.push(path.join(currentDirectory, entry.name));
|
|
@@ -845,7 +870,7 @@ const discoverReactSubprojectsByFilesystem = (rootDirectory) => {
|
|
|
845
870
|
return packages;
|
|
846
871
|
};
|
|
847
872
|
const discoverReactSubprojects = (rootDirectory) => {
|
|
848
|
-
if (!
|
|
873
|
+
if (!isDirectory(rootDirectory)) return [];
|
|
849
874
|
const manifestPackages = listManifestWorkspacePackages(rootDirectory);
|
|
850
875
|
if (manifestPackages.length > 0) return manifestPackages;
|
|
851
876
|
return discoverReactSubprojectsByFilesystem(rootDirectory);
|
|
@@ -956,11 +981,11 @@ const isTailwindAtLeast = (detected, required) => {
|
|
|
956
981
|
return detected.minor >= required.minor;
|
|
957
982
|
};
|
|
958
983
|
//#endregion
|
|
959
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
984
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
|
|
960
985
|
var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
961
|
-
const path$3 = __require("path");
|
|
962
986
|
const WIN_SLASH = "\\\\/";
|
|
963
987
|
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
|
|
988
|
+
const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
|
|
964
989
|
/**
|
|
965
990
|
* Posix glob regex
|
|
966
991
|
*/
|
|
@@ -988,7 +1013,8 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
988
1013
|
NO_DOTS_SLASH: `(?!${DOTS_SLASH})`,
|
|
989
1014
|
QMARK_NO_DOT: `[^.${SLASH_LITERAL}]`,
|
|
990
1015
|
STAR: `${QMARK}*?`,
|
|
991
|
-
START_ANCHOR
|
|
1016
|
+
START_ANCHOR,
|
|
1017
|
+
SEP: "/"
|
|
992
1018
|
};
|
|
993
1019
|
/**
|
|
994
1020
|
* Windows glob regex
|
|
@@ -1005,11 +1031,14 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1005
1031
|
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
|
|
1006
1032
|
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
|
|
1007
1033
|
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
|
|
1008
|
-
END_ANCHOR: `(?:[${WIN_SLASH}]|$)
|
|
1034
|
+
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
|
|
1035
|
+
SEP: "\\"
|
|
1009
1036
|
};
|
|
1010
1037
|
module.exports = {
|
|
1038
|
+
DEFAULT_MAX_EXTGLOB_RECURSION,
|
|
1011
1039
|
MAX_LENGTH: 1024 * 64,
|
|
1012
1040
|
POSIX_REGEX_SOURCE: {
|
|
1041
|
+
__proto__: null,
|
|
1013
1042
|
alnum: "a-zA-Z0-9",
|
|
1014
1043
|
alpha: "a-zA-Z",
|
|
1015
1044
|
ascii: "\\x00-\\x7F",
|
|
@@ -1032,6 +1061,7 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1032
1061
|
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
|
|
1033
1062
|
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
|
|
1034
1063
|
REPLACEMENTS: {
|
|
1064
|
+
__proto__: null,
|
|
1035
1065
|
"***": "*",
|
|
1036
1066
|
"**/**": "**",
|
|
1037
1067
|
"**/**/**": "**"
|
|
@@ -1079,7 +1109,6 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1079
1109
|
CHAR_UNDERSCORE: 95,
|
|
1080
1110
|
CHAR_VERTICAL_LINE: 124,
|
|
1081
1111
|
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
|
|
1082
|
-
SEP: path$3.sep,
|
|
1083
1112
|
/**
|
|
1084
1113
|
* Create EXTGLOB_CHARS
|
|
1085
1114
|
*/
|
|
@@ -1121,30 +1150,27 @@ var require_constants = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1121
1150
|
};
|
|
1122
1151
|
}));
|
|
1123
1152
|
//#endregion
|
|
1124
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1153
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/utils.js
|
|
1125
1154
|
var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
1126
|
-
const path$2 = __require("path");
|
|
1127
|
-
const win32 = process.platform === "win32";
|
|
1128
1155
|
const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
|
|
1129
1156
|
exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
|
|
1130
1157
|
exports.hasRegexChars = (str) => REGEX_SPECIAL_CHARS.test(str);
|
|
1131
1158
|
exports.isRegexChar = (str) => str.length === 1 && exports.hasRegexChars(str);
|
|
1132
1159
|
exports.escapeRegex = (str) => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
|
|
1133
1160
|
exports.toPosixSlashes = (str) => str.replace(REGEX_BACKSLASH, "/");
|
|
1161
|
+
exports.isWindows = () => {
|
|
1162
|
+
if (typeof navigator !== "undefined" && navigator.platform) {
|
|
1163
|
+
const platform = navigator.platform.toLowerCase();
|
|
1164
|
+
return platform === "win32" || platform === "windows";
|
|
1165
|
+
}
|
|
1166
|
+
if (typeof process !== "undefined" && process.platform) return process.platform === "win32";
|
|
1167
|
+
return false;
|
|
1168
|
+
};
|
|
1134
1169
|
exports.removeBackslashes = (str) => {
|
|
1135
1170
|
return str.replace(REGEX_REMOVE_BACKSLASH, (match) => {
|
|
1136
1171
|
return match === "\\" ? "" : match;
|
|
1137
1172
|
});
|
|
1138
1173
|
};
|
|
1139
|
-
exports.supportsLookbehinds = () => {
|
|
1140
|
-
const segs = process.version.slice(1).split(".").map(Number);
|
|
1141
|
-
if (segs.length === 3 && segs[0] >= 9 || segs[0] === 8 && segs[1] >= 10) return true;
|
|
1142
|
-
return false;
|
|
1143
|
-
};
|
|
1144
|
-
exports.isWindows = (options) => {
|
|
1145
|
-
if (options && typeof options.windows === "boolean") return options.windows;
|
|
1146
|
-
return win32 === true || path$2.sep === "\\";
|
|
1147
|
-
};
|
|
1148
1174
|
exports.escapeLast = (input, char, lastIdx) => {
|
|
1149
1175
|
const idx = input.lastIndexOf(char, lastIdx);
|
|
1150
1176
|
if (idx === -1) return input;
|
|
@@ -1164,9 +1190,15 @@ var require_utils = /* @__PURE__ */ __commonJSMin$1(((exports) => {
|
|
|
1164
1190
|
if (state.negated === true) output = `(?:^(?!${output}).*$)`;
|
|
1165
1191
|
return output;
|
|
1166
1192
|
};
|
|
1193
|
+
exports.basename = (path, { windows } = {}) => {
|
|
1194
|
+
const segs = path.split(windows ? /[\\/]/ : "/");
|
|
1195
|
+
const last = segs[segs.length - 1];
|
|
1196
|
+
if (last === "") return segs[segs.length - 2];
|
|
1197
|
+
return last;
|
|
1198
|
+
};
|
|
1167
1199
|
}));
|
|
1168
1200
|
//#endregion
|
|
1169
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1201
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/scan.js
|
|
1170
1202
|
var require_scan = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
1171
1203
|
const utils = require_utils();
|
|
1172
1204
|
const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
|
|
@@ -1453,7 +1485,7 @@ var require_scan = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1453
1485
|
module.exports = scan;
|
|
1454
1486
|
}));
|
|
1455
1487
|
//#endregion
|
|
1456
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
1488
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js
|
|
1457
1489
|
var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
1458
1490
|
const constants = require_constants();
|
|
1459
1491
|
const utils = require_utils();
|
|
@@ -1481,6 +1513,177 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1481
1513
|
const syntaxError = (type, char) => {
|
|
1482
1514
|
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
|
|
1483
1515
|
};
|
|
1516
|
+
const splitTopLevel = (input) => {
|
|
1517
|
+
const parts = [];
|
|
1518
|
+
let bracket = 0;
|
|
1519
|
+
let paren = 0;
|
|
1520
|
+
let quote = 0;
|
|
1521
|
+
let value = "";
|
|
1522
|
+
let escaped = false;
|
|
1523
|
+
for (const ch of input) {
|
|
1524
|
+
if (escaped === true) {
|
|
1525
|
+
value += ch;
|
|
1526
|
+
escaped = false;
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
if (ch === "\\") {
|
|
1530
|
+
value += ch;
|
|
1531
|
+
escaped = true;
|
|
1532
|
+
continue;
|
|
1533
|
+
}
|
|
1534
|
+
if (ch === "\"") {
|
|
1535
|
+
quote = quote === 1 ? 0 : 1;
|
|
1536
|
+
value += ch;
|
|
1537
|
+
continue;
|
|
1538
|
+
}
|
|
1539
|
+
if (quote === 0) {
|
|
1540
|
+
if (ch === "[") bracket++;
|
|
1541
|
+
else if (ch === "]" && bracket > 0) bracket--;
|
|
1542
|
+
else if (bracket === 0) {
|
|
1543
|
+
if (ch === "(") paren++;
|
|
1544
|
+
else if (ch === ")" && paren > 0) paren--;
|
|
1545
|
+
else if (ch === "|" && paren === 0) {
|
|
1546
|
+
parts.push(value);
|
|
1547
|
+
value = "";
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
value += ch;
|
|
1553
|
+
}
|
|
1554
|
+
parts.push(value);
|
|
1555
|
+
return parts;
|
|
1556
|
+
};
|
|
1557
|
+
const isPlainBranch = (branch) => {
|
|
1558
|
+
let escaped = false;
|
|
1559
|
+
for (const ch of branch) {
|
|
1560
|
+
if (escaped === true) {
|
|
1561
|
+
escaped = false;
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
if (ch === "\\") {
|
|
1565
|
+
escaped = true;
|
|
1566
|
+
continue;
|
|
1567
|
+
}
|
|
1568
|
+
if (/[?*+@!()[\]{}]/.test(ch)) return false;
|
|
1569
|
+
}
|
|
1570
|
+
return true;
|
|
1571
|
+
};
|
|
1572
|
+
const normalizeSimpleBranch = (branch) => {
|
|
1573
|
+
let value = branch.trim();
|
|
1574
|
+
let changed = true;
|
|
1575
|
+
while (changed === true) {
|
|
1576
|
+
changed = false;
|
|
1577
|
+
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
|
|
1578
|
+
value = value.slice(2, -1);
|
|
1579
|
+
changed = true;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
if (!isPlainBranch(value)) return;
|
|
1583
|
+
return value.replace(/\\(.)/g, "$1");
|
|
1584
|
+
};
|
|
1585
|
+
const hasRepeatedCharPrefixOverlap = (branches) => {
|
|
1586
|
+
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
|
|
1587
|
+
for (let i = 0; i < values.length; i++) for (let j = i + 1; j < values.length; j++) {
|
|
1588
|
+
const a = values[i];
|
|
1589
|
+
const b = values[j];
|
|
1590
|
+
const char = a[0];
|
|
1591
|
+
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) continue;
|
|
1592
|
+
if (a === b || a.startsWith(b) || b.startsWith(a)) return true;
|
|
1593
|
+
}
|
|
1594
|
+
return false;
|
|
1595
|
+
};
|
|
1596
|
+
const parseRepeatedExtglob = (pattern, requireEnd = true) => {
|
|
1597
|
+
if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") return;
|
|
1598
|
+
let bracket = 0;
|
|
1599
|
+
let paren = 0;
|
|
1600
|
+
let quote = 0;
|
|
1601
|
+
let escaped = false;
|
|
1602
|
+
for (let i = 1; i < pattern.length; i++) {
|
|
1603
|
+
const ch = pattern[i];
|
|
1604
|
+
if (escaped === true) {
|
|
1605
|
+
escaped = false;
|
|
1606
|
+
continue;
|
|
1607
|
+
}
|
|
1608
|
+
if (ch === "\\") {
|
|
1609
|
+
escaped = true;
|
|
1610
|
+
continue;
|
|
1611
|
+
}
|
|
1612
|
+
if (ch === "\"") {
|
|
1613
|
+
quote = quote === 1 ? 0 : 1;
|
|
1614
|
+
continue;
|
|
1615
|
+
}
|
|
1616
|
+
if (quote === 1) continue;
|
|
1617
|
+
if (ch === "[") {
|
|
1618
|
+
bracket++;
|
|
1619
|
+
continue;
|
|
1620
|
+
}
|
|
1621
|
+
if (ch === "]" && bracket > 0) {
|
|
1622
|
+
bracket--;
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
if (bracket > 0) continue;
|
|
1626
|
+
if (ch === "(") {
|
|
1627
|
+
paren++;
|
|
1628
|
+
continue;
|
|
1629
|
+
}
|
|
1630
|
+
if (ch === ")") {
|
|
1631
|
+
paren--;
|
|
1632
|
+
if (paren === 0) {
|
|
1633
|
+
if (requireEnd === true && i !== pattern.length - 1) return;
|
|
1634
|
+
return {
|
|
1635
|
+
type: pattern[0],
|
|
1636
|
+
body: pattern.slice(2, i),
|
|
1637
|
+
end: i
|
|
1638
|
+
};
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
};
|
|
1643
|
+
const getStarExtglobSequenceOutput = (pattern) => {
|
|
1644
|
+
let index = 0;
|
|
1645
|
+
const chars = [];
|
|
1646
|
+
while (index < pattern.length) {
|
|
1647
|
+
const match = parseRepeatedExtglob(pattern.slice(index), false);
|
|
1648
|
+
if (!match || match.type !== "*") return;
|
|
1649
|
+
const branches = splitTopLevel(match.body).map((branch) => branch.trim());
|
|
1650
|
+
if (branches.length !== 1) return;
|
|
1651
|
+
const branch = normalizeSimpleBranch(branches[0]);
|
|
1652
|
+
if (!branch || branch.length !== 1) return;
|
|
1653
|
+
chars.push(branch);
|
|
1654
|
+
index += match.end + 1;
|
|
1655
|
+
}
|
|
1656
|
+
if (chars.length < 1) return;
|
|
1657
|
+
return `${chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`}*`;
|
|
1658
|
+
};
|
|
1659
|
+
const repeatedExtglobRecursion = (pattern) => {
|
|
1660
|
+
let depth = 0;
|
|
1661
|
+
let value = pattern.trim();
|
|
1662
|
+
let match = parseRepeatedExtglob(value);
|
|
1663
|
+
while (match) {
|
|
1664
|
+
depth++;
|
|
1665
|
+
value = match.body.trim();
|
|
1666
|
+
match = parseRepeatedExtglob(value);
|
|
1667
|
+
}
|
|
1668
|
+
return depth;
|
|
1669
|
+
};
|
|
1670
|
+
const analyzeRepeatedExtglob = (body, options) => {
|
|
1671
|
+
if (options.maxExtglobRecursion === false) return { risky: false };
|
|
1672
|
+
const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
|
|
1673
|
+
const branches = splitTopLevel(body).map((branch) => branch.trim());
|
|
1674
|
+
if (branches.length > 1) {
|
|
1675
|
+
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) return { risky: true };
|
|
1676
|
+
}
|
|
1677
|
+
for (const branch of branches) {
|
|
1678
|
+
const safeOutput = getStarExtglobSequenceOutput(branch);
|
|
1679
|
+
if (safeOutput) return {
|
|
1680
|
+
risky: true,
|
|
1681
|
+
safeOutput
|
|
1682
|
+
};
|
|
1683
|
+
if (repeatedExtglobRecursion(branch) > max) return { risky: true };
|
|
1684
|
+
}
|
|
1685
|
+
return { risky: false };
|
|
1686
|
+
};
|
|
1484
1687
|
/**
|
|
1485
1688
|
* Parse the given input string.
|
|
1486
1689
|
* @param {String} input
|
|
@@ -1501,8 +1704,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1501
1704
|
};
|
|
1502
1705
|
const tokens = [bos];
|
|
1503
1706
|
const capture = opts.capture ? "" : "?:";
|
|
1504
|
-
const
|
|
1505
|
-
const PLATFORM_CHARS = constants.globChars(win32);
|
|
1707
|
+
const PLATFORM_CHARS = constants.globChars(opts.windows);
|
|
1506
1708
|
const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
|
|
1507
1709
|
const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS;
|
|
1508
1710
|
const globstar = (opts) => {
|
|
@@ -1594,8 +1796,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1594
1796
|
if (extglobs.length && tok.type !== "paren") extglobs[extglobs.length - 1].inner += tok.value;
|
|
1595
1797
|
if (tok.value || tok.output) append(tok);
|
|
1596
1798
|
if (prev && prev.type === "text" && tok.type === "text") {
|
|
1799
|
+
prev.output = (prev.output || prev.value) + tok.value;
|
|
1597
1800
|
prev.value += tok.value;
|
|
1598
|
-
prev.output = (prev.output || "") + tok.value;
|
|
1599
1801
|
return;
|
|
1600
1802
|
}
|
|
1601
1803
|
tok.prev = prev;
|
|
@@ -1611,6 +1813,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1611
1813
|
token.prev = prev;
|
|
1612
1814
|
token.parens = state.parens;
|
|
1613
1815
|
token.output = state.output;
|
|
1816
|
+
token.startIndex = state.index;
|
|
1817
|
+
token.tokensIndex = tokens.length;
|
|
1614
1818
|
const output = (opts.capture ? "(" : "") + token.open;
|
|
1615
1819
|
increment("parens");
|
|
1616
1820
|
push({
|
|
@@ -1627,6 +1831,30 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1627
1831
|
extglobs.push(token);
|
|
1628
1832
|
};
|
|
1629
1833
|
const extglobClose = (token) => {
|
|
1834
|
+
const literal = input.slice(token.startIndex, state.index + 1);
|
|
1835
|
+
const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
|
|
1836
|
+
if ((token.type === "plus" || token.type === "star") && analysis.risky) {
|
|
1837
|
+
const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
|
|
1838
|
+
const open = tokens[token.tokensIndex];
|
|
1839
|
+
open.type = "text";
|
|
1840
|
+
open.value = literal;
|
|
1841
|
+
open.output = safeOutput || utils.escapeRegex(literal);
|
|
1842
|
+
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
|
|
1843
|
+
tokens[i].value = "";
|
|
1844
|
+
tokens[i].output = "";
|
|
1845
|
+
delete tokens[i].suffix;
|
|
1846
|
+
}
|
|
1847
|
+
state.output = token.output + open.output;
|
|
1848
|
+
state.backtrack = true;
|
|
1849
|
+
push({
|
|
1850
|
+
type: "paren",
|
|
1851
|
+
extglob: true,
|
|
1852
|
+
value,
|
|
1853
|
+
output: ""
|
|
1854
|
+
});
|
|
1855
|
+
decrement("parens");
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1630
1858
|
let output = token.close + (opts.capture ? ")" : "");
|
|
1631
1859
|
let rest;
|
|
1632
1860
|
if (token.type === "negate") {
|
|
@@ -1985,7 +2213,6 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
1985
2213
|
if (prev && prev.type === "paren") {
|
|
1986
2214
|
const next = peek();
|
|
1987
2215
|
let output = value;
|
|
1988
|
-
if (next === "<" && !utils.supportsLookbehinds()) throw new Error("Node.js v10 or higher is required for regex lookbehinds");
|
|
1989
2216
|
if (prev.value === "(" && !/[!=<:]/.test(next) || next === "<" && !/<([!=]|\w+>)/.test(remaining())) output = `\\${value}`;
|
|
1990
2217
|
push({
|
|
1991
2218
|
type: "text",
|
|
@@ -2273,8 +2500,7 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
2273
2500
|
const len = input.length;
|
|
2274
2501
|
if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
|
|
2275
2502
|
input = REPLACEMENTS[input] || input;
|
|
2276
|
-
const
|
|
2277
|
-
const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants.globChars(win32);
|
|
2503
|
+
const { DOT_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOTS, NO_DOTS_SLASH, STAR, START_ANCHOR } = constants.globChars(opts.windows);
|
|
2278
2504
|
const nodot = opts.dot ? NO_DOTS : NO_DOT;
|
|
2279
2505
|
const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
|
|
2280
2506
|
const capture = opts.capture ? "" : "?:";
|
|
@@ -2314,9 +2540,8 @@ var require_parse = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
|
2314
2540
|
module.exports = parse;
|
|
2315
2541
|
}));
|
|
2316
2542
|
//#endregion
|
|
2317
|
-
//#region ../../node_modules/.pnpm/picomatch@
|
|
2543
|
+
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/picomatch.js
|
|
2318
2544
|
var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
2319
|
-
const path$1 = __require("path");
|
|
2320
2545
|
const scan = require_scan();
|
|
2321
2546
|
const parse = require_parse();
|
|
2322
2547
|
const utils = require_utils();
|
|
@@ -2358,7 +2583,7 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2358
2583
|
const isState = isObject(glob) && glob.tokens && glob.input;
|
|
2359
2584
|
if (glob === "" || typeof glob !== "string" && !isState) throw new TypeError("Expected pattern to be a non-empty string");
|
|
2360
2585
|
const opts = options || {};
|
|
2361
|
-
const posix =
|
|
2586
|
+
const posix = opts.windows;
|
|
2362
2587
|
const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
|
|
2363
2588
|
const state = regex.state;
|
|
2364
2589
|
delete regex.state;
|
|
@@ -2454,8 +2679,8 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2454
2679
|
* @return {Boolean}
|
|
2455
2680
|
* @api public
|
|
2456
2681
|
*/
|
|
2457
|
-
picomatch.matchBase = (input, glob, options
|
|
2458
|
-
return (glob instanceof RegExp ? glob : picomatch.makeRe(glob, options)).test(
|
|
2682
|
+
picomatch.matchBase = (input, glob, options) => {
|
|
2683
|
+
return (glob instanceof RegExp ? glob : picomatch.makeRe(glob, options)).test(utils.basename(input));
|
|
2459
2684
|
};
|
|
2460
2685
|
/**
|
|
2461
2686
|
* Returns true if **any** of the given glob `patterns` match the specified `string`.
|
|
@@ -2525,6 +2750,14 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2525
2750
|
* Compile a regular expression from the `state` object returned by the
|
|
2526
2751
|
* [parse()](#parse) method.
|
|
2527
2752
|
*
|
|
2753
|
+
* ```js
|
|
2754
|
+
* const picomatch = require('picomatch');
|
|
2755
|
+
* const state = picomatch.parse('*.js');
|
|
2756
|
+
* // picomatch.compileRe(state[, options]);
|
|
2757
|
+
*
|
|
2758
|
+
* console.log(picomatch.compileRe(state));
|
|
2759
|
+
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
|
2760
|
+
* ```
|
|
2528
2761
|
* @param {Object} `state`
|
|
2529
2762
|
* @param {Object} `options`
|
|
2530
2763
|
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
|
|
@@ -2548,10 +2781,10 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2548
2781
|
*
|
|
2549
2782
|
* ```js
|
|
2550
2783
|
* const picomatch = require('picomatch');
|
|
2551
|
-
*
|
|
2552
|
-
* // picomatch.compileRe(state[, options]);
|
|
2784
|
+
* // picomatch.makeRe(state[, options]);
|
|
2553
2785
|
*
|
|
2554
|
-
*
|
|
2786
|
+
* const result = picomatch.makeRe('*.js');
|
|
2787
|
+
* console.log(result);
|
|
2555
2788
|
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
|
2556
2789
|
* ```
|
|
2557
2790
|
* @param {String} `state` The object returned from the `.parse` method.
|
|
@@ -2609,7 +2842,17 @@ var require_picomatch$1 = /* @__PURE__ */ __commonJSMin$1(((exports, module) =>
|
|
|
2609
2842
|
//#endregion
|
|
2610
2843
|
//#region ../core/dist/index.js
|
|
2611
2844
|
var import_picomatch = /* @__PURE__ */ __toESM$1((/* @__PURE__ */ __commonJSMin$1(((exports, module) => {
|
|
2612
|
-
|
|
2845
|
+
const pico = require_picomatch$1();
|
|
2846
|
+
const utils = require_utils();
|
|
2847
|
+
function picomatch(glob, options, returnState = false) {
|
|
2848
|
+
if (options && (options.windows === null || options.windows === void 0)) options = {
|
|
2849
|
+
...options,
|
|
2850
|
+
windows: utils.isWindows()
|
|
2851
|
+
};
|
|
2852
|
+
return pico(glob, options, returnState);
|
|
2853
|
+
}
|
|
2854
|
+
Object.assign(picomatch, pico);
|
|
2855
|
+
module.exports = picomatch;
|
|
2613
2856
|
})))(), 1);
|
|
2614
2857
|
var __create = Object.create;
|
|
2615
2858
|
var __defProp = Object.defineProperty;
|
|
@@ -4032,12 +4275,7 @@ const findFilesWithDisableDirectivesViaFilesystem = (rootDirectory, includePaths
|
|
|
4032
4275
|
while (stack.length > 0) {
|
|
4033
4276
|
const current = stack.pop();
|
|
4034
4277
|
if (current === void 0) continue;
|
|
4035
|
-
|
|
4036
|
-
try {
|
|
4037
|
-
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
4038
|
-
} catch {
|
|
4039
|
-
continue;
|
|
4040
|
-
}
|
|
4278
|
+
const entries = readDirectoryEntries(current);
|
|
4041
4279
|
for (const entry of entries) {
|
|
4042
4280
|
if (entry.isDirectory()) {
|
|
4043
4281
|
if (entry.name.startsWith(".") || IGNORED_DIRECTORIES.has(entry.name)) continue;
|
|
@@ -4095,7 +4333,7 @@ const resolveConfigRootDir = (config, configSourceDirectory) => {
|
|
|
4095
4333
|
if (trimmedRootDir.length === 0) return null;
|
|
4096
4334
|
const resolvedRootDir = path.isAbsolute(trimmedRootDir) ? trimmedRootDir : path.resolve(configSourceDirectory, trimmedRootDir);
|
|
4097
4335
|
if (resolvedRootDir === configSourceDirectory) return null;
|
|
4098
|
-
if (!
|
|
4336
|
+
if (!isDirectory(resolvedRootDir)) {
|
|
4099
4337
|
logger.warn(`react-doctor config "rootDir" points to "${rawRootDir}" (resolved to ${resolvedRootDir}), which is not a directory. Ignoring.`);
|
|
4100
4338
|
return null;
|
|
4101
4339
|
}
|
|
@@ -4128,7 +4366,7 @@ const listSourceFilesViaFilesystem = (rootDirectory) => {
|
|
|
4128
4366
|
const stack = [rootDirectory];
|
|
4129
4367
|
while (stack.length > 0) {
|
|
4130
4368
|
const currentDirectory = stack.pop();
|
|
4131
|
-
const entries =
|
|
4369
|
+
const entries = readDirectoryEntries(currentDirectory);
|
|
4132
4370
|
for (const entry of entries) {
|
|
4133
4371
|
const absolutePath = path.join(currentDirectory, entry.name);
|
|
4134
4372
|
if (entry.isDirectory()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Diagnose and fix React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -56,15 +56,15 @@
|
|
|
56
56
|
"picocolors": "^1.1.1",
|
|
57
57
|
"prompts": "^2.4.2",
|
|
58
58
|
"typescript": ">=5.0.4 <7",
|
|
59
|
-
"oxlint-plugin-react-doctor": "0.2.
|
|
59
|
+
"oxlint-plugin-react-doctor": "0.2.1"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/prompts": "^2.4.9",
|
|
63
63
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
64
64
|
"eslint-plugin-react-you-might-not-need-an-effect": "^0.10.1",
|
|
65
|
-
"@react-doctor/
|
|
66
|
-
"@react-doctor/types": "0.2.
|
|
67
|
-
"@react-doctor/
|
|
65
|
+
"@react-doctor/core": "0.2.1",
|
|
66
|
+
"@react-doctor/types": "0.2.1",
|
|
67
|
+
"@react-doctor/project-info": "0.2.1"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"eslint-plugin-react-hooks": "^6 || ^7",
|