@dr.pogodin/eslint-configs 0.1.4 → 0.2.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/README.md CHANGED
@@ -21,9 +21,11 @@ This project is invisioned as a replacement for AirBnB ESLint configurations
21
21
  - [Getting Started]
22
22
  - [Provided Configs]
23
23
  - [`configs.javascript`]
24
+ - [`configs.javascriptNoPerf`]
24
25
  - [`configs.jest`]
25
26
  - [`configs.react`]
26
27
  - [`configs.typescript`]
28
+ - [`configs.typescriptNoPerf`]
27
29
 
28
30
  ## Getting Started
29
31
  [Getting Started]: #getting-started
@@ -116,6 +118,18 @@ them the following rule sets:
116
118
  the `recommended` rule set, with minor overrides, and many additional rules
117
119
  enabled.
118
120
 
121
+ - [Perfectionist] — the recommended rule set, with minor overrides,
122
+ such as the custom alphabet that places uppercase characters before lowercase
123
+ ones, and allowance to use empty lines to separate entities into different
124
+ sorting groups.
125
+
126
+ ### `configs.javascriptNoPerf`
127
+ [`configs.javascriptNoPerf`]: #configsjavascriptnoperf
128
+
129
+ The same as [`configs.javascript`] above, but without [Perfectionist] rules.
130
+ Essentially, it is equivalent to [`configs.javascript`] from this library prior
131
+ to its [v0.2.0](https://github.com/birdofpreyru/eslint-configs/releases/tag/v0.2.0) release.
132
+
119
133
  ### `configs.jest`
120
134
  [`configs.jest`]: #configsjest
121
135
 
@@ -162,6 +176,14 @@ and it applies to them the following rule sets:
162
176
  the `recommendedTypeChecked` and `stylisticTypeChecked` rule sets, with minor
163
177
  overrides, and many additional rules enabled.
164
178
 
179
+ ### `configs.typescriptNoPerf`
180
+ [`configs.typescriptNoPerf`]: #configstypescriptnoperf
181
+
182
+ The same as [`configs.typescript`] above, but without [Perfectionist] rules.
183
+ Essentially, it is equivalent to [`configs.typescript`] from this library prior
184
+ to its [v0.2.0](https://github.com/birdofpreyru/eslint-configs/releases/tag/v0.2.0) release.
185
+
165
186
  [Babel]: https://babeljs.io
166
187
  [ESLint]: https://eslint.org
167
- [eslint-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb
188
+ [eslint-config-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb
189
+ [Perfectionist]: https://perfectionist.dev
package/config/index.js CHANGED
@@ -1,13 +1,15 @@
1
- import javascript from './javascript.js';
1
+ import javascript, { javascriptNoPerf } from './javascript.js';
2
2
  import jest from './jest.js';
3
3
  import react from './react.js';
4
- import typescript from './typescript.js';
4
+ import typescript, { typescriptNoPerf } from './typescript.js';
5
5
 
6
6
  export default {
7
7
  configs: {
8
8
  javascript,
9
+ javascriptNoPerf,
9
10
  jest,
10
11
  react,
11
12
  typescript,
13
+ typescriptNoPerf,
12
14
  },
13
15
  };
@@ -2,32 +2,22 @@
2
2
 
3
3
  import { defineConfig } from 'eslint/config';
4
4
  import importPlugin from 'eslint-plugin-import';
5
+ import perfectionist from 'eslint-plugin-perfectionist';
6
+ import { Alphabet } from 'eslint-plugin-perfectionist/alphabet';
5
7
 
6
8
  import babelParser from '@babel/eslint-parser';
7
9
  import babelPlugin from '@babel/eslint-plugin';
8
10
  import js from '@eslint/js';
9
11
  import stylisticPlugin from '@stylistic/eslint-plugin';
10
12
 
11
- export default defineConfig([{
12
- extends: [
13
+ function newConfig({ noPerf } = {}) {
14
+ const extentions = [
13
15
  'js/recommended',
14
16
  '@stylistic/recommended',
15
17
  importPlugin.flatConfigs.recommended,
16
- ],
17
- languageOptions: {
18
- parser: babelParser,
19
- },
20
- linterOptions: {
21
- reportUnusedDisableDirectives: 'error',
22
- reportUnusedInlineConfigs: 'error',
23
- },
24
- name: 'dr.pogodin/javascript',
25
- plugins: {
26
- '@babel': babelPlugin,
27
- '@stylistic': stylisticPlugin,
28
- js,
29
- },
30
- rules: {
18
+ ];
19
+
20
+ const rules = {
31
21
  // These rules are provided by "@babel/eslint-plugin", and they require
32
22
  // to disable (to not enable) their counterparts from ESLint core.
33
23
  '@babel/new-cap': 'error',
@@ -72,9 +62,6 @@ export default defineConfig([{
72
62
  'import/no-unused-modules': 'error',
73
63
  'import/no-useless-path-segments': 'error',
74
64
  'import/no-webpack-loader-syntax': 'error',
75
- 'import/order': ['error', {
76
- groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
77
- }],
78
65
 
79
66
  // These rules are provided by "@stylistic/eslint-plugin",
80
67
  // and (re-)configured for our taste, somewhat differently from
@@ -265,28 +252,71 @@ export default defineConfig([{
265
252
  'require-atomic-updates': 'error',
266
253
  'require-await': 'error',
267
254
  'require-yield': 'error',
268
-
269
- // TODO: Disabled for now, as there is one thing I don't like about it:
270
- // in TypeScript it sorts type imports together with other imported members,
271
- // while I'd prefer to have all type member imports first, followed by other
272
- // imported members after.
273
- /*
274
- 'sort-imports': ['error', {
275
- ignoreDeclarationSort: true,
276
- }],
277
- */
278
-
279
- 'sort-keys': ['error', 'asc', {
280
- allowLineSeparatedGroups: true,
281
- }],
282
255
  'symbol-description': 'error',
283
256
  'unicode-bom': 'error',
284
257
  yoda: 'error',
285
- },
286
- settings: {
258
+ };
259
+
260
+ const settings = {
287
261
  'import/resolver': {
288
262
  node: true,
289
263
  typescript: true,
290
264
  },
291
- },
292
- }]);
265
+ };
266
+
267
+ if (noPerf) {
268
+ // Without Perfectionist. These rules are similar to those Perfectionist
269
+ // provides, but they are provided by other plugins, and we used them in
270
+ // older config versions, thus we keep enabling them for the legacy,
271
+ // "no Perfectionist" config variant.
272
+ rules['import/order'] = ['error', {
273
+ groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
274
+ }];
275
+ rules['sort-keys'] = ['error', 'asc', {
276
+ allowLineSeparatedGroups: true,
277
+ }];
278
+ } else {
279
+ // With Perfectionist.
280
+ // eslint-disable-next-line import/no-named-as-default-member
281
+ extentions.push(perfectionist.configs['recommended-custom']);
282
+
283
+ // TODO: For now it is disabled because of the following Perfectionist bug:
284
+ // https://github.com/azat-io/eslint-plugin-perfectionist/issues/688
285
+ // and we'll keep using "import/order" rule here until the issue is addressed.
286
+ rules['perfectionist/sort-imports'] = 'off';
287
+ rules['import/order'] = ['error', {
288
+ groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
289
+ }];
290
+
291
+ settings.perfectionist = {
292
+ alphabet: Alphabet.generateRecommendedAlphabet()
293
+ .placeAllWithCaseBeforeAllWithOtherCase('uppercase')
294
+ .getCharacters(),
295
+ ignoreCase: false,
296
+ partitionByNewLine: true,
297
+ };
298
+ }
299
+
300
+ return defineConfig([{
301
+ extends: extentions,
302
+ languageOptions: {
303
+ parser: babelParser,
304
+ },
305
+ linterOptions: {
306
+ reportUnusedDisableDirectives: 'error',
307
+ reportUnusedInlineConfigs: 'error',
308
+ },
309
+ name: 'dr.pogodin/javascript',
310
+ plugins: {
311
+ '@babel': babelPlugin,
312
+ '@stylistic': stylisticPlugin,
313
+ js,
314
+ },
315
+ rules,
316
+ settings,
317
+ }]);
318
+ }
319
+
320
+ export const javascriptNoPerf = newConfig({ noPerf: true });
321
+
322
+ export default newConfig();
package/config/react.js CHANGED
@@ -29,6 +29,9 @@ export default defineConfig([{
29
29
 
30
30
  rules: {
31
31
  // Rules provided by "eslint-plugin-perfectionist"
32
+ // NOTE: Not necessary when default JS config is used, which already
33
+ // includes it... but we keep it around to avoid any changes for consumers
34
+ // who may include this config without our default JS/TS one.
32
35
  'perfectionist/sort-jsx-props': ['error', {
33
36
  type: 'natural',
34
37
  }],
@@ -1,101 +1,120 @@
1
+ import { defineConfig } from 'eslint/config';
1
2
  import tsEsLint from 'typescript-eslint';
2
3
 
3
- import jsConfig from './javascript.js';
4
-
5
- export default tsEsLint.config(
6
- {
7
- name: 'dr.pogodin/typescript',
8
-
9
- extends: [
10
- jsConfig,
11
- tsEsLint.configs.recommendedTypeChecked,
12
- tsEsLint.configs.stylisticTypeChecked,
13
- ],
14
- files: ['**/*.ts', '**/*.tsx'],
15
- languageOptions: {
16
- parserOptions: {
17
- projectService: true,
4
+ import jsConfig, { javascriptNoPerf } from './javascript.js';
5
+
6
+ function newConfig({ noPerf } = {}) {
7
+ let extentions = [
8
+ jsConfig,
9
+ tsEsLint.configs.recommendedTypeChecked,
10
+ tsEsLint.configs.stylisticTypeChecked,
11
+ ];
12
+
13
+ const rules = {
14
+ // TypeScript takes care of the same, in a better way.
15
+ '@babel/new-cap': 'off',
16
+ '@babel/no-undef': 'off',
17
+
18
+ // It does not support type imports, and TypeScript itself does necessary
19
+ // checks for imports anyway.
20
+ 'import/named': 'off',
21
+
22
+ '@typescript-eslint/array-type': ['error', {
23
+ default: 'array-simple',
24
+ }],
25
+ '@typescript-eslint/class-methods-use-this': 'error',
26
+ '@typescript-eslint/consistent-return': 'error',
27
+ '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
28
+ '@typescript-eslint/consistent-type-exports': 'error',
29
+ '@typescript-eslint/consistent-type-imports': 'error',
30
+ '@typescript-eslint/default-param-last': 'error',
31
+ '@typescript-eslint/explicit-module-boundary-types': 'error',
32
+ '@typescript-eslint/no-confusing-void-expression': 'error',
33
+ '@typescript-eslint/no-deprecated': 'warn',
34
+ '@typescript-eslint/no-dupe-class-members': 'error',
35
+ '@typescript-eslint/no-empty-interface': 'error',
36
+ '@typescript-eslint/no-extraneous-class': 'error',
37
+ '@typescript-eslint/no-import-type-side-effects': 'error',
38
+ '@typescript-eslint/no-inferrable-types': 'off',
39
+ '@typescript-eslint/no-invalid-this': 'error',
40
+ '@typescript-eslint/no-invalid-void-type': 'error',
41
+ '@typescript-eslint/no-loop-func': 'error',
42
+ '@typescript-eslint/no-loss-of-precision': 'error',
43
+ '@typescript-eslint/no-meaningless-void-operator': 'error',
44
+ '@typescript-eslint/no-misused-spread': 'error',
45
+ '@typescript-eslint/no-mixed-enums': 'error',
46
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
47
+ '@typescript-eslint/no-redeclare': 'error',
48
+ '@typescript-eslint/no-unnecessary-type-conversion': 'error',
49
+ '@typescript-eslint/no-useless-default-assignment': 'error',
50
+
51
+ // NOTE: The core rule variant reports incorrect errors on TypeScript
52
+ // code, thus disabled.
53
+ '@typescript-eslint/no-shadow': 'error',
54
+ 'no-shadow': 'off',
55
+
56
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
57
+ '@typescript-eslint/no-unnecessary-condition': 'error',
58
+ '@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
59
+ '@typescript-eslint/no-unnecessary-qualifier': 'error',
60
+ '@typescript-eslint/no-unnecessary-template-expression': 'error',
61
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
62
+
63
+ // NOTE: Disables the base rule as it can report incorrect errors.
64
+ '@typescript-eslint/no-unused-private-class-members': 'error',
65
+ 'no-unused-private-class-members': 'off',
66
+
67
+ '@typescript-eslint/no-use-before-define': 'error',
68
+ '@typescript-eslint/no-useless-constructor': 'error',
69
+ '@typescript-eslint/no-useless-empty-export': 'error',
70
+ '@typescript-eslint/parameter-properties': ['error', {
71
+ prefer: 'parameter-property',
72
+ }],
73
+
74
+ // NOTE: The core variant of this rule, disabled below, does not work
75
+ // correctly for TypeScript code in some edge cases.
76
+ '@typescript-eslint/prefer-destructuring': 'error',
77
+ 'prefer-destructuring': 'off',
78
+
79
+ '@typescript-eslint/prefer-enum-initializers': 'error',
80
+ '@typescript-eslint/prefer-literal-enum-member': 'error',
81
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
82
+ '@typescript-eslint/prefer-regexp-exec': 'off',
83
+ '@typescript-eslint/prefer-return-this-type': 'error',
84
+ '@typescript-eslint/promise-function-async': 'error',
85
+ '@typescript-eslint/related-getter-setter-pairs': 'error',
86
+ '@typescript-eslint/require-array-sort-compare': 'error',
87
+ '@typescript-eslint/strict-void-return': 'error',
88
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
89
+ '@typescript-eslint/typedef': 'error',
90
+ '@typescript-eslint/unified-signatures': 'error',
91
+ '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
92
+ };
93
+
94
+ if (noPerf) {
95
+ extentions = [javascriptNoPerf, ...extentions];
96
+ } else {
97
+ extentions = [jsConfig, ...extentions];
98
+
99
+ rules['adjacent-overload-signatures'] = 'off';
100
+ }
101
+
102
+ return defineConfig(
103
+ {
104
+ name: 'dr.pogodin/typescript',
105
+
106
+ extends: extentions,
107
+ files: ['**/*.ts', '**/*.tsx'],
108
+ languageOptions: {
109
+ parserOptions: {
110
+ projectService: true,
111
+ },
18
112
  },
113
+ rules,
19
114
  },
20
- rules: {
21
- // TypeScript takes care of the same, in a better way.
22
- '@babel/new-cap': 'off',
23
- '@babel/no-undef': 'off',
24
-
25
- // It does not support type imports, and TypeScript itself does necessary
26
- // checks for imports anyway.
27
- 'import/named': 'off',
28
-
29
- '@typescript-eslint/array-type': ['error', {
30
- default: 'array-simple',
31
- }],
32
- '@typescript-eslint/class-methods-use-this': 'error',
33
- '@typescript-eslint/consistent-return': 'error',
34
- '@typescript-eslint/consistent-type-definitions': ['error', 'type'],
35
- '@typescript-eslint/consistent-type-exports': 'error',
36
- '@typescript-eslint/consistent-type-imports': 'error',
37
- '@typescript-eslint/default-param-last': 'error',
38
- '@typescript-eslint/explicit-module-boundary-types': 'error',
39
- '@typescript-eslint/no-confusing-void-expression': 'error',
40
- '@typescript-eslint/no-deprecated': 'warn',
41
- '@typescript-eslint/no-dupe-class-members': 'error',
42
- '@typescript-eslint/no-empty-interface': 'error',
43
- '@typescript-eslint/no-extraneous-class': 'error',
44
- '@typescript-eslint/no-import-type-side-effects': 'error',
45
- '@typescript-eslint/no-inferrable-types': 'off',
46
- '@typescript-eslint/no-invalid-this': 'error',
47
- '@typescript-eslint/no-invalid-void-type': 'error',
48
- '@typescript-eslint/no-loop-func': 'error',
49
- '@typescript-eslint/no-loss-of-precision': 'error',
50
- '@typescript-eslint/no-meaningless-void-operator': 'error',
51
- '@typescript-eslint/no-misused-spread': 'error',
52
- '@typescript-eslint/no-mixed-enums': 'error',
53
- '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
54
- '@typescript-eslint/no-redeclare': 'error',
55
- '@typescript-eslint/no-unnecessary-type-conversion': 'error',
56
- '@typescript-eslint/no-useless-default-assignment': 'error',
57
-
58
- // NOTE: The core rule variant reports incorrect errors on TypeScript
59
- // code, thus disabled.
60
- '@typescript-eslint/no-shadow': 'error',
61
- 'no-shadow': 'off',
62
-
63
- '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
64
- '@typescript-eslint/no-unnecessary-condition': 'error',
65
- '@typescript-eslint/no-unnecessary-parameter-property-assignment': 'error',
66
- '@typescript-eslint/no-unnecessary-qualifier': 'error',
67
- '@typescript-eslint/no-unnecessary-template-expression': 'error',
68
- '@typescript-eslint/no-unnecessary-type-arguments': 'error',
69
-
70
- // NOTE: Disables the base rule as it can report incorrect errors.
71
- '@typescript-eslint/no-unused-private-class-members': 'error',
72
- 'no-unused-private-class-members': 'off',
73
-
74
- '@typescript-eslint/no-use-before-define': 'error',
75
- '@typescript-eslint/no-useless-constructor': 'error',
76
- '@typescript-eslint/no-useless-empty-export': 'error',
77
- '@typescript-eslint/parameter-properties': ['error', {
78
- prefer: 'parameter-property',
79
- }],
80
-
81
- // NOTE: The core variant of this rule, disabled below, does not work
82
- // correctly for TypeScript code in some edge cases.
83
- '@typescript-eslint/prefer-destructuring': 'error',
84
- 'prefer-destructuring': 'off',
85
-
86
- '@typescript-eslint/prefer-enum-initializers': 'error',
87
- '@typescript-eslint/prefer-literal-enum-member': 'error',
88
- '@typescript-eslint/prefer-reduce-type-parameter': 'error',
89
- '@typescript-eslint/prefer-regexp-exec': 'off',
90
- '@typescript-eslint/prefer-return-this-type': 'error',
91
- '@typescript-eslint/promise-function-async': 'error',
92
- '@typescript-eslint/related-getter-setter-pairs': 'error',
93
- '@typescript-eslint/require-array-sort-compare': 'error',
94
- '@typescript-eslint/strict-void-return': 'error',
95
- '@typescript-eslint/switch-exhaustiveness-check': 'error',
96
- '@typescript-eslint/typedef': 'error',
97
- '@typescript-eslint/unified-signatures': 'error',
98
- '@typescript-eslint/use-unknown-in-catch-callback-variable': 'error',
99
- },
100
- },
101
- );
115
+ );
116
+ }
117
+
118
+ export const typescriptNoPerf = newConfig({ noPerf: true });
119
+
120
+ export default newConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dr.pogodin/eslint-configs",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "ESLint configurations for TypeScript and/or React projects",
5
5
  "type": "module",
6
6
  "main": "./config/index.js",
@@ -40,7 +40,7 @@
40
40
  "eslint-plugin-import": "^2.32.0",
41
41
  "eslint-plugin-jest": "^29.12.1",
42
42
  "eslint-plugin-jsx-a11y": "^6.10.2",
43
- "eslint-plugin-perfectionist": "^5.3.1",
43
+ "eslint-plugin-perfectionist": "^5.4.0",
44
44
  "eslint-plugin-react": "^7.37.4",
45
45
  "eslint-plugin-react-hooks": "^6.1.1",
46
46
  "typescript": "^5.9.3",