@code-pushup/eslint-plugin 0.54.0 → 0.56.0
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/bin.js +47 -71
- package/index.js +292 -145
- package/package.json +5 -5
- package/src/lib/config.d.ts +19 -20
- package/src/lib/meta/groups.d.ts +1 -1
- package/src/lib/meta/index.d.ts +1 -0
- package/src/lib/meta/parse.d.ts +12 -0
- package/src/lib/meta/rules.d.ts +1 -10
- package/src/lib/meta/transform.d.ts +1 -1
- package/src/lib/meta/versions/detect.d.ts +2 -0
- package/src/lib/meta/versions/flat.d.ts +3 -0
- package/src/lib/meta/versions/formats.d.ts +1 -0
- package/src/lib/meta/versions/index.d.ts +6 -0
- package/src/lib/meta/versions/legacy.d.ts +3 -0
- package/src/lib/nx/utils.d.ts +4 -3
- package/src/lib/setup.d.ts +1 -1
package/bin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// packages/plugin-eslint/src/lib/runner/index.ts
|
|
2
|
-
import { writeFile
|
|
3
|
-
import { dirname, join as
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// packages/models/src/lib/implementation/schemas.ts
|
|
6
6
|
import { MATERIAL_ICONS } from "vscode-material-icons";
|
|
@@ -33,7 +33,7 @@ function exists(value) {
|
|
|
33
33
|
return value != null;
|
|
34
34
|
}
|
|
35
35
|
function getMissingRefsForCategories(categories, plugins) {
|
|
36
|
-
if (categories.length === 0) {
|
|
36
|
+
if (!categories || categories.length === 0) {
|
|
37
37
|
return false;
|
|
38
38
|
}
|
|
39
39
|
const auditRefsFromCategory = categories.flatMap(
|
|
@@ -532,12 +532,9 @@ var unrefinedCoreConfigSchema = z14.object({
|
|
|
532
532
|
var coreConfigSchema = refineCoreConfig(unrefinedCoreConfigSchema);
|
|
533
533
|
function refineCoreConfig(schema) {
|
|
534
534
|
return schema.refine(
|
|
535
|
-
(
|
|
536
|
-
(
|
|
537
|
-
message: missingRefsForCategoriesErrorMsg(
|
|
538
|
-
coreCfg.categories ?? [],
|
|
539
|
-
coreCfg.plugins
|
|
540
|
-
)
|
|
535
|
+
({ categories, plugins }) => !getMissingRefsForCategories(categories, plugins),
|
|
536
|
+
({ categories, plugins }) => ({
|
|
537
|
+
message: missingRefsForCategoriesErrorMsg(categories, plugins)
|
|
541
538
|
})
|
|
542
539
|
);
|
|
543
540
|
}
|
|
@@ -589,19 +586,16 @@ var reportSchema = packageVersionSchema({
|
|
|
589
586
|
).merge(
|
|
590
587
|
z15.object(
|
|
591
588
|
{
|
|
592
|
-
categories: z15.array(categoryConfigSchema),
|
|
593
589
|
plugins: z15.array(pluginReportSchema).min(1),
|
|
590
|
+
categories: z15.array(categoryConfigSchema).optional(),
|
|
594
591
|
commit: commitSchema.describe("Git commit for which report was collected").nullable()
|
|
595
592
|
},
|
|
596
593
|
{ description: "Collect output data" }
|
|
597
594
|
)
|
|
598
595
|
).refine(
|
|
599
|
-
(
|
|
600
|
-
(
|
|
601
|
-
message: missingRefsForCategoriesErrorMsg(
|
|
602
|
-
report.categories,
|
|
603
|
-
report.plugins
|
|
604
|
-
)
|
|
596
|
+
({ categories, plugins }) => !getMissingRefsForCategories(categories, plugins),
|
|
597
|
+
({ categories, plugins }) => ({
|
|
598
|
+
message: missingRefsForCategoriesErrorMsg(categories, plugins)
|
|
605
599
|
})
|
|
606
600
|
);
|
|
607
601
|
|
|
@@ -780,7 +774,7 @@ function executeProcess(cfg) {
|
|
|
780
774
|
import { bold, gray } from "ansis";
|
|
781
775
|
import { bundleRequire } from "bundle-require";
|
|
782
776
|
import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
783
|
-
import { join } from "node:path";
|
|
777
|
+
import { dirname, join } from "node:path";
|
|
784
778
|
|
|
785
779
|
// packages/utils/src/lib/formatting.ts
|
|
786
780
|
function slugify(text) {
|
|
@@ -934,22 +928,24 @@ import { MarkdownDocument as MarkdownDocument4, md as md5 } from "build-md";
|
|
|
934
928
|
import { bold as bold4, cyan, cyanBright, green as green2, red } from "ansis";
|
|
935
929
|
|
|
936
930
|
// packages/plugin-eslint/src/lib/runner/lint.ts
|
|
937
|
-
import { rm as rm2, writeFile } from "node:fs/promises";
|
|
938
931
|
import { platform } from "node:os";
|
|
939
|
-
import { join as join2 } from "node:path";
|
|
940
932
|
|
|
941
933
|
// packages/plugin-eslint/src/lib/setup.ts
|
|
942
934
|
import { ESLint } from "eslint";
|
|
943
|
-
function setupESLint(eslintrc) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
baseConfig: eslintrc,
|
|
948
|
-
useEslintrc: false
|
|
949
|
-
},
|
|
935
|
+
async function setupESLint(eslintrc) {
|
|
936
|
+
const eslintConstructor = await loadESLint();
|
|
937
|
+
return new eslintConstructor({
|
|
938
|
+
overrideConfigFile: eslintrc,
|
|
950
939
|
errorOnUnmatchedPattern: false
|
|
951
940
|
});
|
|
952
941
|
}
|
|
942
|
+
async function loadESLint() {
|
|
943
|
+
const eslint = await import("eslint");
|
|
944
|
+
if ("loadESLint" in eslint && typeof eslint.loadESLint === "function") {
|
|
945
|
+
return await eslint.loadESLint();
|
|
946
|
+
}
|
|
947
|
+
return ESLint;
|
|
948
|
+
}
|
|
953
949
|
|
|
954
950
|
// packages/plugin-eslint/src/lib/runner/lint.ts
|
|
955
951
|
async function lint({
|
|
@@ -957,37 +953,35 @@ async function lint({
|
|
|
957
953
|
patterns
|
|
958
954
|
}) {
|
|
959
955
|
const results = await executeLint({ eslintrc, patterns });
|
|
960
|
-
const
|
|
956
|
+
const eslint = await setupESLint(eslintrc);
|
|
957
|
+
const ruleOptionsPerFile = await loadRuleOptionsPerFile(eslint, results);
|
|
961
958
|
return { results, ruleOptionsPerFile };
|
|
962
959
|
}
|
|
963
|
-
function executeLint({
|
|
960
|
+
async function executeLint({
|
|
964
961
|
eslintrc,
|
|
965
962
|
patterns
|
|
966
963
|
}) {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
platform() === "win32" ? pattern : `'${pattern}'`
|
|
980
|
-
)
|
|
964
|
+
const { stdout } = await executeProcess({
|
|
965
|
+
command: "npx",
|
|
966
|
+
args: [
|
|
967
|
+
"eslint",
|
|
968
|
+
...eslintrc ? [`--config=${filePathToCliArg(eslintrc)}`] : [],
|
|
969
|
+
...typeof eslintrc === "object" ? ["--no-eslintrc"] : [],
|
|
970
|
+
"--no-error-on-unmatched-pattern",
|
|
971
|
+
"--format=json",
|
|
972
|
+
...toArray(patterns).map(
|
|
973
|
+
(pattern) => (
|
|
974
|
+
// globs need to be escaped on Unix
|
|
975
|
+
platform() === "win32" ? pattern : `'${pattern}'`
|
|
981
976
|
)
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
return JSON.parse(stdout);
|
|
977
|
+
)
|
|
978
|
+
],
|
|
979
|
+
ignoreExitCode: true,
|
|
980
|
+
cwd: process.cwd()
|
|
987
981
|
});
|
|
982
|
+
return JSON.parse(stdout);
|
|
988
983
|
}
|
|
989
|
-
function loadRuleOptionsPerFile(
|
|
990
|
-
const eslint = setupESLint(eslintrc);
|
|
984
|
+
function loadRuleOptionsPerFile(eslint, results) {
|
|
991
985
|
return results.reduce(async (acc, { filePath, messages }) => {
|
|
992
986
|
const filesMap = await acc;
|
|
993
987
|
const config = await eslint.calculateConfigForFile(
|
|
@@ -1011,24 +1005,6 @@ function loadRuleOptionsPerFile(eslintrc, results) {
|
|
|
1011
1005
|
};
|
|
1012
1006
|
}, Promise.resolve({}));
|
|
1013
1007
|
}
|
|
1014
|
-
async function withConfig(eslintrc, fn) {
|
|
1015
|
-
if (typeof eslintrc !== "object") {
|
|
1016
|
-
return fn(eslintrc);
|
|
1017
|
-
}
|
|
1018
|
-
const configPath = generateTempConfigPath();
|
|
1019
|
-
await writeFile(configPath, JSON.stringify(eslintrc));
|
|
1020
|
-
try {
|
|
1021
|
-
return await fn(configPath);
|
|
1022
|
-
} finally {
|
|
1023
|
-
await rm2(configPath);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
function generateTempConfigPath() {
|
|
1027
|
-
return join2(
|
|
1028
|
-
process.cwd(),
|
|
1029
|
-
`.eslintrc.${Math.random().toString().slice(2)}.json`
|
|
1030
|
-
);
|
|
1031
|
-
}
|
|
1032
1008
|
|
|
1033
1009
|
// packages/plugin-eslint/src/lib/meta/hash.ts
|
|
1034
1010
|
import { createHash } from "node:crypto";
|
|
@@ -1122,8 +1098,8 @@ function convertSeverity(severity) {
|
|
|
1122
1098
|
|
|
1123
1099
|
// packages/plugin-eslint/src/lib/runner/index.ts
|
|
1124
1100
|
var WORKDIR = pluginWorkDir("eslint");
|
|
1125
|
-
var RUNNER_OUTPUT_PATH =
|
|
1126
|
-
var PLUGIN_CONFIG_PATH =
|
|
1101
|
+
var RUNNER_OUTPUT_PATH = join2(WORKDIR, "runner-output.json");
|
|
1102
|
+
var PLUGIN_CONFIG_PATH = join2(
|
|
1127
1103
|
process.cwd(),
|
|
1128
1104
|
WORKDIR,
|
|
1129
1105
|
"plugin-config.json"
|
|
@@ -1145,8 +1121,8 @@ async function executeRunner() {
|
|
|
1145
1121
|
details: { issues: [] }
|
|
1146
1122
|
}
|
|
1147
1123
|
);
|
|
1148
|
-
await ensureDirectoryExists(
|
|
1149
|
-
await
|
|
1124
|
+
await ensureDirectoryExists(dirname2(RUNNER_OUTPUT_PATH));
|
|
1125
|
+
await writeFile(RUNNER_OUTPUT_PATH, JSON.stringify(audits));
|
|
1150
1126
|
}
|
|
1151
1127
|
|
|
1152
1128
|
// packages/plugin-eslint/src/bin.ts
|
package/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// packages/plugin-eslint/src/lib/eslint-plugin.ts
|
|
2
|
-
import { dirname as
|
|
2
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
|
|
5
5
|
// packages/plugin-eslint/package.json
|
|
6
6
|
var name = "@code-pushup/eslint-plugin";
|
|
7
|
-
var version = "0.
|
|
7
|
+
var version = "0.56.0";
|
|
8
8
|
|
|
9
9
|
// packages/plugin-eslint/src/lib/config.ts
|
|
10
10
|
import { z as z17 } from "zod";
|
|
@@ -40,7 +40,7 @@ function exists(value) {
|
|
|
40
40
|
return value != null;
|
|
41
41
|
}
|
|
42
42
|
function getMissingRefsForCategories(categories, plugins) {
|
|
43
|
-
if (categories.length === 0) {
|
|
43
|
+
if (!categories || categories.length === 0) {
|
|
44
44
|
return false;
|
|
45
45
|
}
|
|
46
46
|
const auditRefsFromCategory = categories.flatMap(
|
|
@@ -539,12 +539,9 @@ var unrefinedCoreConfigSchema = z14.object({
|
|
|
539
539
|
var coreConfigSchema = refineCoreConfig(unrefinedCoreConfigSchema);
|
|
540
540
|
function refineCoreConfig(schema) {
|
|
541
541
|
return schema.refine(
|
|
542
|
-
(
|
|
543
|
-
(
|
|
544
|
-
message: missingRefsForCategoriesErrorMsg(
|
|
545
|
-
coreCfg.categories ?? [],
|
|
546
|
-
coreCfg.plugins
|
|
547
|
-
)
|
|
542
|
+
({ categories, plugins }) => !getMissingRefsForCategories(categories, plugins),
|
|
543
|
+
({ categories, plugins }) => ({
|
|
544
|
+
message: missingRefsForCategoriesErrorMsg(categories, plugins)
|
|
548
545
|
})
|
|
549
546
|
);
|
|
550
547
|
}
|
|
@@ -596,19 +593,16 @@ var reportSchema = packageVersionSchema({
|
|
|
596
593
|
).merge(
|
|
597
594
|
z15.object(
|
|
598
595
|
{
|
|
599
|
-
categories: z15.array(categoryConfigSchema),
|
|
600
596
|
plugins: z15.array(pluginReportSchema).min(1),
|
|
597
|
+
categories: z15.array(categoryConfigSchema).optional(),
|
|
601
598
|
commit: commitSchema.describe("Git commit for which report was collected").nullable()
|
|
602
599
|
},
|
|
603
600
|
{ description: "Collect output data" }
|
|
604
601
|
)
|
|
605
602
|
).refine(
|
|
606
|
-
(
|
|
607
|
-
(
|
|
608
|
-
message: missingRefsForCategoriesErrorMsg(
|
|
609
|
-
report.categories,
|
|
610
|
-
report.plugins
|
|
611
|
-
)
|
|
603
|
+
({ categories, plugins }) => !getMissingRefsForCategories(categories, plugins),
|
|
604
|
+
({ categories, plugins }) => ({
|
|
605
|
+
message: missingRefsForCategoriesErrorMsg(categories, plugins)
|
|
612
606
|
})
|
|
613
607
|
);
|
|
614
608
|
|
|
@@ -719,7 +713,7 @@ var TERMINAL_WIDTH = 80;
|
|
|
719
713
|
import { bold, gray } from "ansis";
|
|
720
714
|
import { bundleRequire } from "bundle-require";
|
|
721
715
|
import { mkdir, readFile, readdir, rm, stat } from "node:fs/promises";
|
|
722
|
-
import { join } from "node:path";
|
|
716
|
+
import { dirname, join } from "node:path";
|
|
723
717
|
|
|
724
718
|
// packages/utils/src/lib/formatting.ts
|
|
725
719
|
function slugify(text) {
|
|
@@ -802,6 +796,16 @@ async function ensureDirectoryExists(baseDir) {
|
|
|
802
796
|
function pluginWorkDir(slug) {
|
|
803
797
|
return join("node_modules", ".code-pushup", slug);
|
|
804
798
|
}
|
|
799
|
+
async function findNearestFile(fileNames, cwd = process.cwd()) {
|
|
800
|
+
for (let directory = cwd; directory !== dirname(directory); directory = dirname(directory)) {
|
|
801
|
+
for (const file of fileNames) {
|
|
802
|
+
if (await fileExists(join(directory, file))) {
|
|
803
|
+
return join(directory, file);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return void 0;
|
|
808
|
+
}
|
|
805
809
|
function filePathToCliArg(path) {
|
|
806
810
|
return `"${path}"`;
|
|
807
811
|
}
|
|
@@ -858,15 +862,7 @@ import { bold as bold4, cyan, cyanBright, green as green2, red } from "ansis";
|
|
|
858
862
|
var patternsSchema = z17.union([z17.string(), z17.array(z17.string()).min(1)], {
|
|
859
863
|
description: "Lint target files. May contain file paths, directory paths or glob patterns"
|
|
860
864
|
});
|
|
861
|
-
var eslintrcSchema = z17.
|
|
862
|
-
[
|
|
863
|
-
z17.string({ description: "Path to ESLint config file" }),
|
|
864
|
-
z17.record(z17.string(), z17.unknown(), {
|
|
865
|
-
description: "ESLint config object"
|
|
866
|
-
})
|
|
867
|
-
],
|
|
868
|
-
{ description: "ESLint config as file path or inline object" }
|
|
869
|
-
);
|
|
865
|
+
var eslintrcSchema = z17.string({ description: "Path to ESLint config file" });
|
|
870
866
|
var eslintTargetObjectSchema = z17.object({
|
|
871
867
|
eslintrc: eslintrcSchema.optional(),
|
|
872
868
|
patterns: patternsSchema
|
|
@@ -889,80 +885,16 @@ function jsonHash(data, bytes = 8) {
|
|
|
889
885
|
return createHash("shake256", { outputLength: bytes }).update(JSON.stringify(data) || "null").digest("hex");
|
|
890
886
|
}
|
|
891
887
|
|
|
892
|
-
// packages/plugin-eslint/src/lib/
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
});
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// packages/plugin-eslint/src/lib/meta/rules.ts
|
|
906
|
-
async function listRules(targets) {
|
|
907
|
-
const rulesMap = await targets.reduce(async (acc, { eslintrc, patterns }) => {
|
|
908
|
-
const eslint = setupESLint(eslintrc);
|
|
909
|
-
const prev = await acc;
|
|
910
|
-
const curr = await loadRulesMap(eslint, patterns);
|
|
911
|
-
return mergeRulesMaps(prev, curr);
|
|
912
|
-
}, Promise.resolve({}));
|
|
913
|
-
return Object.values(rulesMap).flatMap(Object.values);
|
|
914
|
-
}
|
|
915
|
-
async function loadRulesMap(eslint, patterns) {
|
|
916
|
-
const configs = await toArray(patterns).reduce(
|
|
917
|
-
async (acc, pattern) => [
|
|
918
|
-
...await acc,
|
|
919
|
-
await eslint.calculateConfigForFile(pattern)
|
|
920
|
-
],
|
|
921
|
-
Promise.resolve([])
|
|
922
|
-
);
|
|
923
|
-
const rulesIds = distinct(
|
|
924
|
-
configs.flatMap((config) => Object.keys(config.rules ?? {}))
|
|
925
|
-
);
|
|
926
|
-
const rulesMeta = eslint.getRulesMetaForResults([
|
|
927
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
928
|
-
{
|
|
929
|
-
messages: rulesIds.map((ruleId) => ({ ruleId })),
|
|
930
|
-
suppressedMessages: []
|
|
931
|
-
}
|
|
932
|
-
]);
|
|
933
|
-
return configs.flatMap((config) => Object.entries(config.rules ?? {})).filter(([, ruleEntry]) => ruleEntry != null && !isRuleOff(ruleEntry)).reduce((acc, [ruleId, ruleEntry]) => {
|
|
934
|
-
const meta = rulesMeta[ruleId];
|
|
935
|
-
if (!meta) {
|
|
936
|
-
ui().logger.warning(`Metadata not found for ESLint rule ${ruleId}`);
|
|
937
|
-
return acc;
|
|
938
|
-
}
|
|
939
|
-
const options = toArray(ruleEntry).slice(1);
|
|
940
|
-
const optionsHash = jsonHash(options);
|
|
941
|
-
const ruleData = {
|
|
942
|
-
ruleId,
|
|
943
|
-
meta,
|
|
944
|
-
options
|
|
945
|
-
};
|
|
946
|
-
return {
|
|
947
|
-
...acc,
|
|
948
|
-
[ruleId]: {
|
|
949
|
-
...acc[ruleId],
|
|
950
|
-
[optionsHash]: ruleData
|
|
951
|
-
}
|
|
952
|
-
};
|
|
953
|
-
}, {});
|
|
954
|
-
}
|
|
955
|
-
function mergeRulesMaps(prev, curr) {
|
|
956
|
-
return Object.entries(curr).reduce(
|
|
957
|
-
(acc, [ruleId, ruleVariants]) => ({
|
|
958
|
-
...acc,
|
|
959
|
-
[ruleId]: {
|
|
960
|
-
...acc[ruleId],
|
|
961
|
-
...ruleVariants
|
|
962
|
-
}
|
|
963
|
-
}),
|
|
964
|
-
prev
|
|
965
|
-
);
|
|
888
|
+
// packages/plugin-eslint/src/lib/meta/parse.ts
|
|
889
|
+
function parseRuleId(ruleId) {
|
|
890
|
+
const i = ruleId.lastIndexOf("/");
|
|
891
|
+
if (i < 0) {
|
|
892
|
+
return { name: ruleId };
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
plugin: ruleId.slice(0, i),
|
|
896
|
+
name: ruleId.slice(i + 1)
|
|
897
|
+
};
|
|
966
898
|
}
|
|
967
899
|
function isRuleOff(entry) {
|
|
968
900
|
const level = Array.isArray(entry) ? entry[0] : entry;
|
|
@@ -977,15 +909,8 @@ function isRuleOff(entry) {
|
|
|
977
909
|
return false;
|
|
978
910
|
}
|
|
979
911
|
}
|
|
980
|
-
function
|
|
981
|
-
|
|
982
|
-
if (i < 0) {
|
|
983
|
-
return { name: ruleId };
|
|
984
|
-
}
|
|
985
|
-
return {
|
|
986
|
-
plugin: ruleId.slice(0, i),
|
|
987
|
-
name: ruleId.slice(i + 1)
|
|
988
|
-
};
|
|
912
|
+
function optionsFromRuleEntry(entry) {
|
|
913
|
+
return toArray(entry).slice(1);
|
|
989
914
|
}
|
|
990
915
|
|
|
991
916
|
// packages/plugin-eslint/src/lib/meta/groups.ts
|
|
@@ -1053,6 +978,191 @@ function groupsFromRuleCategories(rules) {
|
|
|
1053
978
|
return groups.toSorted((a, b) => a.slug.localeCompare(b.slug));
|
|
1054
979
|
}
|
|
1055
980
|
|
|
981
|
+
// packages/plugin-eslint/src/lib/meta/versions/flat.ts
|
|
982
|
+
import { builtinRules } from "eslint/use-at-your-own-risk";
|
|
983
|
+
import { isAbsolute, join as join2 } from "node:path";
|
|
984
|
+
import { pathToFileURL } from "node:url";
|
|
985
|
+
async function loadRulesForFlatConfig({
|
|
986
|
+
eslintrc
|
|
987
|
+
}) {
|
|
988
|
+
const config = eslintrc ? await loadConfigByPath(eslintrc) : await loadConfigByDefaultLocation();
|
|
989
|
+
const configs = toArray(config);
|
|
990
|
+
const rules = findEnabledRulesWithOptions(configs);
|
|
991
|
+
return rules.map((rule) => {
|
|
992
|
+
const meta = findRuleMeta(rule.ruleId, configs);
|
|
993
|
+
if (!meta) {
|
|
994
|
+
ui().logger.warning(`Cannot find metadata for rule ${rule.ruleId}`);
|
|
995
|
+
return null;
|
|
996
|
+
}
|
|
997
|
+
return { ...rule, meta };
|
|
998
|
+
}).filter(exists);
|
|
999
|
+
}
|
|
1000
|
+
async function loadConfigByDefaultLocation() {
|
|
1001
|
+
const flatConfigFileNames = [
|
|
1002
|
+
"eslint.config.js",
|
|
1003
|
+
"eslint.config.mjs",
|
|
1004
|
+
"eslint.config.cjs"
|
|
1005
|
+
];
|
|
1006
|
+
const configPath = await findNearestFile(flatConfigFileNames);
|
|
1007
|
+
if (configPath) {
|
|
1008
|
+
return loadConfigByPath(configPath);
|
|
1009
|
+
}
|
|
1010
|
+
throw new Error(
|
|
1011
|
+
[
|
|
1012
|
+
`ESLint config file not found - expected ${flatConfigFileNames.join("/")} in ${process.cwd()} or some parent directory`,
|
|
1013
|
+
"If your ESLint config is in a non-standard location, use the `eslintrc` parameter to specify the path."
|
|
1014
|
+
].join("\n")
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
async function loadConfigByPath(path) {
|
|
1018
|
+
const absolutePath = isAbsolute(path) ? path : join2(process.cwd(), path);
|
|
1019
|
+
const url = pathToFileURL(absolutePath).toString();
|
|
1020
|
+
const mod = await import(url);
|
|
1021
|
+
return "default" in mod ? mod.default : mod;
|
|
1022
|
+
}
|
|
1023
|
+
function findEnabledRulesWithOptions(configs) {
|
|
1024
|
+
const enabledRules = configs.flatMap(({ rules }) => Object.entries(rules ?? {})).filter(([, entry]) => entry != null && !isRuleOff(entry)).map(([ruleId, entry]) => ({
|
|
1025
|
+
ruleId,
|
|
1026
|
+
options: entry ? optionsFromRuleEntry(entry) : []
|
|
1027
|
+
}));
|
|
1028
|
+
const uniqueRulesMap = new Map(
|
|
1029
|
+
enabledRules.map(({ ruleId, options }) => [
|
|
1030
|
+
`${ruleId}::${jsonHash(options)}`,
|
|
1031
|
+
{ ruleId, options }
|
|
1032
|
+
])
|
|
1033
|
+
);
|
|
1034
|
+
return [...uniqueRulesMap.values()];
|
|
1035
|
+
}
|
|
1036
|
+
function findRuleMeta(ruleId, configs) {
|
|
1037
|
+
const { plugin, name: name2 } = parseRuleId(ruleId);
|
|
1038
|
+
if (!plugin) {
|
|
1039
|
+
return findBuiltinRuleMeta(name2);
|
|
1040
|
+
}
|
|
1041
|
+
return findPluginRuleMeta(plugin, name2, configs);
|
|
1042
|
+
}
|
|
1043
|
+
function findBuiltinRuleMeta(name2) {
|
|
1044
|
+
const rule = builtinRules.get(name2);
|
|
1045
|
+
return rule?.meta;
|
|
1046
|
+
}
|
|
1047
|
+
function findPluginRuleMeta(plugin, name2, configs) {
|
|
1048
|
+
const config = configs.find(({ plugins = {} }) => plugin in plugins);
|
|
1049
|
+
const rule = config?.plugins?.[plugin]?.rules?.[name2];
|
|
1050
|
+
if (typeof rule === "function") {
|
|
1051
|
+
ui().logger.warning(
|
|
1052
|
+
`Cannot parse metadata for rule ${plugin}/${name2}, plugin registers it as a function`
|
|
1053
|
+
);
|
|
1054
|
+
return void 0;
|
|
1055
|
+
}
|
|
1056
|
+
return rule?.meta;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// packages/plugin-eslint/src/lib/setup.ts
|
|
1060
|
+
import { ESLint } from "eslint";
|
|
1061
|
+
async function setupESLint(eslintrc) {
|
|
1062
|
+
const eslintConstructor = await loadESLint();
|
|
1063
|
+
return new eslintConstructor({
|
|
1064
|
+
overrideConfigFile: eslintrc,
|
|
1065
|
+
errorOnUnmatchedPattern: false
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
async function loadESLint() {
|
|
1069
|
+
const eslint = await import("eslint");
|
|
1070
|
+
if ("loadESLint" in eslint && typeof eslint.loadESLint === "function") {
|
|
1071
|
+
return await eslint.loadESLint();
|
|
1072
|
+
}
|
|
1073
|
+
return ESLint;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// packages/plugin-eslint/src/lib/meta/versions/legacy.ts
|
|
1077
|
+
async function loadRulesForLegacyConfig({
|
|
1078
|
+
eslintrc,
|
|
1079
|
+
patterns
|
|
1080
|
+
}) {
|
|
1081
|
+
const eslint = await setupESLint(eslintrc);
|
|
1082
|
+
const configs = await toArray(patterns).reduce(
|
|
1083
|
+
async (acc, pattern) => [
|
|
1084
|
+
...await acc,
|
|
1085
|
+
await eslint.calculateConfigForFile(pattern)
|
|
1086
|
+
],
|
|
1087
|
+
Promise.resolve([])
|
|
1088
|
+
);
|
|
1089
|
+
const rulesIds = distinct(
|
|
1090
|
+
configs.flatMap((config) => Object.keys(config.rules ?? {}))
|
|
1091
|
+
);
|
|
1092
|
+
const rulesMeta = eslint.getRulesMetaForResults([
|
|
1093
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1094
|
+
{
|
|
1095
|
+
messages: rulesIds.map((ruleId) => ({ ruleId })),
|
|
1096
|
+
suppressedMessages: []
|
|
1097
|
+
}
|
|
1098
|
+
]);
|
|
1099
|
+
return configs.flatMap((config) => Object.entries(config.rules ?? {})).map(([ruleId, ruleEntry]) => {
|
|
1100
|
+
if (ruleEntry == null || isRuleOff(ruleEntry)) {
|
|
1101
|
+
return null;
|
|
1102
|
+
}
|
|
1103
|
+
const meta = rulesMeta[ruleId];
|
|
1104
|
+
if (!meta) {
|
|
1105
|
+
ui().logger.warning(`Metadata not found for ESLint rule ${ruleId}`);
|
|
1106
|
+
return null;
|
|
1107
|
+
}
|
|
1108
|
+
const options = optionsFromRuleEntry(ruleEntry);
|
|
1109
|
+
return {
|
|
1110
|
+
ruleId,
|
|
1111
|
+
meta,
|
|
1112
|
+
options
|
|
1113
|
+
};
|
|
1114
|
+
}).filter(exists);
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// packages/plugin-eslint/src/lib/meta/versions/detect.ts
|
|
1118
|
+
import { ESLint as ESLint2 } from "eslint";
|
|
1119
|
+
async function detectConfigVersion() {
|
|
1120
|
+
if (process.env["ESLINT_USE_FLAT_CONFIG"] === "true") {
|
|
1121
|
+
return "flat";
|
|
1122
|
+
}
|
|
1123
|
+
if (process.env["ESLINT_USE_FLAT_CONFIG"] === "false") {
|
|
1124
|
+
return "legacy";
|
|
1125
|
+
}
|
|
1126
|
+
if (ESLint2.version.startsWith("8.")) {
|
|
1127
|
+
if (await fileExists("eslint.config.js")) {
|
|
1128
|
+
return "flat";
|
|
1129
|
+
}
|
|
1130
|
+
return "legacy";
|
|
1131
|
+
}
|
|
1132
|
+
return "flat";
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// packages/plugin-eslint/src/lib/meta/versions/index.ts
|
|
1136
|
+
function selectRulesLoader(version2) {
|
|
1137
|
+
switch (version2) {
|
|
1138
|
+
case "flat":
|
|
1139
|
+
return loadRulesForFlatConfig;
|
|
1140
|
+
case "legacy":
|
|
1141
|
+
return loadRulesForLegacyConfig;
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
// packages/plugin-eslint/src/lib/meta/rules.ts
|
|
1146
|
+
async function listRules(targets) {
|
|
1147
|
+
const version2 = await detectConfigVersion();
|
|
1148
|
+
const loadRulesMap = selectRulesLoader(version2);
|
|
1149
|
+
const rulesMap = await targets.reduce(async (acc, target) => {
|
|
1150
|
+
const map = await acc;
|
|
1151
|
+
const rules = await loadRulesMap(target);
|
|
1152
|
+
return rules.reduce(mergeRuleIntoMap, map);
|
|
1153
|
+
}, Promise.resolve({}));
|
|
1154
|
+
return Object.values(rulesMap).flatMap(Object.values);
|
|
1155
|
+
}
|
|
1156
|
+
function mergeRuleIntoMap(map, rule) {
|
|
1157
|
+
return {
|
|
1158
|
+
...map,
|
|
1159
|
+
[rule.ruleId]: {
|
|
1160
|
+
...map[rule.ruleId],
|
|
1161
|
+
[jsonHash(rule.options)]: rule
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1056
1166
|
// packages/plugin-eslint/src/lib/meta/transform.ts
|
|
1057
1167
|
function ruleToAudit({ ruleId, meta, options }) {
|
|
1058
1168
|
const name2 = ruleId.split("/").at(-1) ?? ruleId;
|
|
@@ -1088,10 +1198,10 @@ async function listAuditsAndGroups(targets) {
|
|
|
1088
1198
|
|
|
1089
1199
|
// packages/plugin-eslint/src/lib/runner/index.ts
|
|
1090
1200
|
import { writeFile } from "node:fs/promises";
|
|
1091
|
-
import { dirname, join as
|
|
1201
|
+
import { dirname as dirname2, join as join3 } from "node:path";
|
|
1092
1202
|
var WORKDIR = pluginWorkDir("eslint");
|
|
1093
|
-
var RUNNER_OUTPUT_PATH =
|
|
1094
|
-
var PLUGIN_CONFIG_PATH =
|
|
1203
|
+
var RUNNER_OUTPUT_PATH = join3(WORKDIR, "runner-output.json");
|
|
1204
|
+
var PLUGIN_CONFIG_PATH = join3(
|
|
1095
1205
|
process.cwd(),
|
|
1096
1206
|
WORKDIR,
|
|
1097
1207
|
"plugin-config.json"
|
|
@@ -1101,7 +1211,7 @@ async function createRunnerConfig(scriptPath, audits, targets) {
|
|
|
1101
1211
|
targets,
|
|
1102
1212
|
slugs: audits.map((audit) => audit.slug)
|
|
1103
1213
|
};
|
|
1104
|
-
await ensureDirectoryExists(
|
|
1214
|
+
await ensureDirectoryExists(dirname2(PLUGIN_CONFIG_PATH));
|
|
1105
1215
|
await writeFile(PLUGIN_CONFIG_PATH, JSON.stringify(config));
|
|
1106
1216
|
return {
|
|
1107
1217
|
command: "node",
|
|
@@ -1114,8 +1224,8 @@ async function createRunnerConfig(scriptPath, audits, targets) {
|
|
|
1114
1224
|
async function eslintPlugin(config) {
|
|
1115
1225
|
const targets = eslintPluginConfigSchema.parse(config);
|
|
1116
1226
|
const { audits, groups } = await listAuditsAndGroups(targets);
|
|
1117
|
-
const runnerScriptPath =
|
|
1118
|
-
fileURLToPath(
|
|
1227
|
+
const runnerScriptPath = join4(
|
|
1228
|
+
fileURLToPath(dirname3(import.meta.url)),
|
|
1119
1229
|
"bin.js"
|
|
1120
1230
|
);
|
|
1121
1231
|
return {
|
|
@@ -1152,25 +1262,74 @@ function filterProjectGraph(projectGraph, exclude = []) {
|
|
|
1152
1262
|
}
|
|
1153
1263
|
|
|
1154
1264
|
// packages/plugin-eslint/src/lib/nx/utils.ts
|
|
1155
|
-
import { join as
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1265
|
+
import { join as join5 } from "node:path";
|
|
1266
|
+
var ESLINT_CONFIG_EXTENSIONS = {
|
|
1267
|
+
// https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file-formats
|
|
1268
|
+
flat: ["js", "mjs", "cjs"],
|
|
1269
|
+
// https://eslint.org/docs/latest/use/configure/configuration-files-deprecated
|
|
1270
|
+
legacy: ["json", "js", "cjs", "yml", "yaml"]
|
|
1271
|
+
};
|
|
1272
|
+
var ESLINT_CONFIG_NAMES = {
|
|
1273
|
+
// https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file-formats
|
|
1274
|
+
flat: ["eslint.config"],
|
|
1275
|
+
// https://eslint.org/docs/latest/use/configure/configuration-files-deprecated
|
|
1276
|
+
legacy: [".eslintrc"]
|
|
1277
|
+
};
|
|
1278
|
+
var CP_ESLINT_CONFIG_NAMES = {
|
|
1279
|
+
flat: [
|
|
1280
|
+
"code-pushup.eslint.config",
|
|
1281
|
+
"eslint.code-pushup.config",
|
|
1282
|
+
"eslint.config.code-pushup",
|
|
1283
|
+
"eslint.strict.config",
|
|
1284
|
+
"eslint.config.strict"
|
|
1285
|
+
],
|
|
1286
|
+
legacy: ["code-pushup.eslintrc", ".eslintrc.code-pushup", ".eslintrc.strict"]
|
|
1287
|
+
};
|
|
1288
|
+
async function findCodePushupEslintConfig(project, format) {
|
|
1289
|
+
return findProjectFile(project, {
|
|
1290
|
+
names: CP_ESLINT_CONFIG_NAMES[format],
|
|
1291
|
+
extensions: ESLINT_CONFIG_EXTENSIONS[format]
|
|
1292
|
+
});
|
|
1166
1293
|
}
|
|
1167
|
-
function
|
|
1294
|
+
async function findEslintConfig(project, format) {
|
|
1168
1295
|
const options = project.targets?.["lint"]?.options;
|
|
1169
|
-
return options?.
|
|
1296
|
+
return options?.eslintConfig ?? await findProjectFile(project, {
|
|
1297
|
+
names: ESLINT_CONFIG_NAMES[format],
|
|
1298
|
+
extensions: ESLINT_CONFIG_EXTENSIONS[format]
|
|
1299
|
+
});
|
|
1170
1300
|
}
|
|
1171
|
-
function
|
|
1301
|
+
function getLintFilePatterns(project, format) {
|
|
1172
1302
|
const options = project.targets?.["lint"]?.options;
|
|
1173
|
-
|
|
1303
|
+
const defaultPatterns = format === "legacy" ? `${project.root}/**/*` : project.root;
|
|
1304
|
+
const patterns = options?.lintFilePatterns == null ? [defaultPatterns] : toArray(options.lintFilePatterns);
|
|
1305
|
+
if (format === "legacy") {
|
|
1306
|
+
return [
|
|
1307
|
+
...patterns,
|
|
1308
|
+
// HACK: ESLint.calculateConfigForFile won't find rules included only for subsets of *.ts when globs used
|
|
1309
|
+
// so we explicitly provide additional patterns used by @code-pushup/eslint-config to ensure those rules are included
|
|
1310
|
+
// this workaround is only necessary for legacy configs (rules are detected more reliably in flat configs)
|
|
1311
|
+
`${project.root}/*.spec.ts`,
|
|
1312
|
+
// jest/* and vitest/* rules
|
|
1313
|
+
`${project.root}/*.cy.ts`,
|
|
1314
|
+
// cypress/* rules
|
|
1315
|
+
`${project.root}/*.stories.ts`,
|
|
1316
|
+
// storybook/* rules
|
|
1317
|
+
`${project.root}/.storybook/main.ts`
|
|
1318
|
+
// storybook/no-uninstalled-addons rule
|
|
1319
|
+
];
|
|
1320
|
+
}
|
|
1321
|
+
return patterns;
|
|
1322
|
+
}
|
|
1323
|
+
async function findProjectFile(project, file) {
|
|
1324
|
+
for (const name2 of file.names) {
|
|
1325
|
+
for (const ext of file.extensions) {
|
|
1326
|
+
const filename = `./${project.root}/${name2}.${ext}`;
|
|
1327
|
+
if (await fileExists(join5(process.cwd(), filename))) {
|
|
1328
|
+
return filename;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
return void 0;
|
|
1174
1333
|
}
|
|
1175
1334
|
|
|
1176
1335
|
// packages/plugin-eslint/src/lib/nx/projects-to-config.ts
|
|
@@ -1178,24 +1337,12 @@ async function nxProjectsToConfig(projectGraph, predicate = () => true) {
|
|
|
1178
1337
|
const { readProjectsConfigurationFromProjectGraph } = await import("@nx/devkit");
|
|
1179
1338
|
const projectsConfiguration = readProjectsConfigurationFromProjectGraph(projectGraph);
|
|
1180
1339
|
const projects = Object.values(projectsConfiguration.projects).filter((project) => "lint" in (project.targets ?? {})).filter(predicate).sort((a, b) => a.root.localeCompare(b.root));
|
|
1340
|
+
const format = await detectConfigVersion();
|
|
1181
1341
|
return Promise.all(
|
|
1182
1342
|
projects.map(
|
|
1183
1343
|
async (project) => ({
|
|
1184
|
-
eslintrc: await
|
|
1185
|
-
patterns:
|
|
1186
|
-
...getLintFilePatterns(project),
|
|
1187
|
-
// HACK: ESLint.calculateConfigForFile won't find rules included only for subsets of *.ts when globs used
|
|
1188
|
-
// so we explicitly provide additional patterns used by @code-pushup/eslint-config to ensure those rules are included
|
|
1189
|
-
// this workaround won't be necessary once flat configs are stable (much easier to find all rules)
|
|
1190
|
-
`${project.sourceRoot}/*.spec.ts`,
|
|
1191
|
-
// jest/* and vitest/* rules
|
|
1192
|
-
`${project.sourceRoot}/*.cy.ts`,
|
|
1193
|
-
// cypress/* rules
|
|
1194
|
-
`${project.sourceRoot}/*.stories.ts`,
|
|
1195
|
-
// storybook/* rules
|
|
1196
|
-
`${project.sourceRoot}/.storybook/main.ts`
|
|
1197
|
-
// storybook/no-uninstalled-addons rule
|
|
1198
|
-
]
|
|
1344
|
+
eslintrc: await findCodePushupEslintConfig(project, format) ?? await findEslintConfig(project, format),
|
|
1345
|
+
patterns: getLintFilePatterns(project, format)
|
|
1199
1346
|
})
|
|
1200
1347
|
)
|
|
1201
1348
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-pushup/eslint-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Code PushUp plugin for detecting problems in source code using ESLint.📋",
|
|
6
6
|
"homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-eslint#readme",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"main": "./index.js",
|
|
41
41
|
"types": "./src/index.d.ts",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@code-pushup/utils": "0.
|
|
44
|
-
"@code-pushup/models": "0.
|
|
45
|
-
"eslint": "^8.46.0",
|
|
43
|
+
"@code-pushup/utils": "0.56.0",
|
|
44
|
+
"@code-pushup/models": "0.56.0",
|
|
46
45
|
"zod": "^3.22.4"
|
|
47
46
|
},
|
|
48
47
|
"peerDependencies": {
|
|
49
|
-
"@nx/devkit": ">=17.0.0"
|
|
48
|
+
"@nx/devkit": ">=17.0.0",
|
|
49
|
+
"eslint": "^8.46.0 || ^9.0.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependenciesMeta": {
|
|
52
52
|
"@nx/devkit": {
|
package/src/lib/config.d.ts
CHANGED
|
@@ -1,61 +1,60 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { type ZodType, z } from 'zod';
|
|
1
|
+
import { z } from 'zod';
|
|
3
2
|
export declare const eslintTargetSchema: z.ZodEffects<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
|
|
4
|
-
eslintrc: z.ZodOptional<z.
|
|
3
|
+
eslintrc: z.ZodOptional<z.ZodString>;
|
|
5
4
|
patterns: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
6
5
|
}, "strip", z.ZodTypeAny, {
|
|
7
6
|
patterns: string | string[];
|
|
8
|
-
eslintrc?: string |
|
|
7
|
+
eslintrc?: string | undefined;
|
|
9
8
|
}, {
|
|
10
9
|
patterns: string | string[];
|
|
11
|
-
eslintrc?: string |
|
|
10
|
+
eslintrc?: string | undefined;
|
|
12
11
|
}>]>, {
|
|
13
12
|
patterns: string | string[];
|
|
14
|
-
eslintrc?: string |
|
|
13
|
+
eslintrc?: string | undefined;
|
|
15
14
|
}, string | string[] | {
|
|
16
15
|
patterns: string | string[];
|
|
17
|
-
eslintrc?: string |
|
|
16
|
+
eslintrc?: string | undefined;
|
|
18
17
|
}>;
|
|
19
18
|
export type ESLintTarget = z.infer<typeof eslintTargetSchema>;
|
|
20
19
|
export declare const eslintPluginConfigSchema: z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
|
|
21
|
-
eslintrc: z.ZodOptional<z.
|
|
20
|
+
eslintrc: z.ZodOptional<z.ZodString>;
|
|
22
21
|
patterns: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
23
22
|
}, "strip", z.ZodTypeAny, {
|
|
24
23
|
patterns: string | string[];
|
|
25
|
-
eslintrc?: string |
|
|
24
|
+
eslintrc?: string | undefined;
|
|
26
25
|
}, {
|
|
27
26
|
patterns: string | string[];
|
|
28
|
-
eslintrc?: string |
|
|
27
|
+
eslintrc?: string | undefined;
|
|
29
28
|
}>]>, {
|
|
30
29
|
patterns: string | string[];
|
|
31
|
-
eslintrc?: string |
|
|
30
|
+
eslintrc?: string | undefined;
|
|
32
31
|
}, string | string[] | {
|
|
33
32
|
patterns: string | string[];
|
|
34
|
-
eslintrc?: string |
|
|
33
|
+
eslintrc?: string | undefined;
|
|
35
34
|
}>, z.ZodArray<z.ZodEffects<z.ZodUnion<[z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, z.ZodObject<{
|
|
36
|
-
eslintrc: z.ZodOptional<z.
|
|
35
|
+
eslintrc: z.ZodOptional<z.ZodString>;
|
|
37
36
|
patterns: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
38
37
|
}, "strip", z.ZodTypeAny, {
|
|
39
38
|
patterns: string | string[];
|
|
40
|
-
eslintrc?: string |
|
|
39
|
+
eslintrc?: string | undefined;
|
|
41
40
|
}, {
|
|
42
41
|
patterns: string | string[];
|
|
43
|
-
eslintrc?: string |
|
|
42
|
+
eslintrc?: string | undefined;
|
|
44
43
|
}>]>, {
|
|
45
44
|
patterns: string | string[];
|
|
46
|
-
eslintrc?: string |
|
|
45
|
+
eslintrc?: string | undefined;
|
|
47
46
|
}, string | string[] | {
|
|
48
47
|
patterns: string | string[];
|
|
49
|
-
eslintrc?: string |
|
|
48
|
+
eslintrc?: string | undefined;
|
|
50
49
|
}>, "many">]>, {
|
|
51
50
|
patterns: string | string[];
|
|
52
|
-
eslintrc?: string |
|
|
51
|
+
eslintrc?: string | undefined;
|
|
53
52
|
}[], string | string[] | {
|
|
54
53
|
patterns: string | string[];
|
|
55
|
-
eslintrc?: string |
|
|
54
|
+
eslintrc?: string | undefined;
|
|
56
55
|
} | (string | string[] | {
|
|
57
56
|
patterns: string | string[];
|
|
58
|
-
eslintrc?: string |
|
|
57
|
+
eslintrc?: string | undefined;
|
|
59
58
|
})[]>;
|
|
60
59
|
export type ESLintPluginConfig = z.input<typeof eslintPluginConfigSchema>;
|
|
61
60
|
export type ESLintPluginRunnerConfig = {
|
package/src/lib/meta/groups.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Group } from '@code-pushup/models';
|
|
2
|
-
import { type RuleData } from './
|
|
2
|
+
import { type RuleData } from './parse';
|
|
3
3
|
export declare function groupsFromRuleTypes(rules: RuleData[]): Group[];
|
|
4
4
|
export declare function groupsFromRuleCategories(rules: RuleData[]): Group[];
|
package/src/lib/meta/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Audit, Group } from '@code-pushup/models';
|
|
2
2
|
import type { ESLintTarget } from '../config';
|
|
3
|
+
export { detectConfigVersion, type ConfigFormat } from './versions';
|
|
3
4
|
export declare function listAuditsAndGroups(targets: ESLintTarget[]): Promise<{
|
|
4
5
|
audits: Audit[];
|
|
5
6
|
groups: Group[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Linter, Rule } from 'eslint';
|
|
2
|
+
export type RuleData = {
|
|
3
|
+
ruleId: string;
|
|
4
|
+
meta: Rule.RuleMetaData;
|
|
5
|
+
options: unknown[] | undefined;
|
|
6
|
+
};
|
|
7
|
+
export declare function parseRuleId(ruleId: string): {
|
|
8
|
+
plugin?: string;
|
|
9
|
+
name: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function isRuleOff(entry: Linter.RuleEntry<unknown[]>): boolean;
|
|
12
|
+
export declare function optionsFromRuleEntry(entry: Linter.RuleEntry<unknown[]>): unknown[];
|
package/src/lib/meta/rules.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
import type { Rule } from 'eslint';
|
|
2
1
|
import type { ESLintTarget } from '../config';
|
|
3
|
-
|
|
4
|
-
ruleId: string;
|
|
5
|
-
meta: Rule.RuleMetaData;
|
|
6
|
-
options: unknown[] | undefined;
|
|
7
|
-
};
|
|
2
|
+
import type { RuleData } from './parse';
|
|
8
3
|
export declare function listRules(targets: ESLintTarget[]): Promise<RuleData[]>;
|
|
9
|
-
export declare function parseRuleId(ruleId: string): {
|
|
10
|
-
plugin?: string;
|
|
11
|
-
name: string;
|
|
12
|
-
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type ConfigFormat = 'flat' | 'legacy';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ESLintTarget } from '../../config';
|
|
2
|
+
import type { RuleData } from '../parse';
|
|
3
|
+
import type { ConfigFormat } from './formats';
|
|
4
|
+
export { detectConfigVersion } from './detect';
|
|
5
|
+
export type { ConfigFormat } from './formats';
|
|
6
|
+
export declare function selectRulesLoader(version: ConfigFormat): (target: ESLintTarget) => Promise<RuleData[]>;
|
package/src/lib/nx/utils.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProjectConfiguration } from '@nx/devkit';
|
|
2
|
-
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function
|
|
2
|
+
import type { ConfigFormat } from '../meta';
|
|
3
|
+
export declare function findCodePushupEslintConfig(project: ProjectConfiguration, format: ConfigFormat): Promise<string | undefined>;
|
|
4
|
+
export declare function findEslintConfig(project: ProjectConfiguration, format: ConfigFormat): Promise<string | undefined>;
|
|
5
|
+
export declare function getLintFilePatterns(project: ProjectConfiguration, format: ConfigFormat): string[];
|
package/src/lib/setup.d.ts
CHANGED