react-doctor 0.8.0 → 0.8.1-dev.0b0b5ac
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 +14 -4
- package/dist/cli.js +1043 -170
- package/dist/index.d.ts +119 -94
- package/dist/index.js +460 -60
- package/dist/lsp.js +461 -61
- package/dist/skills/react-doctor/SKILL.md +5 -0
- package/dist/skills/react-doctor/references/explain.md +1 -0
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4ef51735-a42d-5161-b990-86e4fa9e4d19")}catch(e){}}();
|
|
3
3
|
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
|
|
@@ -33040,7 +33040,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
33040
33040
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
33041
33041
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
33042
33042
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
33043
|
-
const CORE_PACKAGE_VERSION = "0.8.
|
|
33043
|
+
const CORE_PACKAGE_VERSION = "0.8.1";
|
|
33044
33044
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
33045
33045
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
33046
33046
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -33375,10 +33375,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
|
|
|
33375
33375
|
const FRAMEWORK_PACKAGES = {
|
|
33376
33376
|
next: "nextjs",
|
|
33377
33377
|
"@tanstack/react-start": "tanstack-start",
|
|
33378
|
-
vite: "vite",
|
|
33379
|
-
"react-scripts": "cra",
|
|
33380
33378
|
"@remix-run/react": "remix",
|
|
33381
33379
|
gatsby: "gatsby",
|
|
33380
|
+
vite: "vite",
|
|
33381
|
+
"react-scripts": "cra",
|
|
33382
33382
|
expo: "expo",
|
|
33383
33383
|
"react-native": "react-native"
|
|
33384
33384
|
};
|
|
@@ -33402,11 +33402,17 @@ const NEXT_CONFIG_FILENAMES = [
|
|
|
33402
33402
|
];
|
|
33403
33403
|
const BABEL_CONFIG_FILENAMES = [
|
|
33404
33404
|
".babelrc",
|
|
33405
|
+
".babelrc.js",
|
|
33405
33406
|
".babelrc.json",
|
|
33407
|
+
".babelrc.cjs",
|
|
33408
|
+
".babelrc.mjs",
|
|
33409
|
+
".babelrc.cts",
|
|
33406
33410
|
"babel.config.js",
|
|
33407
33411
|
"babel.config.json",
|
|
33408
33412
|
"babel.config.cjs",
|
|
33409
|
-
"babel.config.mjs"
|
|
33413
|
+
"babel.config.mjs",
|
|
33414
|
+
"babel.config.ts",
|
|
33415
|
+
"babel.config.cts"
|
|
33410
33416
|
];
|
|
33411
33417
|
const VITE_CONFIG_FILENAMES = [
|
|
33412
33418
|
"vite.config.js",
|
|
@@ -33418,12 +33424,28 @@ const VITE_CONFIG_FILENAMES = [
|
|
|
33418
33424
|
"vitest.config.ts",
|
|
33419
33425
|
"vitest.config.js"
|
|
33420
33426
|
];
|
|
33427
|
+
const RSBUILD_CONFIG_FILENAMES = [
|
|
33428
|
+
"rsbuild.config.ts",
|
|
33429
|
+
"rsbuild.config.js",
|
|
33430
|
+
"rsbuild.config.mts",
|
|
33431
|
+
"rsbuild.config.mjs",
|
|
33432
|
+
"rsbuild.config.cts",
|
|
33433
|
+
"rsbuild.config.cjs"
|
|
33434
|
+
];
|
|
33435
|
+
const RSPACK_CONFIG_FILENAMES = [
|
|
33436
|
+
"rspack.config.ts",
|
|
33437
|
+
"rspack.config.js",
|
|
33438
|
+
"rspack.config.mts",
|
|
33439
|
+
"rspack.config.mjs",
|
|
33440
|
+
"rspack.config.cts",
|
|
33441
|
+
"rspack.config.cjs"
|
|
33442
|
+
];
|
|
33421
33443
|
const EXPO_APP_CONFIG_FILENAMES = [
|
|
33422
33444
|
"app.json",
|
|
33423
33445
|
"app.config.js",
|
|
33424
33446
|
"app.config.ts"
|
|
33425
33447
|
];
|
|
33426
|
-
const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|["']react-compiler["']/;
|
|
33448
|
+
const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|reactCompilerPreset\s*\(|["']react-compiler["']/;
|
|
33427
33449
|
const REACT_COMPILER_ENABLED_FLAG_PATTERN = /["']?reactCompiler["']?\s*:\s*(?:true\b|\{)/;
|
|
33428
33450
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
33429
33451
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
@@ -33458,6 +33480,8 @@ const detectReactCompiler = (directory, packageJson) => {
|
|
|
33458
33480
|
if (hasCompilerInConfigFiles(directory, NEXT_CONFIG_FILENAMES)) return true;
|
|
33459
33481
|
if (hasCompilerInConfigFiles(directory, BABEL_CONFIG_FILENAMES)) return true;
|
|
33460
33482
|
if (hasCompilerInConfigFiles(directory, VITE_CONFIG_FILENAMES)) return true;
|
|
33483
|
+
if (hasCompilerInConfigFiles(directory, RSBUILD_CONFIG_FILENAMES)) return true;
|
|
33484
|
+
if (hasCompilerInConfigFiles(directory, RSPACK_CONFIG_FILENAMES)) return true;
|
|
33461
33485
|
if (hasCompilerInConfigFiles(directory, EXPO_APP_CONFIG_FILENAMES)) return true;
|
|
33462
33486
|
return hasCompilerPackageInAncestors(directory, REACT_COMPILER_TRANSFORM_PACKAGES);
|
|
33463
33487
|
};
|
|
@@ -33905,19 +33929,6 @@ const getPreactVersion = (packageJson) => {
|
|
|
33905
33929
|
...packageJson.devDependencies
|
|
33906
33930
|
}.preact ?? null;
|
|
33907
33931
|
};
|
|
33908
|
-
const TANSTACK_QUERY_PACKAGES = new Set([
|
|
33909
|
-
"@tanstack/react-query",
|
|
33910
|
-
"@tanstack/query-core",
|
|
33911
|
-
"react-query"
|
|
33912
|
-
]);
|
|
33913
|
-
const hasTanStackQuery = (packageJson) => {
|
|
33914
|
-
const allDependencies = {
|
|
33915
|
-
...packageJson.peerDependencies,
|
|
33916
|
-
...packageJson.dependencies,
|
|
33917
|
-
...packageJson.devDependencies
|
|
33918
|
-
};
|
|
33919
|
-
return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
|
|
33920
|
-
};
|
|
33921
33932
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33922
33933
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33923
33934
|
const catalogName = extractCatalogName(version);
|
|
@@ -34120,7 +34131,60 @@ const listWorkspacePackages = (rootDirectory) => {
|
|
|
34120
34131
|
}
|
|
34121
34132
|
return packages;
|
|
34122
34133
|
};
|
|
34134
|
+
const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
|
|
34135
|
+
const allDependencies = {
|
|
34136
|
+
...packageJson.devDependencies,
|
|
34137
|
+
...packageJson.peerDependencies,
|
|
34138
|
+
...packageJson.dependencies
|
|
34139
|
+
};
|
|
34140
|
+
for (const packageName of packageNames) {
|
|
34141
|
+
const version = allDependencies[packageName];
|
|
34142
|
+
if (version !== void 0) return version;
|
|
34143
|
+
}
|
|
34144
|
+
return null;
|
|
34145
|
+
};
|
|
34146
|
+
const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
|
|
34147
|
+
const getTanStackQueryVersion = (packageJson) => {
|
|
34148
|
+
return getPreferredDependencyVersion({
|
|
34149
|
+
packageJson,
|
|
34150
|
+
packageNames: TANSTACK_REACT_QUERY_PACKAGES
|
|
34151
|
+
});
|
|
34152
|
+
};
|
|
34153
|
+
const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
|
|
34154
|
+
const getStyledComponentsVersion = (packageJson) => {
|
|
34155
|
+
return getPreferredDependencyVersion({
|
|
34156
|
+
packageJson,
|
|
34157
|
+
packageNames: STYLED_COMPONENTS_PACKAGES
|
|
34158
|
+
});
|
|
34159
|
+
};
|
|
34160
|
+
const I18N_PACKAGES = [
|
|
34161
|
+
"i18next",
|
|
34162
|
+
"react-i18next",
|
|
34163
|
+
"next-i18next",
|
|
34164
|
+
"react-intl",
|
|
34165
|
+
"next-intl",
|
|
34166
|
+
"use-intl",
|
|
34167
|
+
"@formatjs/intl",
|
|
34168
|
+
"@lingui/core",
|
|
34169
|
+
"@lingui/react",
|
|
34170
|
+
"typesafe-i18n",
|
|
34171
|
+
"@tolgee/react",
|
|
34172
|
+
"react-intl-universal"
|
|
34173
|
+
];
|
|
34174
|
+
const hasI18nDependency = (packageJson) => {
|
|
34175
|
+
const allDependencies = {
|
|
34176
|
+
...packageJson.peerDependencies,
|
|
34177
|
+
...packageJson.dependencies,
|
|
34178
|
+
...packageJson.devDependencies,
|
|
34179
|
+
...packageJson.optionalDependencies
|
|
34180
|
+
};
|
|
34181
|
+
return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
|
|
34182
|
+
};
|
|
34123
34183
|
const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
|
|
34184
|
+
const MOBX_REACT_PACKAGE_NAME = "mobx-react";
|
|
34185
|
+
const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
|
|
34186
|
+
const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
|
|
34187
|
+
const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
|
|
34124
34188
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
34125
34189
|
const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
|
|
34126
34190
|
const dependencyDeclaration = getDependencyDeclaration({
|
|
@@ -34139,7 +34203,26 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
|
|
|
34139
34203
|
if (nextMajor === null) return false;
|
|
34140
34204
|
return nextMajor < currentMajor;
|
|
34141
34205
|
};
|
|
34142
|
-
const
|
|
34206
|
+
const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
|
|
34207
|
+
if (currentFact.version === null) return true;
|
|
34208
|
+
if (nextFact.version === null) return false;
|
|
34209
|
+
const currentMajor = getLowestDependencyMajor(currentFact.version);
|
|
34210
|
+
const nextMajor = getLowestDependencyMajor(nextFact.version);
|
|
34211
|
+
if (currentMajor === null) return false;
|
|
34212
|
+
if (nextMajor === null) return true;
|
|
34213
|
+
if (currentMajor > latestSupportedMajor) return false;
|
|
34214
|
+
if (nextMajor > latestSupportedMajor) return true;
|
|
34215
|
+
return nextMajor < currentMajor;
|
|
34216
|
+
};
|
|
34217
|
+
const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
|
|
34218
|
+
if (!currentVersion) return true;
|
|
34219
|
+
const currentMajor = getLowestDependencyMajor(currentVersion);
|
|
34220
|
+
const nextMajor = getLowestDependencyMajor(nextVersion);
|
|
34221
|
+
if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
|
|
34222
|
+
if (nextMajor === null) return currentMajor >= 6;
|
|
34223
|
+
return nextMajor < currentMajor;
|
|
34224
|
+
};
|
|
34225
|
+
const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
|
|
34143
34226
|
if (facts.expo.version === null) {
|
|
34144
34227
|
const spec = getDependencySpec(packageJson, "expo");
|
|
34145
34228
|
if (spec !== null) facts.expo = {
|
|
@@ -34161,13 +34244,74 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
|
|
|
34161
34244
|
sourceDirectory: directory
|
|
34162
34245
|
};
|
|
34163
34246
|
}
|
|
34247
|
+
const mobxSpec = getDependencySpec(packageJson, "mobx");
|
|
34248
|
+
if (mobxSpec !== null) {
|
|
34249
|
+
const nextMobxFact = {
|
|
34250
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
34251
|
+
rootDirectory: directory,
|
|
34252
|
+
rootPackageJson: packageJson,
|
|
34253
|
+
packageName: "mobx",
|
|
34254
|
+
version: mobxSpec
|
|
34255
|
+
}),
|
|
34256
|
+
sourceDirectory: directory
|
|
34257
|
+
};
|
|
34258
|
+
if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
|
|
34259
|
+
}
|
|
34260
|
+
facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
|
|
34261
|
+
facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
|
|
34262
|
+
facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
|
|
34263
|
+
facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
|
|
34264
|
+
const zustandSpec = getDependencySpec(packageJson, "zustand");
|
|
34265
|
+
if (zustandSpec !== null) {
|
|
34266
|
+
const nextZustandFact = {
|
|
34267
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
34268
|
+
rootDirectory: directory,
|
|
34269
|
+
rootPackageJson: packageJson,
|
|
34270
|
+
packageName: "zustand",
|
|
34271
|
+
version: zustandSpec
|
|
34272
|
+
}),
|
|
34273
|
+
sourceDirectory: directory
|
|
34274
|
+
};
|
|
34275
|
+
if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
|
|
34276
|
+
}
|
|
34164
34277
|
if (facts.reanimatedVersion === null) {
|
|
34165
34278
|
const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
|
|
34166
34279
|
if (spec !== null) facts.reanimatedVersion = spec;
|
|
34167
34280
|
}
|
|
34281
|
+
if (facts.valtioVersion === null) {
|
|
34282
|
+
const spec = getDependencySpec(packageJson, "valtio");
|
|
34283
|
+
if (spec !== null) facts.valtioVersion = spec;
|
|
34284
|
+
}
|
|
34285
|
+
facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
|
|
34286
|
+
const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
|
|
34287
|
+
rootDirectory: directory,
|
|
34288
|
+
rootPackageJson: packageJson,
|
|
34289
|
+
packageName: "styled-components",
|
|
34290
|
+
version: getStyledComponentsVersion(packageJson)
|
|
34291
|
+
});
|
|
34292
|
+
if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
|
|
34293
|
+
facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
|
|
34168
34294
|
facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
|
|
34169
34295
|
facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
|
|
34170
34296
|
facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
|
|
34297
|
+
const remotionSpec = getDependencySpec(packageJson, "remotion");
|
|
34298
|
+
if (remotionSpec !== null) {
|
|
34299
|
+
facts.hasRemotionDependency = true;
|
|
34300
|
+
const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
|
|
34301
|
+
rootDirectory,
|
|
34302
|
+
rootPackageJson,
|
|
34303
|
+
packageName: "remotion",
|
|
34304
|
+
version: remotionSpec
|
|
34305
|
+
});
|
|
34306
|
+
const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
|
|
34307
|
+
if (remotionMajorVersion === null) {
|
|
34308
|
+
facts.hasUnknownRemotionVersion = true;
|
|
34309
|
+
facts.remotionVersion = null;
|
|
34310
|
+
} else if (!facts.hasUnknownRemotionVersion) {
|
|
34311
|
+
const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
|
|
34312
|
+
if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
|
|
34313
|
+
}
|
|
34314
|
+
}
|
|
34171
34315
|
};
|
|
34172
34316
|
const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
|
|
34173
34317
|
const facts = {
|
|
@@ -34187,12 +34331,31 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34187
34331
|
version: null,
|
|
34188
34332
|
sourceDirectory: null
|
|
34189
34333
|
},
|
|
34334
|
+
valtioVersion: null,
|
|
34335
|
+
mobx: {
|
|
34336
|
+
version: null,
|
|
34337
|
+
sourceDirectory: null
|
|
34338
|
+
},
|
|
34339
|
+
hasMobxReact: false,
|
|
34340
|
+
hasMobxReactLite: false,
|
|
34341
|
+
hasMobxStateTree: false,
|
|
34342
|
+
hasMobxReactObserver: false,
|
|
34343
|
+
zustand: {
|
|
34344
|
+
version: null,
|
|
34345
|
+
sourceDirectory: null
|
|
34346
|
+
},
|
|
34347
|
+
tanstackQueryVersion: null,
|
|
34348
|
+
styledComponentsVersion: null,
|
|
34349
|
+
hasI18nLibrary: false,
|
|
34190
34350
|
hasReactNativeAwarePackage: false,
|
|
34191
34351
|
hasReanimatedAwarePackage: false,
|
|
34192
34352
|
hasSsrDependency: false,
|
|
34353
|
+
hasRemotionDependency: false,
|
|
34354
|
+
hasUnknownRemotionVersion: false,
|
|
34355
|
+
remotionVersion: null,
|
|
34193
34356
|
reanimatedVersion: null
|
|
34194
34357
|
};
|
|
34195
|
-
evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
|
|
34358
|
+
evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
|
|
34196
34359
|
let isReactGroupSettled = !collectReactGroup;
|
|
34197
34360
|
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
34198
34361
|
for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
|
|
@@ -34201,7 +34364,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34201
34364
|
if (visitedDirectories.has(workspaceDirectory)) continue;
|
|
34202
34365
|
visitedDirectories.add(workspaceDirectory);
|
|
34203
34366
|
const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
|
|
34204
|
-
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
|
|
34367
|
+
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
|
|
34205
34368
|
const info = extractDependencyInfo(workspacePackageJson);
|
|
34206
34369
|
if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
|
|
34207
34370
|
if (isReactGroupSettled) continue;
|
|
@@ -34425,11 +34588,27 @@ const discoverProjectWithoutPackageJson = (directory) => {
|
|
|
34425
34588
|
tailwindVersion: null,
|
|
34426
34589
|
zodVersion: null,
|
|
34427
34590
|
zodMajorVersion: null,
|
|
34591
|
+
mobxVersion: null,
|
|
34592
|
+
mobxMajorVersion: null,
|
|
34593
|
+
hasMobxReact: false,
|
|
34594
|
+
hasMobxReactLite: false,
|
|
34595
|
+
hasMobxStateTree: false,
|
|
34596
|
+
hasMobxReactObserver: false,
|
|
34597
|
+
zustandVersion: null,
|
|
34598
|
+
zustandMajorVersion: null,
|
|
34428
34599
|
framework: "unknown",
|
|
34429
34600
|
hasTypeScript: hasOwnTsConfig,
|
|
34430
34601
|
hasReactCompiler: false,
|
|
34431
34602
|
hasReactCompilerLintPlugin: false,
|
|
34432
34603
|
hasTanStackQuery: false,
|
|
34604
|
+
valtioVersion: null,
|
|
34605
|
+
valtioMajorVersion: null,
|
|
34606
|
+
hasRemotion: false,
|
|
34607
|
+
remotionVersion: null,
|
|
34608
|
+
remotionMajorVersion: null,
|
|
34609
|
+
hasI18nLibrary: false,
|
|
34610
|
+
tanstackQueryVersion: null,
|
|
34611
|
+
styledComponentsVersion: null,
|
|
34433
34612
|
hasSsrDependency: false,
|
|
34434
34613
|
preactVersion: null,
|
|
34435
34614
|
preactMajorVersion: null,
|
|
@@ -34528,6 +34707,12 @@ const discoverProject = (directory) => {
|
|
|
34528
34707
|
packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
|
|
34529
34708
|
version: workspaceFacts.shopifyFlashList.version
|
|
34530
34709
|
}) : null;
|
|
34710
|
+
const zustandVersion = resolveCatalogBackedDependencyVersion({
|
|
34711
|
+
rootDirectory: directory,
|
|
34712
|
+
rootPackageJson: packageJson,
|
|
34713
|
+
packageName: "zustand",
|
|
34714
|
+
version: workspaceFacts.zustand.version
|
|
34715
|
+
});
|
|
34531
34716
|
const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
|
|
34532
34717
|
const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
|
|
34533
34718
|
const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
|
|
@@ -34536,7 +34721,21 @@ const discoverProject = (directory) => {
|
|
|
34536
34721
|
packageName: "next",
|
|
34537
34722
|
version: workspaceFacts.next.version
|
|
34538
34723
|
}) : null;
|
|
34724
|
+
const valtioVersion = resolveCatalogBackedDependencyVersion({
|
|
34725
|
+
rootDirectory: directory,
|
|
34726
|
+
rootPackageJson: packageJson,
|
|
34727
|
+
packageName: "valtio",
|
|
34728
|
+
version: workspaceFacts.valtioVersion
|
|
34729
|
+
});
|
|
34730
|
+
const mobxVersion = resolveCatalogBackedDependencyVersion({
|
|
34731
|
+
rootDirectory: directory,
|
|
34732
|
+
rootPackageJson: packageJson,
|
|
34733
|
+
packageName: "mobx",
|
|
34734
|
+
version: workspaceFacts.mobx.version
|
|
34735
|
+
});
|
|
34539
34736
|
const preactVersion = getPreactVersion(packageJson);
|
|
34737
|
+
const remotionVersion = workspaceFacts.remotionVersion;
|
|
34738
|
+
const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
|
|
34540
34739
|
const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
|
|
34541
34740
|
const projectInfo = {
|
|
34542
34741
|
rootDirectory: directory,
|
|
@@ -34546,11 +34745,27 @@ const discoverProject = (directory) => {
|
|
|
34546
34745
|
tailwindVersion,
|
|
34547
34746
|
zodVersion,
|
|
34548
34747
|
zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
|
|
34748
|
+
mobxVersion,
|
|
34749
|
+
mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
|
|
34750
|
+
hasMobxReact: workspaceFacts.hasMobxReact,
|
|
34751
|
+
hasMobxReactLite: workspaceFacts.hasMobxReactLite,
|
|
34752
|
+
hasMobxStateTree: workspaceFacts.hasMobxStateTree,
|
|
34753
|
+
hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
|
|
34754
|
+
zustandVersion,
|
|
34755
|
+
zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
|
|
34549
34756
|
framework,
|
|
34550
34757
|
hasTypeScript,
|
|
34551
34758
|
hasReactCompiler: detectReactCompiler(directory, packageJson),
|
|
34552
34759
|
hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
|
|
34553
|
-
hasTanStackQuery:
|
|
34760
|
+
hasTanStackQuery: tanstackQueryVersion !== null,
|
|
34761
|
+
hasI18nLibrary: workspaceFacts.hasI18nLibrary,
|
|
34762
|
+
tanstackQueryVersion,
|
|
34763
|
+
styledComponentsVersion: workspaceFacts.styledComponentsVersion,
|
|
34764
|
+
valtioVersion,
|
|
34765
|
+
valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
|
|
34766
|
+
hasRemotion: workspaceFacts.hasRemotionDependency,
|
|
34767
|
+
remotionVersion,
|
|
34768
|
+
remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
|
|
34554
34769
|
hasSsrDependency: workspaceFacts.hasSsrDependency,
|
|
34555
34770
|
preactVersion,
|
|
34556
34771
|
preactMajorVersion: parseReactMajor(preactVersion),
|
|
@@ -34784,7 +34999,6 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
|
|
|
34784
34999
|
"react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
|
|
34785
35000
|
"react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
|
|
34786
35001
|
"react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
|
|
34787
|
-
"react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
|
|
34788
35002
|
"react/jsx-no-undef": "react-doctor/jsx-no-undef",
|
|
34789
35003
|
"react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
|
|
34790
35004
|
"react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
|
|
@@ -35155,6 +35369,9 @@ const SCRIPT_EXTENSION_FRAGMENT = "[cm]?[jt]sx?";
|
|
|
35155
35369
|
const STORY_FILE_SUFFIX_PATTERN = new RegExp(`\\.(?:stories|story)\\.(?:${SCRIPT_EXTENSION_FRAGMENT})$`);
|
|
35156
35370
|
const TEST_FILE_SUFFIX_PATTERN = new RegExp(`\\.(?:test|spec|fixture|fixtures)\\.(?:${SCRIPT_EXTENSION_FRAGMENT})$`);
|
|
35157
35371
|
const TEST_FILE_DIRECTORY_PATTERN = /(?:^|\/)(?:__tests__|__test__|tests|test|__mocks__|cypress|e2e|playwright)\//;
|
|
35372
|
+
const AMBIGUOUS_TEST_ROUTE_DIRECTORY_PATTERN = /(?:^|\/)(?:tests|test)\//;
|
|
35373
|
+
const NEXT_APP_ROUTE_FILE_SUFFIX_PATTERN = /\/(?:default|error|forbidden|global-error|layout|loading|not-found|page|route|template|unauthorized)\.[cm]?[jt]sx?$/;
|
|
35374
|
+
const SCRIPT_FILE_SUFFIX_PATTERN = /\.[cm]?[jt]sx?$/;
|
|
35158
35375
|
const FIXTURE_PROJECT_PATTERN = /\/(?:fixtures|__fixtures__)\//;
|
|
35159
35376
|
const SOURCE_ROOT_PATTERN = /\/(?:src|app|lib|components|pages|features|modules|packages|apps|frontend|client)\//g;
|
|
35160
35377
|
const stripAboveSourceRoot = (relativePath) => {
|
|
@@ -35165,6 +35382,14 @@ const stripAboveSourceRoot = (relativePath) => {
|
|
|
35165
35382
|
if (lastIdx >= 0) return relativePath.slice(lastIdx);
|
|
35166
35383
|
return relativePath.slice(fixtureMatch.index + fixtureMatch[0].length - 1);
|
|
35167
35384
|
};
|
|
35385
|
+
const isFrameworkRouteBeforeAmbiguousTestDirectory = (relativePath) => {
|
|
35386
|
+
const testDirectoryMatch = AMBIGUOUS_TEST_ROUTE_DIRECTORY_PATTERN.exec(relativePath);
|
|
35387
|
+
if (testDirectoryMatch === null) return false;
|
|
35388
|
+
let nearestRouteRoot;
|
|
35389
|
+
for (const pathSegment of relativePath.slice(0, testDirectoryMatch.index).split("/")) if (pathSegment === "app" || pathSegment === "pages") nearestRouteRoot = pathSegment;
|
|
35390
|
+
if (nearestRouteRoot === void 0) return false;
|
|
35391
|
+
return nearestRouteRoot === "pages" ? SCRIPT_FILE_SUFFIX_PATTERN.test(relativePath) : NEXT_APP_ROUTE_FILE_SUFFIX_PATTERN.test(relativePath);
|
|
35392
|
+
};
|
|
35168
35393
|
/**
|
|
35169
35394
|
* Classifies where a file sits relative to shipped code. A finding in a
|
|
35170
35395
|
* `.stories.tsx` or `.spec.ts` file never runs in front of users, so
|
|
@@ -35181,6 +35406,7 @@ const classifyFileContext = (relativePath) => {
|
|
|
35181
35406
|
if (STORY_FILE_SUFFIX_PATTERN.test(forwardSlashed)) return "story";
|
|
35182
35407
|
if (TEST_FILE_SUFFIX_PATTERN.test(forwardSlashed)) return "test";
|
|
35183
35408
|
const scoped = stripAboveSourceRoot(forwardSlashed);
|
|
35409
|
+
if (isFrameworkRouteBeforeAmbiguousTestDirectory(scoped)) return "production";
|
|
35184
35410
|
return TEST_FILE_DIRECTORY_PATTERN.test(scoped) ? "test" : "production";
|
|
35185
35411
|
};
|
|
35186
35412
|
/**
|
|
@@ -36044,6 +36270,7 @@ const VALID_RULE_SEVERITIES = [
|
|
|
36044
36270
|
"warn",
|
|
36045
36271
|
"off"
|
|
36046
36272
|
];
|
|
36273
|
+
const VALID_INCLUDED_FILE_CONTEXTS = ["test", "story"];
|
|
36047
36274
|
const KNOWN_CATEGORY_LABEL = DIAGNOSTIC_CATEGORY_BUCKETS.join(", ");
|
|
36048
36275
|
const isDiagnosticCategoryBucket = (value) => DIAGNOSTIC_CATEGORY_BUCKETS.includes(value);
|
|
36049
36276
|
const filterKnownCategories = (fieldName, categories) => categories.filter((category) => {
|
|
@@ -36078,6 +36305,7 @@ const SURFACE_CONTROL_FIELD_NAMES = [
|
|
|
36078
36305
|
"includeRules",
|
|
36079
36306
|
"excludeRules"
|
|
36080
36307
|
];
|
|
36308
|
+
const isIncludedFileContext = (value) => VALID_INCLUDED_FILE_CONTEXTS.some((fileContext) => fileContext === value);
|
|
36081
36309
|
const SEVERITY_FIELD_NAMES = ["rules", "categories"];
|
|
36082
36310
|
const isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36083
36311
|
const formatType = (value) => typeof value === "string" ? `"${value}"` : typeof value;
|
|
@@ -36112,6 +36340,15 @@ const validateSurfaceControls = (surface, rawControls) => {
|
|
|
36112
36340
|
return;
|
|
36113
36341
|
}
|
|
36114
36342
|
const validatedSurfaceControls = {};
|
|
36343
|
+
if (rawControls.includeFileContexts !== void 0) {
|
|
36344
|
+
const qualifiedName = `surfaces.${surface}.includeFileContexts`;
|
|
36345
|
+
const result = validateStringArrayField(qualifiedName, rawControls.includeFileContexts);
|
|
36346
|
+
if (result !== void 0) validatedSurfaceControls.includeFileContexts = result.filter((fileContext) => {
|
|
36347
|
+
if (isIncludedFileContext(fileContext)) return true;
|
|
36348
|
+
warnConfigIssue(`config field "${qualifiedName}" lists "${fileContext}", which is not a non-production file context (expected one of: ${VALID_INCLUDED_FILE_CONTEXTS.join(", ")}); ignoring the entry.`);
|
|
36349
|
+
return false;
|
|
36350
|
+
});
|
|
36351
|
+
}
|
|
36115
36352
|
for (const fieldName of SURFACE_CONTROL_FIELD_NAMES) {
|
|
36116
36353
|
if (rawControls[fieldName] === void 0) continue;
|
|
36117
36354
|
const qualifiedName = `surfaces.${surface}.${fieldName}`;
|
|
@@ -37048,9 +37285,25 @@ const BABEL_CONFIG_FILE_NAMES = [
|
|
|
37048
37285
|
".babelrc.json"
|
|
37049
37286
|
];
|
|
37050
37287
|
const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
|
|
37288
|
+
const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
|
|
37289
|
+
const REACT_NATIVE_PACKAGE = "react-native";
|
|
37290
|
+
const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
|
|
37291
|
+
const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
|
|
37051
37292
|
const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
|
|
37052
37293
|
const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
|
|
37294
|
+
const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
|
|
37295
|
+
const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
|
|
37296
|
+
const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
|
|
37297
|
+
if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
|
|
37298
|
+
const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
|
|
37299
|
+
if (normalizedVersionRange === null) return false;
|
|
37300
|
+
const minimumVersion = import_semver.minVersion(normalizedVersionRange);
|
|
37301
|
+
return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
|
|
37302
|
+
};
|
|
37303
|
+
const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
|
|
37053
37304
|
const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
37305
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
37306
|
+
const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
|
|
37054
37307
|
for (const fileName of BABEL_CONFIG_FILE_NAMES) {
|
|
37055
37308
|
const filePath = Path.join(rootDirectory, fileName);
|
|
37056
37309
|
if (!isFile(filePath)) continue;
|
|
@@ -37060,7 +37313,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
37060
37313
|
} catch {
|
|
37061
37314
|
continue;
|
|
37062
37315
|
}
|
|
37063
|
-
if (
|
|
37316
|
+
if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
|
|
37064
37317
|
filePath: fileName,
|
|
37065
37318
|
rule: "rn-no-metro-babel-preset",
|
|
37066
37319
|
severity: "error",
|
|
@@ -37083,12 +37336,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
|
|
|
37083
37336
|
return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
|
|
37084
37337
|
};
|
|
37085
37338
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
37086
|
-
const DEPENDENCY_SECTIONS = [
|
|
37087
|
-
"dependencies",
|
|
37088
|
-
"devDependencies",
|
|
37089
|
-
"peerDependencies",
|
|
37090
|
-
"optionalDependencies"
|
|
37091
|
-
];
|
|
37092
37339
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
37093
37340
|
"19.0": {
|
|
37094
37341
|
rceFixedVersion: "19.0.1",
|
|
@@ -37135,20 +37382,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
|
|
|
37135
37382
|
for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
|
|
37136
37383
|
return [...directories];
|
|
37137
37384
|
};
|
|
37138
|
-
const readDeclaredSpec = (packageJson, packageName) => {
|
|
37139
|
-
for (const section of DEPENDENCY_SECTIONS) {
|
|
37140
|
-
const spec = packageJson[section]?.[packageName];
|
|
37141
|
-
if (typeof spec === "string") return spec;
|
|
37142
|
-
}
|
|
37143
|
-
return null;
|
|
37144
|
-
};
|
|
37145
37385
|
const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
|
|
37146
37386
|
const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
|
|
37147
37387
|
if (isFile(manifestPath)) {
|
|
37148
37388
|
const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
|
|
37149
37389
|
if (installedVersion !== null) return installedVersion;
|
|
37150
37390
|
}
|
|
37151
|
-
const candidateSpecs = [
|
|
37391
|
+
const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
|
|
37152
37392
|
for (const spec of candidateSpecs) {
|
|
37153
37393
|
const pinnedVersion = spec === null ? null : import_semver.valid(spec);
|
|
37154
37394
|
if (pinnedVersion !== null) return pinnedVersion;
|
|
@@ -37816,21 +38056,50 @@ const buildCapabilities = (project) => {
|
|
|
37816
38056
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
37817
38057
|
if (project.isStaticExport) capabilities.add("nextjs:static-export");
|
|
37818
38058
|
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
|
|
38059
|
+
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
|
|
37819
38060
|
addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
|
|
37820
38061
|
if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
|
|
37821
38062
|
major: 19,
|
|
37822
38063
|
minor: 2
|
|
37823
38064
|
})) capabilities.add("react:19.2");
|
|
37824
|
-
if (project.tailwindVersion !== null)
|
|
37825
|
-
|
|
37826
|
-
|
|
37827
|
-
|
|
37828
|
-
|
|
38065
|
+
if (project.tailwindVersion !== null) {
|
|
38066
|
+
capabilities.add("tailwind");
|
|
38067
|
+
const tailwindVersion = parseTailwindMajorMinor(project.tailwindVersion);
|
|
38068
|
+
if (isMajorMinorAtLeast(tailwindVersion, {
|
|
38069
|
+
major: 3,
|
|
38070
|
+
minor: 4
|
|
38071
|
+
})) capabilities.add("tailwind:3.4");
|
|
38072
|
+
if (tailwindVersion !== null && isMajorMinorAtLeast(tailwindVersion, {
|
|
38073
|
+
major: 4,
|
|
38074
|
+
minor: 0
|
|
38075
|
+
})) capabilities.add("tailwind:4");
|
|
38076
|
+
}
|
|
37829
38077
|
if (project.zodVersion !== null) capabilities.add("zod");
|
|
37830
38078
|
if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
|
|
38079
|
+
if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
|
|
38080
|
+
if (project.hasMobxReact === true) capabilities.add("mobx-react");
|
|
38081
|
+
if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
|
|
38082
|
+
if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
|
|
38083
|
+
if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
|
|
38084
|
+
if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
|
|
38085
|
+
if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
|
|
38086
|
+
if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
|
|
38087
|
+
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
37831
38088
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
37832
38089
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
37833
|
-
if (project.hasTanStackQuery) capabilities.add("tanstack-query");
|
|
38090
|
+
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
38091
|
+
if (project.styledComponentsVersion) {
|
|
38092
|
+
capabilities.add("styled-components");
|
|
38093
|
+
const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
|
|
38094
|
+
if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
|
|
38095
|
+
}
|
|
38096
|
+
if (project.hasI18nLibrary) capabilities.add("i18n");
|
|
38097
|
+
if (project.valtioVersion !== null) capabilities.add("valtio");
|
|
38098
|
+
addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
|
|
38099
|
+
if (project.hasRemotion) {
|
|
38100
|
+
capabilities.add("remotion");
|
|
38101
|
+
addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
|
|
38102
|
+
}
|
|
37834
38103
|
if (project.hasTypeScript) capabilities.add("typescript");
|
|
37835
38104
|
if (project.preactVersion !== null) capabilities.add("preact");
|
|
37836
38105
|
addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
|
|
@@ -37845,7 +38114,7 @@ const getCapabilities = (project) => {
|
|
|
37845
38114
|
capabilitiesByProject.set(project, capabilities);
|
|
37846
38115
|
return capabilities;
|
|
37847
38116
|
};
|
|
37848
|
-
const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen) => {
|
|
38117
|
+
const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen, includedTags) => {
|
|
37849
38118
|
if (requires) {
|
|
37850
38119
|
for (const capability of requires) if (!capabilities.has(capability)) return false;
|
|
37851
38120
|
}
|
|
@@ -37856,20 +38125,29 @@ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhe
|
|
|
37856
38125
|
if (tags) {
|
|
37857
38126
|
for (const tag of tags) if (ignoredTags.has(tag)) return false;
|
|
37858
38127
|
}
|
|
38128
|
+
if (includedTags && includedTags.size > 0) {
|
|
38129
|
+
if (!tags?.some((tag) => includedTags.has(tag))) return false;
|
|
38130
|
+
}
|
|
37859
38131
|
return true;
|
|
37860
38132
|
};
|
|
38133
|
+
const shouldEnableRuleByDefaultStatus = (options) => options.defaultEnabled !== false || options.hasExplicitOverride === true || options.includeTagDefaults && options.hasIncludedTags;
|
|
37861
38134
|
const yieldToEventLoop = () => new Promise((resolve) => {
|
|
37862
38135
|
setImmediate(resolve);
|
|
37863
38136
|
});
|
|
37864
38137
|
const createSecurityScanSession = (rootDirectory, options) => {
|
|
37865
38138
|
const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
|
|
37866
38139
|
const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
|
|
38140
|
+
const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
|
|
37867
38141
|
const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
|
|
37868
38142
|
const rule = entry.rule;
|
|
37869
38143
|
const scan = rule.scan;
|
|
37870
38144
|
if (typeof scan !== "function") return [];
|
|
37871
|
-
if (
|
|
37872
|
-
|
|
38145
|
+
if (!shouldEnableRuleByDefaultStatus({
|
|
38146
|
+
defaultEnabled: rule.defaultEnabled,
|
|
38147
|
+
includeTagDefaults: options.includeTagDefaults === true,
|
|
38148
|
+
hasIncludedTags: includedTags.size > 0
|
|
38149
|
+
})) return [];
|
|
38150
|
+
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) return [];
|
|
37873
38151
|
return [{
|
|
37874
38152
|
entry,
|
|
37875
38153
|
scan,
|
|
@@ -38803,6 +39081,7 @@ const buildResolvedControls = (surface, userControls) => {
|
|
|
38803
39081
|
for (const tag of includeTags) excludeTags.delete(tag);
|
|
38804
39082
|
for (const tag of toStringSet(userControls?.excludeTags)) excludeTags.add(tag);
|
|
38805
39083
|
return {
|
|
39084
|
+
includeFileContexts: toStringSet(userControls?.includeFileContexts),
|
|
38806
39085
|
includeTags,
|
|
38807
39086
|
excludeTags,
|
|
38808
39087
|
includeCategories: toStringSet(userControls?.includeCategories),
|
|
@@ -38818,7 +39097,7 @@ const isDiagnosticOnSurface = (diagnostic, surface, config) => {
|
|
|
38818
39097
|
if (resolved.includeRuleKeys.has(ruleKey)) return true;
|
|
38819
39098
|
if (resolved.includeCategories.has(category)) return true;
|
|
38820
39099
|
if (intersects(tags, resolved.includeTags)) return true;
|
|
38821
|
-
if (diagnostic.fileContext !== void 0 && (surface === "score" || surface === "ciFailure")) return false;
|
|
39100
|
+
if (diagnostic.fileContext !== void 0 && (surface === "score" || surface === "ciFailure") && !resolved.includeFileContexts.has(diagnostic.fileContext)) return false;
|
|
38822
39101
|
if (resolved.excludeRuleKeys.has(ruleKey)) return false;
|
|
38823
39102
|
if (resolved.excludeCategories.has(category)) return false;
|
|
38824
39103
|
if (intersects(tags, resolved.excludeTags)) return false;
|
|
@@ -39066,6 +39345,35 @@ const parseGithubViewerPermission = (stdout) => {
|
|
|
39066
39345
|
return /^[A-Z_]+$/.test(value) ? value.toLowerCase() : null;
|
|
39067
39346
|
};
|
|
39068
39347
|
const splitNullSeparated = (value) => value.split("\0").filter((entry) => entry.length > 0);
|
|
39348
|
+
const parseBaselineDiffPlan = (value) => {
|
|
39349
|
+
const entries = splitNullSeparated(value);
|
|
39350
|
+
const baseFiles = /* @__PURE__ */ new Set();
|
|
39351
|
+
const headFiles = /* @__PURE__ */ new Set();
|
|
39352
|
+
for (let entryIndex = 0; entryIndex < entries.length; entryIndex += 2) {
|
|
39353
|
+
const status = entries[entryIndex];
|
|
39354
|
+
const filePath = entries[entryIndex + 1];
|
|
39355
|
+
if (status === void 0 || filePath === void 0 || status.length !== 1) return null;
|
|
39356
|
+
if (status === "A") {
|
|
39357
|
+
headFiles.add(filePath);
|
|
39358
|
+
continue;
|
|
39359
|
+
}
|
|
39360
|
+
if (status === "D") {
|
|
39361
|
+
baseFiles.add(filePath);
|
|
39362
|
+
continue;
|
|
39363
|
+
}
|
|
39364
|
+
if (status === "M" || status === "T") {
|
|
39365
|
+
baseFiles.add(filePath);
|
|
39366
|
+
headFiles.add(filePath);
|
|
39367
|
+
continue;
|
|
39368
|
+
}
|
|
39369
|
+
return null;
|
|
39370
|
+
}
|
|
39371
|
+
return {
|
|
39372
|
+
baseFiles: [...baseFiles],
|
|
39373
|
+
headFiles: [...headFiles],
|
|
39374
|
+
untrackedFiles: []
|
|
39375
|
+
};
|
|
39376
|
+
};
|
|
39069
39377
|
const UNTRACKED_FILE_LAST_LINE = Number.MAX_SAFE_INTEGER;
|
|
39070
39378
|
/**
|
|
39071
39379
|
* `Git` wraps every `git`-via-subprocess call react-doctor makes
|
|
@@ -39268,6 +39576,45 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
39268
39576
|
githubViewerPermission,
|
|
39269
39577
|
branchExists,
|
|
39270
39578
|
mergeBase,
|
|
39579
|
+
baselineDiffPlan: (input) => {
|
|
39580
|
+
if (!isSafeGitRevision(input.ref)) return succeed$2(null);
|
|
39581
|
+
return gen(function* () {
|
|
39582
|
+
const unmerged = yield* runGit(input.directory, [
|
|
39583
|
+
"diff",
|
|
39584
|
+
"--no-ext-diff",
|
|
39585
|
+
"-z",
|
|
39586
|
+
"--name-only",
|
|
39587
|
+
"--diff-filter=U",
|
|
39588
|
+
"--relative"
|
|
39589
|
+
]);
|
|
39590
|
+
if (unmerged.status !== 0 || unmerged.stdout.length > 0) return null;
|
|
39591
|
+
const result = yield* runGit(input.directory, [
|
|
39592
|
+
"diff",
|
|
39593
|
+
"--no-ext-diff",
|
|
39594
|
+
"--no-textconv",
|
|
39595
|
+
"--no-renames",
|
|
39596
|
+
"-z",
|
|
39597
|
+
"--name-status",
|
|
39598
|
+
"--relative",
|
|
39599
|
+
input.ref
|
|
39600
|
+
]);
|
|
39601
|
+
if (result.status !== 0) return null;
|
|
39602
|
+
const plan = parseBaselineDiffPlan(result.stdout);
|
|
39603
|
+
if (plan === null) return null;
|
|
39604
|
+
const untracked = yield* runGit(input.directory, [
|
|
39605
|
+
"ls-files",
|
|
39606
|
+
"--others",
|
|
39607
|
+
"--exclude-standard",
|
|
39608
|
+
"-z"
|
|
39609
|
+
]);
|
|
39610
|
+
if (untracked.status !== 0) return null;
|
|
39611
|
+
return {
|
|
39612
|
+
baseFiles: plan.baseFiles,
|
|
39613
|
+
headFiles: plan.headFiles,
|
|
39614
|
+
untrackedFiles: splitNullSeparated(untracked.stdout)
|
|
39615
|
+
};
|
|
39616
|
+
}).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.baselineDiffPlan"));
|
|
39617
|
+
},
|
|
39271
39618
|
diffSelection: ({ directory, explicitBaseBranch, includeUntracked = false }) => gen(function* () {
|
|
39272
39619
|
if (explicitBaseBranch !== void 0 && explicitBaseBranch.trim().length === 0) return yield* fail$4(new ReactDoctorError({ reason: new GitBaseBranchInvalid({ detail: "Diff base branch cannot be empty." }) }));
|
|
39273
39620
|
if (explicitBaseBranch !== void 0) {
|
|
@@ -39417,6 +39764,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
39417
39764
|
githubViewerPermission: () => succeed$2(snapshot.githubViewerPermission ?? null),
|
|
39418
39765
|
branchExists: (_directory, branch) => succeed$2(snapshot.branchExists?.get(branch) ?? false),
|
|
39419
39766
|
mergeBase: ({ ref }) => succeed$2(snapshot.mergeBase?.get(ref) ?? null),
|
|
39767
|
+
baselineDiffPlan: () => succeed$2(snapshot.baselineDiffPlan ?? null),
|
|
39420
39768
|
diffSelection: () => succeed$2(snapshot.diffSelection ?? null),
|
|
39421
39769
|
stagedFilePaths: () => succeed$2(snapshot.stagedFiles ?? []),
|
|
39422
39770
|
showStagedContent: (_directory, relativePath) => succeed$2(snapshot.stagedContent?.get(relativePath) ?? null),
|
|
@@ -39785,8 +40133,9 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
39785
40133
|
}
|
|
39786
40134
|
return enabled;
|
|
39787
40135
|
};
|
|
39788
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
39789
|
-
const
|
|
40136
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
40137
|
+
const hasIncludedTags = includedTags.size > 0;
|
|
40138
|
+
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
39790
40139
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
39791
40140
|
const jsPlugins = [];
|
|
39792
40141
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
@@ -39801,9 +40150,14 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
39801
40150
|
if (rule.scan !== void 0) continue;
|
|
39802
40151
|
if (customRulesOnly && registryEntry.originallyExternal) continue;
|
|
39803
40152
|
if (rule.framework !== "global" && !rule.requires) continue;
|
|
39804
|
-
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) continue;
|
|
40153
|
+
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
|
|
39805
40154
|
const explicitRuleOverride = resolveRuleSeverityOverride({ ruleKey: registryEntry.key }, severityControls);
|
|
39806
|
-
if (
|
|
40155
|
+
if (!shouldEnableRuleByDefaultStatus({
|
|
40156
|
+
defaultEnabled: rule.defaultEnabled,
|
|
40157
|
+
includeTagDefaults,
|
|
40158
|
+
hasIncludedTags,
|
|
40159
|
+
hasExplicitOverride: explicitRuleOverride !== void 0
|
|
40160
|
+
})) continue;
|
|
39807
40161
|
const severity = resolveRuleSeverityOverride({
|
|
39808
40162
|
ruleKey: registryEntry.key,
|
|
39809
40163
|
category: rule.category
|
|
@@ -39812,7 +40166,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
39812
40166
|
enabledReactDoctorRules[registryEntry.key] = severity;
|
|
39813
40167
|
}
|
|
39814
40168
|
const userPluginRules = {};
|
|
39815
|
-
if (ruleSelection !== "sidecar") for (const userPlugin of userPlugins) {
|
|
40169
|
+
if (ruleSelection !== "sidecar" && !hasIncludedTags) for (const userPlugin of userPlugins) {
|
|
39816
40170
|
Object.assign(userPluginRules, buildUserPluginRules(userPlugin, severityControls));
|
|
39817
40171
|
jsPlugins.push(userPlugin.entry);
|
|
39818
40172
|
}
|
|
@@ -40029,6 +40383,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
40029
40383
|
}
|
|
40030
40384
|
};
|
|
40031
40385
|
};
|
|
40386
|
+
const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
|
|
40387
|
+
const fingerprintFileContents = (filePath, fingerprintLength) => {
|
|
40388
|
+
const fileStats = NFS.statSync(filePath, { bigint: true });
|
|
40389
|
+
const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
|
|
40390
|
+
if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
|
|
40391
|
+
const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
|
|
40392
|
+
fingerprintCacheByFilePath.set(filePath, {
|
|
40393
|
+
fingerprint,
|
|
40394
|
+
modifiedTimeNanoseconds: fileStats.mtimeNs,
|
|
40395
|
+
sizeBytes: fileStats.size
|
|
40396
|
+
});
|
|
40397
|
+
return fingerprint;
|
|
40398
|
+
};
|
|
40032
40399
|
const bundledRequire = createRequire(import.meta.url);
|
|
40033
40400
|
const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
|
|
40034
40401
|
const resolveChildNodeVersion = (nodeBinaryPath) => {
|
|
@@ -40052,6 +40419,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
|
|
|
40052
40419
|
"oxlint-plugin-react-doctor/package.json",
|
|
40053
40420
|
"eslint-plugin-react-hooks/package.json"
|
|
40054
40421
|
];
|
|
40422
|
+
const resolvePluginFingerprint = () => {
|
|
40423
|
+
try {
|
|
40424
|
+
return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
|
|
40425
|
+
} catch {
|
|
40426
|
+
return "unresolved";
|
|
40427
|
+
}
|
|
40428
|
+
};
|
|
40055
40429
|
const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
40056
40430
|
const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
|
|
40057
40431
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
|
|
@@ -40061,6 +40435,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
|
40061
40435
|
} catch {
|
|
40062
40436
|
versions.push(`${specifier}=missing`);
|
|
40063
40437
|
}
|
|
40438
|
+
versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
|
|
40064
40439
|
return versions;
|
|
40065
40440
|
};
|
|
40066
40441
|
const esmRequire = createRequire(import.meta.url);
|
|
@@ -40754,12 +41129,17 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
|
|
|
40754
41129
|
const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
|
|
40755
41130
|
const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
|
|
40756
41131
|
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`.";
|
|
41132
|
+
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`.";
|
|
40757
41133
|
const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
|
|
40758
41134
|
const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
|
|
40759
41135
|
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
40760
41136
|
if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
|
|
40761
41137
|
return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
|
|
40762
41138
|
};
|
|
41139
|
+
const buildSetStateInEffectMessage = (reasonSummary) => {
|
|
41140
|
+
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
41141
|
+
return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
|
|
41142
|
+
};
|
|
40763
41143
|
const PLUGIN_CATEGORY_MAP = {
|
|
40764
41144
|
react: "Bugs",
|
|
40765
41145
|
"react-hooks": "Bugs",
|
|
@@ -40817,6 +41197,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
|
|
|
40817
41197
|
message: REACT_ERROR_BOUNDARY_MESSAGE,
|
|
40818
41198
|
help: reasonDetail || help
|
|
40819
41199
|
};
|
|
41200
|
+
if (rule === "set-state-in-effect") return {
|
|
41201
|
+
message: buildSetStateInEffectMessage(reasonSummary.trim()),
|
|
41202
|
+
help: reasonDetail || help
|
|
41203
|
+
};
|
|
40820
41204
|
return {
|
|
40821
41205
|
message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
|
|
40822
41206
|
help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
|
|
@@ -41527,7 +41911,7 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
41527
41911
|
* 6. always restore disable directives + clean up the temp dir
|
|
41528
41912
|
*/
|
|
41529
41913
|
const runOxlint = async (options) => {
|
|
41530
|
-
const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
|
|
41914
|
+
const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
|
|
41531
41915
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
41532
41916
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
41533
41917
|
validateRuleRegistration();
|
|
@@ -41541,13 +41925,15 @@ const runOxlint = async (options) => {
|
|
|
41541
41925
|
}
|
|
41542
41926
|
const pluginPath = resolvePluginPath();
|
|
41543
41927
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
41544
|
-
const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
41928
|
+
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
41545
41929
|
const buildConfig = (overrides) => createOxlintConfig({
|
|
41546
41930
|
pluginPath,
|
|
41547
41931
|
project,
|
|
41548
41932
|
customRulesOnly,
|
|
41549
41933
|
extendsPaths: overrides.extendsPaths,
|
|
41550
41934
|
ignoredTags,
|
|
41935
|
+
includedTags,
|
|
41936
|
+
includeTagDefaults,
|
|
41551
41937
|
serverAuthFunctionNames,
|
|
41552
41938
|
severityControls,
|
|
41553
41939
|
userPlugins,
|
|
@@ -41936,6 +42322,8 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
|
|
|
41936
42322
|
respectInlineDisables: input.respectInlineDisables,
|
|
41937
42323
|
adoptExistingLintConfig: input.adoptExistingLintConfig,
|
|
41938
42324
|
ignoredTags: input.ignoredTags,
|
|
42325
|
+
includedTags: input.includedTags,
|
|
42326
|
+
includeTagDefaults: input.includeTagDefaults,
|
|
41939
42327
|
userConfig: input.userConfig ?? null,
|
|
41940
42328
|
configSourceDirectory: input.configSourceDirectory,
|
|
41941
42329
|
onPartialFailure: (reason) => {
|
|
@@ -42784,7 +43172,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42784
43172
|
const securityScanFailedRef = yield* make$13(false);
|
|
42785
43173
|
const securityScanFiber = yield* forkChild(runCollect(applyPerElementPipeline(isDiffMode ? empty$4 : unwrap(tryPromise(() => checkSecurityScanCooperative(scanDirectory, {
|
|
42786
43174
|
project,
|
|
42787
|
-
ignoredTags: input.ignoredTags
|
|
43175
|
+
ignoredTags: input.ignoredTags,
|
|
43176
|
+
includedTags: input.includedTags,
|
|
43177
|
+
includeTagDefaults: input.includeTagDefaults
|
|
42788
43178
|
})).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)), catch_$1(() => set(securityScanFailedRef, true).pipe(as(empty$4))))))).pipe(withSpan("SecurityScan.run")));
|
|
42789
43179
|
const shouldRunSupplyChain = !isDiffMode || (input.supplyChainManifestChanged ?? false);
|
|
42790
43180
|
const supplyChainOverlapTimeout = yield* SupplyChainOverlapTimeoutMs;
|
|
@@ -42875,6 +43265,8 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42875
43265
|
respectInlineDisables: input.respectInlineDisables,
|
|
42876
43266
|
adoptExistingLintConfig: input.adoptExistingLintConfig,
|
|
42877
43267
|
ignoredTags: input.ignoredTags,
|
|
43268
|
+
includedTags: input.includedTags,
|
|
43269
|
+
includeTagDefaults: input.includeTagDefaults,
|
|
42878
43270
|
userConfig: resolvedConfig.config ?? void 0,
|
|
42879
43271
|
configSourceDirectory: resolvedConfig.configSourceDirectory ?? void 0,
|
|
42880
43272
|
onFileProgress: (scannedFileCount, totalFileCount) => {
|
|
@@ -43142,12 +43534,19 @@ const isPathInsideDirectory = (childAbsolutePath, parentAbsolutePath) => {
|
|
|
43142
43534
|
*/
|
|
43143
43535
|
const materializeSourceTree = (input) => gen(function* () {
|
|
43144
43536
|
const materializedFiles = [];
|
|
43537
|
+
const unmaterializedFiles = [];
|
|
43145
43538
|
const resolvedTempDirectory = path.resolve(input.tempDirectory);
|
|
43146
43539
|
for (const relativePath of input.files) {
|
|
43147
43540
|
const content = yield* input.readContent(relativePath).pipe(orElseSucceed(() => null));
|
|
43148
|
-
if (content === null)
|
|
43541
|
+
if (content === null) {
|
|
43542
|
+
unmaterializedFiles.push(relativePath);
|
|
43543
|
+
continue;
|
|
43544
|
+
}
|
|
43149
43545
|
const candidateTargetPath = path.resolve(resolvedTempDirectory, relativePath);
|
|
43150
|
-
if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory))
|
|
43546
|
+
if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory)) {
|
|
43547
|
+
unmaterializedFiles.push(relativePath);
|
|
43548
|
+
continue;
|
|
43549
|
+
}
|
|
43151
43550
|
yield* sync(() => {
|
|
43152
43551
|
fs.mkdirSync(path.dirname(candidateTargetPath), { recursive: true });
|
|
43153
43552
|
fs.writeFileSync(candidateTargetPath, content);
|
|
@@ -43164,6 +43563,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
43164
43563
|
return {
|
|
43165
43564
|
tempDirectory: input.tempDirectory,
|
|
43166
43565
|
materializedFiles,
|
|
43566
|
+
unmaterializedFiles,
|
|
43167
43567
|
cleanup: () => {
|
|
43168
43568
|
try {
|
|
43169
43569
|
fs.rmSync(input.tempDirectory, {
|
|
@@ -43727,4 +44127,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
43727
44127
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
43728
44128
|
|
|
43729
44129
|
//# sourceMappingURL=index.js.map
|
|
43730
|
-
//# debugId=
|
|
44130
|
+
//# debugId=4ef51735-a42d-5161-b990-86e4fa9e4d19
|