@jkba/eslint-config-angular 1.7.1 → 2.1.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 (3) hide show
  1. package/README.md +4 -7
  2. package/eslint.config.js +167 -184
  3. package/package.json +7 -10
package/README.md CHANGED
@@ -5,25 +5,22 @@
5
5
 
6
6
  Opinionated ESLint config for Angular projects
7
7
 
8
- > ⚠️ **Support for ESLint v9**: See issue https://github.com/jmeinlschmidt/eslint-config-angular/issues/17
9
-
10
8
 
11
9
  ## Installation
12
10
 
13
11
  ```sh
14
12
  npm i -D \
15
13
  prettier \
16
- @angular-eslint/eslint-plugin \
17
- @angular-eslint/eslint-plugin-template \
18
- @angular-eslint/template-parser \
19
- @typescript-eslint/eslint-plugin \
20
- @typescript-eslint/parser \
14
+ angular-eslint \
21
15
  eslint-plugin-import \
22
16
  eslint-config-prettier \
23
17
  eslint-plugin-prettier \
24
18
  eslint-plugin-rxjs \
25
19
  eslint-plugin-rxjs-angular \
26
20
  eslint-import-resolver-typescript \
21
+ @eslint/js \
22
+ typescript-eslint \
23
+ @smarttools/eslint-plugin-rxjs \
27
24
  @jkba/eslint-config-angular
28
25
 
29
26
  ```
package/eslint.config.js CHANGED
@@ -1,194 +1,177 @@
1
- module.exports = {
2
- overrides: [
3
- {
4
- files: [
5
- '*.ts'
6
- ],
7
- parser: '@typescript-eslint/parser',
8
- parserOptions: {
9
- ecmaVersion: 2019,
10
- project: './tsconfig.json',
11
- sourceType: 'module',
12
- },
13
- extends: [
14
- 'eslint:recommended',
15
- 'plugin:@typescript-eslint/stylistic-type-checked',
16
- 'plugin:@typescript-eslint/strict-type-checked',
17
- 'plugin:@angular-eslint/recommended',
18
- 'plugin:@angular-eslint/template/process-inline-templates',
19
- 'plugin:rxjs/recommended', // For some unknown weird reason, this plugin needs to be installed in child project as well.
20
- 'plugin:import/recommended',
21
- 'plugin:import/typescript',
1
+ // @ts-check
22
2
 
23
- // Prettier rule must always be the very last!
24
- // This rule might intentionally disable some rules declared above due to conflicts
25
- 'plugin:prettier/recommended',
26
- ],
27
- plugins: ['@typescript-eslint', '@angular-eslint', 'rxjs', 'rxjs-angular', 'import'],
28
- settings: {
29
- // Reference https://www.npmjs.com/package/eslint-plugin-import
30
- 'import/resolver': {
31
- // You will also need to install and configure the TypeScript resolver
32
- // See also https://github.com/import-js/eslint-import-resolver-typescript#configuration
33
- 'typescript': true,
34
- 'node': true,
35
- }
3
+ const eslint = require('@eslint/js');
4
+ const tseslint = require('typescript-eslint');
5
+ const angular = require('angular-eslint');
6
+ const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');
7
+ const importPlugin = require('eslint-plugin-import');
8
+ const rxjs = require('@smarttools/eslint-plugin-rxjs');
9
+
10
+ const config = tseslint.config(
11
+ {
12
+ files: ['**/*.ts'],
13
+ processor: angular.processInlineTemplates,
14
+ extends: [
15
+ eslint.configs.recommended,
16
+ tseslint.configs.stylisticTypeChecked,
17
+ tseslint.configs.strictTypeChecked,
18
+ angular.configs.tsRecommended,
19
+ // TODO
20
+ // 'plugin:rxjs/recommended', // For some unknown weird reason, this plugin needs to be installed in child project as well.
21
+ importPlugin.flatConfigs?.recommended,
22
+ importPlugin.flatConfigs?.typescript,
23
+ ],
24
+ plugins: { rxjs },
25
+ settings: {
26
+ // Reference https://www.npmjs.com/package/eslint-plugin-import
27
+ 'import/resolver': {
28
+ // You will also need to install and configure the TypeScript resolver
29
+ // See also https://github.com/import-js/eslint-import-resolver-typescript#configuration
30
+ typescript: true,
31
+ node: true,
36
32
  },
37
- rules: {
38
- 'no-implicit-coercion': 'error',
39
- 'no-self-compare': 'error',
40
- 'no-unmodified-loop-condition': 'error',
41
- 'no-unreachable-loop': 'error',
42
- 'default-case': 'warn',
43
- 'eqeqeq': 'error',
44
- 'max-classes-per-file': 'error',
45
- 'no-warning-comments': [ 'error', { 'terms': ['todo', 'fixme'], 'location': 'anywhere' } ],
46
- 'no-console': 'error',
47
- 'prefer-template': 'error',
48
- 'arrow-body-style': ['error', 'as-needed'],
33
+ },
34
+ rules: {
35
+ 'no-implicit-coercion': 'error',
36
+ 'no-self-compare': 'error',
37
+ 'no-unmodified-loop-condition': 'error',
38
+ 'no-unreachable-loop': 'error',
39
+ 'default-case': 'warn',
40
+ eqeqeq: 'error',
41
+ 'max-classes-per-file': 'error',
42
+ 'no-warning-comments': ['error', { terms: ['todo', 'fixme'], location: 'anywhere' }],
43
+ 'no-console': 'error',
44
+ 'prefer-template': 'error',
45
+ 'arrow-body-style': ['error', 'as-needed'],
49
46
 
50
- /**
51
- * Declaration sort is handled by import/order rule.
52
- * This rule handles order within {}-brackets only.
53
- */
54
- 'sort-imports': [ 'error', { 'ignoreDeclarationSort': true }],
47
+ /**
48
+ * Declaration sort is handled by import/order rule.
49
+ * This rule handles order within {}-brackets only.
50
+ */
51
+ 'sort-imports': ['error', { ignoreDeclarationSort: true }],
55
52
 
56
- /**
57
- * Handled by https://typescript-eslint.io/rules/no-unused-vars/
58
- * You must disable the base rule as it can report incorrect errors
59
- */
60
- 'no-unused-vars': 'off',
53
+ /**
54
+ * Handled by https://typescript-eslint.io/rules/no-unused-vars/
55
+ * You must disable the base rule as it can report incorrect errors
56
+ */
57
+ 'no-unused-vars': 'off',
61
58
 
62
- 'rxjs-angular/prefer-async-pipe': 'warn',
63
- 'rxjs-angular/prefer-composition': 'off', // I prefer takeUntilDestroyed() operator
64
- 'rxjs-angular/prefer-takeuntil': [
65
- 'warn',
66
- {
67
- alias: ['takeUntilDestroyed'],
68
- checkDestroy: false,
69
- checkComplete: false,
70
- }
71
- ],
59
+ // Reference https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/finnish.md
60
+ 'rxjs/finnish': [
61
+ 'error',
62
+ {
63
+ functions: false,
64
+ methods: false,
65
+ names: {
66
+ '^(canActivate|canActivateChild|canDeactivate|canLoad|intercept|resolve|validate)$': false,
67
+ },
68
+ parameters: true,
69
+ properties: true,
70
+ strict: false,
71
+ types: {
72
+ '^EventEmitter$': false,
73
+ '^Store$': false,
74
+ },
75
+ variables: true,
76
+ },
77
+ ],
78
+ 'rxjs/no-exposed-subjects': ['error', { allowProtected: true }],
79
+ 'rxjs/no-compat': 'error',
80
+ 'rxjs/throw-error': 'error',
72
81
 
73
- // Reference https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/finnish.md
74
- 'rxjs/finnish': [
75
- 'error',
76
- {
77
- 'functions': false,
78
- 'methods': false,
79
- 'names': {
80
- '^(canActivate|canActivateChild|canDeactivate|canLoad|intercept|resolve|validate)$': false
81
- },
82
- 'parameters': true,
83
- 'properties': true,
84
- 'strict': false,
85
- 'types': {
86
- '^EventEmitter$': false,
87
- '^Store$': false
88
- },
89
- 'variables': true
90
- }
91
- ],
92
- 'rxjs/no-exposed-subjects': [ 'error', { 'allowProtected': true } ],
93
- 'rxjs/no-compat': 'error',
94
- 'rxjs/throw-error': 'error',
95
-
96
- '@typescript-eslint/no-unused-vars': ['error', { 'args': 'after-used' }],
97
- '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }], // Ignore `Validators.required` etc.
98
- '@typescript-eslint/no-confusing-void-expression': 'off', // I just simply disagree with this rule
99
- '@typescript-eslint/explicit-member-accessibility': [
100
- 'error', { 'overrides': { 'constructors': 'no-public' } }
101
- ],
102
- "@typescript-eslint/prefer-optional-chain": "error",
103
-
104
- '@angular-eslint/no-input-rename': 'off', // I just simply disagree with this rule. Especially while using "transform" property.
105
- '@angular-eslint/sort-ngmodule-metadata-arrays': 'error',
106
- '@angular-eslint/prefer-on-push-component-change-detection': 'error',
107
- '@angular-eslint/use-component-view-encapsulation': 'warn', // For me, it is only a suggestion
108
- '@angular-eslint/prefer-output-readonly': 'error', // TODO: https://github.com/jmeinlschmidt/eslint-config-angular/issues/14
109
- '@angular-eslint/contextual-decorator': 'error',
110
- '@angular-eslint/component-max-inline-declarations': [ 'error', { 'template': 20 } ],
111
- '@angular-eslint/no-attribute-decorator': 'error',
112
- '@angular-eslint/no-conflicting-lifecycle': 'error',
113
- '@angular-eslint/no-empty-lifecycle-method': 'error',
114
- '@angular-eslint/no-forward-ref': 'warn', // For me, it is only a suggestion
115
- '@angular-eslint/no-input-prefix': 'error',
116
- '@angular-eslint/no-lifecycle-call': 'error',
117
- '@angular-eslint/no-pipe-impure': 'error',
118
- '@angular-eslint/no-queries-metadata-property': 'error',
119
- '@angular-eslint/prefer-standalone-component': 'error',
120
- '@angular-eslint/relative-url-prefix': 'error',
121
- // '@angular-eslint/require-localize-metadata': 'error', // TODO: https://github.com/jmeinlschmidt/eslint-config-angular/issues/13
122
- '@angular-eslint/use-component-selector': 'error',
123
- "@angular-eslint/component-selector": [
124
- "error",
125
- {
126
- "type": "element",
127
- "prefix": "app",
128
- "style": "kebab-case",
129
- }
130
- ],
131
- "@angular-eslint/directive-selector": [
132
- "error",
133
- {
134
- "type": "attribute",
135
- "prefix": "app",
136
- "style": "kebab-case", // I just don't really agree with using camelCase. Material isn't using it neither.
137
- }
138
- ],
139
-
140
- 'import/no-absolute-path': 'error',
141
- 'import/newline-after-import': [ 'error', { 'count': 1 } ],
142
- 'import/order': [
143
- 'error',
144
- {
145
- 'groups': [
146
- ['builtin', 'external'],
147
- 'internal',
148
- 'parent',
149
- 'sibling',
150
- 'index',
151
- ],
152
- 'newlines-between': 'always',
153
- 'alphabetize': {
154
- 'order': 'asc',
155
- 'caseInsensitive': true
156
- }
157
- }
158
- ],
159
- 'import/no-useless-path-segments': ['error', { noUselessIndex: true }],
160
- // 'import/no-deprecated': 'error', // Throws false-positive for RxJS,
161
- 'import/no-self-import': 'error',
162
- },
163
- },
164
- {
165
- files: [
166
- '*.html'
82
+ '@typescript-eslint/no-unused-vars': ['error', { args: 'after-used' }],
83
+ '@typescript-eslint/unbound-method': ['error', { ignoreStatic: true }], // Ignore `Validators.required` etc.
84
+ '@typescript-eslint/no-confusing-void-expression': 'off', // I just simply disagree with this rule
85
+ '@typescript-eslint/explicit-member-accessibility': [
86
+ 'error',
87
+ { overrides: { constructors: 'no-public' } },
167
88
  ],
168
- parser: '@angular-eslint/template-parser',
169
- extends: [
170
- 'plugin:@angular-eslint/template/accessibility',
171
- 'plugin:@angular-eslint/template/recommended',
89
+ '@typescript-eslint/prefer-optional-chain': 'error',
172
90
 
173
- // Prettier rule must always be the very last!
174
- // This rule might intentionally disable some rules declared above due to conflicts
175
- 'plugin:prettier/recommended',
91
+ '@angular-eslint/no-input-rename': 'off', // I just simply disagree with this rule. Especially while using "transform" property.
92
+ '@angular-eslint/prefer-on-push-component-change-detection': 'error',
93
+ '@angular-eslint/use-component-view-encapsulation': 'warn', // For me, it is only a suggestion
94
+ '@angular-eslint/prefer-output-readonly': 'error', // TODO: https://github.com/jmeinlschmidt/eslint-config-angular/issues/14
95
+ '@angular-eslint/contextual-decorator': 'error',
96
+ '@angular-eslint/component-max-inline-declarations': ['error', { template: 20 }],
97
+ '@angular-eslint/no-attribute-decorator': 'error',
98
+ '@angular-eslint/no-conflicting-lifecycle': 'error',
99
+ '@angular-eslint/no-empty-lifecycle-method': 'error',
100
+ '@angular-eslint/no-forward-ref': 'warn', // For me, it is only a suggestion
101
+ '@angular-eslint/no-input-prefix': 'error',
102
+ '@angular-eslint/no-lifecycle-call': 'error',
103
+ '@angular-eslint/no-pipe-impure': 'error',
104
+ '@angular-eslint/no-queries-metadata-property': 'error',
105
+ '@angular-eslint/prefer-standalone': 'error',
106
+ '@angular-eslint/prefer-signals': 'error',
107
+ '@angular-eslint/relative-url-prefix': 'error',
108
+ // '@angular-eslint/require-localize-metadata': 'error', // TODO: https://github.com/jmeinlschmidt/eslint-config-angular/issues/13
109
+ '@angular-eslint/use-component-selector': 'error',
110
+ '@angular-eslint/component-selector': [
111
+ 'error',
112
+ {
113
+ type: 'element',
114
+ prefix: 'app',
115
+ style: 'kebab-case',
116
+ },
117
+ ],
118
+ '@angular-eslint/directive-selector': [
119
+ 'error',
120
+ {
121
+ type: 'attribute',
122
+ prefix: 'app',
123
+ style: 'kebab-case', // I just don't really agree with using camelCase. Material isn't using it neither.
124
+ },
176
125
  ],
177
- plugins: ['@angular-eslint/template'],
178
- rules: {
179
- '@angular-eslint/template/attributes-order': 'error',
180
- '@angular-eslint/template/no-inline-styles': 'warn', // For me, it is only a suggestion
181
- '@angular-eslint/template/conditional-complexity': [
182
- 'error', { 'maxComplexity': 3 } // Max 3 is enough, create derived variable with proper naming
183
- ],
184
- '@angular-eslint/template/i18n': 'error',
185
- '@angular-eslint/template/no-any': 'error',
186
- '@angular-eslint/template/no-duplicate-attributes': 'error',
187
- '@angular-eslint/template/no-interpolation-in-attributes': 'error',
188
- '@angular-eslint/template/prefer-self-closing-tags': 'error',
189
- '@angular-eslint/template/use-track-by-function': 'error',
190
- '@angular-eslint/template/prefer-control-flow': 'error'
191
- }
126
+
127
+ 'import/no-absolute-path': 'error',
128
+ 'import/newline-after-import': ['error', { count: 1 }],
129
+ 'import/order': [
130
+ 'error',
131
+ {
132
+ groups: [['builtin', 'external'], 'internal', 'parent', 'sibling', 'index'],
133
+ 'newlines-between': 'always',
134
+ alphabetize: {
135
+ order: 'asc',
136
+ caseInsensitive: true,
137
+ },
138
+ },
139
+ ],
140
+ 'import/no-useless-path-segments': ['error', { noUselessIndex: true }],
141
+ // 'import/no-deprecated': 'error', // Throws false-positive for RxJS,
142
+ 'import/no-self-import': 'error',
143
+ },
144
+ },
145
+ {
146
+ files: ['**/*.html'],
147
+ extends: [...angular.configs.templateRecommended, ...angular.configs.templateAccessibility],
148
+ rules: {
149
+ '@angular-eslint/template/attributes-order': 'error',
150
+ '@angular-eslint/template/no-inline-styles': 'warn', // For me, it is only a suggestion
151
+ '@angular-eslint/template/conditional-complexity': [
152
+ 'error',
153
+ { maxComplexity: 3 }, // Max 3 is enough, create derived variable with proper naming
154
+ ],
155
+ '@angular-eslint/template/i18n': 'error',
156
+ '@angular-eslint/template/no-any': 'error',
157
+ '@angular-eslint/template/no-duplicate-attributes': 'error',
158
+ '@angular-eslint/template/no-interpolation-in-attributes': 'error',
159
+ '@angular-eslint/template/prefer-self-closing-tags': 'error',
160
+ '@angular-eslint/template/use-track-by-function': 'error',
161
+ '@angular-eslint/template/prefer-control-flow': 'error',
192
162
  },
193
- ],
194
- }
163
+ },
164
+ // Prettier rule must always be the very last!
165
+ // This rule might intentionally disable some rules declared above due to conflicts
166
+ eslintPluginPrettierRecommended,
167
+ );
168
+
169
+ module.exports = config;
170
+
171
+ // notes
172
+
173
+ // these two are not supported anymore
174
+ // "eslint-plugin-rxjs": ">=5",
175
+ // "eslint-plugin-rxjs-angular": ">=2",
176
+
177
+ // todo, test if we really need peer deps
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jkba/eslint-config-angular",
3
- "version": "1.7.1",
3
+ "version": "2.1.0",
4
4
  "description": "Opinionated ESLint config for Angular projects",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -32,19 +32,16 @@
32
32
  },
33
33
  "homepage": "https://github.com/jmeinlschmidt/eslint-config-angular#readme",
34
34
  "peerDependencies": {
35
- "@angular-eslint/eslint-plugin": ">=16",
36
- "@angular-eslint/eslint-plugin-template": ">=16",
37
- "@angular-eslint/template-parser": ">=16",
38
- "@typescript-eslint/eslint-plugin": ">=6",
39
- "@typescript-eslint/parser": ">=6",
40
- "eslint": "^8",
35
+ "angular-eslint": "^19",
36
+ "eslint": "^9",
37
+ "@eslint/js": "^9",
41
38
  "eslint-config-prettier": ">=8",
42
39
  "eslint-import-resolver-typescript": ">=3.5.5",
43
40
  "eslint-plugin-import": ">=2.27.0",
44
41
  "eslint-plugin-prettier": ">=5",
45
- "eslint-plugin-rxjs": ">=5",
46
- "eslint-plugin-rxjs-angular": ">=2",
47
42
  "prettier": ">=3",
48
- "typescript": ">=4"
43
+ "typescript": ">=4",
44
+ "typescript-eslint": "^8",
45
+ "@smarttools/eslint-plugin-rxjs": "^1.0.0"
49
46
  }
50
47
  }