@bpa-dev/eslint-config 1.0.2 → 1.0.3-beta.1

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
@@ -34,17 +34,17 @@ npm install --save-dev @bpa-dev/eslint-config eslint prettier typescript
34
34
  Создайте файл `eslint.config.js` в корне проекта:
35
35
 
36
36
  ```javascript
37
- import bpaConfig from '@bpa-dev/eslint-config';
37
+ import bpaConfig from '@bpa-dev/eslint-config'
38
38
 
39
- export default bpaConfig;
39
+ export default bpaConfig
40
40
  ```
41
41
 
42
42
  #### Для React проектов
43
43
 
44
44
  ```javascript
45
- import bpaReactConfig from '@bpa-dev/eslint-config/react';
45
+ import bpaReactConfig from '@bpa-dev/eslint-config/react'
46
46
 
47
- export default bpaReactConfig;
47
+ export default bpaReactConfig
48
48
  ```
49
49
 
50
50
  #### Расширение конфигурации
@@ -52,17 +52,17 @@ export default bpaReactConfig;
52
52
  Вы можете добавить свои правила:
53
53
 
54
54
  ```javascript
55
- import bpaConfig from '@bpa-dev/eslint-config';
55
+ import bpaConfig from '@bpa-dev/eslint-config'
56
56
 
57
57
  export default [
58
58
  ...bpaConfig,
59
59
  {
60
60
  rules: {
61
61
  // Ваши дополнительные правила
62
- 'no-console': 'off',
63
- },
64
- },
65
- ];
62
+ 'no-console': 'off'
63
+ }
64
+ }
65
+ ]
66
66
  ```
67
67
 
68
68
  ### Prettier
@@ -70,20 +70,20 @@ export default [
70
70
  Создайте файл `prettier.config.js` в корне проекта:
71
71
 
72
72
  ```javascript
73
- import bpaPrettierConfig from '@bpa-dev/eslint-config/prettier';
73
+ import bpaPrettierConfig from '@bpa-dev/eslint-config/prettier'
74
74
 
75
- export default bpaPrettierConfig;
75
+ export default bpaPrettierConfig
76
76
  ```
77
77
 
78
78
  Или расширьте конфигурацию:
79
79
 
80
80
  ```javascript
81
- import bpaPrettierConfig from '@bpa-dev/eslint-config/prettier';
81
+ import bpaPrettierConfig from '@bpa-dev/eslint-config/prettier'
82
82
 
83
83
  export default {
84
84
  ...bpaPrettierConfig,
85
- printWidth: 120, // переопределение настроек
86
- };
85
+ printWidth: 120 // переопределение настроек
86
+ }
87
87
  ```
88
88
 
89
89
  ### package.json скрипты
@@ -117,11 +117,6 @@ export default {
117
117
  "editor.codeActionsOnSave": {
118
118
  "source.fixAll.eslint": "explicit"
119
119
  },
120
- "eslint.validate": [
121
- "javascript",
122
- "javascriptreact",
123
- "typescript",
124
- "typescriptreact"
125
- ]
120
+ "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"]
126
121
  }
127
122
  ```
package/index.js CHANGED
@@ -3,14 +3,19 @@
3
3
  * Используется ESLint 9+ Flat Config
4
4
  * @see https://eslint.org/docs/latest/use/configure/configuration-files
5
5
  */
6
- import js from '@eslint/js';
7
- import tseslint from 'typescript-eslint';
8
- import eslintPluginPrettier from "eslint-plugin-prettier/recommended";
9
- import importPlugin from 'eslint-plugin-import';
10
- import globals from 'globals';
6
+ import js from '@eslint/js'
7
+ import { defineConfig } from 'eslint/config'
8
+ import importPlugin from 'eslint-plugin-import'
9
+ import perfectionistPlugin from 'eslint-plugin-perfectionist'
10
+ import prettierPlugin from 'eslint-plugin-prettier/recommended'
11
+ // @ts-expect-error - no types available
12
+ import promisePlugin from 'eslint-plugin-promise'
13
+ // @ts-expect-error - no types available
14
+ import securityPlugin from 'eslint-plugin-security'
15
+ import unicornPlugin from 'eslint-plugin-unicorn'
16
+ import { configs as tseslintPlugin } from 'typescript-eslint'
11
17
 
12
- export default tseslint.config(
13
- // Игнорируемые файлы
18
+ export default defineConfig([
14
19
  {
15
20
  ignores: [
16
21
  '**/node_modules/**',
@@ -21,141 +26,82 @@ export default tseslint.config(
21
26
  '**/coverage/**',
22
27
  '**/.turbo/**',
23
28
  '**/.cache/**',
24
- '**/*.min.js',
25
- ],
29
+ '**/*.min.js'
30
+ ]
26
31
  },
32
+ { files: ['**/*.{js,mjs,cjs,jsx,ts,tsx,mts,cts}'] },
33
+ js.configs.recommended,
34
+ tseslintPlugin.all,
35
+ perfectionistPlugin.configs['recommended-natural'],
36
+ importPlugin.flatConfigs.recommended,
37
+ importPlugin.flatConfigs.typescript,
38
+ prettierPlugin,
39
+ unicornPlugin.configs.all,
40
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
41
+ securityPlugin.configs.recommended,
42
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
43
+ promisePlugin.configs['flat/recommended'],
27
44
 
28
- // Базовые правила для всех JS файлов
29
45
  {
30
- files: ['**/*.{js,mjs,cjs,jsx}'],
31
- languageOptions: {
32
- ecmaVersion: 2024,
33
- sourceType: 'module',
34
- globals: {
35
- ...globals.browser,
36
- ...globals.node,
37
- ...globals.es2021,
38
- },
39
- },
40
- plugins: {
41
- import: importPlugin,
42
- },
43
46
  rules: {
44
- ...js.configs.recommended.rules,
45
-
46
- // Общие правила
47
- 'no-console': ['warn', { allow: ['warn', 'error'] }],
48
- 'no-debugger': 'warn',
49
- 'no-alert': 'warn',
50
- 'no-var': 'error',
51
- 'prefer-const': 'error',
52
- 'prefer-arrow-callback': 'error',
53
- 'prefer-template': 'error',
54
- 'prefer-destructuring': ['error', { object: true, array: false }],
55
- 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
56
- 'no-duplicate-imports': 'error',
57
- 'object-shorthand': ['error', 'always'],
58
- 'no-return-await': 'error',
59
- eqeqeq: ['error', 'always', { null: 'ignore' }],
60
- curly: ['error', 'all'],
61
-
62
- // Import правила
63
- 'import/order': [
47
+ '@typescript-eslint/consistent-return': 'off',
48
+ '@typescript-eslint/explicit-function-return-type': 'off',
49
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
50
+ '@typescript-eslint/naming-convention': 'off',
51
+ '@typescript-eslint/no-magic-numbers': 'off',
52
+ '@typescript-eslint/no-unsafe-assignment': 'warn',
53
+ '@typescript-eslint/no-unsafe-member-access': 'warn',
54
+ '@typescript-eslint/no-unsafe-type-assertion': 'warn',
55
+ '@typescript-eslint/prefer-readonly-parameter-types': 'off',
56
+ '@typescript-eslint/prefer-reduce-type-parameter': 'warn',
57
+ '@typescript-eslint/restrict-template-expressions': ['error', { allowNumber: true }],
58
+ '@typescript-eslint/strict-boolean-expressions': 'warn',
59
+ 'import/extensions': [
64
60
  'error',
61
+ 'ignorePackages',
65
62
  {
66
- groups: [
67
- 'builtin',
68
- 'external',
69
- 'internal',
70
- ['parent', 'sibling'],
71
- 'index',
72
- 'object',
73
- 'type',
74
- ],
75
- 'newlines-between': 'always',
76
- alphabetize: { order: 'asc', caseInsensitive: true },
77
- },
63
+ ts: 'never',
64
+ tsx: 'never'
65
+ }
78
66
  ],
79
- 'import/no-duplicates': 'error',
80
67
  'import/newline-after-import': 'error',
81
- 'import/no-unresolved': 'off',
82
- },
83
- },
84
-
85
- // TypeScript файлы
86
- {
87
- files: ['**/*.{ts,tsx,mts,cts}'],
88
- languageOptions: {
89
- parser: tseslint.parser,
90
- parserOptions: {
91
- ecmaVersion: 2024,
92
- sourceType: 'module',
93
- },
94
- globals: {
95
- ...globals.browser,
96
- ...globals.node,
97
- ...globals.es2021,
98
- },
99
- },
100
- plugins: {
101
- '@typescript-eslint': tseslint.plugin,
102
- import: importPlugin,
103
- },
104
- rules: {
105
- ...js.configs.recommended.rules,
106
- ...tseslint.configs.recommended.rules,
107
-
108
- 'no-unused-vars': 'off',
109
- '@typescript-eslint/no-unused-vars': [
110
- 'error',
111
- { argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
112
- ],
113
-
114
- // TypeScript специфичные правила
115
- '@typescript-eslint/explicit-module-boundary-types': 'off',
116
- '@typescript-eslint/no-explicit-any': 'warn',
117
- '@typescript-eslint/no-non-null-assertion': 'warn',
118
- '@typescript-eslint/consistent-type-imports': [
119
- 'error',
120
- { prefer: 'type-imports', fixStyle: 'separate-type-imports' },
121
- ],
122
- // Временно отключено - требует parserOptions.projectService
123
- // '@typescript-eslint/consistent-type-exports': 'error',
124
- '@typescript-eslint/no-import-type-side-effects': 'error',
125
-
126
- // Общие правила
127
- 'no-console': ['warn', { allow: ['warn', 'error'] }],
128
- 'no-debugger': 'warn',
129
- 'no-alert': 'warn',
130
- 'prefer-const': 'error',
131
- 'prefer-arrow-callback': 'error',
132
- 'prefer-template': 'error',
133
- 'object-shorthand': ['error', 'always'],
134
- eqeqeq: ['error', 'always', { null: 'ignore' }],
135
- curly: ['error', 'all'],
136
-
137
- // Import правила
68
+ 'import/no-duplicates': 'error',
69
+ 'import/no-named-as-default': 'error',
70
+ 'import/no-unresolved': 'error',
138
71
  'import/order': [
139
72
  'error',
140
73
  {
141
- groups: [
142
- 'builtin',
143
- 'external',
144
- 'internal',
145
- ['parent', 'sibling'],
146
- 'index',
147
- 'object',
148
- 'type',
149
- ],
150
- 'newlines-between': 'always',
151
- alphabetize: { order: 'asc', caseInsensitive: true },
152
- },
74
+ alphabetize: { caseInsensitive: true, order: 'asc' },
75
+ groups: ['builtin', 'external', 'internal', ['parent', 'sibling'], 'index', 'object', 'type'],
76
+ 'newlines-between': 'always'
77
+ }
153
78
  ],
154
- 'import/no-duplicates': 'error',
155
- 'import/newline-after-import': 'error',
79
+ 'no-console': 'error',
80
+ 'perfectionist/sort-classes': 'off',
81
+ 'perfectionist/sort-imports': 'off',
82
+ 'unicorn/filename-case': 'off',
83
+ 'unicorn/no-array-callback-reference': 'off',
84
+ 'unicorn/no-keyword-prefix': 'off',
85
+ 'unicorn/no-null': 'off',
86
+ 'unicorn/no-useless-undefined': 'off',
87
+ 'unicorn/prefer-at': ['error', { checkAllIndexAccess: true }],
88
+ 'unicorn/prefer-ternary': 'off',
89
+ 'unicorn/prevent-abbreviations': 'off'
156
90
  },
91
+ settings: {
92
+ 'import/resolver': {
93
+ typescript: {
94
+ alwaysTryTypes: true,
95
+ project: './tsconfig.json'
96
+ }
97
+ }
98
+ }
157
99
  },
158
-
159
- // Отключаем конфликтующие с Prettier правила
160
- eslintPluginPrettier
161
- );
100
+ {
101
+ languageOptions: {
102
+ parserOptions: {
103
+ projectService: true
104
+ }
105
+ }
106
+ }
107
+ ])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpa-dev/eslint-config",
3
- "version": "1.0.2",
3
+ "version": "1.0.3-beta.1",
4
4
  "description": "Набор конфигураций для ESLint и Prettier для проектов BPA",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -25,6 +25,11 @@
25
25
  ],
26
26
  "author": "BPA",
27
27
  "license": "MIT",
28
+ "scripts": {
29
+ "eslint:fix": "eslint . --fix -c index.js",
30
+ "prettier:write": "prettier . --write",
31
+ "format": "npm run eslint:fix && npm run prettier:write"
32
+ },
28
33
  "peerDependencies": {
29
34
  "eslint": "^9.0.0",
30
35
  "prettier": "^3.0.0",
@@ -35,17 +40,22 @@
35
40
  "@typescript-eslint/eslint-plugin": "^8.53.1",
36
41
  "@typescript-eslint/parser": "^8.53.1",
37
42
  "eslint-config-prettier": "^10.1.8",
43
+ "eslint-import-resolver-typescript": "^4.4.4",
38
44
  "eslint-plugin-import": "^2.32.0",
39
45
  "eslint-plugin-jsx-a11y": "^6.10.2",
46
+ "eslint-plugin-perfectionist": "^5.4.0",
40
47
  "eslint-plugin-prettier": "^5.5.5",
48
+ "eslint-plugin-promise": "^7.2.1",
41
49
  "eslint-plugin-react": "^7.37.5",
42
50
  "eslint-plugin-react-hooks": "^7.0.1",
43
- "globals": "^17.0.0",
51
+ "eslint-plugin-security": "^3.0.1",
52
+ "eslint-plugin-unicorn": "^62.0.0",
44
53
  "typescript-eslint": "^8.53.1"
45
54
  },
46
55
  "devDependencies": {
47
56
  "eslint": "^9.39.2",
48
- "prettier": "^3.8.0",
57
+ "globals": "^17.0.0",
58
+ "prettier": "^3.8.1",
49
59
  "typescript": "^5.9.3"
50
60
  }
51
61
  }
@@ -4,15 +4,15 @@
4
4
  * @type {import("prettier").Config}
5
5
  */
6
6
  const config = {
7
- semi: false,
8
- tabWidth: 2,
7
+ arrowParens: 'always',
8
+ bracketSpacing: true,
9
+ endOfLine: 'auto',
10
+ jsxSingleQuote: true,
9
11
  printWidth: 120,
12
+ semi: false,
10
13
  singleQuote: true,
11
- trailingComma: 'none',
12
- jsxSingleQuote: true,
13
- endOfLine: 'auto',
14
- bracketSpacing: true,
15
- arrowParens: 'always'
14
+ tabWidth: 2,
15
+ trailingComma: 'none'
16
16
  }
17
17
 
18
- export default config
18
+ export default config
package/react.js CHANGED
@@ -1,70 +1,59 @@
1
+ import { defineConfig } from 'eslint/config'
2
+ import a11yPlugin from 'eslint-plugin-jsx-a11y'
3
+ import reactPlugin from 'eslint-plugin-react'
4
+ import reactHooksPlugin from 'eslint-plugin-react-hooks'
5
+
1
6
  /**
2
7
  * ESLint конфиг для React проектов BPA
3
8
  * Расширяет базовый конфиг с поддержкой React и JSX
4
9
  */
5
- import baseConfig from './index.js';
6
- import react from 'eslint-plugin-react';
7
- import reactHooks from 'eslint-plugin-react-hooks';
8
- import jsxA11y from 'eslint-plugin-jsx-a11y';
9
- import globals from 'globals';
10
+ import baseConfig from './index.js'
10
11
 
11
- export default [
12
+ export default defineConfig([
12
13
  ...baseConfig,
13
-
14
- // React конфигурация
15
14
  {
16
15
  files: ['**/*.{jsx,tsx}'],
17
- languageOptions: {
18
- parserOptions: {
19
- ecmaFeatures: {
20
- jsx: true,
21
- },
22
- },
23
- globals: {
24
- ...globals.browser,
25
- },
26
- },
27
16
  plugins: {
28
- react,
29
- 'react-hooks': reactHooks,
30
- 'jsx-a11y': jsxA11y,
31
- },
32
- settings: {
33
- react: {
34
- version: 'detect',
35
- },
17
+ 'jsx-a11y': a11yPlugin,
18
+ react: reactPlugin,
19
+ 'react-hooks': reactHooksPlugin
36
20
  },
37
21
  rules: {
38
22
  // React основные правила
39
- ...react.configs.recommended.rules,
40
- 'react/react-in-jsx-scope': 'off',
41
- 'react/prop-types': 'off',
42
- 'react/jsx-no-target-blank': 'error',
43
- 'react/jsx-key': ['error', { checkFragmentShorthand: true }],
44
- 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
45
- 'react/self-closing-comp': 'error',
23
+ ...reactPlugin.configs.recommended.rules,
46
24
  'react/jsx-boolean-value': ['error', 'never'],
25
+ 'react/jsx-curly-brace-presence': ['error', { children: 'never', props: 'never' }],
26
+ 'react/jsx-fragments': ['error', 'syntax'],
27
+ 'react/jsx-key': ['error', { checkFragmentShorthand: true }],
28
+ 'react/jsx-no-target-blank': 'error',
47
29
  'react/jsx-pascal-case': 'error',
48
30
  'react/no-array-index-key': 'warn',
49
31
  'react/no-unstable-nested-components': 'error',
50
- 'react/jsx-fragments': ['error', 'syntax'],
32
+ 'react/prop-types': 'off',
33
+ 'react/react-in-jsx-scope': 'off',
34
+ 'react/self-closing-comp': 'error',
51
35
 
52
36
  // React Hooks правила
53
- ...reactHooks.configs.recommended.rules,
37
+ ...reactHooksPlugin.configs.recommended.rules,
38
+ 'react-hooks/exhaustive-deps': 'error',
54
39
  'react-hooks/rules-of-hooks': 'error',
55
- 'react-hooks/exhaustive-deps': 'warn',
56
40
 
57
41
  // Доступность
58
- ...jsxA11y.configs.recommended.rules,
42
+ ...a11yPlugin.configs.recommended.rules,
59
43
  'jsx-a11y/anchor-is-valid': [
60
44
  'error',
61
45
  {
62
46
  components: ['Link'],
63
- specialLink: ['to'],
64
- },
47
+ specialLink: ['to']
48
+ }
65
49
  ],
66
50
  'jsx-a11y/click-events-have-key-events': 'warn',
67
- 'jsx-a11y/no-static-element-interactions': 'warn',
51
+ 'jsx-a11y/no-static-element-interactions': 'warn'
68
52
  },
69
- },
70
- ];
53
+ settings: {
54
+ react: {
55
+ version: 'detect'
56
+ }
57
+ }
58
+ }
59
+ ])