Skip to content

Commit

Permalink
feat(eslint-plugin): support ESLint v9 (and v8) (#4371)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored Jun 5, 2024
1 parent 822a5e0 commit e8d9ffa
Show file tree
Hide file tree
Showing 153 changed files with 2,888 additions and 2,214 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ version: 2.1
# See https://blog.daemonl.com/2016/02/yaml.html
# To validate changes, use an online parser, eg.
# https://yaml-online-parser.appspot.com/
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.14.1
var_1: &cache_key yarn-cache-{{ checksum "yarn.lock" }}-0.18.0
var_2: &run_in_node
docker:
- image: cimg/node:20.11
Expand Down
4 changes: 1 addition & 3 deletions modules/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,11 @@
},
"sideEffects": false,
"dependencies": {
"@typescript-eslint/experimental-utils": "^5.4.0",
"eslint-etc": "^5.1.0",
"semver": "^7.3.5",
"strip-json-comments": "3.1.1"
},
"peerDependencies": {
"eslint": ">=8.0.0",
"eslint": "^8.57.0 || ^9.0.0",
"typescript": "*"
}
}
67 changes: 26 additions & 41 deletions modules/eslint-plugin/schematics/ng-add/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,15 @@
"default": "recommended",
"enum": [
"recommended",
"recommended-requiring-type-checking",
"strict",
"strict-requiring-type-checking",
"store",
"store-strict",
"effects",
"effects-requiring-type-checking",
"effects-strict",
"component-store",
"component-store-strict",
"all",
"all-requiring-type-checking"
"store-recommended",
"store-all",
"effects-recommended",
"effects-all",
"component-store-recommended",
"component-store-all",
"operators-recommended",
"operators-all"
],
"x-prompt": {
"message": "Which ESLint configuration would you like to use?",
Expand All @@ -32,52 +29,40 @@
"label": "recommended"
},
{
"value": "recommended-requiring-type-checking",
"label": "recommended with type checking"
},
{
"value": "strict",
"label": "strict"
},
{
"value": "strict-requiring-type-checking",
"label": "strict with type checking"
},
{
"value": "store",
"label": "store"
"value": "all",
"label": "all"
},
{
"value": "store-strict",
"label": "strict store"
"value": "store-recommended",
"label": "store-recommended"
},
{
"value": "effects",
"label": "effects"
"value": "store-all",
"label": "store-all"
},
{
"value": "effects-requiring-type-checking",
"label": "effects with type checking"
"value": "effects-recommended",
"label": "effects-recommended"
},
{
"value": "effects-strict",
"label": "strict effects"
"value": "effects-all",
"label": "effects-all"
},
{
"value": "component-store",
"label": "component-store"
"value": "component-store-recommended",
"label": "component-store-recommended"
},
{
"value": "component-store-strict",
"label": "strict component-store"
"value": "component-store-all",
"label": "component-store-all"
},
{
"value": "all",
"label": "all"
"value": "operators-recommended",
"label": "operators-recommended"
},
{
"value": "all-requiring-type-checking",
"label": "all with type checking"
"value": "operators-all",
"label": "operators-all"
}
]
}
Expand Down
175 changes: 86 additions & 89 deletions modules/eslint-plugin/scripts/generate-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,118 +2,71 @@ import { writeFileSync } from 'fs';
import { join } from 'path';
import { format, resolveConfig } from 'prettier';
import type { NgRxRuleModule } from '../src/rule-creator';
import { rules } from '../src/rules';
import { rulesForGenerate } from '../src/utils/helper-functions/rules';

const prettierConfig = resolveConfig.sync(__dirname);

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

writeConfig(
'recommended',
(rule) =>
!!rule.meta.docs?.recommended && !rule.meta.docs?.requiresTypeChecking
);

writeConfig('all', (rule) => !rule.meta.docs?.requiresTypeChecking);

writeConfig(
'strict',
(rule) => !rule.meta.docs?.requiresTypeChecking,
() => 'error'
);

writeConfig(
'recommended-requiring-type-checking',
(rule) => !!rule.meta.docs?.recommended
);

writeConfig('all-requiring-type-checking', () => true);

writeConfig(
'strict-requiring-type-checking',
() => true,
() => 'error'
);
writeConfig('recommended', (rule) => !rule.meta.docs?.requiresTypeChecking);
writeConfig('all', (_rule) => true);

writeConfig(
'store',
'store-recommended',
(rule) =>
rule.meta.ngrxModule === 'store' && !rule.meta.docs?.requiresTypeChecking
);
writeConfig('store-all', (rule) => rule.meta.ngrxModule === 'store');

writeConfig(
'store-strict',
(rule) =>
rule.meta.ngrxModule === 'store' && !rule.meta.docs?.requiresTypeChecking,
() => 'error'
);

writeConfig(
'effects',
'effects-recommended',
(rule) =>
rule.meta.ngrxModule === 'effects' && !rule.meta.docs?.requiresTypeChecking
);
writeConfig('effects-all', (rule) => rule.meta.ngrxModule === 'effects');

writeConfig(
'effects-strict',
'component-store-recommended',
(rule) =>
rule.meta.ngrxModule === 'effects' && !rule.meta.docs?.requiresTypeChecking,
() => 'error'
);

writeConfig(
'effects-requiring-type-checking',
(rule) => rule.meta.ngrxModule === 'effects'
rule.meta.ngrxModule === 'component-store' &&
!rule.meta.docs?.requiresTypeChecking
);

writeConfig(
'effects-strict-requiring-type-checking',
(rule) => rule.meta.ngrxModule === 'effects',
() => 'error'
'component-store-all',
(rule) => rule.meta.ngrxModule === 'component-store'
);

writeConfig(
'component-store',
'operators-recommended',
(rule) =>
rule.meta.ngrxModule === 'component-store' &&
rule.meta.ngrxModule === 'operators' &&
!rule.meta.docs?.requiresTypeChecking
);

writeConfig(
'component-store-strict',
(rule) =>
rule.meta.ngrxModule === 'component-store' &&
!rule.meta.docs?.requiresTypeChecking,
() => 'error'
);
writeConfig('operators-all', (rule) => rule.meta.ngrxModule === 'operators');

function writeConfig(
configName:
| 'all'
| 'recommended'
| 'strict'
| 'all-requiring-type-checking'
| 'recommended-requiring-type-checking'
| 'strict-requiring-type-checking'
| 'store'
| 'store-strict'
| 'effects'
| 'effects-requiring-type-checking'
| 'effects-strict'
| 'effects-strict-requiring-type-checking'
| 'component-store'
| 'component-store-strict',
predicate: (rule: NgRxRuleModule<[], string>) => boolean,
setting = (rule: NgRxRuleModule<[], string>) =>
rule.meta.docs?.recommended || 'warn'
| 'store-recommended'
| 'store-all'
| 'effects-recommended'
| 'effects-all'
| 'component-store-recommended'
| 'component-store-all'
| 'operators-recommended'
| 'operators-all',
predicate: (rule: NgRxRuleModule<[], string>) => boolean
) {
const rulesForConfig = Object.entries(rules).filter(([_, rule]) =>
const rulesForConfig = Object.entries(rulesForGenerate).filter(([_, rule]) =>
predicate(rule)
);
const configRules = rulesForConfig.reduce<Record<string, string>>(
(rules, [ruleName, rule]) => {
rules[`${RULE_MODULE}/${ruleName}`] = setting(rule);
(rules, [ruleName, _rule]) => {
rules[`${RULE_MODULE}/${ruleName}`] = 'error';
return rules;
},
{}
Expand All @@ -127,22 +80,66 @@ function writeConfig(
}
: null;

const code = `
/**
* DO NOT EDIT
* This file is generated
*/
export = {
parser: "@typescript-eslint/parser",
${parserOptions ? `parserOptions: ${JSON.stringify(parserOptions)},` : ''}
plugins: ["${RULE_MODULE}"],
rules: ${JSON.stringify(configRules)},
}
`;
const config = format(code, {
const tsCode = `
/**
* DO NOT EDIT
* This file is generated
*/
import type { TSESLint } from '@typescript-eslint/utils';
export default (
plugin: TSESLint.FlatConfig.Plugin,
parser: TSESLint.FlatConfig.Parser,
): TSESLint.FlatConfig.ConfigArray => [
{
name: 'ngrx/base',
languageOptions: {
parser,
sourceType: 'module',
},
plugins: {
'@ngrx': plugin,
},
},
{
name: 'ngrx/${configName}',
languageOptions: {
parser,
${
parserOptions
? `parserOptions: ${JSON.stringify(parserOptions, null, 2)},`
: ''
}
},
rules: ${JSON.stringify(configRules, null, 2)}
},
];`;
const tsConfigFormatted = format(tsCode, {
parser: 'typescript',
...prettierConfig,
});
writeFileSync(join(CONFIG_DIRECTORY, `${configName}.ts`), config);
writeFileSync(join(CONFIG_DIRECTORY, `${configName}.ts`), tsConfigFormatted);

const jsonConfig: { [key: string]: any } = {
parser: '@typescript-eslint/parser',
plugins: ['@ngrx'],
rules: configRules,
};
if (configName.includes('all')) {
jsonConfig.parserOptions = {
ecmaVersion: 2020,
sourceType: 'module',
project: './tsconfig.json',
};
}
const jsonConfigFormatted = format(JSON.stringify(jsonConfig, null, 2), {
parser: 'json',
...prettierConfig,
});

writeFileSync(
join(CONFIG_DIRECTORY, `${configName}.json`),
jsonConfigFormatted
);
}
9 changes: 5 additions & 4 deletions modules/eslint-plugin/scripts/generate-docs.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { readFileSync, writeFileSync, existsSync } from 'fs';
import * as path from 'path';
import { format, resolveConfig } from 'prettier';
import { rules } from '../src/rules';
import { rulesForGenerate } from '../src/utils/helper-functions/rules';

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

for (const [ruleName, { meta }] of Object.entries(rules)) {
for (const [ruleName, { meta }] of Object.entries(rulesForGenerate)) {
const docPath = path.join(RULES_PATH, `${ruleName}.md`);
if (!existsSync(docPath)) {
writeFileSync(docPath, ``);
Expand All @@ -24,11 +24,12 @@ ${meta.version ? '> Required NgRx Version Range: ${meta.version}' : ''}
${meta.docs?.description}
- **Type**: ${meta.type}
- **Recommended**: ${meta.docs?.recommended ? 'Yes' : 'No'}
- **Fixable**: ${meta.fixable ? 'Yes' : 'No'}
- **Suggestion**: ${meta.hasSuggestions ? 'Yes' : 'No'}
- **Requires type checking**: ${meta.docs?.requiresTypeChecking ? 'Yes' : 'No'}
- **Configurable**: ${meta.schema.length ? 'Yes' : 'No'}
- **Configurable**: ${
Array.isArray(meta.schema) && meta.schema.length ? 'Yes' : 'No'
}
<!-- Everything above this generated, do not edit -->
<!-- MANUAL-DOC:START -->
Expand Down
Loading

0 comments on commit e8d9ffa

Please sign in to comment.