@code-pushup/eslint-plugin 0.56.0 → 0.58.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.
Files changed (83) hide show
  1. package/README.md +36 -0
  2. package/package.json +9 -7
  3. package/src/bin.js +6 -0
  4. package/src/bin.js.map +1 -0
  5. package/src/index.d.ts +3 -3
  6. package/src/index.js +4 -0
  7. package/src/index.js.map +1 -0
  8. package/src/lib/config.d.ts +59 -0
  9. package/src/lib/config.js +40 -0
  10. package/src/lib/config.js.map +1 -0
  11. package/src/lib/eslint-plugin.d.ts +3 -2
  12. package/src/lib/eslint-plugin.js +54 -0
  13. package/src/lib/eslint-plugin.js.map +1 -0
  14. package/src/lib/meta/groups.d.ts +8 -1
  15. package/src/lib/meta/groups.js +112 -0
  16. package/src/lib/meta/groups.js.map +1 -0
  17. package/src/lib/meta/hash.d.ts +2 -0
  18. package/src/lib/meta/hash.js +19 -0
  19. package/src/lib/meta/hash.js.map +1 -0
  20. package/src/lib/meta/index.d.ts +4 -3
  21. package/src/lib/meta/index.js +19 -0
  22. package/src/lib/meta/index.js.map +1 -0
  23. package/src/lib/meta/parse.d.ts +2 -1
  24. package/src/lib/meta/parse.js +36 -0
  25. package/src/lib/meta/parse.js.map +1 -0
  26. package/src/lib/meta/rules.d.ts +3 -2
  27. package/src/lib/meta/rules.js +26 -0
  28. package/src/lib/meta/rules.js.map +1 -0
  29. package/src/lib/meta/transform.d.ts +2 -2
  30. package/src/lib/meta/transform.js +21 -0
  31. package/src/lib/meta/transform.js.map +1 -0
  32. package/src/lib/meta/versions/detect.d.ts +1 -1
  33. package/src/lib/meta/versions/detect.js +22 -0
  34. package/src/lib/meta/versions/detect.js.map +1 -0
  35. package/src/lib/meta/versions/flat.d.ts +2 -2
  36. package/src/lib/meta/versions/flat.js +81 -0
  37. package/src/lib/meta/versions/flat.js.map +1 -0
  38. package/src/lib/meta/versions/formats.js +2 -0
  39. package/src/lib/meta/versions/formats.js.map +1 -0
  40. package/src/lib/meta/versions/index.d.ts +5 -5
  41. package/src/lib/meta/versions/index.js +12 -0
  42. package/src/lib/meta/versions/index.js.map +1 -0
  43. package/src/lib/meta/versions/legacy.d.ts +2 -2
  44. package/src/lib/meta/versions/legacy.js +36 -0
  45. package/src/lib/meta/versions/legacy.js.map +1 -0
  46. package/src/lib/nx/filter-project-graph.js +12 -0
  47. package/src/lib/nx/filter-project-graph.js.map +1 -0
  48. package/src/lib/nx/find-all-projects.d.ts +1 -1
  49. package/src/lib/nx/find-all-projects.js +40 -0
  50. package/src/lib/nx/find-all-projects.js.map +1 -0
  51. package/src/lib/nx/find-project-with-deps.d.ts +1 -1
  52. package/src/lib/nx/find-project-with-deps.js +35 -0
  53. package/src/lib/nx/find-project-with-deps.js.map +1 -0
  54. package/src/lib/nx/find-project-without-deps.d.ts +1 -1
  55. package/src/lib/nx/find-project-without-deps.js +36 -0
  56. package/src/lib/nx/find-project-without-deps.js.map +1 -0
  57. package/src/lib/nx/index.d.ts +3 -3
  58. package/src/lib/nx/index.js +4 -0
  59. package/src/lib/nx/index.js.map +1 -0
  60. package/src/lib/nx/projects-to-config.d.ts +1 -1
  61. package/src/lib/nx/projects-to-config.js +18 -0
  62. package/src/lib/nx/projects-to-config.js.map +1 -0
  63. package/src/lib/nx/traverse-graph.js +21 -0
  64. package/src/lib/nx/traverse-graph.js.map +1 -0
  65. package/src/lib/nx/utils.d.ts +1 -1
  66. package/src/lib/nx/utils.js +75 -0
  67. package/src/lib/nx/utils.js.map +1 -0
  68. package/src/lib/runner/index.d.ts +3 -6
  69. package/src/lib/runner/index.js +38 -0
  70. package/src/lib/runner/index.js.map +1 -0
  71. package/src/lib/runner/lint.d.ts +2 -2
  72. package/src/lib/runner/lint.js +49 -0
  73. package/src/lib/runner/lint.js.map +1 -0
  74. package/src/lib/runner/transform.d.ts +1 -1
  75. package/src/lib/runner/transform.js +74 -0
  76. package/src/lib/runner/transform.js.map +1 -0
  77. package/src/lib/runner/types.js +2 -0
  78. package/src/lib/runner/types.js.map +1 -0
  79. package/src/lib/setup.d.ts +1 -1
  80. package/src/lib/setup.js +17 -0
  81. package/src/lib/setup.js.map +1 -0
  82. package/bin.js +0 -1129
  83. package/index.js +0 -1413
package/README.md CHANGED
@@ -93,6 +93,42 @@ Detected ESLint rules are mapped to Code PushUp audits. Audit reports are calcul
93
93
 
94
94
  5. Run the CLI with `npx code-pushup collect` and view or upload report (refer to [CLI docs](../cli/README.md)).
95
95
 
96
+ ### Custom groups
97
+
98
+ You can extend the plugin configuration with custom groups to categorize ESLint rules according to your project's specific needs. Custom groups allow you to assign weights to individual rules, influencing their impact on the report. Rules can be defined as an object with explicit weights or as an array where each rule defaults to a weight of 1. Additionally, you can use wildcard patterns (`*`) to include multiple rules with similar prefixes.
99
+
100
+ ```js
101
+ import eslintPlugin from '@code-pushup/eslint-plugin';
102
+
103
+ export default {
104
+ // ...
105
+ plugins: [
106
+ // ...
107
+ await eslintPlugin(
108
+ { eslintrc: '.eslintrc.js', patterns: ['src/**/*.js'] },
109
+ {
110
+ groups: [
111
+ {
112
+ slug: 'modern-angular',
113
+ title: 'Modern Angular',
114
+ rules: {
115
+ '@angular-eslint/template/prefer-control-flow': 3,
116
+ '@angular-eslint/template/prefer-ngsrc': 2,
117
+ '@angular-eslint/component-selector': 1,
118
+ },
119
+ },
120
+ {
121
+ slug: 'type-safety',
122
+ title: 'Type safety',
123
+ rules: ['@typescript-eslint/no-unsafe-*'],
124
+ },
125
+ ],
126
+ },
127
+ ),
128
+ ],
129
+ };
130
+ ```
131
+
96
132
  ### Optionally set up categories
97
133
 
98
134
  1. Reference audits (or groups) which you wish to include in custom categories (use `npx code-pushup print-config` to list audits and groups).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/eslint-plugin",
3
- "version": "0.56.0",
3
+ "version": "0.58.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",
@@ -37,11 +37,10 @@
37
37
  "access": "public"
38
38
  },
39
39
  "type": "module",
40
- "main": "./index.js",
41
- "types": "./src/index.d.ts",
42
40
  "dependencies": {
43
- "@code-pushup/utils": "0.56.0",
44
- "@code-pushup/models": "0.56.0",
41
+ "@code-pushup/utils": "0.58.0",
42
+ "@code-pushup/models": "0.58.0",
43
+ "yargs": "^17.7.2",
45
44
  "zod": "^3.22.4"
46
45
  },
47
46
  "peerDependencies": {
@@ -52,5 +51,8 @@
52
51
  "@nx/devkit": {
53
52
  "optional": true
54
53
  }
55
- }
56
- }
54
+ },
55
+ "module": "./src/index.js",
56
+ "main": "./src/index.js",
57
+ "types": "./src/index.d.ts"
58
+ }
package/src/bin.js ADDED
@@ -0,0 +1,6 @@
1
+ import process from 'node:process';
2
+ import { Parser } from 'yargs/helpers';
3
+ import { executeRunner } from './lib/runner/index.js';
4
+ const { runnerConfigPath, runnerOutputPath } = Parser(process.argv);
5
+ await executeRunner({ runnerConfigPath, runnerOutputPath });
6
+ //# sourceMappingURL=bin.js.map
package/src/bin.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../../../packages/plugin-eslint/src/bin.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpE,MAAM,aAAa,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC,CAAC"}
package/src/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { eslintPlugin } from './lib/eslint-plugin';
1
+ import { eslintPlugin } from './lib/eslint-plugin.js';
2
2
  export default eslintPlugin;
3
- export type { ESLintPluginConfig } from './lib/config';
4
- export { eslintConfigFromNxProjectAndDeps, eslintConfigFromNxProjects, eslintConfigFromAllNxProjects, eslintConfigFromNxProject, } from './lib/nx';
3
+ export type { ESLintPluginConfig } from './lib/config.js';
4
+ export { eslintConfigFromAllNxProjects, eslintConfigFromNxProject, eslintConfigFromNxProjectAndDeps, eslintConfigFromNxProjects, } from './lib/nx/index.js';
package/src/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { eslintPlugin } from './lib/eslint-plugin.js';
2
+ export default eslintPlugin;
3
+ export { eslintConfigFromAllNxProjects, eslintConfigFromNxProject, eslintConfigFromNxProjectAndDeps, eslintConfigFromNxProjects, } from './lib/nx/index.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/plugin-eslint/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,eAAe,YAAY,CAAC;AAI5B,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,EACzB,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC"}
@@ -61,3 +61,62 @@ export type ESLintPluginRunnerConfig = {
61
61
  targets: ESLintTarget[];
62
62
  slugs: string[];
63
63
  };
64
+ declare const customGroupSchema: z.ZodObject<{
65
+ slug: z.ZodString;
66
+ title: z.ZodString;
67
+ description: z.ZodOptional<z.ZodString>;
68
+ docsUrl: z.ZodOptional<z.ZodString>;
69
+ rules: z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodNumber>, Record<string, number>, Record<string, number>>]>;
70
+ }, "strip", z.ZodTypeAny, {
71
+ slug: string;
72
+ title: string;
73
+ rules: string[] | Record<string, number>;
74
+ description?: string | undefined;
75
+ docsUrl?: string | undefined;
76
+ }, {
77
+ slug: string;
78
+ title: string;
79
+ rules: string[] | Record<string, number>;
80
+ description?: string | undefined;
81
+ docsUrl?: string | undefined;
82
+ }>;
83
+ export type CustomGroup = z.infer<typeof customGroupSchema>;
84
+ export declare const eslintPluginOptionsSchema: z.ZodObject<{
85
+ groups: z.ZodOptional<z.ZodArray<z.ZodObject<{
86
+ slug: z.ZodString;
87
+ title: z.ZodString;
88
+ description: z.ZodOptional<z.ZodString>;
89
+ docsUrl: z.ZodOptional<z.ZodString>;
90
+ rules: z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodEffects<z.ZodRecord<z.ZodString, z.ZodNumber>, Record<string, number>, Record<string, number>>]>;
91
+ }, "strip", z.ZodTypeAny, {
92
+ slug: string;
93
+ title: string;
94
+ rules: string[] | Record<string, number>;
95
+ description?: string | undefined;
96
+ docsUrl?: string | undefined;
97
+ }, {
98
+ slug: string;
99
+ title: string;
100
+ rules: string[] | Record<string, number>;
101
+ description?: string | undefined;
102
+ docsUrl?: string | undefined;
103
+ }>, "many">>;
104
+ }, "strip", z.ZodTypeAny, {
105
+ groups?: {
106
+ slug: string;
107
+ title: string;
108
+ rules: string[] | Record<string, number>;
109
+ description?: string | undefined;
110
+ docsUrl?: string | undefined;
111
+ }[] | undefined;
112
+ }, {
113
+ groups?: {
114
+ slug: string;
115
+ title: string;
116
+ rules: string[] | Record<string, number>;
117
+ description?: string | undefined;
118
+ docsUrl?: string | undefined;
119
+ }[] | undefined;
120
+ }>;
121
+ export type ESLintPluginOptions = z.infer<typeof eslintPluginOptionsSchema>;
122
+ export {};
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod';
2
+ import { toArray } from '@code-pushup/utils';
3
+ const patternsSchema = z.union([z.string(), z.array(z.string()).min(1)], {
4
+ description: 'Lint target files. May contain file paths, directory paths or glob patterns',
5
+ });
6
+ const eslintrcSchema = z.string({ description: 'Path to ESLint config file' });
7
+ const eslintTargetObjectSchema = z.object({
8
+ eslintrc: eslintrcSchema.optional(),
9
+ patterns: patternsSchema,
10
+ });
11
+ export const eslintTargetSchema = z
12
+ .union([patternsSchema, eslintTargetObjectSchema])
13
+ .transform((target) => typeof target === 'string' || Array.isArray(target)
14
+ ? { patterns: target }
15
+ : target);
16
+ export const eslintPluginConfigSchema = z
17
+ .union([eslintTargetSchema, z.array(eslintTargetSchema).min(1)])
18
+ .transform(toArray);
19
+ const customGroupRulesSchema = z.union([
20
+ z
21
+ .array(z.string())
22
+ .min(1, 'Custom group rules must contain at least 1 element'),
23
+ z.record(z.string(), z.number()).refine(schema => Object.keys(schema).length > 0, () => ({
24
+ code: 'too_small',
25
+ message: 'Custom group rules must contain at least 1 element',
26
+ })),
27
+ ], {
28
+ description: 'Array of rule IDs with equal weights or object mapping rule IDs to specific weights',
29
+ });
30
+ const customGroupSchema = z.object({
31
+ slug: z.string({ description: 'Unique group identifier' }),
32
+ title: z.string({ description: 'Group display title' }),
33
+ description: z.string({ description: 'Group metadata' }).optional(),
34
+ docsUrl: z.string({ description: 'Group documentation site' }).optional(),
35
+ rules: customGroupRulesSchema,
36
+ });
37
+ export const eslintPluginOptionsSchema = z.object({
38
+ groups: z.array(customGroupSchema).optional(),
39
+ });
40
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../packages/plugin-eslint/src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE;IACvE,WAAW,EACT,6EAA6E;CAChF,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4BAA4B,EAAE,CAAC,CAAC;AAE/E,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,QAAQ,EAAE,cAAc,CAAC,QAAQ,EAAE;IACnC,QAAQ,EAAE,cAAc;CACzB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC;KAChC,KAAK,CAAC,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;KACjD,SAAS,CACR,CAAC,MAAM,EAAsB,EAAE,CAC7B,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;IACjD,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE;IACtB,CAAC,CAAC,MAAM,CACb,CAAC;AAGJ,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,KAAK,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/D,SAAS,CAAC,OAAO,CAAC,CAAC;AAQtB,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CACpC;IACE,CAAC;SACE,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,CAAC,EAAE,oDAAoD,CAAC;IAC/D,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CACrC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EACxC,GAAG,EAAE,CAAC,CAAC;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,oDAAoD;KAC9D,CAAC,CACH;CACF,EACD;IACE,WAAW,EACT,qFAAqF;CACxF,CACF,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yBAAyB,EAAE,CAAC;IAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC;IACvD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAAC,QAAQ,EAAE;IACnE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,0BAA0B,EAAE,CAAC,CAAC,QAAQ,EAAE;IACzE,KAAK,EAAE,sBAAsB;CAC9B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;CAC9C,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { PluginConfig } from '@code-pushup/models';
2
- import { type ESLintPluginConfig } from './config';
2
+ import { type ESLintPluginConfig, type ESLintPluginOptions } from './config.js';
3
3
  /**
4
4
  * Instantiates Code PushUp ESLint plugin for use in core config.
5
5
  *
@@ -18,6 +18,7 @@ import { type ESLintPluginConfig } from './config';
18
18
  * }
19
19
  *
20
20
  * @param config Configuration options.
21
+ * @param options Optional settings for customizing the plugin behavior.
21
22
  * @returns Plugin configuration as a promise.
22
23
  */
23
- export declare function eslintPlugin(config: ESLintPluginConfig): Promise<PluginConfig>;
24
+ export declare function eslintPlugin(config: ESLintPluginConfig, options?: ESLintPluginOptions): Promise<PluginConfig>;
@@ -0,0 +1,54 @@
1
+ import { createRequire } from 'node:module';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { parseSchema } from '@code-pushup/utils';
5
+ import { eslintPluginConfigSchema, eslintPluginOptionsSchema, } from './config.js';
6
+ import { listAuditsAndGroups } from './meta/index.js';
7
+ import { createRunnerConfig } from './runner/index.js';
8
+ /**
9
+ * Instantiates Code PushUp ESLint plugin for use in core config.
10
+ *
11
+ * @example
12
+ * import eslintPlugin from '@code-pushup/eslint-plugin'
13
+ *
14
+ * export default {
15
+ * // ... core config ...
16
+ * plugins: [
17
+ * // ... other plugins ...
18
+ * await eslintPlugin({
19
+ * eslintrc: '.eslintrc.json',
20
+ * patterns: ['src', 'test/*.spec.js']
21
+ * })
22
+ * ]
23
+ * }
24
+ *
25
+ * @param config Configuration options.
26
+ * @param options Optional settings for customizing the plugin behavior.
27
+ * @returns Plugin configuration as a promise.
28
+ */
29
+ export async function eslintPlugin(config, options) {
30
+ const targets = parseSchema(eslintPluginConfigSchema, config, {
31
+ schemaType: 'ESLint plugin config',
32
+ });
33
+ const customGroups = options
34
+ ? parseSchema(eslintPluginOptionsSchema, options, {
35
+ schemaType: 'ESLint plugin options',
36
+ }).groups
37
+ : undefined;
38
+ const { audits, groups } = await listAuditsAndGroups(targets, customGroups);
39
+ const runnerScriptPath = path.join(fileURLToPath(path.dirname(import.meta.url)), '..', 'bin.js');
40
+ const packageJson = createRequire(import.meta.url)('../../package.json');
41
+ return {
42
+ slug: 'eslint',
43
+ title: 'ESLint',
44
+ icon: 'eslint',
45
+ description: 'Official Code PushUp ESLint plugin',
46
+ docsUrl: 'https://www.npmjs.com/package/@code-pushup/eslint-plugin',
47
+ packageName: packageJson.name,
48
+ version: packageJson.version,
49
+ audits,
50
+ groups,
51
+ runner: await createRunnerConfig(runnerScriptPath, audits, targets),
52
+ };
53
+ }
54
+ //# sourceMappingURL=eslint-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eslint-plugin.js","sourceRoot":"","sources":["../../../../../packages/plugin-eslint/src/lib/eslint-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAGL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAA0B,EAC1B,OAA6B;IAE7B,MAAM,OAAO,GAAG,WAAW,CAAC,wBAAwB,EAAE,MAAM,EAAE;QAC5D,UAAU,EAAE,sBAAsB;KACnC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,OAAO;QAC1B,CAAC,CAAC,WAAW,CAAC,yBAAyB,EAAE,OAAO,EAAE;YAC9C,UAAU,EAAE,uBAAuB;SACpC,CAAC,CAAC,MAAM;QACX,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAChC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAC5C,IAAI,EACJ,QAAQ,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAChD,oBAAoB,CACkB,CAAC;IAEzC,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,0DAA0D;QACnE,WAAW,EAAE,WAAW,CAAC,IAAI;QAC7B,OAAO,EAAE,WAAW,CAAC,OAAO;QAE5B,MAAM;QACN,MAAM;QAEN,MAAM,EAAE,MAAM,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC;KACpE,CAAC;AACJ,CAAC"}
@@ -1,4 +1,11 @@
1
1
  import type { Group } from '@code-pushup/models';
2
- import { type RuleData } from './parse';
2
+ import type { CustomGroup } from '../config.js';
3
+ import { type RuleData } from './parse.js';
3
4
  export declare function groupsFromRuleTypes(rules: RuleData[]): Group[];
4
5
  export declare function groupsFromRuleCategories(rules: RuleData[]): Group[];
6
+ export declare function groupsFromCustomConfig(rules: RuleData[], groups: CustomGroup[]): Group[];
7
+ export declare function createRulesMap(rules: RuleData[]): Record<string, RuleData[]>;
8
+ export declare function resolveGroupRefs(groupRules: Record<string, number>, rulesMap: Record<string, RuleData[]>): {
9
+ refs: Group['refs'];
10
+ invalidRules: string[];
11
+ };
@@ -0,0 +1,112 @@
1
+ import { objectToKeys, slugify, ui } from '@code-pushup/utils';
2
+ import { ruleToSlug } from './hash.js';
3
+ import { parseRuleId } from './parse.js';
4
+ import { expandWildcardRules } from './rules.js';
5
+ // docs on meta.type: https://eslint.org/docs/latest/extend/custom-rules#rule-structure
6
+ const typeGroups = {
7
+ problem: {
8
+ slug: 'problems',
9
+ title: 'Problems',
10
+ description: 'Code that either will cause an error or may cause confusing behavior. Developers should consider this a high priority to resolve.',
11
+ },
12
+ suggestion: {
13
+ slug: 'suggestions',
14
+ title: 'Suggestions',
15
+ description: "Something that could be done in a better way but no errors will occur if the code isn't changed.",
16
+ },
17
+ layout: {
18
+ slug: 'formatting',
19
+ title: 'Formatting',
20
+ description: 'Primarily about whitespace, semicolons, commas, and parentheses, all the parts of the program that determine how the code looks rather than how it executes.',
21
+ },
22
+ };
23
+ export function groupsFromRuleTypes(rules) {
24
+ const allTypes = objectToKeys(typeGroups);
25
+ const auditSlugsMap = rules.reduce((acc, rule) => rule.meta.type == null
26
+ ? acc
27
+ : {
28
+ ...acc,
29
+ [rule.meta.type]: [
30
+ ...(acc[rule.meta.type] ?? []),
31
+ ruleToSlug(rule),
32
+ ],
33
+ }, {});
34
+ return allTypes
35
+ .map(type => ({
36
+ ...typeGroups[type],
37
+ refs: auditSlugsMap[type]?.map((slug) => ({ slug, weight: 1 })) ??
38
+ [],
39
+ }))
40
+ .filter(group => group.refs.length);
41
+ }
42
+ export function groupsFromRuleCategories(rules) {
43
+ const categoriesMap = rules.reduce((acc, rule) => {
44
+ // meta.docs.category still used by some popular plugins (e.g. import, react, functional)
45
+ const category = rule.meta.docs?.category;
46
+ if (!category) {
47
+ return acc;
48
+ }
49
+ const { plugin = '' } = parseRuleId(rule.id);
50
+ return {
51
+ ...acc,
52
+ [plugin]: {
53
+ ...acc[plugin],
54
+ [category]: [...(acc[plugin]?.[category] ?? []), ruleToSlug(rule)],
55
+ },
56
+ };
57
+ }, {});
58
+ const groups = Object.entries(categoriesMap).flatMap(([plugin, categories]) => Object.entries(categories).map(([category, slugs]) => ({
59
+ slug: `${slugify(plugin)}-${slugify(category)}`,
60
+ title: `${category} (${plugin})`,
61
+ refs: slugs.map(slug => ({ slug, weight: 1 })),
62
+ })));
63
+ return groups.toSorted((a, b) => a.slug.localeCompare(b.slug));
64
+ }
65
+ export function groupsFromCustomConfig(rules, groups) {
66
+ const rulesMap = createRulesMap(rules);
67
+ return groups.map(group => {
68
+ const groupRules = Array.isArray(group.rules)
69
+ ? Object.fromEntries(group.rules.map(rule => [rule, 1]))
70
+ : group.rules;
71
+ const { refs, invalidRules } = resolveGroupRefs(groupRules, rulesMap);
72
+ if (invalidRules.length > 0 && Object.entries(groupRules).length > 0) {
73
+ if (refs.length === 0) {
74
+ throw new Error(`Invalid rule configuration in group ${group.slug}. All rules are invalid.`);
75
+ }
76
+ ui().logger.warning(`Some rules in group ${group.slug} are invalid: ${invalidRules.join(', ')}`);
77
+ }
78
+ return {
79
+ slug: group.slug,
80
+ title: group.title,
81
+ refs,
82
+ };
83
+ });
84
+ }
85
+ export function createRulesMap(rules) {
86
+ return rules.reduce((acc, rule) => ({
87
+ ...acc,
88
+ [rule.id]: [...(acc[rule.id] || []), rule],
89
+ }), {});
90
+ }
91
+ export function resolveGroupRefs(groupRules, rulesMap) {
92
+ return Object.entries(groupRules).reduce((acc, [rule, weight]) => {
93
+ const matchedRuleIds = rule.endsWith('*')
94
+ ? expandWildcardRules(rule, Object.keys(rulesMap))
95
+ : [rule];
96
+ const matchedRefs = matchedRuleIds.flatMap(ruleId => {
97
+ const matchingRules = rulesMap[ruleId] || [];
98
+ const weightPerRule = weight / matchingRules.length;
99
+ return matchingRules.map(ruleData => ({
100
+ slug: ruleToSlug(ruleData),
101
+ weight: weightPerRule,
102
+ }));
103
+ });
104
+ return {
105
+ refs: [...acc.refs, ...matchedRefs],
106
+ invalidRules: matchedRefs.length > 0
107
+ ? acc.invalidRules
108
+ : [...acc.invalidRules, rule],
109
+ };
110
+ }, { refs: [], invalidRules: [] });
111
+ }
112
+ //# sourceMappingURL=groups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"groups.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/groups.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,4 @@
1
+ import { type RuleData } from './parse.js';
2
+ export declare function ruleToSlug(rule: RuleData): string;
1
3
  export declare function ruleIdToSlug(ruleId: string, options: unknown[] | undefined): string;
2
4
  export declare function jsonHash(data: unknown, bytes?: number): string;
@@ -0,0 +1,19 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { slugify } from '@code-pushup/utils';
3
+ import { resolveRuleOptions } from './parse.js';
4
+ export function ruleToSlug(rule) {
5
+ return ruleIdToSlug(rule.id, resolveRuleOptions(rule));
6
+ }
7
+ export function ruleIdToSlug(ruleId, options) {
8
+ const slug = slugify(ruleId);
9
+ if (!options?.length) {
10
+ return slug;
11
+ }
12
+ return `${slug}-${jsonHash(options)}`;
13
+ }
14
+ export function jsonHash(data, bytes = 8) {
15
+ return createHash('shake256', { outputLength: bytes })
16
+ .update(JSON.stringify(data) || 'null')
17
+ .digest('hex');
18
+ }
19
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAiB,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE/D,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,OAA8B;IAE9B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,IAAI,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAa,EAAE,KAAK,GAAG,CAAC;IAC/C,OAAO,UAAU,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;SACnD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;SACtC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import type { Audit, Group } from '@code-pushup/models';
2
- import type { ESLintTarget } from '../config';
3
- export { detectConfigVersion, type ConfigFormat } from './versions';
4
- export declare function listAuditsAndGroups(targets: ESLintTarget[]): Promise<{
2
+ import type { CustomGroup, ESLintTarget } from '../config.js';
3
+ export { ruleIdToSlug } from './hash.js';
4
+ export { detectConfigVersion, type ConfigFormat } from './versions/index.js';
5
+ export declare function listAuditsAndGroups(targets: ESLintTarget[], customGroups?: CustomGroup[] | undefined): Promise<{
5
6
  audits: Audit[];
6
7
  groups: Group[];
7
8
  }>;
@@ -0,0 +1,19 @@
1
+ import { groupsFromCustomConfig, groupsFromRuleCategories, groupsFromRuleTypes, } from './groups.js';
2
+ import { listRules } from './rules.js';
3
+ import { ruleToAudit } from './transform.js';
4
+ export { ruleIdToSlug } from './hash.js';
5
+ export { detectConfigVersion } from './versions/index.js';
6
+ export async function listAuditsAndGroups(targets, customGroups) {
7
+ const rules = await listRules(targets);
8
+ const resolvedCustomGroups = customGroups
9
+ ? groupsFromCustomConfig(rules, customGroups)
10
+ : [];
11
+ const audits = rules.map(ruleToAudit);
12
+ const groups = [
13
+ ...groupsFromRuleTypes(rules),
14
+ ...groupsFromRuleCategories(rules),
15
+ ...resolvedCustomGroups,
16
+ ];
17
+ return { audits, groups };
18
+ }
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAqB,MAAM,qBAAqB,CAAC;AAE7E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAuB,EACvB,YAAwC;IAExC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IAEvC,MAAM,oBAAoB,GAAG,YAAY;QACvC,CAAC,CAAC,sBAAsB,CAAC,KAAK,EAAE,YAAY,CAAC;QAC7C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG;QACb,GAAG,mBAAmB,CAAC,KAAK,CAAC;QAC7B,GAAG,wBAAwB,CAAC,KAAK,CAAC;QAClC,GAAG,oBAAoB;KACxB,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { Linter, Rule } from 'eslint';
2
2
  export type RuleData = {
3
- ruleId: string;
3
+ id: string;
4
4
  meta: Rule.RuleMetaData;
5
5
  options: unknown[] | undefined;
6
6
  };
@@ -10,3 +10,4 @@ export declare function parseRuleId(ruleId: string): {
10
10
  };
11
11
  export declare function isRuleOff(entry: Linter.RuleEntry<unknown[]>): boolean;
12
12
  export declare function optionsFromRuleEntry(entry: Linter.RuleEntry<unknown[]>): unknown[];
13
+ export declare function resolveRuleOptions(rule: RuleData): unknown[] | undefined;
@@ -0,0 +1,36 @@
1
+ import { toArray } from '@code-pushup/utils';
2
+ export function parseRuleId(ruleId) {
3
+ const i = ruleId.startsWith('@')
4
+ ? ruleId.lastIndexOf('/')
5
+ : ruleId.indexOf('/');
6
+ if (i === -1) {
7
+ return { name: ruleId };
8
+ }
9
+ return {
10
+ plugin: ruleId.slice(0, i),
11
+ name: ruleId.slice(i + 1),
12
+ };
13
+ }
14
+ export function isRuleOff(entry) {
15
+ const level = Array.isArray(entry) ? entry[0] : entry;
16
+ switch (level) {
17
+ case 0:
18
+ case 'off':
19
+ return true;
20
+ case 1:
21
+ case 2:
22
+ case 'warn':
23
+ case 'error':
24
+ return false;
25
+ }
26
+ }
27
+ export function optionsFromRuleEntry(entry) {
28
+ return toArray(entry).slice(1);
29
+ }
30
+ export function resolveRuleOptions(rule) {
31
+ if (rule.options?.length) {
32
+ return rule.options;
33
+ }
34
+ return rule.meta.defaultOptions;
35
+ }
36
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/parse.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAQ7C,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC;QACzB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACb,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAkC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEtD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,CAAC,CAAC;QACP,KAAK,KAAK;YACR,OAAO,IAAI,CAAC;QACd,KAAK,CAAC,CAAC;QACP,KAAK,CAAC,CAAC;QACP,KAAK,MAAM,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAkC;IAElC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;AAClC,CAAC"}
@@ -1,3 +1,4 @@
1
- import type { ESLintTarget } from '../config';
2
- import type { RuleData } from './parse';
1
+ import type { ESLintTarget } from '../config.js';
2
+ import type { RuleData } from './parse.js';
3
3
  export declare function listRules(targets: ESLintTarget[]): Promise<RuleData[]>;
4
+ export declare function expandWildcardRules(wildcard: string, rules: string[]): string[];
@@ -0,0 +1,26 @@
1
+ import { jsonHash } from './hash.js';
2
+ import { detectConfigVersion, selectRulesLoader } from './versions/index.js';
3
+ export async function listRules(targets) {
4
+ const version = await detectConfigVersion();
5
+ const loadRulesMap = selectRulesLoader(version);
6
+ const rulesMap = await targets.reduce(async (acc, target) => {
7
+ const map = await acc;
8
+ const rules = await loadRulesMap(target);
9
+ return rules.reduce(mergeRuleIntoMap, map);
10
+ }, Promise.resolve({}));
11
+ return Object.values(rulesMap).flatMap(Object.values);
12
+ }
13
+ function mergeRuleIntoMap(map, rule) {
14
+ return {
15
+ ...map,
16
+ [rule.id]: {
17
+ ...map[rule.id],
18
+ [jsonHash(rule.options)]: rule,
19
+ },
20
+ };
21
+ }
22
+ export function expandWildcardRules(wildcard, rules) {
23
+ const prefix = wildcard.slice(0, -1);
24
+ return rules.filter(rule => rule.startsWith(prefix));
25
+ }
26
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI7E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAuB;IACrD,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAC5C,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC;QACtB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC,EAAE,OAAO,CAAC,OAAO,CAAW,EAAE,CAAC,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAW,MAAM,CAAC,MAAM,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAa,EAAE,IAAc;IACrD,OAAO;QACL,GAAG,GAAG;QACN,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;YACT,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACf,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAgB,EAChB,KAAe;IAEf,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AACvD,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import type { Audit } from '@code-pushup/models';
2
- import type { RuleData } from './parse';
3
- export declare function ruleToAudit({ ruleId, meta, options }: RuleData): Audit;
2
+ import type { RuleData } from './parse.js';
3
+ export declare function ruleToAudit(rule: RuleData): Audit;
@@ -0,0 +1,21 @@
1
+ import { truncateDescription, truncateTitle } from '@code-pushup/utils';
2
+ import { ruleToSlug } from './hash.js';
3
+ export function ruleToAudit(rule) {
4
+ const name = rule.id.split('/').at(-1) ?? rule.id;
5
+ const plugin = name === rule.id ? null : rule.id.slice(0, rule.id.lastIndexOf('/'));
6
+ const pluginContext = plugin ? `, from _${plugin}_ plugin` : '';
7
+ const lines = [
8
+ `ESLint rule **${name}**${pluginContext}.`,
9
+ ...(rule.options?.length ? ['Custom options:'] : []),
10
+ ...(rule.options?.map(option => ['```json', JSON.stringify(option, null, 2), '```'].join('\n')) ?? []),
11
+ ];
12
+ return {
13
+ slug: ruleToSlug(rule),
14
+ title: truncateTitle(rule.meta.docs?.description ?? name),
15
+ description: truncateDescription(lines.join('\n\n')),
16
+ ...(rule.meta.docs?.url && {
17
+ docsUrl: rule.meta.docs.url,
18
+ }),
19
+ };
20
+ }
21
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../../../../packages/plugin-eslint/src/lib/meta/transform.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;IAClD,MAAM,MAAM,GACV,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,MAAM,KAAK,GAAa;QACtB,iBAAiB,IAAI,KAAK,aAAa,GAAG;QAC1C,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAC7B,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC/D,IAAI,EAAE,CAAC;KACT,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC;QACtB,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;QACzD,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI;YACzB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SAC5B,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -1,2 +1,2 @@
1
- import type { ConfigFormat } from './formats';
1
+ import type { ConfigFormat } from './formats.js';
2
2
  export declare function detectConfigVersion(): Promise<ConfigFormat>;