Skip to content

Commit e8d9ffa

Browse files
feat(eslint-plugin): support ESLint v9 (and v8) (#4371)
1 parent 822a5e0 commit e8d9ffa

File tree

153 files changed

+2888
-2214
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+2888
-2214
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ version: 2.1
1010
# See https://blog.daemonl.com/2016/02/yaml.html
1111
# To validate changes, use an online parser, eg.
1212
# https://yaml-online-parser.appspot.com/
13-
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.14.1
13+
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.18.0
1414
var_2: &run_in_node
1515
docker:
1616
- image: cimg/node:20.11

modules/eslint-plugin/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,11 @@
4040
},
4141
"sideEffects": false,
4242
"dependencies": {
43-
"@typescript-eslint/experimental-utils": "^5.4.0",
44-
"eslint-etc": "^5.1.0",
4543
"semver": "^7.3.5",
4644
"strip-json-comments": "3.1.1"
4745
},
4846
"peerDependencies": {
49-
"eslint": ">=8.0.0",
47+
"eslint": "^8.57.0 || ^9.0.0",
5048
"typescript": "*"
5149
}
5250
}

modules/eslint-plugin/schematics/ng-add/schema.json

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@
1010
"default": "recommended",
1111
"enum": [
1212
"recommended",
13-
"recommended-requiring-type-checking",
14-
"strict",
15-
"strict-requiring-type-checking",
16-
"store",
17-
"store-strict",
18-
"effects",
19-
"effects-requiring-type-checking",
20-
"effects-strict",
21-
"component-store",
22-
"component-store-strict",
2313
"all",
24-
"all-requiring-type-checking"
14+
"store-recommended",
15+
"store-all",
16+
"effects-recommended",
17+
"effects-all",
18+
"component-store-recommended",
19+
"component-store-all",
20+
"operators-recommended",
21+
"operators-all"
2522
],
2623
"x-prompt": {
2724
"message": "Which ESLint configuration would you like to use?",
@@ -32,52 +29,40 @@
3229
"label": "recommended"
3330
},
3431
{
35-
"value": "recommended-requiring-type-checking",
36-
"label": "recommended with type checking"
37-
},
38-
{
39-
"value": "strict",
40-
"label": "strict"
41-
},
42-
{
43-
"value": "strict-requiring-type-checking",
44-
"label": "strict with type checking"
45-
},
46-
{
47-
"value": "store",
48-
"label": "store"
32+
"value": "all",
33+
"label": "all"
4934
},
5035
{
51-
"value": "store-strict",
52-
"label": "strict store"
36+
"value": "store-recommended",
37+
"label": "store-recommended"
5338
},
5439
{
55-
"value": "effects",
56-
"label": "effects"
40+
"value": "store-all",
41+
"label": "store-all"
5742
},
5843
{
59-
"value": "effects-requiring-type-checking",
60-
"label": "effects with type checking"
44+
"value": "effects-recommended",
45+
"label": "effects-recommended"
6146
},
6247
{
63-
"value": "effects-strict",
64-
"label": "strict effects"
48+
"value": "effects-all",
49+
"label": "effects-all"
6550
},
6651
{
67-
"value": "component-store",
68-
"label": "component-store"
52+
"value": "component-store-recommended",
53+
"label": "component-store-recommended"
6954
},
7055
{
71-
"value": "component-store-strict",
72-
"label": "strict component-store"
56+
"value": "component-store-all",
57+
"label": "component-store-all"
7358
},
7459
{
75-
"value": "all",
76-
"label": "all"
60+
"value": "operators-recommended",
61+
"label": "operators-recommended"
7762
},
7863
{
79-
"value": "all-requiring-type-checking",
80-
"label": "all with type checking"
64+
"value": "operators-all",
65+
"label": "operators-all"
8166
}
8267
]
8368
}

modules/eslint-plugin/scripts/generate-config.ts

Lines changed: 86 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,71 @@ import { writeFileSync } from 'fs';
22
import { join } from 'path';
33
import { format, resolveConfig } from 'prettier';
44
import type { NgRxRuleModule } from '../src/rule-creator';
5-
import { rules } from '../src/rules';
5+
import { rulesForGenerate } from '../src/utils/helper-functions/rules';
66

77
const prettierConfig = resolveConfig.sync(__dirname);
88

99
const RULE_MODULE = '@ngrx';
1010
const CONFIG_DIRECTORY = './modules/eslint-plugin/src/configs/';
1111

12-
writeConfig(
13-
'recommended',
14-
(rule) =>
15-
!!rule.meta.docs?.recommended && !rule.meta.docs?.requiresTypeChecking
16-
);
17-
18-
writeConfig('all', (rule) => !rule.meta.docs?.requiresTypeChecking);
19-
20-
writeConfig(
21-
'strict',
22-
(rule) => !rule.meta.docs?.requiresTypeChecking,
23-
() => 'error'
24-
);
25-
26-
writeConfig(
27-
'recommended-requiring-type-checking',
28-
(rule) => !!rule.meta.docs?.recommended
29-
);
30-
31-
writeConfig('all-requiring-type-checking', () => true);
32-
33-
writeConfig(
34-
'strict-requiring-type-checking',
35-
() => true,
36-
() => 'error'
37-
);
12+
writeConfig('recommended', (rule) => !rule.meta.docs?.requiresTypeChecking);
13+
writeConfig('all', (_rule) => true);
3814

3915
writeConfig(
40-
'store',
16+
'store-recommended',
4117
(rule) =>
4218
rule.meta.ngrxModule === 'store' && !rule.meta.docs?.requiresTypeChecking
4319
);
20+
writeConfig('store-all', (rule) => rule.meta.ngrxModule === 'store');
4421

4522
writeConfig(
46-
'store-strict',
47-
(rule) =>
48-
rule.meta.ngrxModule === 'store' && !rule.meta.docs?.requiresTypeChecking,
49-
() => 'error'
50-
);
51-
52-
writeConfig(
53-
'effects',
23+
'effects-recommended',
5424
(rule) =>
5525
rule.meta.ngrxModule === 'effects' && !rule.meta.docs?.requiresTypeChecking
5626
);
27+
writeConfig('effects-all', (rule) => rule.meta.ngrxModule === 'effects');
5728

5829
writeConfig(
59-
'effects-strict',
30+
'component-store-recommended',
6031
(rule) =>
61-
rule.meta.ngrxModule === 'effects' && !rule.meta.docs?.requiresTypeChecking,
62-
() => 'error'
63-
);
64-
65-
writeConfig(
66-
'effects-requiring-type-checking',
67-
(rule) => rule.meta.ngrxModule === 'effects'
32+
rule.meta.ngrxModule === 'component-store' &&
33+
!rule.meta.docs?.requiresTypeChecking
6834
);
6935

7036
writeConfig(
71-
'effects-strict-requiring-type-checking',
72-
(rule) => rule.meta.ngrxModule === 'effects',
73-
() => 'error'
37+
'component-store-all',
38+
(rule) => rule.meta.ngrxModule === 'component-store'
7439
);
7540

7641
writeConfig(
77-
'component-store',
42+
'operators-recommended',
7843
(rule) =>
79-
rule.meta.ngrxModule === 'component-store' &&
44+
rule.meta.ngrxModule === 'operators' &&
8045
!rule.meta.docs?.requiresTypeChecking
8146
);
8247

83-
writeConfig(
84-
'component-store-strict',
85-
(rule) =>
86-
rule.meta.ngrxModule === 'component-store' &&
87-
!rule.meta.docs?.requiresTypeChecking,
88-
() => 'error'
89-
);
48+
writeConfig('operators-all', (rule) => rule.meta.ngrxModule === 'operators');
9049

9150
function writeConfig(
9251
configName:
9352
| 'all'
9453
| 'recommended'
95-
| 'strict'
96-
| 'all-requiring-type-checking'
97-
| 'recommended-requiring-type-checking'
98-
| 'strict-requiring-type-checking'
99-
| 'store'
100-
| 'store-strict'
101-
| 'effects'
102-
| 'effects-requiring-type-checking'
103-
| 'effects-strict'
104-
| 'effects-strict-requiring-type-checking'
105-
| 'component-store'
106-
| 'component-store-strict',
107-
predicate: (rule: NgRxRuleModule<[], string>) => boolean,
108-
setting = (rule: NgRxRuleModule<[], string>) =>
109-
rule.meta.docs?.recommended || 'warn'
54+
| 'store-recommended'
55+
| 'store-all'
56+
| 'effects-recommended'
57+
| 'effects-all'
58+
| 'component-store-recommended'
59+
| 'component-store-all'
60+
| 'operators-recommended'
61+
| 'operators-all',
62+
predicate: (rule: NgRxRuleModule<[], string>) => boolean
11063
) {
111-
const rulesForConfig = Object.entries(rules).filter(([_, rule]) =>
64+
const rulesForConfig = Object.entries(rulesForGenerate).filter(([_, rule]) =>
11265
predicate(rule)
11366
);
11467
const configRules = rulesForConfig.reduce<Record<string, string>>(
115-
(rules, [ruleName, rule]) => {
116-
rules[`${RULE_MODULE}/${ruleName}`] = setting(rule);
68+
(rules, [ruleName, _rule]) => {
69+
rules[`${RULE_MODULE}/${ruleName}`] = 'error';
11770
return rules;
11871
},
11972
{}
@@ -127,22 +80,66 @@ function writeConfig(
12780
}
12881
: null;
12982

130-
const code = `
131-
/**
132-
* DO NOT EDIT
133-
* This file is generated
134-
*/
135-
136-
export = {
137-
parser: "@typescript-eslint/parser",
138-
${parserOptions ? `parserOptions: ${JSON.stringify(parserOptions)},` : ''}
139-
plugins: ["${RULE_MODULE}"],
140-
rules: ${JSON.stringify(configRules)},
141-
}
142-
`;
143-
const config = format(code, {
83+
const tsCode = `
84+
/**
85+
* DO NOT EDIT
86+
* This file is generated
87+
*/
88+
89+
import type { TSESLint } from '@typescript-eslint/utils';
90+
91+
export default (
92+
plugin: TSESLint.FlatConfig.Plugin,
93+
parser: TSESLint.FlatConfig.Parser,
94+
): TSESLint.FlatConfig.ConfigArray => [
95+
{
96+
name: 'ngrx/base',
97+
languageOptions: {
98+
parser,
99+
sourceType: 'module',
100+
},
101+
plugins: {
102+
'@ngrx': plugin,
103+
},
104+
},
105+
{
106+
name: 'ngrx/${configName}',
107+
languageOptions: {
108+
parser,
109+
${
110+
parserOptions
111+
? `parserOptions: ${JSON.stringify(parserOptions, null, 2)},`
112+
: ''
113+
}
114+
},
115+
rules: ${JSON.stringify(configRules, null, 2)}
116+
},
117+
];`;
118+
const tsConfigFormatted = format(tsCode, {
144119
parser: 'typescript',
145120
...prettierConfig,
146121
});
147-
writeFileSync(join(CONFIG_DIRECTORY, `${configName}.ts`), config);
122+
writeFileSync(join(CONFIG_DIRECTORY, `${configName}.ts`), tsConfigFormatted);
123+
124+
const jsonConfig: { [key: string]: any } = {
125+
parser: '@typescript-eslint/parser',
126+
plugins: ['@ngrx'],
127+
rules: configRules,
128+
};
129+
if (configName.includes('all')) {
130+
jsonConfig.parserOptions = {
131+
ecmaVersion: 2020,
132+
sourceType: 'module',
133+
project: './tsconfig.json',
134+
};
135+
}
136+
const jsonConfigFormatted = format(JSON.stringify(jsonConfig, null, 2), {
137+
parser: 'json',
138+
...prettierConfig,
139+
});
140+
141+
writeFileSync(
142+
join(CONFIG_DIRECTORY, `${configName}.json`),
143+
jsonConfigFormatted
144+
);
148145
}

modules/eslint-plugin/scripts/generate-docs.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { readFileSync, writeFileSync, existsSync } from 'fs';
22
import * as path from 'path';
33
import { format, resolveConfig } from 'prettier';
4-
import { rules } from '../src/rules';
4+
import { rulesForGenerate } from '../src/utils/helper-functions/rules';
55

66
const prettierConfig = resolveConfig.sync(__dirname);
77
const PLACEHOLDER = '<!-- MANUAL-DOC:START -->';
88
const RULES_PATH = './projects/ngrx.io/content/guide/eslint-plugin/rules';
99

10-
for (const [ruleName, { meta }] of Object.entries(rules)) {
10+
for (const [ruleName, { meta }] of Object.entries(rulesForGenerate)) {
1111
const docPath = path.join(RULES_PATH, `${ruleName}.md`);
1212
if (!existsSync(docPath)) {
1313
writeFileSync(docPath, ``);
@@ -24,11 +24,12 @@ ${meta.version ? '> Required NgRx Version Range: ${meta.version}' : ''}
2424
${meta.docs?.description}
2525
2626
- **Type**: ${meta.type}
27-
- **Recommended**: ${meta.docs?.recommended ? 'Yes' : 'No'}
2827
- **Fixable**: ${meta.fixable ? 'Yes' : 'No'}
2928
- **Suggestion**: ${meta.hasSuggestions ? 'Yes' : 'No'}
3029
- **Requires type checking**: ${meta.docs?.requiresTypeChecking ? 'Yes' : 'No'}
31-
- **Configurable**: ${meta.schema.length ? 'Yes' : 'No'}
30+
- **Configurable**: ${
31+
Array.isArray(meta.schema) && meta.schema.length ? 'Yes' : 'No'
32+
}
3233
3334
<!-- Everything above this generated, do not edit -->
3435
<!-- MANUAL-DOC:START -->

0 commit comments

Comments
 (0)