@codacy/tools-eslint-9 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +458 -38
- package/package.json +17 -17
package/dist/index.js
CHANGED
|
@@ -37,8 +37,8 @@ var import_tooling2 = require("@codacy/tooling");
|
|
|
37
37
|
|
|
38
38
|
// src/adapter.ts
|
|
39
39
|
var import_tooling = require("@codacy/tooling");
|
|
40
|
-
var
|
|
41
|
-
var
|
|
40
|
+
var import_path3 = __toESM(require("path"));
|
|
41
|
+
var import_fs3 = __toESM(require("fs"));
|
|
42
42
|
|
|
43
43
|
// src/patterns.json
|
|
44
44
|
var patterns_default = [
|
|
@@ -28427,15 +28427,55 @@ var patterns_default = [
|
|
|
28427
28427
|
}
|
|
28428
28428
|
];
|
|
28429
28429
|
|
|
28430
|
+
// src/config-builder.ts
|
|
28431
|
+
var import_fs2 = __toESM(require("fs"));
|
|
28432
|
+
var import_path2 = __toESM(require("path"));
|
|
28433
|
+
|
|
28430
28434
|
// src/blacklist.ts
|
|
28435
|
+
var import_fs = __toESM(require("fs"));
|
|
28436
|
+
var import_path = __toESM(require("path"));
|
|
28437
|
+
var BLACKLISTED_RULE_PATTERNS = [
|
|
28438
|
+
// `eslint-plugin-unused-imports` ships duplicate `-ts` variants (e.g.
|
|
28439
|
+
// `no-unused-imports-ts`) that are meant for codebases NOT using the
|
|
28440
|
+
// `@typescript-eslint` plugin. In our config `@typescript-eslint/
|
|
28441
|
+
// no-unused-vars` is always available for TS files, so the `-ts`
|
|
28442
|
+
// variants are redundant and conflict with it.
|
|
28443
|
+
/^unused-imports\/.*-ts$/,
|
|
28444
|
+
// `eslint-plugin-angular` targets AngularJS 1.x (not Angular 2+) and
|
|
28445
|
+
// also calls removed ESLint 9 APIs in several rules
|
|
28446
|
+
// (`angular/component-limit`, `angular/di*`, `angular/dumb-inject`,
|
|
28447
|
+
// `angular/no-directive-replace`, `angular/no-run-logic`,
|
|
28448
|
+
// `angular/prefer-component`, `angular/service-name`, …). The modern
|
|
28449
|
+
// `@angular-eslint/*` plugin (Angular 2+) is unaffected and stays
|
|
28450
|
+
// enabled.
|
|
28451
|
+
/^angular\//,
|
|
28452
|
+
// `eslint-plugin-eslint-plugin` targets ESLint plugin authors. Several
|
|
28453
|
+
// of its rules (`no-property-in-node`, …) also call removed AST
|
|
28454
|
+
// utilities and fail on ESLint 9. Not useful for end-user code
|
|
28455
|
+
// analysis either.
|
|
28456
|
+
/^eslint-plugin\//
|
|
28457
|
+
];
|
|
28431
28458
|
var BLACKLISTED_RULES = /* @__PURE__ */ new Set([
|
|
28432
|
-
// --- Plugin rules that crash
|
|
28433
|
-
|
|
28434
|
-
|
|
28459
|
+
// --- Plugin rules that crash on ESLint 9 (but aren't covered by a
|
|
28460
|
+
// blanket namespace above) ---------------------------------------
|
|
28461
|
+
// `@typescript-eslint/consistent-type-imports` is incompatible with
|
|
28462
|
+
// the `verbatimModuleSyntax` tsconfig flag (now the recommended TS
|
|
28463
|
+
// setting) and emits conflicting auto-fixes when both are enabled.
|
|
28435
28464
|
"@typescript-eslint/consistent-type-imports",
|
|
28436
|
-
|
|
28437
|
-
|
|
28465
|
+
// `ember/template-indent` reformats Handlebars templates in a way that
|
|
28466
|
+
// fights both the ember-template-lint formatter and Prettier. Source
|
|
28467
|
+
// of persistent whitespace false positives; preserved from the
|
|
28468
|
+
// codacy-eslint blacklist history.
|
|
28438
28469
|
"ember/template-indent",
|
|
28470
|
+
// --- eslint-plugin-functional family ------------------------------
|
|
28471
|
+
//
|
|
28472
|
+
// The `functional` plugin enforces an extremely strict pure-FP style
|
|
28473
|
+
// (no mutation, no `let`, no throw, no void return, …). On general
|
|
28474
|
+
// JavaScript/TypeScript codebases every one of these rules produces
|
|
28475
|
+
// a flood of false positives that drowns out every other finding.
|
|
28476
|
+
// They are only appropriate for codebases that have opted into the
|
|
28477
|
+
// plugin explicitly — which users can do via their own local
|
|
28478
|
+
// `eslint.config.js` + `useLocalConfigurationFile`.
|
|
28439
28479
|
"functional/functional-parameters",
|
|
28440
28480
|
"functional/immutable-data",
|
|
28441
28481
|
"functional/no-conditional-statements",
|
|
@@ -28447,8 +28487,19 @@ var BLACKLISTED_RULES = /* @__PURE__ */ new Set([
|
|
|
28447
28487
|
"functional/no-try-statements",
|
|
28448
28488
|
"functional/prefer-immutable-types",
|
|
28449
28489
|
"functional/type-declaration-immutability",
|
|
28490
|
+
// `yml/sort-sequence-values` is the YAML counterpart of `jsonc/sort-
|
|
28491
|
+
// array-values` — it requires a non-empty options array (pathPattern
|
|
28492
|
+
// + order) and crashes without one. Listed as unconditional because
|
|
28493
|
+
// patterns.json does not surface a parameter schema that lets us
|
|
28494
|
+
// tell "user supplied" from "default" for this rule; revisit if a
|
|
28495
|
+
// user complains.
|
|
28450
28496
|
"yml/sort-sequence-values",
|
|
28451
|
-
// --- Core rules
|
|
28497
|
+
// --- Core formatting rules conflicting with @stylistic ------------
|
|
28498
|
+
//
|
|
28499
|
+
// When both a core layout rule and its `@stylistic/*` equivalent are
|
|
28500
|
+
// enabled, they fight each other (same AST, different fixers). We
|
|
28501
|
+
// prefer the `@stylistic` versions because they track ESLint's
|
|
28502
|
+
// modern layout semantics and handle TS syntax natively.
|
|
28452
28503
|
"arrow-parens",
|
|
28453
28504
|
"indent",
|
|
28454
28505
|
"computed-property-spacing",
|
|
@@ -28458,15 +28509,125 @@ var BLACKLISTED_RULES = /* @__PURE__ */ new Set([
|
|
|
28458
28509
|
"semi",
|
|
28459
28510
|
"comma-dangle",
|
|
28460
28511
|
"no-mixed-spaces-and-tabs",
|
|
28461
|
-
//
|
|
28512
|
+
// `@typescript-eslint/brace-style` and `@typescript-eslint/indent` are
|
|
28513
|
+
// also deprecated in favour of the `@stylistic` equivalents for the
|
|
28514
|
+
// same reason.
|
|
28462
28515
|
"@typescript-eslint/brace-style",
|
|
28463
28516
|
"@typescript-eslint/indent"
|
|
28464
28517
|
]);
|
|
28465
|
-
var
|
|
28518
|
+
var requireAnyUserParam = (pattern) => !pattern.parameters || Object.keys(pattern.parameters).length === 0;
|
|
28519
|
+
var CONDITIONAL_BLACKLIST = /* @__PURE__ */ new Map([
|
|
28520
|
+
// `ember/no-restricted-service-injections` requires at least one of
|
|
28521
|
+
// `paths` or `services` to have a non-empty entry — without a real
|
|
28522
|
+
// value the plugin's own JSON schema rejects the options and aborts
|
|
28523
|
+
// the whole run. Codacy's declared default is `[""]` (an array with
|
|
28524
|
+
// a single empty string) which is nonsensical as a match list. Only
|
|
28525
|
+
// keep the rule when the user has actually configured something.
|
|
28526
|
+
[
|
|
28527
|
+
"ember/no-restricted-service-injections",
|
|
28528
|
+
(pattern) => !hasUserSuppliedAny(pattern, "services", "paths")
|
|
28529
|
+
],
|
|
28530
|
+
// `ember/no-restricted-property-modifications` has the same pattern:
|
|
28531
|
+
// it takes a list of property names to watch, and is unusable without
|
|
28532
|
+
// one.
|
|
28533
|
+
[
|
|
28534
|
+
"ember/no-restricted-property-modifications",
|
|
28535
|
+
(pattern) => !hasUserSuppliedAny(pattern, "properties")
|
|
28536
|
+
],
|
|
28537
|
+
// `jsonc/sort-array-values` / `jsonc/sort-keys` need a non-empty
|
|
28538
|
+
// `pathPattern` or `order` — the default placeholder (`^$` / `{}`)
|
|
28539
|
+
// matches nothing meaningful and makes the rule schema-invalid.
|
|
28540
|
+
["jsonc/sort-array-values", (pattern) => !hasUserSuppliedAny(pattern, "pathPattern", "order")],
|
|
28541
|
+
["jsonc/sort-keys", (pattern) => !hasUserSuppliedAny(pattern, "pathPattern", "order")],
|
|
28542
|
+
// `jest/no-deprecated-functions` inspects the analysed project's
|
|
28543
|
+
// installed jest version at rule-load time. In a repo without jest
|
|
28544
|
+
// in `package.json` the rule throws `Unable to detect Jest version`
|
|
28545
|
+
// after ESLint has already walked every file, aborting the whole
|
|
28546
|
+
// run. Skip the rule when the target repo has no jest dependency.
|
|
28547
|
+
["jest/no-deprecated-functions", (_p, ctx) => !hasTargetDependency(ctx.repositoryRoot, "jest")],
|
|
28548
|
+
// `eslint-plugin-check-file` rules require the user to supply a
|
|
28549
|
+
// non-empty naming-pattern object. Without it, each rule fires on
|
|
28550
|
+
// *every* JS/TS file with
|
|
28551
|
+
// `The naming pattern object "undefined" does not appear to be an
|
|
28552
|
+
// Object type, please double-check it and try again`
|
|
28553
|
+
// Codacy's `patterns.json` exposes no parameters for these rules, so
|
|
28554
|
+
// they are never useful without a user-provided override. If a user
|
|
28555
|
+
// supplies a `rules` / `patterns` parameter, trust them and run.
|
|
28556
|
+
["check-file/filename-blocklist", requireAnyUserParam],
|
|
28557
|
+
["check-file/filename-naming-convention", requireAnyUserParam],
|
|
28558
|
+
["check-file/folder-match-with-fex", requireAnyUserParam],
|
|
28559
|
+
["check-file/folder-naming-convention", requireAnyUserParam],
|
|
28560
|
+
// `jsdoc/no-missing-syntax` requires a non-empty `contexts` option.
|
|
28561
|
+
// The Codacy-declared default is `[]`, which the rule itself rejects
|
|
28562
|
+
// at runtime with
|
|
28563
|
+
// `Rule no-missing-syntax is missing a 'contexts' option`
|
|
28564
|
+
// Skip unless the user has supplied a real value.
|
|
28565
|
+
["jsdoc/no-missing-syntax", (pattern) => !hasUserSuppliedAny(pattern, "contexts")],
|
|
28566
|
+
// `jsdoc/imports-as-dependencies` synchronously reads the analysed
|
|
28567
|
+
// repo's `package.json` to verify every `@import` tag references a
|
|
28568
|
+
// listed dependency. If the file is missing the rule crashes with
|
|
28569
|
+
// `ENOENT: no such file or directory, open '<root>/package.json'`
|
|
28570
|
+
// and that sync throw propagates through the rule visitor, aborting
|
|
28571
|
+
// the run mid-way. Skip the rule unless the target repo actually
|
|
28572
|
+
// has a `package.json`.
|
|
28573
|
+
["jsdoc/imports-as-dependencies", (_p, ctx) => !hasTargetPackageJson(ctx.repositoryRoot)]
|
|
28574
|
+
]);
|
|
28575
|
+
function hasUserSuppliedAny(pattern, ...paramNames) {
|
|
28576
|
+
const params = pattern.parameters;
|
|
28577
|
+
if (!params) return false;
|
|
28578
|
+
for (const name of paramNames) {
|
|
28579
|
+
const raw = params[name];
|
|
28580
|
+
if (raw === void 0 || raw === "") continue;
|
|
28581
|
+
const parsed = tryParseCollection(raw);
|
|
28582
|
+
if (Array.isArray(parsed)) {
|
|
28583
|
+
if (parsed.length > 0 && parsed.some((v) => v !== "" && v != null)) return true;
|
|
28584
|
+
} else if (parsed && typeof parsed === "object") {
|
|
28585
|
+
if (Object.keys(parsed).length > 0) return true;
|
|
28586
|
+
} else if (typeof parsed === "string") {
|
|
28587
|
+
if (parsed.length > 0 && parsed !== "^$") return true;
|
|
28588
|
+
} else if (parsed !== void 0 && parsed !== null) {
|
|
28589
|
+
return true;
|
|
28590
|
+
}
|
|
28591
|
+
}
|
|
28592
|
+
return false;
|
|
28593
|
+
}
|
|
28594
|
+
function tryParseCollection(raw) {
|
|
28595
|
+
const trimmed = raw.trim();
|
|
28596
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]") || trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
28597
|
+
try {
|
|
28598
|
+
return JSON.parse(trimmed);
|
|
28599
|
+
} catch {
|
|
28600
|
+
}
|
|
28601
|
+
}
|
|
28602
|
+
return trimmed;
|
|
28603
|
+
}
|
|
28604
|
+
function hasTargetPackageJson(repositoryRoot) {
|
|
28605
|
+
try {
|
|
28606
|
+
import_fs.default.accessSync(import_path.default.join(repositoryRoot, "package.json"), import_fs.default.constants.R_OK);
|
|
28607
|
+
return true;
|
|
28608
|
+
} catch {
|
|
28609
|
+
return false;
|
|
28610
|
+
}
|
|
28611
|
+
}
|
|
28612
|
+
function hasTargetDependency(repositoryRoot, dependencyName) {
|
|
28613
|
+
try {
|
|
28614
|
+
const pkgPath = import_path.default.join(repositoryRoot, "package.json");
|
|
28615
|
+
const raw = import_fs.default.readFileSync(pkgPath, "utf-8");
|
|
28616
|
+
const pkg = JSON.parse(raw);
|
|
28617
|
+
return !!pkg.dependencies?.[dependencyName] || !!pkg.devDependencies?.[dependencyName] || !!pkg.peerDependencies?.[dependencyName] || !!pkg.optionalDependencies?.[dependencyName];
|
|
28618
|
+
} catch {
|
|
28619
|
+
return false;
|
|
28620
|
+
}
|
|
28621
|
+
}
|
|
28466
28622
|
function isBlacklisted(ruleId) {
|
|
28467
28623
|
if (BLACKLISTED_RULES.has(ruleId)) return true;
|
|
28468
28624
|
return BLACKLISTED_RULE_PATTERNS.some((re) => re.test(ruleId));
|
|
28469
28625
|
}
|
|
28626
|
+
function shouldSkipRule(ruleId, pattern, ctx) {
|
|
28627
|
+
if (isBlacklisted(ruleId)) return true;
|
|
28628
|
+
const predicate = CONDITIONAL_BLACKLIST.get(ruleId);
|
|
28629
|
+
return predicate ? predicate(pattern, ctx) : false;
|
|
28630
|
+
}
|
|
28470
28631
|
|
|
28471
28632
|
// src/plugin-registry.ts
|
|
28472
28633
|
async function loadPlugin(packageName) {
|
|
@@ -28609,6 +28770,30 @@ function extractPluginPrefix(ruleId) {
|
|
|
28609
28770
|
}
|
|
28610
28771
|
|
|
28611
28772
|
// src/config-builder.ts
|
|
28773
|
+
var TSCONFIG_CANDIDATES = [
|
|
28774
|
+
"tsconfig.json",
|
|
28775
|
+
"tsconfig.base.json",
|
|
28776
|
+
"tsconfig.eslint.json",
|
|
28777
|
+
"jsconfig.json"
|
|
28778
|
+
];
|
|
28779
|
+
function hasTypeScriptProjectConfig(repositoryRoot) {
|
|
28780
|
+
for (const name of TSCONFIG_CANDIDATES) {
|
|
28781
|
+
try {
|
|
28782
|
+
import_fs2.default.accessSync(import_path2.default.join(repositoryRoot, name));
|
|
28783
|
+
return true;
|
|
28784
|
+
} catch {
|
|
28785
|
+
}
|
|
28786
|
+
}
|
|
28787
|
+
return false;
|
|
28788
|
+
}
|
|
28789
|
+
var PATTERN_DEFAULTS = new Map(
|
|
28790
|
+
patterns_default.filter((p) => Array.isArray(p.parameters) && p.parameters.length > 0).map((p) => [
|
|
28791
|
+
p.id,
|
|
28792
|
+
Object.fromEntries(
|
|
28793
|
+
(p.parameters ?? []).filter((param) => param.default !== void 0).map((param) => [param.name, param.default ?? ""])
|
|
28794
|
+
)
|
|
28795
|
+
])
|
|
28796
|
+
);
|
|
28612
28797
|
var TOOL_ID = "ESLint9";
|
|
28613
28798
|
var PREFIX = `${TOOL_ID}_`;
|
|
28614
28799
|
var CORE_TO_TS_EXTENSION = /* @__PURE__ */ new Map([
|
|
@@ -28645,11 +28830,11 @@ function decodePatternId(patternId) {
|
|
|
28645
28830
|
function encodePatternId(ruleId) {
|
|
28646
28831
|
return `${PREFIX}${ruleId.replace(/_/g, "__").replace(/\//g, "_")}`;
|
|
28647
28832
|
}
|
|
28648
|
-
async function buildESLintConfig(patterns) {
|
|
28833
|
+
async function buildESLintConfig(patterns, ctx = { repositoryRoot: process.cwd() }) {
|
|
28649
28834
|
const ruleEntries = [];
|
|
28650
28835
|
for (const p of patterns) {
|
|
28651
28836
|
const ruleId = decodePatternId(p.patternId);
|
|
28652
|
-
if (
|
|
28837
|
+
if (shouldSkipRule(ruleId, p, ctx)) continue;
|
|
28653
28838
|
ruleEntries.push({ ruleId, pattern: p });
|
|
28654
28839
|
}
|
|
28655
28840
|
const allRuleIds = ruleEntries.map((e) => e.ruleId);
|
|
@@ -28662,6 +28847,7 @@ async function buildESLintConfig(patterns) {
|
|
|
28662
28847
|
if (!prefix) {
|
|
28663
28848
|
coreRules[ruleId] = ruleValue;
|
|
28664
28849
|
} else if (plugins.has(prefix)) {
|
|
28850
|
+
if (!pluginExposesRule(plugins.get(prefix), prefix, ruleId)) continue;
|
|
28665
28851
|
if (!pluginRuleGroups.has(prefix)) {
|
|
28666
28852
|
pluginRuleGroups.set(prefix, {});
|
|
28667
28853
|
}
|
|
@@ -28669,6 +28855,14 @@ async function buildESLintConfig(patterns) {
|
|
|
28669
28855
|
}
|
|
28670
28856
|
}
|
|
28671
28857
|
const configs = [];
|
|
28858
|
+
configs.push({
|
|
28859
|
+
files: ["**/*.jsx", "**/*.tsx"],
|
|
28860
|
+
languageOptions: {
|
|
28861
|
+
parserOptions: {
|
|
28862
|
+
ecmaFeatures: { jsx: true }
|
|
28863
|
+
}
|
|
28864
|
+
}
|
|
28865
|
+
});
|
|
28672
28866
|
if (Object.keys(coreRules).length > 0) {
|
|
28673
28867
|
configs.push({
|
|
28674
28868
|
files: ["**/*.js", "**/*.jsx", "**/*.mjs", "**/*.cjs", "**/*.ts", "**/*.tsx"],
|
|
@@ -28678,17 +28872,16 @@ async function buildESLintConfig(patterns) {
|
|
|
28678
28872
|
const tsPlugin = plugins.get("@typescript-eslint");
|
|
28679
28873
|
const tsRules = pluginRuleGroups.get("@typescript-eslint");
|
|
28680
28874
|
if (tsRules && tsPlugin) {
|
|
28875
|
+
const tsLanguageOptions = {
|
|
28876
|
+
parser: await loadTsParser()
|
|
28877
|
+
};
|
|
28878
|
+
if (hasTypeScriptProjectConfig(ctx.repositoryRoot)) {
|
|
28879
|
+
tsLanguageOptions.parserOptions = { projectService: true };
|
|
28880
|
+
}
|
|
28681
28881
|
configs.push({
|
|
28682
28882
|
files: ["**/*.ts", "**/*.tsx"],
|
|
28683
28883
|
plugins: { "@typescript-eslint": tsPlugin },
|
|
28684
|
-
languageOptions:
|
|
28685
|
-
parser: await loadTsParser(),
|
|
28686
|
-
parserOptions: {
|
|
28687
|
-
projectService: {
|
|
28688
|
-
allowDefaultProject: ["*.ts", "*.tsx"]
|
|
28689
|
-
}
|
|
28690
|
-
}
|
|
28691
|
-
},
|
|
28884
|
+
languageOptions: tsLanguageOptions,
|
|
28692
28885
|
rules: tsRules
|
|
28693
28886
|
});
|
|
28694
28887
|
pluginRuleGroups.delete("@typescript-eslint");
|
|
@@ -28713,6 +28906,26 @@ async function buildESLintConfig(patterns) {
|
|
|
28713
28906
|
if (prefix === "yml") {
|
|
28714
28907
|
configItem.files = ["**/*.yml", "**/*.yaml"];
|
|
28715
28908
|
}
|
|
28909
|
+
if (prefix === "storybook") {
|
|
28910
|
+
configItem.files = [
|
|
28911
|
+
"**/*.stories.js",
|
|
28912
|
+
"**/*.stories.jsx",
|
|
28913
|
+
"**/*.stories.mjs",
|
|
28914
|
+
"**/*.stories.cjs",
|
|
28915
|
+
"**/*.stories.ts",
|
|
28916
|
+
"**/*.stories.tsx",
|
|
28917
|
+
"**/*.story.js",
|
|
28918
|
+
"**/*.story.jsx",
|
|
28919
|
+
"**/*.story.mjs",
|
|
28920
|
+
"**/*.story.cjs",
|
|
28921
|
+
"**/*.story.ts",
|
|
28922
|
+
"**/*.story.tsx"
|
|
28923
|
+
];
|
|
28924
|
+
}
|
|
28925
|
+
if (prefix === "react") {
|
|
28926
|
+
const version = hasTargetDependency(ctx.repositoryRoot, "react") ? "detect" : "999.999.999";
|
|
28927
|
+
configItem.settings = { react: { version } };
|
|
28928
|
+
}
|
|
28716
28929
|
configs.push(configItem);
|
|
28717
28930
|
}
|
|
28718
28931
|
const tsOverrideRules = {};
|
|
@@ -28734,16 +28947,18 @@ async function buildESLintConfig(patterns) {
|
|
|
28734
28947
|
return configs;
|
|
28735
28948
|
}
|
|
28736
28949
|
function buildRuleValue(pattern) {
|
|
28737
|
-
|
|
28950
|
+
const defaults = PATTERN_DEFAULTS.get(pattern.patternId) ?? {};
|
|
28951
|
+
const merged = { ...defaults, ...pattern.parameters ?? {} };
|
|
28952
|
+
if (Object.keys(merged).length === 0) {
|
|
28738
28953
|
return "error";
|
|
28739
28954
|
}
|
|
28740
28955
|
const result = ["error"];
|
|
28741
28956
|
const optionsObj = {};
|
|
28742
|
-
for (const [name, rawValue] of Object.entries(
|
|
28957
|
+
for (const [name, rawValue] of Object.entries(merged)) {
|
|
28743
28958
|
const value = parseParamValue(rawValue);
|
|
28744
28959
|
if (name === "unnamedParam") {
|
|
28745
28960
|
result.splice(1, 0, value);
|
|
28746
|
-
} else {
|
|
28961
|
+
} else if (!isEmptyCollection(value)) {
|
|
28747
28962
|
optionsObj[name] = value;
|
|
28748
28963
|
}
|
|
28749
28964
|
}
|
|
@@ -28752,6 +28967,13 @@ function buildRuleValue(pattern) {
|
|
|
28752
28967
|
}
|
|
28753
28968
|
return result.length === 1 ? "error" : result;
|
|
28754
28969
|
}
|
|
28970
|
+
function isEmptyCollection(value) {
|
|
28971
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
28972
|
+
if (value !== null && typeof value === "object") {
|
|
28973
|
+
return Object.keys(value).length === 0;
|
|
28974
|
+
}
|
|
28975
|
+
return false;
|
|
28976
|
+
}
|
|
28755
28977
|
function parseParamValue(value) {
|
|
28756
28978
|
const trimmed = value.trim();
|
|
28757
28979
|
if (trimmed === "true") return true;
|
|
@@ -28770,6 +28992,15 @@ async function loadTsParser() {
|
|
|
28770
28992
|
const mod = await import("typescript-eslint");
|
|
28771
28993
|
return mod.default?.parser ?? mod.parser;
|
|
28772
28994
|
}
|
|
28995
|
+
function pluginExposesRule(plugin, prefix, fullRuleId) {
|
|
28996
|
+
if (!plugin || typeof plugin !== "object") return false;
|
|
28997
|
+
const rules = plugin.rules;
|
|
28998
|
+
if (!rules || typeof rules !== "object") {
|
|
28999
|
+
return true;
|
|
29000
|
+
}
|
|
29001
|
+
const shortName = fullRuleId.startsWith(prefix + "/") ? fullRuleId.slice(prefix.length + 1) : fullRuleId;
|
|
29002
|
+
return Object.prototype.hasOwnProperty.call(rules, shortName);
|
|
29003
|
+
}
|
|
28773
29004
|
|
|
28774
29005
|
// src/metadata.ts
|
|
28775
29006
|
var descriptor = {
|
|
@@ -28806,14 +29037,75 @@ function ruleMetadata(ruleId) {
|
|
|
28806
29037
|
const patternId = encodePatternId(ruleId);
|
|
28807
29038
|
return PATTERN_META.get(patternId) ?? { category: "BestPractice", severity: "Info" };
|
|
28808
29039
|
}
|
|
28809
|
-
|
|
28810
|
-
|
|
28811
|
-
|
|
28812
|
-
|
|
28813
|
-
|
|
28814
|
-
|
|
28815
|
-
|
|
29040
|
+
var PROBE_SNIPPETS = [
|
|
29041
|
+
{ filePath: "__codacy_probe__.js", source: "var x=0;\n" },
|
|
29042
|
+
{ filePath: "__codacy_probe__.jsx", source: "const x=<div/>;\n" },
|
|
29043
|
+
{ filePath: "__codacy_probe__.ts", source: "const x: number = 0;\n" },
|
|
29044
|
+
{ filePath: "__codacy_probe__.tsx", source: "const x:unknown=<div/>;\n" },
|
|
29045
|
+
{ filePath: "__codacy_probe__.vue", source: "<template><div/></template>\n" },
|
|
29046
|
+
{ filePath: "__codacy_probe__.svelte", source: "<div></div>\n" },
|
|
29047
|
+
{ filePath: "__codacy_probe__.json", source: "{}\n" },
|
|
29048
|
+
{ filePath: "__codacy_probe__.yml", source: "a: 1\n" },
|
|
29049
|
+
{ filePath: "__codacy_probe__.md", source: "# probe\n" }
|
|
29050
|
+
];
|
|
29051
|
+
async function probeConfig(eslint, repositoryRoot) {
|
|
29052
|
+
for (const { filePath, source } of PROBE_SNIPPETS) {
|
|
29053
|
+
try {
|
|
29054
|
+
await eslint.lintText(source, { filePath: import_path3.default.join(repositoryRoot, filePath) });
|
|
29055
|
+
} catch (err) {
|
|
29056
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
29057
|
+
}
|
|
28816
29058
|
}
|
|
29059
|
+
return void 0;
|
|
29060
|
+
}
|
|
29061
|
+
function truncateForError(message) {
|
|
29062
|
+
const oneLine = message.replace(/\s+/g, " ").trim();
|
|
29063
|
+
return oneLine.length > 240 ? oneLine.slice(0, 237) + "\u2026" : oneLine;
|
|
29064
|
+
}
|
|
29065
|
+
function extractInvalidRule(message) {
|
|
29066
|
+
const flatMatch = message.match(/Key "rules":\s*Key "([^"]+)"/);
|
|
29067
|
+
if (flatMatch) return flatMatch[1];
|
|
29068
|
+
const legacyMatch = message.match(/Configuration for rule "([^"]+)" is invalid/);
|
|
29069
|
+
if (legacyMatch) return legacyMatch[1];
|
|
29070
|
+
const loadMatch = message.match(/Error while loading rule ['"]([^'"]+)['"]/);
|
|
29071
|
+
if (loadMatch) return loadMatch[1];
|
|
29072
|
+
const trailingRule = message.match(/Rule: ['"]([^'"]+)['"]/);
|
|
29073
|
+
if (trailingRule) return trailingRule[1];
|
|
29074
|
+
return void 0;
|
|
29075
|
+
}
|
|
29076
|
+
function removeRuleFromFlatConfig(config, ruleId) {
|
|
29077
|
+
if (!Array.isArray(config)) return false;
|
|
29078
|
+
let removed = false;
|
|
29079
|
+
for (const entry of config) {
|
|
29080
|
+
if (entry?.rules && Object.prototype.hasOwnProperty.call(entry.rules, ruleId)) {
|
|
29081
|
+
delete entry.rules[ruleId];
|
|
29082
|
+
removed = true;
|
|
29083
|
+
}
|
|
29084
|
+
}
|
|
29085
|
+
return removed;
|
|
29086
|
+
}
|
|
29087
|
+
function isParserServicesError(message) {
|
|
29088
|
+
return /requires parserServices|parserOptions\.project|requires type information/.test(message);
|
|
29089
|
+
}
|
|
29090
|
+
function rulePluginPrefix(ruleId) {
|
|
29091
|
+
const slashIdx = ruleId.indexOf("/");
|
|
29092
|
+
if (slashIdx <= 0) return void 0;
|
|
29093
|
+
return ruleId.slice(0, slashIdx);
|
|
29094
|
+
}
|
|
29095
|
+
function removeRulesByPluginFromFlatConfig(config, pluginPrefix) {
|
|
29096
|
+
if (!Array.isArray(config)) return [];
|
|
29097
|
+
const removed = [];
|
|
29098
|
+
const prefix = pluginPrefix + "/";
|
|
29099
|
+
for (const entry of config) {
|
|
29100
|
+
if (!entry?.rules) continue;
|
|
29101
|
+
for (const key of Object.keys(entry.rules)) {
|
|
29102
|
+
if (key.startsWith(prefix)) {
|
|
29103
|
+
delete entry.rules[key];
|
|
29104
|
+
if (!removed.includes(key)) removed.push(key);
|
|
29105
|
+
}
|
|
29106
|
+
}
|
|
29107
|
+
}
|
|
29108
|
+
return removed;
|
|
28817
29109
|
}
|
|
28818
29110
|
var adapter = {
|
|
28819
29111
|
...descriptor,
|
|
@@ -28854,9 +29146,9 @@ var adapter = {
|
|
|
28854
29146
|
async checkLocalConfigurationFile(ctx) {
|
|
28855
29147
|
ctx.logger.debug("Checking for local config", { toolId: TOOL_ID2 });
|
|
28856
29148
|
for (const name of LOCAL_CONFIG_FILES) {
|
|
28857
|
-
const candidate =
|
|
29149
|
+
const candidate = import_path3.default.join(ctx.repositoryRoot, name);
|
|
28858
29150
|
try {
|
|
28859
|
-
|
|
29151
|
+
import_fs3.default.accessSync(candidate);
|
|
28860
29152
|
ctx.logger.debug("Local config found", { toolId: TOOL_ID2, path: candidate });
|
|
28861
29153
|
return { found: true, path: candidate };
|
|
28862
29154
|
} catch {
|
|
@@ -28878,7 +29170,7 @@ var adapter = {
|
|
|
28878
29170
|
const startedAt = /* @__PURE__ */ new Date();
|
|
28879
29171
|
const issues = [];
|
|
28880
29172
|
const errors = [];
|
|
28881
|
-
const absoluteFiles = ctx.targetFiles.map((f) =>
|
|
29173
|
+
const absoluteFiles = ctx.targetFiles.map((f) => import_path3.default.resolve(ctx.repositoryRoot, f));
|
|
28882
29174
|
if (absoluteFiles.length === 0) {
|
|
28883
29175
|
const completedAt2 = /* @__PURE__ */ new Date();
|
|
28884
29176
|
return (0, import_tooling.buildResult)(TOOL_ID2, startedAt, completedAt2, issues, errors, ctx.targetFiles.length);
|
|
@@ -28902,10 +29194,19 @@ var adapter = {
|
|
|
28902
29194
|
if (codacyConfig.useLocalConfigurationFile && codacyConfig.localConfigurationFile) {
|
|
28903
29195
|
eslintOptions.overrideConfigFile = codacyConfig.localConfigurationFile;
|
|
28904
29196
|
} else if (codacyConfig.patterns.length > 0) {
|
|
29197
|
+
const buildStartMs = Date.now();
|
|
28905
29198
|
try {
|
|
28906
|
-
const config = await buildESLintConfig(codacyConfig.patterns
|
|
29199
|
+
const config = await buildESLintConfig(codacyConfig.patterns, {
|
|
29200
|
+
repositoryRoot: ctx.repositoryRoot
|
|
29201
|
+
});
|
|
28907
29202
|
eslintOptions.overrideConfig = config;
|
|
28908
29203
|
eslintOptions.overrideConfigFile = true;
|
|
29204
|
+
ctx.logger.debug("Flat config built", {
|
|
29205
|
+
toolId: TOOL_ID2,
|
|
29206
|
+
durationMs: Date.now() - buildStartMs,
|
|
29207
|
+
configEntries: Array.isArray(config) ? config.length : 0,
|
|
29208
|
+
patternCount: codacyConfig.patterns.length
|
|
29209
|
+
});
|
|
28909
29210
|
} catch (err) {
|
|
28910
29211
|
errors.push({
|
|
28911
29212
|
toolId: TOOL_ID2,
|
|
@@ -28923,14 +29224,130 @@ var adapter = {
|
|
|
28923
29224
|
return (0, import_tooling.buildResult)(TOOL_ID2, startedAt, /* @__PURE__ */ new Date(), issues, errors, ctx.targetFiles.length);
|
|
28924
29225
|
}
|
|
28925
29226
|
const enabledPatterns = new Set(codacyConfig.patterns.map((p) => p.patternId));
|
|
29227
|
+
const MAX_CONFIG_RETRIES = 30;
|
|
29228
|
+
let attempt = 0;
|
|
29229
|
+
let results = [];
|
|
28926
29230
|
try {
|
|
28927
|
-
const
|
|
28928
|
-
|
|
29231
|
+
const probeStartMs = Date.now();
|
|
29232
|
+
let lastProbeFailure;
|
|
29233
|
+
while (attempt <= MAX_CONFIG_RETRIES) {
|
|
29234
|
+
const probeEslint = new ESLintClass(eslintOptions);
|
|
29235
|
+
const failure = await probeConfig(probeEslint, ctx.repositoryRoot);
|
|
29236
|
+
if (!failure) {
|
|
29237
|
+
lastProbeFailure = void 0;
|
|
29238
|
+
break;
|
|
29239
|
+
}
|
|
29240
|
+
lastProbeFailure = failure;
|
|
29241
|
+
const rule = extractInvalidRule(failure.message);
|
|
29242
|
+
if (!rule) throw failure;
|
|
29243
|
+
if (isParserServicesError(failure.message)) {
|
|
29244
|
+
const prefix = rulePluginPrefix(rule);
|
|
29245
|
+
if (prefix) {
|
|
29246
|
+
const removedRules = removeRulesByPluginFromFlatConfig(
|
|
29247
|
+
eslintOptions.overrideConfig,
|
|
29248
|
+
prefix
|
|
29249
|
+
);
|
|
29250
|
+
if (removedRules.length > 0) {
|
|
29251
|
+
ctx.logger.warn("Skipping plugin requiring parserServices", {
|
|
29252
|
+
toolId: TOOL_ID2,
|
|
29253
|
+
plugin: prefix,
|
|
29254
|
+
count: removedRules.length
|
|
29255
|
+
});
|
|
29256
|
+
errors.push({
|
|
29257
|
+
toolId: TOOL_ID2,
|
|
29258
|
+
phase: "toolConfig",
|
|
29259
|
+
kind: "InvalidRuleConfig",
|
|
29260
|
+
message: `Plugin "${prefix}/*" (${removedRules.length} rule${removedRules.length === 1 ? "" : "s"}) skipped: requires typescript-eslint parserServices (no tsconfig.json in the analysed repo).`,
|
|
29261
|
+
level: "warning"
|
|
29262
|
+
});
|
|
29263
|
+
attempt++;
|
|
29264
|
+
continue;
|
|
29265
|
+
}
|
|
29266
|
+
}
|
|
29267
|
+
}
|
|
29268
|
+
const removed = removeRuleFromFlatConfig(eslintOptions.overrideConfig, rule);
|
|
29269
|
+
if (!removed) throw failure;
|
|
29270
|
+
ctx.logger.warn("Skipping rule rejected during probe", { toolId: TOOL_ID2, rule });
|
|
29271
|
+
errors.push({
|
|
29272
|
+
toolId: TOOL_ID2,
|
|
29273
|
+
phase: "toolConfig",
|
|
29274
|
+
kind: "InvalidRuleConfig",
|
|
29275
|
+
message: `Rule "${rule}" was skipped: ${truncateForError(failure.message)}`,
|
|
29276
|
+
level: "warning"
|
|
29277
|
+
});
|
|
29278
|
+
attempt++;
|
|
29279
|
+
}
|
|
29280
|
+
ctx.logger.debug("Config probe complete", {
|
|
29281
|
+
toolId: TOOL_ID2,
|
|
29282
|
+
durationMs: Date.now() - probeStartMs,
|
|
29283
|
+
rulesSkipped: attempt
|
|
29284
|
+
});
|
|
29285
|
+
if (lastProbeFailure) throw lastProbeFailure;
|
|
29286
|
+
while (true) {
|
|
29287
|
+
try {
|
|
29288
|
+
const instantiateStartMs = Date.now();
|
|
29289
|
+
const eslint = new ESLintClass(eslintOptions);
|
|
29290
|
+
ctx.logger.debug("ESLint instance created", {
|
|
29291
|
+
toolId: TOOL_ID2,
|
|
29292
|
+
durationMs: Date.now() - instantiateStartMs
|
|
29293
|
+
});
|
|
29294
|
+
const lintStartMs = Date.now();
|
|
29295
|
+
results = await eslint.lintFiles(absoluteFiles);
|
|
29296
|
+
ctx.logger.debug("lintFiles() complete", {
|
|
29297
|
+
toolId: TOOL_ID2,
|
|
29298
|
+
durationMs: Date.now() - lintStartMs,
|
|
29299
|
+
fileCount: results.length
|
|
29300
|
+
});
|
|
29301
|
+
break;
|
|
29302
|
+
} catch (err) {
|
|
29303
|
+
const rule = err instanceof Error ? extractInvalidRule(err.message) : void 0;
|
|
29304
|
+
if (!rule || attempt >= MAX_CONFIG_RETRIES) throw err;
|
|
29305
|
+
const parserServicesCause = err instanceof Error && isParserServicesError(err.message);
|
|
29306
|
+
const prefix = rulePluginPrefix(rule);
|
|
29307
|
+
if (prefix) {
|
|
29308
|
+
const removedRules = removeRulesByPluginFromFlatConfig(
|
|
29309
|
+
eslintOptions.overrideConfig,
|
|
29310
|
+
prefix
|
|
29311
|
+
);
|
|
29312
|
+
if (removedRules.length > 0) {
|
|
29313
|
+
const message = parserServicesCause ? `Plugin "${prefix}/*" (${removedRules.length} rule${removedRules.length === 1 ? "" : "s"}) skipped: requires typescript-eslint parserServices (no tsconfig.json / tsconfig.base.json / tsconfig.eslint.json / jsconfig.json found at the repository root).` : `Plugin "${prefix}/*" (${removedRules.length} rule${removedRules.length === 1 ? "" : "s"}) skipped after lintFiles failure on "${rule}": ${truncateForError(err instanceof Error ? err.message : String(err))}`;
|
|
29314
|
+
ctx.logger.warn(
|
|
29315
|
+
parserServicesCause ? "Skipping plugin requiring parserServices" : "Skipping plugin that failed during lintFiles",
|
|
29316
|
+
{ toolId: TOOL_ID2, plugin: prefix, count: removedRules.length, rule }
|
|
29317
|
+
);
|
|
29318
|
+
errors.push({
|
|
29319
|
+
toolId: TOOL_ID2,
|
|
29320
|
+
phase: "toolConfig",
|
|
29321
|
+
kind: "InvalidRuleConfig",
|
|
29322
|
+
message,
|
|
29323
|
+
level: "warning"
|
|
29324
|
+
});
|
|
29325
|
+
attempt++;
|
|
29326
|
+
continue;
|
|
29327
|
+
}
|
|
29328
|
+
}
|
|
29329
|
+
const removed = removeRuleFromFlatConfig(eslintOptions.overrideConfig, rule);
|
|
29330
|
+
if (!removed) throw err;
|
|
29331
|
+
ctx.logger.warn("Skipping rule that failed during lintFiles", { toolId: TOOL_ID2, rule });
|
|
29332
|
+
errors.push({
|
|
29333
|
+
toolId: TOOL_ID2,
|
|
29334
|
+
phase: "toolConfig",
|
|
29335
|
+
kind: "InvalidRuleConfig",
|
|
29336
|
+
message: `Rule "${rule}" was skipped after lintFiles failure: ${truncateForError(err instanceof Error ? err.message : String(err))}`,
|
|
29337
|
+
level: "warning"
|
|
29338
|
+
});
|
|
29339
|
+
attempt++;
|
|
29340
|
+
}
|
|
29341
|
+
}
|
|
28929
29342
|
for (const fileResult of results) {
|
|
28930
|
-
|
|
29343
|
+
if (fileResult.messages.length === 0) continue;
|
|
29344
|
+
const relPath = import_path3.default.relative(ctx.repositoryRoot, fileResult.filePath);
|
|
29345
|
+
let lines;
|
|
28931
29346
|
for (const msg of fileResult.messages) {
|
|
28932
29347
|
if (!msg.ruleId) continue;
|
|
28933
29348
|
if (isBlacklisted(msg.ruleId)) continue;
|
|
29349
|
+
if (msg.message.startsWith("Definition for rule ")) continue;
|
|
29350
|
+
if (msg.line === 0) continue;
|
|
28934
29351
|
const patternId = encodePatternId(msg.ruleId);
|
|
28935
29352
|
if (enabledPatterns.size > 0 && !enabledPatterns.has(patternId)) continue;
|
|
28936
29353
|
const meta = ruleMetadata(msg.ruleId);
|
|
@@ -28938,6 +29355,9 @@ var adapter = {
|
|
|
28938
29355
|
if (msg.suggestions && msg.suggestions.length > 0) {
|
|
28939
29356
|
suggestion = msg.suggestions[0].desc;
|
|
28940
29357
|
}
|
|
29358
|
+
if (lines === void 0) {
|
|
29359
|
+
lines = await (0, import_tooling.readFileLines)(fileResult.filePath);
|
|
29360
|
+
}
|
|
28941
29361
|
issues.push({
|
|
28942
29362
|
filePath: relPath,
|
|
28943
29363
|
patternId,
|
|
@@ -28947,7 +29367,7 @@ var adapter = {
|
|
|
28947
29367
|
endLine: msg.endLine,
|
|
28948
29368
|
endColumn: msg.endColumn,
|
|
28949
29369
|
message: msg.message,
|
|
28950
|
-
lineContent:
|
|
29370
|
+
lineContent: (0, import_tooling.getLineContent)(lines, msg.line),
|
|
28951
29371
|
category: meta.category,
|
|
28952
29372
|
severity: meta.severity,
|
|
28953
29373
|
suggestion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codacy/tools-eslint-9",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "ESLint 9 adapter — Library-mode JavaScript/TypeScript linter",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -8,21 +8,21 @@
|
|
|
8
8
|
"dist"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"eslint": "^9.
|
|
12
|
-
"@eslint/js": "^9.
|
|
11
|
+
"eslint": "^9.38.0",
|
|
12
|
+
"@eslint/js": "^9.38.0",
|
|
13
13
|
"typescript-eslint": "^8.0.0",
|
|
14
14
|
"globals": "^16.5.0",
|
|
15
15
|
"@angular-eslint/eslint-plugin": "^19.0.0",
|
|
16
|
-
"@lwc/eslint-plugin-lwc": "^
|
|
17
|
-
"@salesforce/eslint-plugin-lightning": "^
|
|
18
|
-
"@shopify/eslint-plugin": "^
|
|
16
|
+
"@lwc/eslint-plugin-lwc": "^3.0.0",
|
|
17
|
+
"@salesforce/eslint-plugin-lightning": "^2.0.0",
|
|
18
|
+
"@shopify/eslint-plugin": "^48.0.2",
|
|
19
19
|
"@stylistic/eslint-plugin": "^4.0.0",
|
|
20
20
|
"@tanstack/eslint-plugin-query": "^5.0.0",
|
|
21
21
|
"@vitest/eslint-plugin": "^1.0.0",
|
|
22
22
|
"eslint-plugin-angular": "^4.0.0",
|
|
23
|
-
"eslint-plugin-ava": "^
|
|
23
|
+
"eslint-plugin-ava": "^15.0.1",
|
|
24
24
|
"eslint-plugin-backbone": "^2.0.0",
|
|
25
|
-
"eslint-plugin-check-file": "^2.0
|
|
25
|
+
"eslint-plugin-check-file": "^3.2.0",
|
|
26
26
|
"eslint-plugin-compat": "^6.0.0",
|
|
27
27
|
"eslint-plugin-cypress": "^4.0.0",
|
|
28
28
|
"eslint-plugin-ember": "^12.0.0",
|
|
@@ -30,22 +30,22 @@
|
|
|
30
30
|
"eslint-plugin-es-x": "^8.0.0",
|
|
31
31
|
"eslint-plugin-eslint-plugin": "^6.0.0",
|
|
32
32
|
"eslint-plugin-fp": "^2.0.0",
|
|
33
|
-
"eslint-plugin-functional": "^
|
|
33
|
+
"eslint-plugin-functional": "^9.0.1",
|
|
34
34
|
"eslint-plugin-i18next": "^6.0.0",
|
|
35
35
|
"eslint-plugin-import": "^2.0.0",
|
|
36
36
|
"eslint-plugin-jasmine": "^4.0.0",
|
|
37
37
|
"eslint-plugin-jest": "^28.0.0",
|
|
38
38
|
"eslint-plugin-jest-dom": "^5.0.0",
|
|
39
|
-
"eslint-plugin-jest-extended": "^
|
|
39
|
+
"eslint-plugin-jest-extended": "^3.0.0",
|
|
40
40
|
"eslint-plugin-jest-formatting": "^3.0.0",
|
|
41
41
|
"eslint-plugin-jsdoc": "^50.0.0",
|
|
42
42
|
"eslint-plugin-jsonc": "^2.0.0",
|
|
43
43
|
"eslint-plugin-jsx-a11y": "^6.0.0",
|
|
44
|
-
"eslint-plugin-lit": "^1.
|
|
44
|
+
"eslint-plugin-lit": "^2.1.1",
|
|
45
45
|
"eslint-plugin-lodash": "^8.0.0",
|
|
46
46
|
"eslint-plugin-lodash-fp": "^2.0.0",
|
|
47
47
|
"eslint-plugin-meteor": "^7.0.0",
|
|
48
|
-
"eslint-plugin-mocha": "^
|
|
48
|
+
"eslint-plugin-mocha": "^11.0.0",
|
|
49
49
|
"eslint-plugin-n": "^17.0.0",
|
|
50
50
|
"eslint-plugin-nuxt": "^4.0.0",
|
|
51
51
|
"eslint-plugin-perfectionist": "^4.0.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"eslint-plugin-prettier": "^5.0.0",
|
|
54
54
|
"eslint-plugin-promise": "^7.0.0",
|
|
55
55
|
"eslint-plugin-react": "^7.0.0",
|
|
56
|
-
"eslint-plugin-react-hooks": "^
|
|
56
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
57
57
|
"eslint-plugin-react-perf": "^3.0.0",
|
|
58
58
|
"eslint-plugin-react-redux": "^4.0.0",
|
|
59
59
|
"eslint-plugin-redux-saga": "^1.0.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"eslint-plugin-security": "^3.0.0",
|
|
62
62
|
"eslint-plugin-security-node": "^1.0.0",
|
|
63
63
|
"eslint-plugin-sonarjs": "^3.0.0",
|
|
64
|
-
"eslint-plugin-sort": "^
|
|
64
|
+
"eslint-plugin-sort": "^4.0.0",
|
|
65
65
|
"eslint-plugin-sort-destructure-keys": "^2.0.0",
|
|
66
66
|
"eslint-plugin-storybook": "^0.11.0",
|
|
67
67
|
"eslint-plugin-suitescript": "^1.0.0",
|
|
@@ -70,16 +70,16 @@
|
|
|
70
70
|
"eslint-plugin-test-selectors": "^2.0.0",
|
|
71
71
|
"eslint-plugin-testing-library": "^7.0.0",
|
|
72
72
|
"eslint-plugin-typescript-sort-keys": "^3.0.0",
|
|
73
|
-
"eslint-plugin-unicorn": "^
|
|
73
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
74
74
|
"eslint-plugin-unused-imports": "^4.0.0",
|
|
75
|
-
"eslint-plugin-vue": "^
|
|
75
|
+
"eslint-plugin-vue": "^10.1.0",
|
|
76
76
|
"eslint-plugin-vue-scoped-css": "^2.0.0",
|
|
77
77
|
"eslint-plugin-vuejs-accessibility": "^2.0.0",
|
|
78
78
|
"eslint-plugin-vuetify": "^2.0.0",
|
|
79
79
|
"eslint-plugin-wdio": "^9.0.0",
|
|
80
80
|
"eslint-plugin-xss": "^0.1.0",
|
|
81
81
|
"eslint-plugin-yml": "^1.0.0",
|
|
82
|
-
"@codacy/tooling": "0.6.
|
|
82
|
+
"@codacy/tooling": "0.6.2"
|
|
83
83
|
},
|
|
84
84
|
"license": "MIT",
|
|
85
85
|
"author": "Codacy <support@codacy.com> (https://www.codacy.com)",
|