@mrpalmer/eslint-config 2.0.0 → 2.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/.turbo/turbo-build.log +8 -0
- package/CHANGELOG.md +27 -0
- package/configs/base.js +43 -38
- package/configs/jest.js +5 -1
- package/configs/react.js +66 -104
- package/configs/typescript.js +14 -5
- package/index.js +1 -1
- package/package.json +22 -11
- package/tsconfig.json +10 -0
- package/turbo.json +8 -0
- package/types/configs/base.d.ts +2 -0
- package/types/configs/jest.d.ts +2 -0
- package/types/configs/react.d.ts +2 -0
- package/types/configs/typescript.d.ts +2 -0
- package/types/index.d.ts +20 -0
- package/types/utils/deprecated.d.ts +4 -0
- package/types/utils/packageJson.d.ts +14 -0
- package/utils/deprecated.js +19 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# @mrpalmer/eslint-config
|
|
2
|
+
|
|
3
|
+
## 2.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- afbdd32: Replace `eslint-plugin-react` with `@eslint-react/eslint-plugin`
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 1e43272: Update ESLint plugins
|
|
12
|
+
- 32711bf: Fix order of configs in "all"
|
|
13
|
+
- df14ce7: Export TypeScript types
|
|
14
|
+
- Updated dependencies [96a657e]
|
|
15
|
+
- @mrpalmer/eslint-plugin@1.0.1
|
|
16
|
+
|
|
17
|
+
## 2.1.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- 63cec80: - Replace `eslint-plugin-import` with `eslint-plugin-import-x`
|
|
22
|
+
- Add `@mrpalmer/eslint-plugin` to default config
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies [1e5fa18]
|
|
27
|
+
- @mrpalmer/eslint-plugin@1.0.0
|
package/configs/base.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import eslint from '@eslint/js'
|
|
2
|
-
import
|
|
2
|
+
import mrpalmerPlugin from '@mrpalmer/eslint-plugin'
|
|
3
|
+
import pluginImport from 'eslint-plugin-import-x'
|
|
3
4
|
import { config } from 'typescript-eslint'
|
|
4
5
|
|
|
5
6
|
export default config(
|
|
@@ -7,6 +8,7 @@ export default config(
|
|
|
7
8
|
name: 'eslint/recommended',
|
|
8
9
|
...eslint.configs.recommended,
|
|
9
10
|
},
|
|
11
|
+
mrpalmerPlugin.configs.recommended,
|
|
10
12
|
{
|
|
11
13
|
name: 'mrpalmer/base',
|
|
12
14
|
|
|
@@ -186,48 +188,51 @@ export default config(
|
|
|
186
188
|
{
|
|
187
189
|
name: 'mrpalmer/import',
|
|
188
190
|
rules: {
|
|
189
|
-
'import/consistent-type-specifier-style': ['error', 'prefer-inline'],
|
|
190
|
-
'import/dynamic-import-chunkname': 'off',
|
|
191
|
-
'import/exports-last': 'off',
|
|
192
|
-
'import/extensions': 'off',
|
|
193
|
-
'import/first': 'error',
|
|
194
|
-
'import/group-exports': 'off',
|
|
195
|
-
'import/max-dependencies': 'off',
|
|
196
|
-
'import/newline-after-import': 'off',
|
|
197
|
-
'import/no-absolute-path': 'error',
|
|
198
|
-
'import/no-amd': 'error',
|
|
199
|
-
'import/no-anonymous-default-export': [
|
|
191
|
+
'import-x/consistent-type-specifier-style': ['error', 'prefer-inline'],
|
|
192
|
+
'import-x/dynamic-import-chunkname': 'off',
|
|
193
|
+
'import-x/exports-last': 'off',
|
|
194
|
+
'import-x/extensions': 'off',
|
|
195
|
+
'import-x/first': 'error',
|
|
196
|
+
'import-x/group-exports': 'off',
|
|
197
|
+
'import-x/max-dependencies': 'off',
|
|
198
|
+
'import-x/newline-after-import': 'off',
|
|
199
|
+
'import-x/no-absolute-path': 'error',
|
|
200
|
+
'import-x/no-amd': 'error',
|
|
201
|
+
'import-x/no-anonymous-default-export': [
|
|
200
202
|
'error',
|
|
201
203
|
{ allowArray: true, allowObject: true },
|
|
202
204
|
],
|
|
203
|
-
'import/no-commonjs': 'off',
|
|
204
|
-
'import/no-cycle': 'off',
|
|
205
|
-
'import/no-default-export': 'off',
|
|
206
|
-
'import/no-deprecated': 'warn',
|
|
207
|
-
'import/no-dynamic-require': 'off',
|
|
208
|
-
'import/no-empty-named-blocks': 'warn',
|
|
209
|
-
'import/no-extraneous-dependencies': 'error',
|
|
210
|
-
'import/no-import-module-exports': 'error',
|
|
211
|
-
'import/no-internal-modules': 'off',
|
|
212
|
-
'import/no-mutable-exports': 'error',
|
|
213
|
-
'import/no-named-default': 'error',
|
|
214
|
-
'import/no-named-export': 'off',
|
|
215
|
-
'import/no-namespace': 'off',
|
|
216
|
-
'import/no-nodejs-modules': 'off',
|
|
217
|
-
'import/no-relative-packages': 'warn',
|
|
218
|
-
'import/no-relative-parent-imports': 'off',
|
|
219
|
-
'import/no-
|
|
220
|
-
'import/no-
|
|
221
|
-
'import/no-
|
|
222
|
-
'import/no-
|
|
223
|
-
'import/no-
|
|
224
|
-
'import/no-
|
|
225
|
-
'import/
|
|
226
|
-
'import/
|
|
227
|
-
'import/
|
|
205
|
+
'import-x/no-commonjs': 'off',
|
|
206
|
+
'import-x/no-cycle': 'off',
|
|
207
|
+
'import-x/no-default-export': 'off',
|
|
208
|
+
'import-x/no-deprecated': 'warn',
|
|
209
|
+
'import-x/no-dynamic-require': 'off',
|
|
210
|
+
'import-x/no-empty-named-blocks': 'warn',
|
|
211
|
+
'import-x/no-extraneous-dependencies': 'error',
|
|
212
|
+
'import-x/no-import-module-exports': 'error',
|
|
213
|
+
'import-x/no-internal-modules': 'off',
|
|
214
|
+
'import-x/no-mutable-exports': 'error',
|
|
215
|
+
'import-x/no-named-default': 'error',
|
|
216
|
+
'import-x/no-named-export': 'off',
|
|
217
|
+
'import-x/no-namespace': 'off',
|
|
218
|
+
'import-x/no-nodejs-modules': 'off',
|
|
219
|
+
'import-x/no-relative-packages': 'warn',
|
|
220
|
+
'import-x/no-relative-parent-imports': 'off',
|
|
221
|
+
'import-x/no-rename-default': 'off',
|
|
222
|
+
'import-x/no-restricted-paths': 'off',
|
|
223
|
+
'import-x/no-self-import': 'error',
|
|
224
|
+
'import-x/no-unassigned-import': 'off',
|
|
225
|
+
'import-x/no-unused-modules': 'off',
|
|
226
|
+
'import-x/no-useless-path-segments': 'error',
|
|
227
|
+
'import-x/no-webpack-loader-syntax': 'error',
|
|
228
|
+
'import-x/order': 'off',
|
|
229
|
+
'import-x/prefer-default-export': 'off',
|
|
230
|
+
'import-x/prefer-namespace-import': 'off',
|
|
231
|
+
'import-x/unambiguous': 'off',
|
|
228
232
|
},
|
|
229
233
|
settings: {
|
|
230
|
-
'import/ignore': ['node_modules', '.json$', '.(scss|less|css|styl)$'],
|
|
234
|
+
'import-x/ignore': ['node_modules', '.json$', '.(scss|less|css|styl)$'],
|
|
235
|
+
'import-x/resolver-x': [pluginImport.createNodeResolver()],
|
|
231
236
|
},
|
|
232
237
|
}
|
|
233
238
|
)
|
package/configs/jest.js
CHANGED
|
@@ -36,7 +36,9 @@ export default tseslint.config(
|
|
|
36
36
|
name: 'mrpalmer/jest',
|
|
37
37
|
|
|
38
38
|
rules: {
|
|
39
|
-
|
|
39
|
+
// we don't need a display name in test files
|
|
40
|
+
'@eslint-react/no-missing-component-display-name': 'off',
|
|
41
|
+
'@eslint-react/no-missing-context-display-name': 'off',
|
|
40
42
|
|
|
41
43
|
'jest/consistent-test-it': 'off',
|
|
42
44
|
'jest/max-expects': 'off',
|
|
@@ -61,6 +63,7 @@ export default tseslint.config(
|
|
|
61
63
|
'jest/prefer-called-with': 'error',
|
|
62
64
|
'jest/prefer-comparison-matcher': 'warn',
|
|
63
65
|
'jest/prefer-each': 'warn',
|
|
66
|
+
'jest/prefer-ending-with-an-expect': 'warn',
|
|
64
67
|
'jest/prefer-equality-matcher': 'warn',
|
|
65
68
|
'jest/prefer-expect-assertions': 'off',
|
|
66
69
|
'jest/prefer-expect-resolves': 'off',
|
|
@@ -82,6 +85,7 @@ export default tseslint.config(
|
|
|
82
85
|
...(hasTestingLibrary
|
|
83
86
|
? {
|
|
84
87
|
'testing-library/consistent-data-testid': 'off',
|
|
88
|
+
'testing-library/no-test-id-queries': 'warn',
|
|
85
89
|
'testing-library/prefer-explicit-assert': 'warn',
|
|
86
90
|
'testing-library/prefer-implicit-assert': 'off',
|
|
87
91
|
'testing-library/prefer-query-matchers': 'off',
|
package/configs/react.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import pluginReact from '@eslint-react/eslint-plugin'
|
|
1
2
|
import pluginJsxA11y from 'eslint-plugin-jsx-a11y'
|
|
2
|
-
import pluginReact from 'eslint-plugin-react'
|
|
3
3
|
import pluginReactHooks from 'eslint-plugin-react-hooks'
|
|
4
4
|
import globals from 'globals'
|
|
5
5
|
import tseslint from 'typescript-eslint'
|
|
6
|
+
import * as deprecated from '../utils/deprecated.js'
|
|
6
7
|
import {
|
|
7
8
|
getAllDependencies,
|
|
8
9
|
getMinimumSupportedVersion,
|
|
@@ -13,19 +14,18 @@ const oldestSupportedReactVersion = '16.5.2'
|
|
|
13
14
|
const allDeps = getAllDependencies()
|
|
14
15
|
const minimumSupportedReactVersion =
|
|
15
16
|
getMinimumSupportedVersion(allDeps, 'react') ?? oldestSupportedReactVersion
|
|
16
|
-
const hasPropTypes = Object.hasOwn(allDeps, 'prop-types')
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const jsxA11yRecommended = deprecated.remove(
|
|
19
|
+
pluginJsxA11y.flatConfigs.recommended,
|
|
20
|
+
// jsx-a11y/label-has-for is deprecated but still defined in the recommended config
|
|
21
|
+
['jsx-a11y/label-has-for']
|
|
22
|
+
)
|
|
20
23
|
|
|
21
24
|
export default tseslint.config(
|
|
22
25
|
{
|
|
23
26
|
extends: [
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
...pluginReact.configs.flat.recommended,
|
|
27
|
-
},
|
|
28
|
-
pluginJsxA11y.flatConfigs.recommended,
|
|
27
|
+
pluginReact.configs.recommended,
|
|
28
|
+
jsxA11yRecommended,
|
|
29
29
|
{
|
|
30
30
|
name: 'react-hooks/recommended',
|
|
31
31
|
plugins: {
|
|
@@ -42,113 +42,75 @@ export default tseslint.config(
|
|
|
42
42
|
},
|
|
43
43
|
name: 'mrpalmer/react',
|
|
44
44
|
rules: {
|
|
45
|
-
'react/boolean-prop-naming': 'off',
|
|
46
|
-
'react/button-has-type': 'off',
|
|
47
|
-
'react/checked-requires-onchange-or-readonly': 'error',
|
|
48
|
-
'react/default-props-match-prop-types': hasPropTypes ? 'error' : 'off',
|
|
49
|
-
'react/destructuring-assignment': 'off',
|
|
50
|
-
'react/forbid-component-props': 'off',
|
|
51
|
-
'react/forbid-dom-props': 'off',
|
|
52
|
-
'react/forbid-elements': 'off',
|
|
53
|
-
'react/forbid-foreign-prop-types': hasPropTypes ? 'error' : 'off',
|
|
54
|
-
'react/forbid-prop-types': 'off',
|
|
55
|
-
'react/forward-ref-uses-ref': 'error',
|
|
56
|
-
'react/function-component-definition': 'off',
|
|
57
|
-
'react/hook-use-state': 'off',
|
|
58
|
-
'react/iframe-missing-sandbox': 'warn',
|
|
59
|
-
'react/jsx-boolean-value': 'off',
|
|
60
|
-
'react/jsx-child-element-spacing': 'warn',
|
|
61
|
-
'react/jsx-closing-bracket-location': 'off',
|
|
62
|
-
'react/jsx-closing-tag-location': 'off',
|
|
63
|
-
'react/jsx-curly-brace-presence': [
|
|
64
|
-
'warn',
|
|
65
|
-
{ children: 'ignore', propElementValues: 'always', props: 'never' },
|
|
66
|
-
],
|
|
67
|
-
'react/jsx-curly-newline': 'off',
|
|
68
|
-
'react/jsx-curly-spacing': 'off',
|
|
69
|
-
'react/jsx-equals-spacing': 'off',
|
|
70
|
-
'react/jsx-filename-extension': ['error', { extensions: ['.js'] }],
|
|
71
|
-
'react/jsx-first-prop-new-line': 'off',
|
|
72
|
-
'react/jsx-fragments': 'off',
|
|
73
|
-
'react/jsx-handler-names': 'off',
|
|
74
|
-
'react/jsx-indent': 'off',
|
|
75
|
-
'react/jsx-indent-props': 'off',
|
|
76
|
-
'react/jsx-max-depth': 'off',
|
|
77
|
-
'react/jsx-max-props-per-line': 'off',
|
|
78
|
-
'react/jsx-newline': 'off',
|
|
79
|
-
'react/jsx-no-bind': 'off',
|
|
80
|
-
'react/jsx-no-constructed-context-values': 'off',
|
|
81
|
-
'react/jsx-no-leaked-render': 'off',
|
|
82
|
-
'react/jsx-no-literals': 'off',
|
|
83
|
-
'react/jsx-no-script-url': 'error',
|
|
84
|
-
'react/jsx-no-useless-fragment': 'warn',
|
|
85
|
-
'react/jsx-one-expression-per-line': 'off',
|
|
86
|
-
'react/jsx-pascal-case': 'error',
|
|
87
|
-
'react/jsx-props-no-multi-spaces': 'off',
|
|
88
|
-
'react/jsx-props-no-spread-multi': 'warn',
|
|
89
|
-
'react/jsx-props-no-spreading': 'off',
|
|
90
|
-
'react/jsx-sort-props': 'off',
|
|
91
|
-
'react/jsx-tag-spacing': 'off',
|
|
92
|
-
'react/jsx-wrap-multilines': 'off',
|
|
93
|
-
'react/no-access-state-in-setstate': 'error',
|
|
94
|
-
'react/no-adjacent-inline-elements': 'off',
|
|
95
|
-
'react/no-array-index-key': 'off', // sometimes you don't care about the issues, or they don't apply
|
|
96
|
-
'react/no-arrow-function-lifecycle': 'error',
|
|
97
|
-
'react/no-danger': 'off',
|
|
98
|
-
'react/no-did-mount-set-state': 'error',
|
|
99
|
-
'react/no-did-update-set-state': 'error',
|
|
100
|
-
'react/no-invalid-html-attribute': 'error',
|
|
101
|
-
'react/no-multi-comp': 'off',
|
|
102
|
-
'react/no-namespace': 'error',
|
|
103
|
-
'react/no-object-type-as-default-prop': 'warn',
|
|
104
|
-
'react/no-redundant-should-component-update': 'error',
|
|
105
|
-
'react/no-set-state': 'off',
|
|
106
|
-
'react/no-this-in-sfc': 'error',
|
|
107
|
-
'react/no-typos': 'error',
|
|
108
|
-
'react/no-unescaped-entities': 'warn',
|
|
109
|
-
'react/no-unsafe': 'warn', // if you need it there should be a comment explaining why
|
|
110
|
-
'react/no-unstable-nested-components': ['error', { allowAsProps: true }],
|
|
111
|
-
'react/no-unused-class-component-methods': 'error',
|
|
112
|
-
'react/no-unused-prop-types': hasPropTypes ? 'error' : 'off',
|
|
113
|
-
'react/no-unused-state': 'error',
|
|
114
|
-
'react/no-will-update-set-state': 'error',
|
|
115
|
-
'react/prefer-es6-class': 'off',
|
|
116
|
-
'react/prefer-exact-props': 'off',
|
|
117
|
-
'react/prefer-read-only-props': 'off',
|
|
118
|
-
'react/prefer-stateless-function': 'off',
|
|
119
|
-
'react/prop-types': hasPropTypes ? 'error' : 'off',
|
|
120
|
-
'react/require-default-props': 'off', // sometimes the default value is undefined so that's fine...
|
|
121
|
-
'react/require-optimization': 'off',
|
|
122
|
-
'react/self-closing-comp': 'error',
|
|
123
|
-
'react/sort-comp': 'off',
|
|
124
|
-
'react/sort-default-props': 'off',
|
|
125
|
-
'react/sort-prop-types': 'off',
|
|
126
|
-
'react/state-in-constructor': 'off',
|
|
127
|
-
'react/static-property-placement': 'off',
|
|
128
|
-
'react/style-prop-object': 'error',
|
|
129
|
-
'react/void-dom-elements-no-children': 'error',
|
|
130
|
-
|
|
131
45
|
'jsx-a11y/lang': 'error',
|
|
132
46
|
'jsx-a11y/no-aria-hidden-on-focusable': 'off',
|
|
133
47
|
'jsx-a11y/no-autofocus': 'off',
|
|
134
48
|
'jsx-a11y/prefer-tag-over-role': 'off',
|
|
135
49
|
'jsx-a11y/tabindex-no-positive': 'warn',
|
|
50
|
+
|
|
51
|
+
'@eslint-react/avoid-shorthand-boolean': 'off',
|
|
52
|
+
'@eslint-react/avoid-shorthand-fragment': 'off',
|
|
53
|
+
'@eslint-react/jsx-no-iife': 'warn',
|
|
54
|
+
'@eslint-react/jsx-no-undef': 'error',
|
|
55
|
+
'@eslint-react/no-children-prop': 'warn',
|
|
56
|
+
'@eslint-react/no-class-component': 'warn',
|
|
57
|
+
'@eslint-react/no-complex-conditional-rendering': 'warn',
|
|
58
|
+
'@eslint-react/no-leaked-conditional-rendering': 'off', // will be enabled for typescript files below
|
|
59
|
+
'@eslint-react/no-missing-component-display-name': 'warn',
|
|
60
|
+
'@eslint-react/no-missing-context-display-name': 'warn',
|
|
61
|
+
'@eslint-react/no-useless-fragment': 'warn',
|
|
62
|
+
'@eslint-react/prefer-destructuring-assignment': 'warn',
|
|
63
|
+
'@eslint-react/prefer-react-namespace-import': 'warn',
|
|
64
|
+
'@eslint-react/prefer-read-only-props': 'off', // may be enabled for typescript files below
|
|
65
|
+
'@eslint-react/prefer-shorthand-boolean': 'warn',
|
|
66
|
+
'@eslint-react/prefer-shorthand-fragment': 'warn',
|
|
67
|
+
|
|
68
|
+
'@eslint-react/debug/class-component': 'off',
|
|
69
|
+
'@eslint-react/debug/function-component': 'off',
|
|
70
|
+
'@eslint-react/debug/hook': 'off',
|
|
71
|
+
'@eslint-react/debug/is-from-react': 'off',
|
|
72
|
+
'@eslint-react/debug/jsx': 'off',
|
|
73
|
+
'@eslint-react/debug/react-hooks': 'off',
|
|
74
|
+
|
|
75
|
+
'@eslint-react/dom/no-children-in-void-dom-elements': 'error',
|
|
76
|
+
'@eslint-react/dom/no-unknown-property': 'error',
|
|
77
|
+
|
|
78
|
+
'@eslint-react/hooks-extra/no-direct-set-state-in-use-layout-effect':
|
|
79
|
+
'warn',
|
|
80
|
+
'@eslint-react/hooks-extra/no-unnecessary-use-callback': 'warn',
|
|
81
|
+
'@eslint-react/hooks-extra/no-unnecessary-use-memo': 'warn',
|
|
82
|
+
|
|
83
|
+
'@eslint-react/naming-convention/component-name': 'warn',
|
|
84
|
+
'@eslint-react/naming-convention/filename': 'off', // this needs to be configured per project
|
|
85
|
+
'@eslint-react/naming-convention/filename-extension': [
|
|
86
|
+
'warn',
|
|
87
|
+
'as-needed',
|
|
88
|
+
],
|
|
89
|
+
'@eslint-react/naming-convention/use-state': 'off',
|
|
90
|
+
|
|
91
|
+
// @eslint-react/eslint-plugin marks their rules as deprecated in jsdoc,
|
|
92
|
+
// but not in the rule's metadata.
|
|
93
|
+
...deprecated.disable('@eslint-react', [
|
|
94
|
+
'ensure-forward-ref-using-ref',
|
|
95
|
+
'no-complicated-conditional-rendering',
|
|
96
|
+
'no-duplicate-jsx-props',
|
|
97
|
+
'no-nested-components',
|
|
98
|
+
'use-jsx-vars',
|
|
99
|
+
'hooks-extra/ensure-custom-hooks-using-other-hooks',
|
|
100
|
+
'hooks-extra/ensure-use-callback-has-non-empty-deps',
|
|
101
|
+
'hooks-extra/ensure-use-memo-has-non-empty-deps',
|
|
102
|
+
'hooks-extra/no-redundant-custom-hook',
|
|
103
|
+
'hooks-extra/no-useless-custom-hooks',
|
|
104
|
+
]),
|
|
136
105
|
},
|
|
137
106
|
settings: {
|
|
138
|
-
react: {
|
|
107
|
+
'react-x': {
|
|
139
108
|
version: minimumSupportedReactVersion,
|
|
140
109
|
},
|
|
141
110
|
},
|
|
142
111
|
},
|
|
143
112
|
{
|
|
144
113
|
files: ['**/*.ts?(x)'],
|
|
145
|
-
|
|
146
|
-
rules: {
|
|
147
|
-
'react/jsx-filename-extension': [
|
|
148
|
-
'error',
|
|
149
|
-
{ extensions: ['.ts', '.tsx'] },
|
|
150
|
-
],
|
|
151
|
-
'react/prop-types': 'off',
|
|
152
|
-
},
|
|
114
|
+
...pluginReact.configs['recommended-type-checked'],
|
|
153
115
|
}
|
|
154
116
|
)
|
package/configs/typescript.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'
|
|
2
|
+
import pluginImport from 'eslint-plugin-import-x'
|
|
2
3
|
import tseslint from 'typescript-eslint'
|
|
3
4
|
|
|
4
5
|
// typescript-eslint still enables a couple of base rules that are deprecated in v9
|
|
@@ -10,11 +11,13 @@ function disableDeprecatedRules(config) {
|
|
|
10
11
|
tseslint.configs.strictTypeChecked.forEach(disableDeprecatedRules)
|
|
11
12
|
tseslint.configs.stylisticTypeChecked.forEach(disableDeprecatedRules)
|
|
12
13
|
|
|
14
|
+
delete pluginImport.flatConfigs.typescript.settings['import-x/resolver']
|
|
15
|
+
|
|
13
16
|
export default tseslint.config({
|
|
14
17
|
extends: [
|
|
15
18
|
...tseslint.configs.strictTypeChecked,
|
|
16
19
|
...tseslint.configs.stylisticTypeChecked,
|
|
17
|
-
pluginImport.
|
|
20
|
+
pluginImport.flatConfigs.typescript,
|
|
18
21
|
],
|
|
19
22
|
files: ['**/*.ts?(x)'],
|
|
20
23
|
languageOptions: {
|
|
@@ -24,8 +27,8 @@ export default tseslint.config({
|
|
|
24
27
|
},
|
|
25
28
|
name: 'mrpalmer/typescript',
|
|
26
29
|
rules: {
|
|
27
|
-
'import/consistent-type-specifier-style': 'off',
|
|
28
|
-
'import/no-unresolved': 'off', // ts(2307)
|
|
30
|
+
'import-x/consistent-type-specifier-style': 'off',
|
|
31
|
+
'import-x/no-unresolved': 'off', // ts(2307)
|
|
29
32
|
|
|
30
33
|
'constructor-super': 'off', // ts(2335) & ts(2377)
|
|
31
34
|
'getter-return': 'off', // ts(2378)
|
|
@@ -127,6 +130,7 @@ export default tseslint.config({
|
|
|
127
130
|
'@typescript-eslint/no-unnecessary-parameter-property-assignment': 'warn',
|
|
128
131
|
'@typescript-eslint/no-unnecessary-qualifier': 'warn',
|
|
129
132
|
'@typescript-eslint/no-unnecessary-type-arguments': 'warn',
|
|
133
|
+
'@typescript-eslint/no-unnecessary-type-conversion': 'warn',
|
|
130
134
|
'@typescript-eslint/no-unsafe-type-assertion': 'error',
|
|
131
135
|
'@typescript-eslint/no-useless-empty-export': 'error',
|
|
132
136
|
'@typescript-eslint/parameter-properties': [
|
|
@@ -145,6 +149,11 @@ export default tseslint.config({
|
|
|
145
149
|
],
|
|
146
150
|
'@typescript-eslint/strict-boolean-expressions': 'off',
|
|
147
151
|
'@typescript-eslint/switch-exhaustiveness-check': 'error',
|
|
148
|
-
|
|
152
|
+
},
|
|
153
|
+
settings: {
|
|
154
|
+
'import-x/resolver-next': [
|
|
155
|
+
createTypeScriptImportResolver(),
|
|
156
|
+
pluginImport.createNodeResolver(),
|
|
157
|
+
],
|
|
149
158
|
},
|
|
150
159
|
})
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrpalmer/eslint-config",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Mike Palmer's personal ESLint rules",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./index.js",
|
|
10
|
+
"types": "./types/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
7
14
|
"main": "index.js",
|
|
15
|
+
"types": "types/index.d.ts",
|
|
8
16
|
"scripts": {
|
|
17
|
+
"prebuild": "rm -rf types",
|
|
18
|
+
"build": "tsc",
|
|
9
19
|
"check-config": "run-p check-config:*",
|
|
10
20
|
"check-config:jest": "cd test && validate-config -f component.test.js",
|
|
11
21
|
"check-config:jest-ts": "cd test && validate-config -f component.test.ts",
|
|
@@ -15,19 +25,20 @@
|
|
|
15
25
|
"validate": "npm run check-config"
|
|
16
26
|
},
|
|
17
27
|
"dependencies": {
|
|
18
|
-
"@eslint/
|
|
19
|
-
"@
|
|
20
|
-
"eslint-plugin
|
|
21
|
-
"eslint-
|
|
28
|
+
"@eslint-react/eslint-plugin": "^1.52.3",
|
|
29
|
+
"@eslint/js": "^9.31.0",
|
|
30
|
+
"@mrpalmer/eslint-plugin": "^1.0.1",
|
|
31
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
32
|
+
"eslint-plugin-import-x": "^4.16.1",
|
|
33
|
+
"eslint-plugin-jest": "^29.0.1",
|
|
22
34
|
"eslint-plugin-jest-dom": "^5.5.0",
|
|
23
35
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
24
|
-
"eslint-plugin-react": "^
|
|
25
|
-
"eslint-plugin-
|
|
26
|
-
"
|
|
27
|
-
"globals": "^15.14.0",
|
|
36
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
37
|
+
"eslint-plugin-testing-library": "^7.5.4",
|
|
38
|
+
"globals": "^16.3.0",
|
|
28
39
|
"read-package-up": "^11.0.0",
|
|
29
|
-
"semver": "^7.
|
|
30
|
-
"typescript-eslint": "^8.
|
|
40
|
+
"semver": "^7.7.2",
|
|
41
|
+
"typescript-eslint": "^8.36.0"
|
|
31
42
|
},
|
|
32
43
|
"peerDependencies": {
|
|
33
44
|
"@testing-library/dom": "*",
|
package/tsconfig.json
ADDED
package/turbo.json
ADDED
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export { config };
|
|
3
|
+
export { configs };
|
|
4
|
+
export { globals };
|
|
5
|
+
}
|
|
6
|
+
export default _default;
|
|
7
|
+
import { config } from 'typescript-eslint';
|
|
8
|
+
export namespace configs {
|
|
9
|
+
export let all: import("@typescript-eslint/utils/ts-eslint").FlatConfig.Config[];
|
|
10
|
+
export { base };
|
|
11
|
+
export { jest };
|
|
12
|
+
export { react };
|
|
13
|
+
export { typescript };
|
|
14
|
+
}
|
|
15
|
+
import globals from 'globals';
|
|
16
|
+
import base from './configs/base.js';
|
|
17
|
+
import jest from './configs/jest.js';
|
|
18
|
+
import react from './configs/react.js';
|
|
19
|
+
import typescript from './configs/typescript.js';
|
|
20
|
+
export { config, globals };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @typedef {Record<string, string>} Dependencies */
|
|
2
|
+
/**
|
|
3
|
+
* Get all dependencies from the current project
|
|
4
|
+
* @returns {Dependencies}
|
|
5
|
+
*/
|
|
6
|
+
export function getAllDependencies(): Dependencies;
|
|
7
|
+
/**
|
|
8
|
+
* Get the installed version of a dependency
|
|
9
|
+
* @param {Dependencies} allDeps
|
|
10
|
+
* @param {string} depName
|
|
11
|
+
* @returns {string | undefined}
|
|
12
|
+
*/
|
|
13
|
+
export function getMinimumSupportedVersion(allDeps: Dependencies, depName: string): string | undefined;
|
|
14
|
+
export type Dependencies = Record<string, string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function remove(config, ruleNames) {
|
|
2
|
+
if (!config || !config.rules) {
|
|
3
|
+
return config
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
for (const ruleName of ruleNames) {
|
|
7
|
+
if (Object.hasOwn(config.rules, ruleName)) {
|
|
8
|
+
delete config.rules[ruleName]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return config
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function disable(pluginName, ruleNames) {
|
|
16
|
+
return Object.fromEntries(
|
|
17
|
+
ruleNames.map((ruleName) => [`${pluginName}/${ruleName}`, 'off'])
|
|
18
|
+
)
|
|
19
|
+
}
|