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/lsp.js
CHANGED
|
@@ -33092,7 +33092,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
33092
33092
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
33093
33093
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
33094
33094
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
33095
|
-
const CORE_PACKAGE_VERSION = "0.8.
|
|
33095
|
+
const CORE_PACKAGE_VERSION = "0.8.1";
|
|
33096
33096
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
33097
33097
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
33098
33098
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -33427,10 +33427,10 @@ const FALLBACK_TSCONFIG_FILENAMES = ["tsconfig.app.json", "tsconfig.build.json"]
|
|
|
33427
33427
|
const FRAMEWORK_PACKAGES = {
|
|
33428
33428
|
next: "nextjs",
|
|
33429
33429
|
"@tanstack/react-start": "tanstack-start",
|
|
33430
|
-
vite: "vite",
|
|
33431
|
-
"react-scripts": "cra",
|
|
33432
33430
|
"@remix-run/react": "remix",
|
|
33433
33431
|
gatsby: "gatsby",
|
|
33432
|
+
vite: "vite",
|
|
33433
|
+
"react-scripts": "cra",
|
|
33434
33434
|
expo: "expo",
|
|
33435
33435
|
"react-native": "react-native"
|
|
33436
33436
|
};
|
|
@@ -33454,11 +33454,17 @@ const NEXT_CONFIG_FILENAMES = [
|
|
|
33454
33454
|
];
|
|
33455
33455
|
const BABEL_CONFIG_FILENAMES = [
|
|
33456
33456
|
".babelrc",
|
|
33457
|
+
".babelrc.js",
|
|
33457
33458
|
".babelrc.json",
|
|
33459
|
+
".babelrc.cjs",
|
|
33460
|
+
".babelrc.mjs",
|
|
33461
|
+
".babelrc.cts",
|
|
33458
33462
|
"babel.config.js",
|
|
33459
33463
|
"babel.config.json",
|
|
33460
33464
|
"babel.config.cjs",
|
|
33461
|
-
"babel.config.mjs"
|
|
33465
|
+
"babel.config.mjs",
|
|
33466
|
+
"babel.config.ts",
|
|
33467
|
+
"babel.config.cts"
|
|
33462
33468
|
];
|
|
33463
33469
|
const VITE_CONFIG_FILENAMES = [
|
|
33464
33470
|
"vite.config.js",
|
|
@@ -33470,12 +33476,28 @@ const VITE_CONFIG_FILENAMES = [
|
|
|
33470
33476
|
"vitest.config.ts",
|
|
33471
33477
|
"vitest.config.js"
|
|
33472
33478
|
];
|
|
33479
|
+
const RSBUILD_CONFIG_FILENAMES = [
|
|
33480
|
+
"rsbuild.config.ts",
|
|
33481
|
+
"rsbuild.config.js",
|
|
33482
|
+
"rsbuild.config.mts",
|
|
33483
|
+
"rsbuild.config.mjs",
|
|
33484
|
+
"rsbuild.config.cts",
|
|
33485
|
+
"rsbuild.config.cjs"
|
|
33486
|
+
];
|
|
33487
|
+
const RSPACK_CONFIG_FILENAMES = [
|
|
33488
|
+
"rspack.config.ts",
|
|
33489
|
+
"rspack.config.js",
|
|
33490
|
+
"rspack.config.mts",
|
|
33491
|
+
"rspack.config.mjs",
|
|
33492
|
+
"rspack.config.cts",
|
|
33493
|
+
"rspack.config.cjs"
|
|
33494
|
+
];
|
|
33473
33495
|
const EXPO_APP_CONFIG_FILENAMES = [
|
|
33474
33496
|
"app.json",
|
|
33475
33497
|
"app.config.js",
|
|
33476
33498
|
"app.config.ts"
|
|
33477
33499
|
];
|
|
33478
|
-
const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|["']react-compiler["']/;
|
|
33500
|
+
const REACT_COMPILER_PACKAGE_REFERENCE_PATTERN = /babel-plugin-react-compiler|react-compiler-runtime|reactCompilerPreset\s*\(|["']react-compiler["']/;
|
|
33479
33501
|
const REACT_COMPILER_ENABLED_FLAG_PATTERN = /["']?reactCompiler["']?\s*:\s*(?:true\b|\{)/;
|
|
33480
33502
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
33481
33503
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
@@ -33510,6 +33532,8 @@ const detectReactCompiler = (directory, packageJson) => {
|
|
|
33510
33532
|
if (hasCompilerInConfigFiles(directory, NEXT_CONFIG_FILENAMES)) return true;
|
|
33511
33533
|
if (hasCompilerInConfigFiles(directory, BABEL_CONFIG_FILENAMES)) return true;
|
|
33512
33534
|
if (hasCompilerInConfigFiles(directory, VITE_CONFIG_FILENAMES)) return true;
|
|
33535
|
+
if (hasCompilerInConfigFiles(directory, RSBUILD_CONFIG_FILENAMES)) return true;
|
|
33536
|
+
if (hasCompilerInConfigFiles(directory, RSPACK_CONFIG_FILENAMES)) return true;
|
|
33513
33537
|
if (hasCompilerInConfigFiles(directory, EXPO_APP_CONFIG_FILENAMES)) return true;
|
|
33514
33538
|
return hasCompilerPackageInAncestors(directory, REACT_COMPILER_TRANSFORM_PACKAGES);
|
|
33515
33539
|
};
|
|
@@ -33957,19 +33981,6 @@ const getPreactVersion = (packageJson) => {
|
|
|
33957
33981
|
...packageJson.devDependencies
|
|
33958
33982
|
}.preact ?? null;
|
|
33959
33983
|
};
|
|
33960
|
-
const TANSTACK_QUERY_PACKAGES = new Set([
|
|
33961
|
-
"@tanstack/react-query",
|
|
33962
|
-
"@tanstack/query-core",
|
|
33963
|
-
"react-query"
|
|
33964
|
-
]);
|
|
33965
|
-
const hasTanStackQuery = (packageJson) => {
|
|
33966
|
-
const allDependencies = {
|
|
33967
|
-
...packageJson.peerDependencies,
|
|
33968
|
-
...packageJson.dependencies,
|
|
33969
|
-
...packageJson.devDependencies
|
|
33970
|
-
};
|
|
33971
|
-
return Object.keys(allDependencies).some((packageName) => TANSTACK_QUERY_PACKAGES.has(packageName));
|
|
33972
|
-
};
|
|
33973
33984
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33974
33985
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33975
33986
|
const catalogName = extractCatalogName(version);
|
|
@@ -34172,7 +34183,60 @@ const listWorkspacePackages = (rootDirectory) => {
|
|
|
34172
34183
|
}
|
|
34173
34184
|
return packages;
|
|
34174
34185
|
};
|
|
34186
|
+
const getPreferredDependencyVersion = ({ packageJson, packageNames }) => {
|
|
34187
|
+
const allDependencies = {
|
|
34188
|
+
...packageJson.devDependencies,
|
|
34189
|
+
...packageJson.peerDependencies,
|
|
34190
|
+
...packageJson.dependencies
|
|
34191
|
+
};
|
|
34192
|
+
for (const packageName of packageNames) {
|
|
34193
|
+
const version = allDependencies[packageName];
|
|
34194
|
+
if (version !== void 0) return version;
|
|
34195
|
+
}
|
|
34196
|
+
return null;
|
|
34197
|
+
};
|
|
34198
|
+
const TANSTACK_REACT_QUERY_PACKAGES = ["@tanstack/react-query", "react-query"];
|
|
34199
|
+
const getTanStackQueryVersion = (packageJson) => {
|
|
34200
|
+
return getPreferredDependencyVersion({
|
|
34201
|
+
packageJson,
|
|
34202
|
+
packageNames: TANSTACK_REACT_QUERY_PACKAGES
|
|
34203
|
+
});
|
|
34204
|
+
};
|
|
34205
|
+
const STYLED_COMPONENTS_PACKAGES = ["styled-components"];
|
|
34206
|
+
const getStyledComponentsVersion = (packageJson) => {
|
|
34207
|
+
return getPreferredDependencyVersion({
|
|
34208
|
+
packageJson,
|
|
34209
|
+
packageNames: STYLED_COMPONENTS_PACKAGES
|
|
34210
|
+
});
|
|
34211
|
+
};
|
|
34212
|
+
const I18N_PACKAGES = [
|
|
34213
|
+
"i18next",
|
|
34214
|
+
"react-i18next",
|
|
34215
|
+
"next-i18next",
|
|
34216
|
+
"react-intl",
|
|
34217
|
+
"next-intl",
|
|
34218
|
+
"use-intl",
|
|
34219
|
+
"@formatjs/intl",
|
|
34220
|
+
"@lingui/core",
|
|
34221
|
+
"@lingui/react",
|
|
34222
|
+
"typesafe-i18n",
|
|
34223
|
+
"@tolgee/react",
|
|
34224
|
+
"react-intl-universal"
|
|
34225
|
+
];
|
|
34226
|
+
const hasI18nDependency = (packageJson) => {
|
|
34227
|
+
const allDependencies = {
|
|
34228
|
+
...packageJson.peerDependencies,
|
|
34229
|
+
...packageJson.dependencies,
|
|
34230
|
+
...packageJson.devDependencies,
|
|
34231
|
+
...packageJson.optionalDependencies
|
|
34232
|
+
};
|
|
34233
|
+
return I18N_PACKAGES.some((packageName) => allDependencies[packageName] !== void 0);
|
|
34234
|
+
};
|
|
34175
34235
|
const REANIMATED_DEPENDENCY_NAME = "react-native-reanimated";
|
|
34236
|
+
const MOBX_REACT_PACKAGE_NAME = "mobx-react";
|
|
34237
|
+
const MOBX_REACT_LITE_PACKAGE_NAME = "mobx-react-lite";
|
|
34238
|
+
const MOBX_STATE_TREE_PACKAGE_NAME = "mobx-state-tree";
|
|
34239
|
+
const MOBX_REACT_OBSERVER_PACKAGE_NAME = "mobx-react-observer";
|
|
34176
34240
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
34177
34241
|
const resolveWorkspaceDependencyVersion = ({ concreteVersion, packageName, rootDirectory, rootPackageJson, sections, workspaceDirectory, workspacePackageJson }) => {
|
|
34178
34242
|
const dependencyDeclaration = getDependencyDeclaration({
|
|
@@ -34191,7 +34255,26 @@ const shouldReplaceReactVersion = (currentVersion, nextVersion) => {
|
|
|
34191
34255
|
if (nextMajor === null) return false;
|
|
34192
34256
|
return nextMajor < currentMajor;
|
|
34193
34257
|
};
|
|
34194
|
-
const
|
|
34258
|
+
const shouldReplaceSupportedDependencyFact = (currentFact, nextFact, latestSupportedMajor) => {
|
|
34259
|
+
if (currentFact.version === null) return true;
|
|
34260
|
+
if (nextFact.version === null) return false;
|
|
34261
|
+
const currentMajor = getLowestDependencyMajor(currentFact.version);
|
|
34262
|
+
const nextMajor = getLowestDependencyMajor(nextFact.version);
|
|
34263
|
+
if (currentMajor === null) return false;
|
|
34264
|
+
if (nextMajor === null) return true;
|
|
34265
|
+
if (currentMajor > latestSupportedMajor) return false;
|
|
34266
|
+
if (nextMajor > latestSupportedMajor) return true;
|
|
34267
|
+
return nextMajor < currentMajor;
|
|
34268
|
+
};
|
|
34269
|
+
const shouldReplaceStyledComponentsVersion = (currentVersion, nextVersion) => {
|
|
34270
|
+
if (!currentVersion) return true;
|
|
34271
|
+
const currentMajor = getLowestDependencyMajor(currentVersion);
|
|
34272
|
+
const nextMajor = getLowestDependencyMajor(nextVersion);
|
|
34273
|
+
if (currentMajor === null) return nextMajor !== null && nextMajor < 6;
|
|
34274
|
+
if (nextMajor === null) return currentMajor >= 6;
|
|
34275
|
+
return nextMajor < currentMajor;
|
|
34276
|
+
};
|
|
34277
|
+
const evaluateManifestFacts = (facts, packageJson, directory, rootDirectory, rootPackageJson) => {
|
|
34195
34278
|
if (facts.expo.version === null) {
|
|
34196
34279
|
const spec = getDependencySpec(packageJson, "expo");
|
|
34197
34280
|
if (spec !== null) facts.expo = {
|
|
@@ -34213,13 +34296,74 @@ const evaluateManifestFacts = (facts, packageJson, directory) => {
|
|
|
34213
34296
|
sourceDirectory: directory
|
|
34214
34297
|
};
|
|
34215
34298
|
}
|
|
34299
|
+
const mobxSpec = getDependencySpec(packageJson, "mobx");
|
|
34300
|
+
if (mobxSpec !== null) {
|
|
34301
|
+
const nextMobxFact = {
|
|
34302
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
34303
|
+
rootDirectory: directory,
|
|
34304
|
+
rootPackageJson: packageJson,
|
|
34305
|
+
packageName: "mobx",
|
|
34306
|
+
version: mobxSpec
|
|
34307
|
+
}),
|
|
34308
|
+
sourceDirectory: directory
|
|
34309
|
+
};
|
|
34310
|
+
if (shouldReplaceSupportedDependencyFact(facts.mobx, nextMobxFact, 6)) facts.mobx = nextMobxFact;
|
|
34311
|
+
}
|
|
34312
|
+
facts.hasMobxReact = facts.hasMobxReact || getDependencySpec(packageJson, MOBX_REACT_PACKAGE_NAME) !== null;
|
|
34313
|
+
facts.hasMobxReactLite = facts.hasMobxReactLite || getDependencySpec(packageJson, MOBX_REACT_LITE_PACKAGE_NAME) !== null;
|
|
34314
|
+
facts.hasMobxStateTree = facts.hasMobxStateTree || getDependencySpec(packageJson, MOBX_STATE_TREE_PACKAGE_NAME) !== null;
|
|
34315
|
+
facts.hasMobxReactObserver = facts.hasMobxReactObserver || getDependencySpec(packageJson, MOBX_REACT_OBSERVER_PACKAGE_NAME) !== null;
|
|
34316
|
+
const zustandSpec = getDependencySpec(packageJson, "zustand");
|
|
34317
|
+
if (zustandSpec !== null) {
|
|
34318
|
+
const nextZustandFact = {
|
|
34319
|
+
version: resolveCatalogBackedDependencyVersion({
|
|
34320
|
+
rootDirectory: directory,
|
|
34321
|
+
rootPackageJson: packageJson,
|
|
34322
|
+
packageName: "zustand",
|
|
34323
|
+
version: zustandSpec
|
|
34324
|
+
}),
|
|
34325
|
+
sourceDirectory: directory
|
|
34326
|
+
};
|
|
34327
|
+
if (shouldReplaceSupportedDependencyFact(facts.zustand, nextZustandFact, 5)) facts.zustand = nextZustandFact;
|
|
34328
|
+
}
|
|
34216
34329
|
if (facts.reanimatedVersion === null) {
|
|
34217
34330
|
const spec = getDependencySpec(packageJson, REANIMATED_DEPENDENCY_NAME);
|
|
34218
34331
|
if (spec !== null) facts.reanimatedVersion = spec;
|
|
34219
34332
|
}
|
|
34333
|
+
if (facts.valtioVersion === null) {
|
|
34334
|
+
const spec = getDependencySpec(packageJson, "valtio");
|
|
34335
|
+
if (spec !== null) facts.valtioVersion = spec;
|
|
34336
|
+
}
|
|
34337
|
+
facts.tanstackQueryVersion ??= getTanStackQueryVersion(packageJson);
|
|
34338
|
+
const styledComponentsVersion = resolveCatalogBackedDependencyVersion({
|
|
34339
|
+
rootDirectory: directory,
|
|
34340
|
+
rootPackageJson: packageJson,
|
|
34341
|
+
packageName: "styled-components",
|
|
34342
|
+
version: getStyledComponentsVersion(packageJson)
|
|
34343
|
+
});
|
|
34344
|
+
if (styledComponentsVersion && shouldReplaceStyledComponentsVersion(facts.styledComponentsVersion, styledComponentsVersion)) facts.styledComponentsVersion = styledComponentsVersion;
|
|
34345
|
+
facts.hasI18nLibrary = facts.hasI18nLibrary || hasI18nDependency(packageJson);
|
|
34220
34346
|
facts.hasReactNativeAwarePackage = facts.hasReactNativeAwarePackage || isPackageJsonReactNativeAware(packageJson);
|
|
34221
34347
|
facts.hasReanimatedAwarePackage = facts.hasReanimatedAwarePackage || isPackageJsonReanimatedAware(packageJson);
|
|
34222
34348
|
facts.hasSsrDependency = facts.hasSsrDependency || isPackageJsonSsrAware(packageJson);
|
|
34349
|
+
const remotionSpec = getDependencySpec(packageJson, "remotion");
|
|
34350
|
+
if (remotionSpec !== null) {
|
|
34351
|
+
facts.hasRemotionDependency = true;
|
|
34352
|
+
const resolvedRemotionVersion = resolveCatalogBackedDependencyVersion({
|
|
34353
|
+
rootDirectory,
|
|
34354
|
+
rootPackageJson,
|
|
34355
|
+
packageName: "remotion",
|
|
34356
|
+
version: remotionSpec
|
|
34357
|
+
});
|
|
34358
|
+
const remotionMajorVersion = resolvedRemotionVersion === null ? null : getLowestDependencyMajor(resolvedRemotionVersion);
|
|
34359
|
+
if (remotionMajorVersion === null) {
|
|
34360
|
+
facts.hasUnknownRemotionVersion = true;
|
|
34361
|
+
facts.remotionVersion = null;
|
|
34362
|
+
} else if (!facts.hasUnknownRemotionVersion) {
|
|
34363
|
+
const currentRemotionMajorVersion = facts.remotionVersion === null ? null : getLowestDependencyMajor(facts.remotionVersion);
|
|
34364
|
+
if (currentRemotionMajorVersion === null || remotionMajorVersion < currentRemotionMajorVersion) facts.remotionVersion = resolvedRemotionVersion;
|
|
34365
|
+
}
|
|
34366
|
+
}
|
|
34223
34367
|
};
|
|
34224
34368
|
const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGroup }) => {
|
|
34225
34369
|
const facts = {
|
|
@@ -34239,12 +34383,31 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34239
34383
|
version: null,
|
|
34240
34384
|
sourceDirectory: null
|
|
34241
34385
|
},
|
|
34386
|
+
valtioVersion: null,
|
|
34387
|
+
mobx: {
|
|
34388
|
+
version: null,
|
|
34389
|
+
sourceDirectory: null
|
|
34390
|
+
},
|
|
34391
|
+
hasMobxReact: false,
|
|
34392
|
+
hasMobxReactLite: false,
|
|
34393
|
+
hasMobxStateTree: false,
|
|
34394
|
+
hasMobxReactObserver: false,
|
|
34395
|
+
zustand: {
|
|
34396
|
+
version: null,
|
|
34397
|
+
sourceDirectory: null
|
|
34398
|
+
},
|
|
34399
|
+
tanstackQueryVersion: null,
|
|
34400
|
+
styledComponentsVersion: null,
|
|
34401
|
+
hasI18nLibrary: false,
|
|
34242
34402
|
hasReactNativeAwarePackage: false,
|
|
34243
34403
|
hasReanimatedAwarePackage: false,
|
|
34244
34404
|
hasSsrDependency: false,
|
|
34405
|
+
hasRemotionDependency: false,
|
|
34406
|
+
hasUnknownRemotionVersion: false,
|
|
34407
|
+
remotionVersion: null,
|
|
34245
34408
|
reanimatedVersion: null
|
|
34246
34409
|
};
|
|
34247
|
-
evaluateManifestFacts(facts, rootPackageJson, rootDirectory);
|
|
34410
|
+
evaluateManifestFacts(facts, rootPackageJson, rootDirectory, rootDirectory, rootPackageJson);
|
|
34248
34411
|
let isReactGroupSettled = !collectReactGroup;
|
|
34249
34412
|
const visitedDirectories = /* @__PURE__ */ new Set();
|
|
34250
34413
|
for (const pattern of getWorkspacePatterns(rootDirectory, rootPackageJson)) {
|
|
@@ -34253,7 +34416,7 @@ const collectWorkspaceFacts = (rootDirectory, rootPackageJson, { collectReactGro
|
|
|
34253
34416
|
if (visitedDirectories.has(workspaceDirectory)) continue;
|
|
34254
34417
|
visitedDirectories.add(workspaceDirectory);
|
|
34255
34418
|
const workspacePackageJson = readPackageJson(Path.join(workspaceDirectory, "package.json"));
|
|
34256
|
-
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory);
|
|
34419
|
+
evaluateManifestFacts(facts, workspacePackageJson, workspaceDirectory, rootDirectory, rootPackageJson);
|
|
34257
34420
|
const info = extractDependencyInfo(workspacePackageJson);
|
|
34258
34421
|
if (info.framework !== "unknown" && frameworkMergeRank(info.framework) < frameworkMergeRank(facts.framework)) facts.framework = info.framework;
|
|
34259
34422
|
if (isReactGroupSettled) continue;
|
|
@@ -34477,11 +34640,27 @@ const discoverProjectWithoutPackageJson = (directory) => {
|
|
|
34477
34640
|
tailwindVersion: null,
|
|
34478
34641
|
zodVersion: null,
|
|
34479
34642
|
zodMajorVersion: null,
|
|
34643
|
+
mobxVersion: null,
|
|
34644
|
+
mobxMajorVersion: null,
|
|
34645
|
+
hasMobxReact: false,
|
|
34646
|
+
hasMobxReactLite: false,
|
|
34647
|
+
hasMobxStateTree: false,
|
|
34648
|
+
hasMobxReactObserver: false,
|
|
34649
|
+
zustandVersion: null,
|
|
34650
|
+
zustandMajorVersion: null,
|
|
34480
34651
|
framework: "unknown",
|
|
34481
34652
|
hasTypeScript: hasOwnTsConfig,
|
|
34482
34653
|
hasReactCompiler: false,
|
|
34483
34654
|
hasReactCompilerLintPlugin: false,
|
|
34484
34655
|
hasTanStackQuery: false,
|
|
34656
|
+
valtioVersion: null,
|
|
34657
|
+
valtioMajorVersion: null,
|
|
34658
|
+
hasRemotion: false,
|
|
34659
|
+
remotionVersion: null,
|
|
34660
|
+
remotionMajorVersion: null,
|
|
34661
|
+
hasI18nLibrary: false,
|
|
34662
|
+
tanstackQueryVersion: null,
|
|
34663
|
+
styledComponentsVersion: null,
|
|
34485
34664
|
hasSsrDependency: false,
|
|
34486
34665
|
preactVersion: null,
|
|
34487
34666
|
preactMajorVersion: null,
|
|
@@ -34580,6 +34759,12 @@ const discoverProject = (directory) => {
|
|
|
34580
34759
|
packageName: SHOPIFY_FLASH_LIST_PACKAGE_NAME,
|
|
34581
34760
|
version: workspaceFacts.shopifyFlashList.version
|
|
34582
34761
|
}) : null;
|
|
34762
|
+
const zustandVersion = resolveCatalogBackedDependencyVersion({
|
|
34763
|
+
rootDirectory: directory,
|
|
34764
|
+
rootPackageJson: packageJson,
|
|
34765
|
+
packageName: "zustand",
|
|
34766
|
+
version: workspaceFacts.zustand.version
|
|
34767
|
+
});
|
|
34583
34768
|
const hasReanimated = hasReactNativeWorkspace && workspaceFacts.hasReanimatedAwarePackage;
|
|
34584
34769
|
const reanimatedVersion = hasReanimated ? workspaceFacts.reanimatedVersion : null;
|
|
34585
34770
|
const nextjsVersion = framework === "nextjs" ? resolveCatalogBackedDependencyVersion({
|
|
@@ -34588,7 +34773,21 @@ const discoverProject = (directory) => {
|
|
|
34588
34773
|
packageName: "next",
|
|
34589
34774
|
version: workspaceFacts.next.version
|
|
34590
34775
|
}) : null;
|
|
34776
|
+
const valtioVersion = resolveCatalogBackedDependencyVersion({
|
|
34777
|
+
rootDirectory: directory,
|
|
34778
|
+
rootPackageJson: packageJson,
|
|
34779
|
+
packageName: "valtio",
|
|
34780
|
+
version: workspaceFacts.valtioVersion
|
|
34781
|
+
});
|
|
34782
|
+
const mobxVersion = resolveCatalogBackedDependencyVersion({
|
|
34783
|
+
rootDirectory: directory,
|
|
34784
|
+
rootPackageJson: packageJson,
|
|
34785
|
+
packageName: "mobx",
|
|
34786
|
+
version: workspaceFacts.mobx.version
|
|
34787
|
+
});
|
|
34591
34788
|
const preactVersion = getPreactVersion(packageJson);
|
|
34789
|
+
const remotionVersion = workspaceFacts.remotionVersion;
|
|
34790
|
+
const tanstackQueryVersion = getTanStackQueryVersion(packageJson) ?? workspaceFacts.tanstackQueryVersion;
|
|
34592
34791
|
const isPreES2023Target = hasTypeScript && detectPreES2023Target(directory);
|
|
34593
34792
|
const projectInfo = {
|
|
34594
34793
|
rootDirectory: directory,
|
|
@@ -34598,11 +34797,27 @@ const discoverProject = (directory) => {
|
|
|
34598
34797
|
tailwindVersion,
|
|
34599
34798
|
zodVersion,
|
|
34600
34799
|
zodMajorVersion: zodVersion === null ? null : getLowestDependencyMajor(zodVersion),
|
|
34800
|
+
mobxVersion,
|
|
34801
|
+
mobxMajorVersion: mobxVersion === null ? null : getLowestDependencyMajor(mobxVersion),
|
|
34802
|
+
hasMobxReact: workspaceFacts.hasMobxReact,
|
|
34803
|
+
hasMobxReactLite: workspaceFacts.hasMobxReactLite,
|
|
34804
|
+
hasMobxStateTree: workspaceFacts.hasMobxStateTree,
|
|
34805
|
+
hasMobxReactObserver: workspaceFacts.hasMobxReactObserver,
|
|
34806
|
+
zustandVersion,
|
|
34807
|
+
zustandMajorVersion: zustandVersion === null ? null : getLowestDependencyMajor(zustandVersion),
|
|
34601
34808
|
framework,
|
|
34602
34809
|
hasTypeScript,
|
|
34603
34810
|
hasReactCompiler: detectReactCompiler(directory, packageJson),
|
|
34604
34811
|
hasReactCompilerLintPlugin: detectReactCompilerLintPlugin(directory, packageJson),
|
|
34605
|
-
hasTanStackQuery:
|
|
34812
|
+
hasTanStackQuery: tanstackQueryVersion !== null,
|
|
34813
|
+
hasI18nLibrary: workspaceFacts.hasI18nLibrary,
|
|
34814
|
+
tanstackQueryVersion,
|
|
34815
|
+
styledComponentsVersion: workspaceFacts.styledComponentsVersion,
|
|
34816
|
+
valtioVersion,
|
|
34817
|
+
valtioMajorVersion: valtioVersion === null ? null : getLowestDependencyMajor(valtioVersion),
|
|
34818
|
+
hasRemotion: workspaceFacts.hasRemotionDependency,
|
|
34819
|
+
remotionVersion,
|
|
34820
|
+
remotionMajorVersion: remotionVersion === null ? null : getLowestDependencyMajor(remotionVersion),
|
|
34606
34821
|
hasSsrDependency: workspaceFacts.hasSsrDependency,
|
|
34607
34822
|
preactVersion,
|
|
34608
34823
|
preactMajorVersion: parseReactMajor(preactVersion),
|
|
@@ -34836,7 +35051,6 @@ const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
|
|
|
34836
35051
|
"react/jsx-no-new-function-as-prop": "react-doctor/jsx-no-new-function-as-prop",
|
|
34837
35052
|
"react/jsx-no-new-object-as-prop": "react-doctor/jsx-no-new-object-as-prop",
|
|
34838
35053
|
"react/jsx-no-script-url": "react-doctor/jsx-no-script-url",
|
|
34839
|
-
"react/jsx-no-target-blank": "react-doctor/jsx-no-target-blank",
|
|
34840
35054
|
"react/jsx-no-undef": "react-doctor/jsx-no-undef",
|
|
34841
35055
|
"react/jsx-no-useless-fragment": "react-doctor/jsx-no-useless-fragment",
|
|
34842
35056
|
"react/jsx-pascal-case": "react-doctor/jsx-pascal-case",
|
|
@@ -35207,6 +35421,9 @@ const SCRIPT_EXTENSION_FRAGMENT = "[cm]?[jt]sx?";
|
|
|
35207
35421
|
const STORY_FILE_SUFFIX_PATTERN = new RegExp(`\\.(?:stories|story)\\.(?:${SCRIPT_EXTENSION_FRAGMENT})$`);
|
|
35208
35422
|
const TEST_FILE_SUFFIX_PATTERN = new RegExp(`\\.(?:test|spec|fixture|fixtures)\\.(?:${SCRIPT_EXTENSION_FRAGMENT})$`);
|
|
35209
35423
|
const TEST_FILE_DIRECTORY_PATTERN = /(?:^|\/)(?:__tests__|__test__|tests|test|__mocks__|cypress|e2e|playwright)\//;
|
|
35424
|
+
const AMBIGUOUS_TEST_ROUTE_DIRECTORY_PATTERN = /(?:^|\/)(?:tests|test)\//;
|
|
35425
|
+
const NEXT_APP_ROUTE_FILE_SUFFIX_PATTERN = /\/(?:default|error|forbidden|global-error|layout|loading|not-found|page|route|template|unauthorized)\.[cm]?[jt]sx?$/;
|
|
35426
|
+
const SCRIPT_FILE_SUFFIX_PATTERN = /\.[cm]?[jt]sx?$/;
|
|
35210
35427
|
const FIXTURE_PROJECT_PATTERN = /\/(?:fixtures|__fixtures__)\//;
|
|
35211
35428
|
const SOURCE_ROOT_PATTERN = /\/(?:src|app|lib|components|pages|features|modules|packages|apps|frontend|client)\//g;
|
|
35212
35429
|
const stripAboveSourceRoot = (relativePath) => {
|
|
@@ -35217,6 +35434,14 @@ const stripAboveSourceRoot = (relativePath) => {
|
|
|
35217
35434
|
if (lastIdx >= 0) return relativePath.slice(lastIdx);
|
|
35218
35435
|
return relativePath.slice(fixtureMatch.index + fixtureMatch[0].length - 1);
|
|
35219
35436
|
};
|
|
35437
|
+
const isFrameworkRouteBeforeAmbiguousTestDirectory = (relativePath) => {
|
|
35438
|
+
const testDirectoryMatch = AMBIGUOUS_TEST_ROUTE_DIRECTORY_PATTERN.exec(relativePath);
|
|
35439
|
+
if (testDirectoryMatch === null) return false;
|
|
35440
|
+
let nearestRouteRoot;
|
|
35441
|
+
for (const pathSegment of relativePath.slice(0, testDirectoryMatch.index).split("/")) if (pathSegment === "app" || pathSegment === "pages") nearestRouteRoot = pathSegment;
|
|
35442
|
+
if (nearestRouteRoot === void 0) return false;
|
|
35443
|
+
return nearestRouteRoot === "pages" ? SCRIPT_FILE_SUFFIX_PATTERN.test(relativePath) : NEXT_APP_ROUTE_FILE_SUFFIX_PATTERN.test(relativePath);
|
|
35444
|
+
};
|
|
35220
35445
|
/**
|
|
35221
35446
|
* Classifies where a file sits relative to shipped code. A finding in a
|
|
35222
35447
|
* `.stories.tsx` or `.spec.ts` file never runs in front of users, so
|
|
@@ -35233,6 +35458,7 @@ const classifyFileContext = (relativePath) => {
|
|
|
35233
35458
|
if (STORY_FILE_SUFFIX_PATTERN.test(forwardSlashed)) return "story";
|
|
35234
35459
|
if (TEST_FILE_SUFFIX_PATTERN.test(forwardSlashed)) return "test";
|
|
35235
35460
|
const scoped = stripAboveSourceRoot(forwardSlashed);
|
|
35461
|
+
if (isFrameworkRouteBeforeAmbiguousTestDirectory(scoped)) return "production";
|
|
35236
35462
|
return TEST_FILE_DIRECTORY_PATTERN.test(scoped) ? "test" : "production";
|
|
35237
35463
|
};
|
|
35238
35464
|
/**
|
|
@@ -36070,6 +36296,7 @@ const VALID_RULE_SEVERITIES = [
|
|
|
36070
36296
|
"warn",
|
|
36071
36297
|
"off"
|
|
36072
36298
|
];
|
|
36299
|
+
const VALID_INCLUDED_FILE_CONTEXTS = ["test", "story"];
|
|
36073
36300
|
const KNOWN_CATEGORY_LABEL = DIAGNOSTIC_CATEGORY_BUCKETS.join(", ");
|
|
36074
36301
|
const isDiagnosticCategoryBucket = (value) => DIAGNOSTIC_CATEGORY_BUCKETS.includes(value);
|
|
36075
36302
|
const filterKnownCategories = (fieldName, categories) => categories.filter((category) => {
|
|
@@ -36104,6 +36331,7 @@ const SURFACE_CONTROL_FIELD_NAMES = [
|
|
|
36104
36331
|
"includeRules",
|
|
36105
36332
|
"excludeRules"
|
|
36106
36333
|
];
|
|
36334
|
+
const isIncludedFileContext = (value) => VALID_INCLUDED_FILE_CONTEXTS.some((fileContext) => fileContext === value);
|
|
36107
36335
|
const SEVERITY_FIELD_NAMES = ["rules", "categories"];
|
|
36108
36336
|
const isPlainObject$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36109
36337
|
const formatType = (value) => typeof value === "string" ? `"${value}"` : typeof value;
|
|
@@ -36138,6 +36366,15 @@ const validateSurfaceControls = (surface, rawControls) => {
|
|
|
36138
36366
|
return;
|
|
36139
36367
|
}
|
|
36140
36368
|
const validatedSurfaceControls = {};
|
|
36369
|
+
if (rawControls.includeFileContexts !== void 0) {
|
|
36370
|
+
const qualifiedName = `surfaces.${surface}.includeFileContexts`;
|
|
36371
|
+
const result = validateStringArrayField(qualifiedName, rawControls.includeFileContexts);
|
|
36372
|
+
if (result !== void 0) validatedSurfaceControls.includeFileContexts = result.filter((fileContext) => {
|
|
36373
|
+
if (isIncludedFileContext(fileContext)) return true;
|
|
36374
|
+
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.`);
|
|
36375
|
+
return false;
|
|
36376
|
+
});
|
|
36377
|
+
}
|
|
36141
36378
|
for (const fieldName of SURFACE_CONTROL_FIELD_NAMES) {
|
|
36142
36379
|
if (rawControls[fieldName] === void 0) continue;
|
|
36143
36380
|
const qualifiedName = `surfaces.${surface}.${fieldName}`;
|
|
@@ -37026,9 +37263,25 @@ const BABEL_CONFIG_FILE_NAMES = [
|
|
|
37026
37263
|
".babelrc.json"
|
|
37027
37264
|
];
|
|
37028
37265
|
const LEGACY_PRESET_SPEC = "module:metro-react-native-babel-preset";
|
|
37266
|
+
const LEGACY_PRESET_PACKAGE = "metro-react-native-babel-preset";
|
|
37267
|
+
const REACT_NATIVE_PACKAGE = "react-native";
|
|
37268
|
+
const PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION = "0.73.0";
|
|
37269
|
+
const LEGACY_PRESET_REFERENCE = new RegExp(`['"]${LEGACY_PRESET_SPEC}['"]`);
|
|
37029
37270
|
const MODERN_PRESET_REFERENCE = new RegExp(`['"]module:@react-native/babel-preset['"]`);
|
|
37030
37271
|
const ENABLE_BABEL_RUNTIME_VERSION = /enableBabelRuntime["']?\s*:\s*['"]/;
|
|
37272
|
+
const isReactNativeVersionAtLeastPresetRename = (rootDirectory, packageJson) => {
|
|
37273
|
+
const installedReactNativeManifestPath = Path.join(rootDirectory, "node_modules", REACT_NATIVE_PACKAGE, "package.json");
|
|
37274
|
+
const reactNativeVersionSpec = (isFile(installedReactNativeManifestPath) ? readPackageJson(installedReactNativeManifestPath).version : void 0) ?? getDependencySpec(packageJson, REACT_NATIVE_PACKAGE);
|
|
37275
|
+
if (reactNativeVersionSpec === null || reactNativeVersionSpec === void 0) return false;
|
|
37276
|
+
const normalizedVersionRange = import_semver.validRange(reactNativeVersionSpec);
|
|
37277
|
+
if (normalizedVersionRange === null) return false;
|
|
37278
|
+
const minimumVersion = import_semver.minVersion(normalizedVersionRange);
|
|
37279
|
+
return minimumVersion !== null && import_semver.gte(minimumVersion, PRESET_RENAME_MINIMUM_REACT_NATIVE_VERSION);
|
|
37280
|
+
};
|
|
37281
|
+
const canResolveLegacyPreset = (rootDirectory, packageJson) => getDependencySpec(packageJson, LEGACY_PRESET_PACKAGE) !== null || isFile(Path.join(rootDirectory, "node_modules", LEGACY_PRESET_PACKAGE, "package.json"));
|
|
37031
37282
|
const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
37283
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
37284
|
+
const shouldReportLegacyPreset = isReactNativeVersionAtLeastPresetRename(rootDirectory, packageJson) && !canResolveLegacyPreset(rootDirectory, packageJson);
|
|
37032
37285
|
for (const fileName of BABEL_CONFIG_FILE_NAMES) {
|
|
37033
37286
|
const filePath = Path.join(rootDirectory, fileName);
|
|
37034
37287
|
if (!isFile(filePath)) continue;
|
|
@@ -37038,7 +37291,7 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
37038
37291
|
} catch {
|
|
37039
37292
|
continue;
|
|
37040
37293
|
}
|
|
37041
|
-
if (
|
|
37294
|
+
if (shouldReportLegacyPreset && LEGACY_PRESET_REFERENCE.test(contents)) return [buildReactNativeDiagnostic({
|
|
37042
37295
|
filePath: fileName,
|
|
37043
37296
|
rule: "rn-no-metro-babel-preset",
|
|
37044
37297
|
severity: "error",
|
|
@@ -37061,12 +37314,6 @@ const checkReactNativeProject = (rootDirectory, project) => {
|
|
|
37061
37314
|
return [...checkReactNativeMetroBabelPreset(rootDirectory), ...checkReactNativeLibraryDependencies(rootDirectory)];
|
|
37062
37315
|
};
|
|
37063
37316
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
37064
|
-
const DEPENDENCY_SECTIONS = [
|
|
37065
|
-
"dependencies",
|
|
37066
|
-
"devDependencies",
|
|
37067
|
-
"peerDependencies",
|
|
37068
|
-
"optionalDependencies"
|
|
37069
|
-
];
|
|
37070
37317
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
37071
37318
|
"19.0": {
|
|
37072
37319
|
rceFixedVersion: "19.0.1",
|
|
@@ -37113,20 +37360,13 @@ const enumerateWorkspaceDirectories = (workspaceRoot) => {
|
|
|
37113
37360
|
for (const pattern of patterns) for (const directory of resolveWorkspaceDirectories(workspaceRoot, pattern)) directories.add(directory);
|
|
37114
37361
|
return [...directories];
|
|
37115
37362
|
};
|
|
37116
|
-
const readDeclaredSpec = (packageJson, packageName) => {
|
|
37117
|
-
for (const section of DEPENDENCY_SECTIONS) {
|
|
37118
|
-
const spec = packageJson[section]?.[packageName];
|
|
37119
|
-
if (typeof spec === "string") return spec;
|
|
37120
|
-
}
|
|
37121
|
-
return null;
|
|
37122
|
-
};
|
|
37123
37363
|
const resolveVersionInDirectory = (directory, packageName, declaredSpecOverride) => {
|
|
37124
37364
|
const manifestPath = Path.join(directory, "node_modules", packageName, "package.json");
|
|
37125
37365
|
if (isFile(manifestPath)) {
|
|
37126
37366
|
const installedVersion = import_semver.valid(readPackageJson(manifestPath).version ?? null);
|
|
37127
37367
|
if (installedVersion !== null) return installedVersion;
|
|
37128
37368
|
}
|
|
37129
|
-
const candidateSpecs = [
|
|
37369
|
+
const candidateSpecs = [getDependencySpec(readPackageJson(Path.join(directory, "package.json")), packageName), declaredSpecOverride];
|
|
37130
37370
|
for (const spec of candidateSpecs) {
|
|
37131
37371
|
const pinnedVersion = spec === null ? null : import_semver.valid(spec);
|
|
37132
37372
|
if (pinnedVersion !== null) return pinnedVersion;
|
|
@@ -37794,21 +38034,50 @@ const buildCapabilities = (project) => {
|
|
|
37794
38034
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
37795
38035
|
if (project.isStaticExport) capabilities.add("nextjs:static-export");
|
|
37796
38036
|
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 15) capabilities.add("nextjs:15");
|
|
38037
|
+
if (project.nextjsMajorVersion !== null && project.nextjsMajorVersion >= 16) capabilities.add("nextjs:16");
|
|
37797
38038
|
addMajorLadder(capabilities, "react", project.reactMajorVersion, 17, 30);
|
|
37798
38039
|
if (project.reactMajorVersion !== null && project.reactMajorVersion >= 19 && isMajorMinorAtLeast(parseReactMajorMinor(project.reactVersion), {
|
|
37799
38040
|
major: 19,
|
|
37800
38041
|
minor: 2
|
|
37801
38042
|
})) capabilities.add("react:19.2");
|
|
37802
|
-
if (project.tailwindVersion !== null)
|
|
37803
|
-
|
|
37804
|
-
|
|
37805
|
-
|
|
37806
|
-
|
|
38043
|
+
if (project.tailwindVersion !== null) {
|
|
38044
|
+
capabilities.add("tailwind");
|
|
38045
|
+
const tailwindVersion = parseTailwindMajorMinor(project.tailwindVersion);
|
|
38046
|
+
if (isMajorMinorAtLeast(tailwindVersion, {
|
|
38047
|
+
major: 3,
|
|
38048
|
+
minor: 4
|
|
38049
|
+
})) capabilities.add("tailwind:3.4");
|
|
38050
|
+
if (tailwindVersion !== null && isMajorMinorAtLeast(tailwindVersion, {
|
|
38051
|
+
major: 4,
|
|
38052
|
+
minor: 0
|
|
38053
|
+
})) capabilities.add("tailwind:4");
|
|
38054
|
+
}
|
|
37807
38055
|
if (project.zodVersion !== null) capabilities.add("zod");
|
|
37808
38056
|
if (project.zodMajorVersion !== null && project.zodMajorVersion >= 4) capabilities.add("zod:4");
|
|
38057
|
+
if (project.mobxVersion !== void 0 && project.mobxVersion !== null || project.hasMobxReact === true || project.hasMobxReactLite === true || project.hasMobxStateTree === true || project.hasMobxReactObserver === true) capabilities.add("mobx");
|
|
38058
|
+
if (project.hasMobxReact === true) capabilities.add("mobx-react");
|
|
38059
|
+
if (project.hasMobxReactLite === true) capabilities.add("mobx-react-lite");
|
|
38060
|
+
if (project.hasMobxReact === true || project.hasMobxReactLite === true) capabilities.add("mobx-react-binding");
|
|
38061
|
+
if (project.hasMobxStateTree === true) capabilities.add("mobx-state-tree");
|
|
38062
|
+
if (project.hasMobxReactObserver === true) capabilities.add("mobx-react-observer");
|
|
38063
|
+
if (project.mobxMajorVersion !== void 0 && project.mobxMajorVersion !== null && project.mobxMajorVersion >= 4 && project.mobxMajorVersion <= 6) addMajorLadder(capabilities, "mobx", project.mobxMajorVersion, 4, 6);
|
|
38064
|
+
if (project.zustandVersion !== void 0 && project.zustandVersion !== null) capabilities.add("zustand");
|
|
38065
|
+
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addMajorLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
37809
38066
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
37810
38067
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
37811
|
-
if (project.hasTanStackQuery) capabilities.add("tanstack-query");
|
|
38068
|
+
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
38069
|
+
if (project.styledComponentsVersion) {
|
|
38070
|
+
capabilities.add("styled-components");
|
|
38071
|
+
const styledComponentsMajor = getLowestDependencyMajor(project.styledComponentsVersion);
|
|
38072
|
+
if (styledComponentsMajor !== null && styledComponentsMajor >= 6) capabilities.add("styled-components:6");
|
|
38073
|
+
}
|
|
38074
|
+
if (project.hasI18nLibrary) capabilities.add("i18n");
|
|
38075
|
+
if (project.valtioVersion !== null) capabilities.add("valtio");
|
|
38076
|
+
addMajorLadder(capabilities, "valtio", project.valtioMajorVersion, 1, 10);
|
|
38077
|
+
if (project.hasRemotion) {
|
|
38078
|
+
capabilities.add("remotion");
|
|
38079
|
+
addMajorLadder(capabilities, "remotion", project.remotionMajorVersion ?? null, 4, 30);
|
|
38080
|
+
}
|
|
37812
38081
|
if (project.hasTypeScript) capabilities.add("typescript");
|
|
37813
38082
|
if (project.preactVersion !== null) capabilities.add("preact");
|
|
37814
38083
|
addMajorLadder(capabilities, "preact", project.preactMajorVersion, 10, 20);
|
|
@@ -37823,7 +38092,7 @@ const getCapabilities = (project) => {
|
|
|
37823
38092
|
capabilitiesByProject.set(project, capabilities);
|
|
37824
38093
|
return capabilities;
|
|
37825
38094
|
};
|
|
37826
|
-
const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen) => {
|
|
38095
|
+
const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhen, includedTags) => {
|
|
37827
38096
|
if (requires) {
|
|
37828
38097
|
for (const capability of requires) if (!capabilities.has(capability)) return false;
|
|
37829
38098
|
}
|
|
@@ -37834,20 +38103,29 @@ const shouldEnableRule = (requires, tags, capabilities, ignoredTags, disabledWhe
|
|
|
37834
38103
|
if (tags) {
|
|
37835
38104
|
for (const tag of tags) if (ignoredTags.has(tag)) return false;
|
|
37836
38105
|
}
|
|
38106
|
+
if (includedTags && includedTags.size > 0) {
|
|
38107
|
+
if (!tags?.some((tag) => includedTags.has(tag))) return false;
|
|
38108
|
+
}
|
|
37837
38109
|
return true;
|
|
37838
38110
|
};
|
|
38111
|
+
const shouldEnableRuleByDefaultStatus = (options) => options.defaultEnabled !== false || options.hasExplicitOverride === true || options.includeTagDefaults && options.hasIncludedTags;
|
|
37839
38112
|
const yieldToEventLoop = () => new Promise((resolve) => {
|
|
37840
38113
|
setImmediate(resolve);
|
|
37841
38114
|
});
|
|
37842
38115
|
const createSecurityScanSession = (rootDirectory, options) => {
|
|
37843
38116
|
const capabilities = options.project ? getCapabilities(options.project) : /* @__PURE__ */ new Set();
|
|
37844
38117
|
const ignoredTags = options.ignoredTags ?? /* @__PURE__ */ new Set();
|
|
38118
|
+
const includedTags = options.includedTags ?? /* @__PURE__ */ new Set();
|
|
37845
38119
|
const enabledScanRules = REACT_DOCTOR_RULES.flatMap((entry) => {
|
|
37846
38120
|
const rule = entry.rule;
|
|
37847
38121
|
const scan = rule.scan;
|
|
37848
38122
|
if (typeof scan !== "function") return [];
|
|
37849
|
-
if (
|
|
37850
|
-
|
|
38123
|
+
if (!shouldEnableRuleByDefaultStatus({
|
|
38124
|
+
defaultEnabled: rule.defaultEnabled,
|
|
38125
|
+
includeTagDefaults: options.includeTagDefaults === true,
|
|
38126
|
+
hasIncludedTags: includedTags.size > 0
|
|
38127
|
+
})) return [];
|
|
38128
|
+
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) return [];
|
|
37851
38129
|
return [{
|
|
37852
38130
|
entry,
|
|
37853
38131
|
scan,
|
|
@@ -38781,6 +39059,7 @@ const buildResolvedControls = (surface, userControls) => {
|
|
|
38781
39059
|
for (const tag of includeTags) excludeTags.delete(tag);
|
|
38782
39060
|
for (const tag of toStringSet(userControls?.excludeTags)) excludeTags.add(tag);
|
|
38783
39061
|
return {
|
|
39062
|
+
includeFileContexts: toStringSet(userControls?.includeFileContexts),
|
|
38784
39063
|
includeTags,
|
|
38785
39064
|
excludeTags,
|
|
38786
39065
|
includeCategories: toStringSet(userControls?.includeCategories),
|
|
@@ -38796,7 +39075,7 @@ const isDiagnosticOnSurface = (diagnostic, surface, config) => {
|
|
|
38796
39075
|
if (resolved.includeRuleKeys.has(ruleKey)) return true;
|
|
38797
39076
|
if (resolved.includeCategories.has(category)) return true;
|
|
38798
39077
|
if (intersects(tags, resolved.includeTags)) return true;
|
|
38799
|
-
if (diagnostic.fileContext !== void 0 && (surface === "score" || surface === "ciFailure")) return false;
|
|
39078
|
+
if (diagnostic.fileContext !== void 0 && (surface === "score" || surface === "ciFailure") && !resolved.includeFileContexts.has(diagnostic.fileContext)) return false;
|
|
38800
39079
|
if (resolved.excludeRuleKeys.has(ruleKey)) return false;
|
|
38801
39080
|
if (resolved.excludeCategories.has(category)) return false;
|
|
38802
39081
|
if (intersects(tags, resolved.excludeTags)) return false;
|
|
@@ -39044,6 +39323,35 @@ const parseGithubViewerPermission = (stdout) => {
|
|
|
39044
39323
|
return /^[A-Z_]+$/.test(value) ? value.toLowerCase() : null;
|
|
39045
39324
|
};
|
|
39046
39325
|
const splitNullSeparated = (value) => value.split("\0").filter((entry) => entry.length > 0);
|
|
39326
|
+
const parseBaselineDiffPlan = (value) => {
|
|
39327
|
+
const entries = splitNullSeparated(value);
|
|
39328
|
+
const baseFiles = /* @__PURE__ */ new Set();
|
|
39329
|
+
const headFiles = /* @__PURE__ */ new Set();
|
|
39330
|
+
for (let entryIndex = 0; entryIndex < entries.length; entryIndex += 2) {
|
|
39331
|
+
const status = entries[entryIndex];
|
|
39332
|
+
const filePath = entries[entryIndex + 1];
|
|
39333
|
+
if (status === void 0 || filePath === void 0 || status.length !== 1) return null;
|
|
39334
|
+
if (status === "A") {
|
|
39335
|
+
headFiles.add(filePath);
|
|
39336
|
+
continue;
|
|
39337
|
+
}
|
|
39338
|
+
if (status === "D") {
|
|
39339
|
+
baseFiles.add(filePath);
|
|
39340
|
+
continue;
|
|
39341
|
+
}
|
|
39342
|
+
if (status === "M" || status === "T") {
|
|
39343
|
+
baseFiles.add(filePath);
|
|
39344
|
+
headFiles.add(filePath);
|
|
39345
|
+
continue;
|
|
39346
|
+
}
|
|
39347
|
+
return null;
|
|
39348
|
+
}
|
|
39349
|
+
return {
|
|
39350
|
+
baseFiles: [...baseFiles],
|
|
39351
|
+
headFiles: [...headFiles],
|
|
39352
|
+
untrackedFiles: []
|
|
39353
|
+
};
|
|
39354
|
+
};
|
|
39047
39355
|
const UNTRACKED_FILE_LAST_LINE = Number.MAX_SAFE_INTEGER;
|
|
39048
39356
|
/**
|
|
39049
39357
|
* `Git` wraps every `git`-via-subprocess call react-doctor makes
|
|
@@ -39246,6 +39554,45 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
39246
39554
|
githubViewerPermission,
|
|
39247
39555
|
branchExists,
|
|
39248
39556
|
mergeBase,
|
|
39557
|
+
baselineDiffPlan: (input) => {
|
|
39558
|
+
if (!isSafeGitRevision(input.ref)) return succeed$2(null);
|
|
39559
|
+
return gen(function* () {
|
|
39560
|
+
const unmerged = yield* runGit(input.directory, [
|
|
39561
|
+
"diff",
|
|
39562
|
+
"--no-ext-diff",
|
|
39563
|
+
"-z",
|
|
39564
|
+
"--name-only",
|
|
39565
|
+
"--diff-filter=U",
|
|
39566
|
+
"--relative"
|
|
39567
|
+
]);
|
|
39568
|
+
if (unmerged.status !== 0 || unmerged.stdout.length > 0) return null;
|
|
39569
|
+
const result = yield* runGit(input.directory, [
|
|
39570
|
+
"diff",
|
|
39571
|
+
"--no-ext-diff",
|
|
39572
|
+
"--no-textconv",
|
|
39573
|
+
"--no-renames",
|
|
39574
|
+
"-z",
|
|
39575
|
+
"--name-status",
|
|
39576
|
+
"--relative",
|
|
39577
|
+
input.ref
|
|
39578
|
+
]);
|
|
39579
|
+
if (result.status !== 0) return null;
|
|
39580
|
+
const plan = parseBaselineDiffPlan(result.stdout);
|
|
39581
|
+
if (plan === null) return null;
|
|
39582
|
+
const untracked = yield* runGit(input.directory, [
|
|
39583
|
+
"ls-files",
|
|
39584
|
+
"--others",
|
|
39585
|
+
"--exclude-standard",
|
|
39586
|
+
"-z"
|
|
39587
|
+
]);
|
|
39588
|
+
if (untracked.status !== 0) return null;
|
|
39589
|
+
return {
|
|
39590
|
+
baseFiles: plan.baseFiles,
|
|
39591
|
+
headFiles: plan.headFiles,
|
|
39592
|
+
untrackedFiles: splitNullSeparated(untracked.stdout)
|
|
39593
|
+
};
|
|
39594
|
+
}).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.baselineDiffPlan"));
|
|
39595
|
+
},
|
|
39249
39596
|
diffSelection: ({ directory, explicitBaseBranch, includeUntracked = false }) => gen(function* () {
|
|
39250
39597
|
if (explicitBaseBranch !== void 0 && explicitBaseBranch.trim().length === 0) return yield* fail$4(new ReactDoctorError({ reason: new GitBaseBranchInvalid({ detail: "Diff base branch cannot be empty." }) }));
|
|
39251
39598
|
if (explicitBaseBranch !== void 0) {
|
|
@@ -39395,6 +39742,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
39395
39742
|
githubViewerPermission: () => succeed$2(snapshot.githubViewerPermission ?? null),
|
|
39396
39743
|
branchExists: (_directory, branch) => succeed$2(snapshot.branchExists?.get(branch) ?? false),
|
|
39397
39744
|
mergeBase: ({ ref }) => succeed$2(snapshot.mergeBase?.get(ref) ?? null),
|
|
39745
|
+
baselineDiffPlan: () => succeed$2(snapshot.baselineDiffPlan ?? null),
|
|
39398
39746
|
diffSelection: () => succeed$2(snapshot.diffSelection ?? null),
|
|
39399
39747
|
stagedFilePaths: () => succeed$2(snapshot.stagedFiles ?? []),
|
|
39400
39748
|
showStagedContent: (_directory, relativePath) => succeed$2(snapshot.stagedContent?.get(relativePath) ?? null),
|
|
@@ -39763,8 +40111,9 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
39763
40111
|
}
|
|
39764
40112
|
return enabled;
|
|
39765
40113
|
};
|
|
39766
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
39767
|
-
const
|
|
40114
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
40115
|
+
const hasIncludedTags = includedTags.size > 0;
|
|
40116
|
+
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
39768
40117
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
39769
40118
|
const jsPlugins = [];
|
|
39770
40119
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
@@ -39779,9 +40128,14 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
39779
40128
|
if (rule.scan !== void 0) continue;
|
|
39780
40129
|
if (customRulesOnly && registryEntry.originallyExternal) continue;
|
|
39781
40130
|
if (rule.framework !== "global" && !rule.requires) continue;
|
|
39782
|
-
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen)) continue;
|
|
40131
|
+
if (!shouldEnableRule(rule.requires, rule.tags, capabilities, ignoredTags, rule.disabledWhen, includedTags)) continue;
|
|
39783
40132
|
const explicitRuleOverride = resolveRuleSeverityOverride({ ruleKey: registryEntry.key }, severityControls);
|
|
39784
|
-
if (
|
|
40133
|
+
if (!shouldEnableRuleByDefaultStatus({
|
|
40134
|
+
defaultEnabled: rule.defaultEnabled,
|
|
40135
|
+
includeTagDefaults,
|
|
40136
|
+
hasIncludedTags,
|
|
40137
|
+
hasExplicitOverride: explicitRuleOverride !== void 0
|
|
40138
|
+
})) continue;
|
|
39785
40139
|
const severity = resolveRuleSeverityOverride({
|
|
39786
40140
|
ruleKey: registryEntry.key,
|
|
39787
40141
|
category: rule.category
|
|
@@ -39790,7 +40144,7 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
39790
40144
|
enabledReactDoctorRules[registryEntry.key] = severity;
|
|
39791
40145
|
}
|
|
39792
40146
|
const userPluginRules = {};
|
|
39793
|
-
if (ruleSelection !== "sidecar") for (const userPlugin of userPlugins) {
|
|
40147
|
+
if (ruleSelection !== "sidecar" && !hasIncludedTags) for (const userPlugin of userPlugins) {
|
|
39794
40148
|
Object.assign(userPluginRules, buildUserPluginRules(userPlugin, severityControls));
|
|
39795
40149
|
jsPlugins.push(userPlugin.entry);
|
|
39796
40150
|
}
|
|
@@ -40007,6 +40361,19 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
40007
40361
|
}
|
|
40008
40362
|
};
|
|
40009
40363
|
};
|
|
40364
|
+
const fingerprintCacheByFilePath = /* @__PURE__ */ new Map();
|
|
40365
|
+
const fingerprintFileContents = (filePath, fingerprintLength) => {
|
|
40366
|
+
const fileStats = NFS.statSync(filePath, { bigint: true });
|
|
40367
|
+
const cachedFingerprint = fingerprintCacheByFilePath.get(filePath);
|
|
40368
|
+
if (cachedFingerprint?.modifiedTimeNanoseconds === fileStats.mtimeNs && cachedFingerprint.sizeBytes === fileStats.size) return cachedFingerprint.fingerprint;
|
|
40369
|
+
const fingerprint = crypto.createHash("sha256").update(NFS.readFileSync(filePath)).digest("hex").slice(0, fingerprintLength);
|
|
40370
|
+
fingerprintCacheByFilePath.set(filePath, {
|
|
40371
|
+
fingerprint,
|
|
40372
|
+
modifiedTimeNanoseconds: fileStats.mtimeNs,
|
|
40373
|
+
sizeBytes: fileStats.size
|
|
40374
|
+
});
|
|
40375
|
+
return fingerprint;
|
|
40376
|
+
};
|
|
40010
40377
|
const bundledRequire = createRequire(import.meta.url);
|
|
40011
40378
|
const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
|
|
40012
40379
|
const resolveChildNodeVersion = (nodeBinaryPath) => {
|
|
@@ -40030,6 +40397,13 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS = [
|
|
|
40030
40397
|
"oxlint-plugin-react-doctor/package.json",
|
|
40031
40398
|
"eslint-plugin-react-hooks/package.json"
|
|
40032
40399
|
];
|
|
40400
|
+
const resolvePluginFingerprint = () => {
|
|
40401
|
+
try {
|
|
40402
|
+
return fingerprintFileContents(bundledRequire.resolve("oxlint-plugin-react-doctor"), 16);
|
|
40403
|
+
} catch {
|
|
40404
|
+
return "unresolved";
|
|
40405
|
+
}
|
|
40406
|
+
};
|
|
40033
40407
|
const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
40034
40408
|
const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
|
|
40035
40409
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS) try {
|
|
@@ -40039,6 +40413,7 @@ const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
|
40039
40413
|
} catch {
|
|
40040
40414
|
versions.push(`${specifier}=missing`);
|
|
40041
40415
|
}
|
|
40416
|
+
versions.push(`oxlint-plugin-react-doctor#fingerprint=${resolvePluginFingerprint()}`);
|
|
40042
40417
|
return versions;
|
|
40043
40418
|
};
|
|
40044
40419
|
const esmRequire = createRequire(import.meta.url);
|
|
@@ -40732,12 +41107,17 @@ const REACT_ERROR_BOUNDARY_MESSAGE = "This try/catch cannot catch errors thrown
|
|
|
40732
41107
|
const REACT_COMPILER_IMPACT = "This component misses React Compiler's automatic memoization & re-renders more than it should";
|
|
40733
41108
|
const REACT_COMPILER_ACTION = "Rewrite the flagged code so the compiler can optimize it.";
|
|
40734
41109
|
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`.";
|
|
41110
|
+
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`.";
|
|
40735
41111
|
const REACT_COMPILER_GENERIC_MESSAGE = `${REACT_COMPILER_IMPACT}. ${REACT_COMPILER_ACTION}`;
|
|
40736
41112
|
const buildReactCompilerMessage = (reasonSummary, action = REACT_COMPILER_ACTION) => {
|
|
40737
41113
|
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
40738
41114
|
if (!normalizedSummary) return `${REACT_COMPILER_IMPACT}. ${action}`;
|
|
40739
41115
|
return `${REACT_COMPILER_IMPACT}: ${normalizedSummary}. ${action}`;
|
|
40740
41116
|
};
|
|
41117
|
+
const buildSetStateInEffectMessage = (reasonSummary) => {
|
|
41118
|
+
const normalizedSummary = reasonSummary.replace(TRAILING_PERIOD_PATTERN, "");
|
|
41119
|
+
return `This synchronous effect update causes an extra render${normalizedSummary ? `: ${normalizedSummary}` : ""}. ${SET_STATE_IN_EFFECT_ACTION}`;
|
|
41120
|
+
};
|
|
40741
41121
|
const PLUGIN_CATEGORY_MAP = {
|
|
40742
41122
|
react: "Bugs",
|
|
40743
41123
|
"react-hooks": "Bugs",
|
|
@@ -40795,6 +41175,10 @@ const resolveCleanedDiagnostic = (message, help, plugin, rule, project) => {
|
|
|
40795
41175
|
message: REACT_ERROR_BOUNDARY_MESSAGE,
|
|
40796
41176
|
help: reasonDetail || help
|
|
40797
41177
|
};
|
|
41178
|
+
if (rule === "set-state-in-effect") return {
|
|
41179
|
+
message: buildSetStateInEffectMessage(reasonSummary.trim()),
|
|
41180
|
+
help: reasonDetail || help
|
|
41181
|
+
};
|
|
40798
41182
|
return {
|
|
40799
41183
|
message: buildReactCompilerMessage(reasonSummary.trim(), rule === "incompatible-library" ? REACT_COMPILER_INCOMPATIBLE_LIBRARY_ACTION : REACT_COMPILER_ACTION),
|
|
40800
41184
|
help: appendReanimatedSharedValueHint(reasonDetail || help, rule, project)
|
|
@@ -41505,7 +41889,7 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
41505
41889
|
* 6. always restore disable directives + clean up the temp dir
|
|
41506
41890
|
*/
|
|
41507
41891
|
const runOxlint = async (options) => {
|
|
41508
|
-
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;
|
|
41892
|
+
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;
|
|
41509
41893
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
41510
41894
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
41511
41895
|
validateRuleRegistration();
|
|
@@ -41519,13 +41903,15 @@ const runOxlint = async (options) => {
|
|
|
41519
41903
|
}
|
|
41520
41904
|
const pluginPath = resolvePluginPath();
|
|
41521
41905
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
41522
|
-
const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
41906
|
+
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
41523
41907
|
const buildConfig = (overrides) => createOxlintConfig({
|
|
41524
41908
|
pluginPath,
|
|
41525
41909
|
project,
|
|
41526
41910
|
customRulesOnly,
|
|
41527
41911
|
extendsPaths: overrides.extendsPaths,
|
|
41528
41912
|
ignoredTags,
|
|
41913
|
+
includedTags,
|
|
41914
|
+
includeTagDefaults,
|
|
41529
41915
|
serverAuthFunctionNames,
|
|
41530
41916
|
severityControls,
|
|
41531
41917
|
userPlugins,
|
|
@@ -41914,6 +42300,8 @@ var Linter = class Linter extends Service()("react-doctor/Linter") {
|
|
|
41914
42300
|
respectInlineDisables: input.respectInlineDisables,
|
|
41915
42301
|
adoptExistingLintConfig: input.adoptExistingLintConfig,
|
|
41916
42302
|
ignoredTags: input.ignoredTags,
|
|
42303
|
+
includedTags: input.includedTags,
|
|
42304
|
+
includeTagDefaults: input.includeTagDefaults,
|
|
41917
42305
|
userConfig: input.userConfig ?? null,
|
|
41918
42306
|
configSourceDirectory: input.configSourceDirectory,
|
|
41919
42307
|
onPartialFailure: (reason) => {
|
|
@@ -42762,7 +43150,9 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42762
43150
|
const securityScanFailedRef = yield* make$13(false);
|
|
42763
43151
|
const securityScanFiber = yield* forkChild(runCollect(applyPerElementPipeline(isDiffMode ? empty$4 : unwrap(tryPromise(() => checkSecurityScanCooperative(scanDirectory, {
|
|
42764
43152
|
project,
|
|
42765
|
-
ignoredTags: input.ignoredTags
|
|
43153
|
+
ignoredTags: input.ignoredTags,
|
|
43154
|
+
includedTags: input.includedTags,
|
|
43155
|
+
includeTagDefaults: input.includeTagDefaults
|
|
42766
43156
|
})).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)), catch_$1(() => set(securityScanFailedRef, true).pipe(as(empty$4))))))).pipe(withSpan("SecurityScan.run")));
|
|
42767
43157
|
const shouldRunSupplyChain = !isDiffMode || (input.supplyChainManifestChanged ?? false);
|
|
42768
43158
|
const supplyChainOverlapTimeout = yield* SupplyChainOverlapTimeoutMs;
|
|
@@ -42853,6 +43243,8 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42853
43243
|
respectInlineDisables: input.respectInlineDisables,
|
|
42854
43244
|
adoptExistingLintConfig: input.adoptExistingLintConfig,
|
|
42855
43245
|
ignoredTags: input.ignoredTags,
|
|
43246
|
+
includedTags: input.includedTags,
|
|
43247
|
+
includeTagDefaults: input.includeTagDefaults,
|
|
42856
43248
|
userConfig: resolvedConfig.config ?? void 0,
|
|
42857
43249
|
configSourceDirectory: resolvedConfig.configSourceDirectory ?? void 0,
|
|
42858
43250
|
onFileProgress: (scannedFileCount, totalFileCount) => {
|
|
@@ -43120,12 +43512,19 @@ const isPathInsideDirectory = (childAbsolutePath, parentAbsolutePath) => {
|
|
|
43120
43512
|
*/
|
|
43121
43513
|
const materializeSourceTree = (input) => gen(function* () {
|
|
43122
43514
|
const materializedFiles = [];
|
|
43515
|
+
const unmaterializedFiles = [];
|
|
43123
43516
|
const resolvedTempDirectory = path.resolve(input.tempDirectory);
|
|
43124
43517
|
for (const relativePath of input.files) {
|
|
43125
43518
|
const content = yield* input.readContent(relativePath).pipe(orElseSucceed(() => null));
|
|
43126
|
-
if (content === null)
|
|
43519
|
+
if (content === null) {
|
|
43520
|
+
unmaterializedFiles.push(relativePath);
|
|
43521
|
+
continue;
|
|
43522
|
+
}
|
|
43127
43523
|
const candidateTargetPath = path.resolve(resolvedTempDirectory, relativePath);
|
|
43128
|
-
if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory))
|
|
43524
|
+
if (!isPathInsideDirectory(candidateTargetPath, resolvedTempDirectory)) {
|
|
43525
|
+
unmaterializedFiles.push(relativePath);
|
|
43526
|
+
continue;
|
|
43527
|
+
}
|
|
43129
43528
|
yield* sync(() => {
|
|
43130
43529
|
fs.mkdirSync(path.dirname(candidateTargetPath), { recursive: true });
|
|
43131
43530
|
fs.writeFileSync(candidateTargetPath, content);
|
|
@@ -43142,6 +43541,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
43142
43541
|
return {
|
|
43143
43542
|
tempDirectory: input.tempDirectory,
|
|
43144
43543
|
materializedFiles,
|
|
43544
|
+
unmaterializedFiles,
|
|
43145
43545
|
cleanup: () => {
|
|
43146
43546
|
try {
|
|
43147
43547
|
fs.rmSync(input.tempDirectory, {
|
|
@@ -43317,7 +43717,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
|
|
|
43317
43717
|
/** Display name used in client-facing messages and progress titles. */
|
|
43318
43718
|
const SERVER_DISPLAY_NAME = "React Doctor";
|
|
43319
43719
|
/** Server version reported in `serverInfo`; injected at build, `dev` from source. */
|
|
43320
|
-
const SERVER_VERSION = "0.8.
|
|
43720
|
+
const SERVER_VERSION = "0.8.1";
|
|
43321
43721
|
/** `Diagnostic.source` shown next to every published diagnostic. */
|
|
43322
43722
|
const DIAGNOSTIC_SOURCE = "react-doctor";
|
|
43323
43723
|
/**
|
|
@@ -45347,5 +45747,5 @@ const startLanguageServer = () => {
|
|
|
45347
45747
|
};
|
|
45348
45748
|
//#endregion
|
|
45349
45749
|
export { startLanguageServer };
|
|
45350
|
-
!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]="
|
|
45351
|
-
//# debugId=
|
|
45750
|
+
!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]="6c3f6717-c00e-5081-bb66-501f2fd8a0d1")}catch(e){}}();
|
|
45751
|
+
//# debugId=6c3f6717-c00e-5081-bb66-501f2fd8a0d1
|