@mrpalmer/eslint-config 1.0.1 → 2.0.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/index.js CHANGED
@@ -1,341 +1,21 @@
1
- const fs = require('fs')
2
- const path = require('path')
3
-
4
- const tsConfig = fs.existsSync('tsconfig.json')
5
- ? path.resolve('tsconfig.json')
6
- : fs.existsSync('types/tsconfig.json')
7
- ? path.resolve('types/tsconfig.json')
8
- : undefined
9
-
10
- module.exports = {
11
- env: {
12
- browser: true,
13
- es6: true,
14
- node: true,
15
- },
16
- extends: ['eslint:recommended', 'prettier', './import.js'],
17
- rules: {
18
- 'accessor-pairs': 'error',
19
- 'array-callback-return': 'error',
20
- 'arrow-body-style': 'off',
21
- 'block-scoped-var': 'error',
22
- camelcase: 'off',
23
- 'capitalized-comments': 'off',
24
- 'class-methods-use-this': 'off',
25
- complexity: ['error', 20],
26
- 'consistent-return': 'error',
27
- 'consistent-this': 'off',
28
- curly: ['error', 'multi-line'],
29
- 'default-case': 'error',
30
- 'default-case-last': 'error',
31
- 'default-param-last': 'off',
32
- 'dot-notation': 'error',
33
- eqeqeq: ['error', 'smart'],
34
- 'func-name-matching': 'error',
35
- 'func-names': 'error',
36
- 'func-style': 'off',
37
- 'getter-return': ['error', { allowImplicit: true }],
38
- 'grouped-accessor-pairs': 'off',
39
- 'guard-for-in': 'error',
40
- 'id-denylist': 'error',
41
- 'id-length': 'off',
42
- 'id-match': [
43
- 'error',
44
- // camelCase, PascalCase, __filename, CONST_VALUE, stream$, $el
45
- '^\\$?(__)?(([A-Z]|[a-z]|[0-9]+)|([A-Z_]))*\\$?$',
46
- ],
47
- 'init-declarations': 'off',
48
- 'line-comment-position': 'off',
49
- 'logical-assignment-operators': [
50
- 'warn',
51
- 'always',
52
- { enforceForIfStatements: true },
53
- ],
54
- 'max-classes-per-file': 'off',
55
- 'max-depth': ['error', 4],
56
- 'max-lines': [
57
- 'error',
58
- { max: 2500, skipBlankLines: false, skipComments: false },
59
- ],
60
- 'max-lines-per-function': 'off',
61
- 'max-nested-callbacks': ['error', 7],
62
- 'max-params': ['error', { max: 7 }],
63
- 'max-statements': 'off',
64
- 'multiline-comment-style': 'off',
65
- 'new-cap': 'error',
66
- 'no-alert': 'error',
67
- 'no-array-constructor': 'error',
68
- 'no-await-in-loop': 'error',
69
- 'no-bitwise': 'error',
70
- 'no-caller': 'error',
71
- 'no-console': 'off',
72
- 'no-constant-binary-expression': 'error',
73
- 'no-constructor-return': 'error',
74
- 'no-continue': 'off',
75
- 'no-div-regex': 'error',
76
- 'no-duplicate-imports': 'off',
77
- 'no-else-return': 'off',
78
- 'no-empty-function': 'off',
79
- 'no-empty-static-block': 'warn',
80
- 'no-eq-null': 'off',
81
- 'no-eval': 'error',
82
- 'no-extend-native': 'error',
83
- 'no-extra-bind': 'error',
84
- 'no-extra-label': 'error',
85
- 'no-implicit-coercion': 'off',
86
- 'no-implicit-globals': 'error',
87
- 'no-implied-eval': 'error',
88
- 'no-inline-comments': 'off',
89
- 'no-invalid-this': 'error',
90
- 'no-iterator': 'error',
91
- 'no-label-var': 'error',
92
- 'no-labels': 'error',
93
- 'no-lone-blocks': 'error',
94
- 'no-lonely-if': 'error',
95
- 'no-loop-func': 'error',
96
- 'no-magic-numbers': 'off',
97
- 'no-multi-assign': 'error',
98
- 'no-multi-str': 'error',
99
- 'no-negated-condition': 'error',
100
- 'no-nested-ternary': 'off',
101
- 'no-new': 'error',
102
- 'no-new-func': 'error',
103
- 'no-new-native-nonconstructor': 'error',
104
- 'no-new-wrappers': 'error',
105
- 'no-object-constructor': 'error',
106
- 'no-octal-escape': 'error',
107
- 'no-param-reassign': 'off',
108
- 'no-plusplus': 'off',
109
- 'no-promise-executor-return': 'off',
110
- 'no-proto': 'error',
111
- 'no-restricted-exports': 'off',
112
- 'no-restricted-globals': ['error', 'event', 'fdescribe'],
113
- 'no-restricted-imports': 'off',
114
- 'no-restricted-properties': 'off',
115
- 'no-restricted-syntax': ['error', 'WithStatement'],
116
- 'no-return-assign': 'error',
117
- 'no-script-url': 'error',
118
- 'no-self-compare': 'error',
119
- 'no-sequences': 'error',
120
- 'no-shadow': 'off',
121
- 'no-template-curly-in-string': 'error',
122
- 'no-ternary': 'off',
123
- 'no-throw-literal': 'error',
124
- 'no-undef-init': 'error',
125
- 'no-undefined': 'off',
126
- 'no-underscore-dangle': 'off',
127
- 'no-unmodified-loop-condition': 'error',
128
- 'no-unneeded-ternary': 'error',
129
- 'no-unreachable-loop': 'error',
130
- 'no-unused-expressions': 'off',
131
- 'no-unused-private-class-members': 'error',
132
- 'no-unused-vars': [
133
- 'error',
134
- {
135
- args: 'after-used',
136
- argsIgnorePattern: '^_',
137
- ignoreRestSiblings: true,
138
- varsIgnorePattern: '^ignored',
139
- },
140
- ],
141
- 'no-use-before-define': ['error', 'nofunc'],
142
- 'no-useless-call': 'error',
143
- 'no-useless-computed-key': 'error',
144
- 'no-useless-concat': 'error',
145
- 'no-useless-constructor': 'error',
146
- 'no-useless-rename': 'error',
147
- 'no-useless-return': 'error',
148
- 'no-var': 'error',
149
- 'no-void': 'off',
150
- 'no-warning-comments': [
151
- 'error',
152
- { location: 'anywhere', terms: ['fixme'] },
153
- ],
154
- 'object-shorthand': ['error', 'properties'],
155
- 'one-var': ['error', { initialized: 'never', uninitialized: 'always' }],
156
- 'operator-assignment': 'off',
157
- 'prefer-arrow-callback': [
158
- 'error',
159
- { allowNamedFunctions: true, allowUnboundThis: true },
160
- ],
161
- 'prefer-const': 'error',
162
- 'prefer-destructuring': 'off',
163
- 'prefer-exponentiation-operator': 'warn',
164
- 'prefer-named-capture-group': 'off',
165
- 'prefer-numeric-literals': 'error',
166
- 'prefer-object-has-own': 'error',
167
- 'prefer-object-spread': 'warn',
168
- 'prefer-promise-reject-errors': 'off',
169
- 'prefer-regex-literals': 'off',
170
- 'prefer-rest-params': 'error',
171
- 'prefer-spread': 'error',
172
- 'prefer-template': 'error',
173
- radix: 'error',
174
- 'require-atomic-updates': 'off',
175
- 'require-await': 'off',
176
- 'require-unicode-regexp': 'off',
177
- 'sort-imports': 'off',
178
- 'sort-keys': 'off',
179
- 'sort-vars': 'off',
180
- strict: 'error',
181
- 'symbol-description': 'error',
182
- 'unicode-bom': ['error', 'never'],
183
- 'vars-on-top': 'error',
184
- yoda: 'error',
185
- },
186
- overrides: [
187
- {
188
- files: ['**/*.ts?(x)'],
189
- parser: '@typescript-eslint/parser',
190
- parserOptions: {
191
- ecmaVersion: 2018,
192
- project: tsConfig,
193
- sourceType: 'module',
194
- },
195
- plugins: ['@typescript-eslint'],
196
- extends: [
197
- 'plugin:@typescript-eslint/strict-type-checked',
198
- 'plugin:@typescript-eslint/stylistic-type-checked',
199
- ],
200
- rules: {
201
- 'constructor-super': 'off', // ts(2335) & ts(2377)
202
- 'getter-return': 'off', // ts(2378)
203
- 'no-const-assign': 'off', // ts(2588)
204
- 'no-dupe-args': 'off', // ts(2300)
205
- 'no-dupe-keys': 'off', // ts(1117)
206
- 'no-func-assign': 'off', // ts(2539)
207
- 'no-import-assign': 'off', // ts(2539) & ts(2540)
208
- 'no-new-symbol': 'off', // ts(2588)
209
- 'no-obj-calls': 'off', // ts(2349)
210
- 'no-setter-return': 'off', // ts(2408)
211
- 'no-this-before-super': 'off', // ts(2376)
212
- 'no-undef': 'off', // ts(2304)
213
- 'no-unreachable': 'off', // ts(7027)
214
- 'no-unsafe-negation': 'off', // ts(2365) & ts(2360) & ts(2358)
215
- 'valid-typeof': 'off', // ts(2367)
216
-
217
- 'no-var': 'error', // TS transpiles let/const to var, so no need for vars anymore
218
- 'prefer-const': 'error', // TS provides better types with const
219
- 'prefer-rest-params': 'error', // TS provides better types with rest args over arguments
220
- 'prefer-spread': 'error', // TS transpiles spread to apply, so no need for manual apply
221
-
222
- 'consistent-return': 'off',
223
- '@typescript-eslint/consistent-return': 'error',
224
-
225
- 'default-param-last': 'off',
226
- '@typescript-eslint/default-param-last': 'off',
227
-
228
- 'init-declarations': 'off',
229
- '@typescript-eslint/init-declarations': 'off',
230
-
231
- 'max-params': 'off',
232
- '@typescript-eslint/max-params': ['error', { max: 7 }],
233
-
234
- 'no-dupe-class-members': 'off',
235
- '@typescript-eslint/no-dupe-class-members': 'off', // ts(2393) & ts(2300)
236
-
237
- 'no-empty-function': 'off',
238
- '@typescript-eslint/no-empty-function': 'off',
239
-
240
- 'no-invalid-this': 'off',
241
- '@typescript-eslint/no-invalid-this': 'error',
242
-
243
- 'no-loop-func': 'off',
244
- '@typescript-eslint/no-loop-func': 'error',
245
-
246
- 'no-magic-numbers': 'off',
247
- '@typescript-eslint/no-magic-numbers': 'off',
248
-
249
- 'no-redeclare': 'off',
250
- '@typescript-eslint/no-redeclare': 'off', // ts(2451)
251
-
252
- 'no-shadow': 'off',
253
- '@typescript-eslint/no-shadow': 'off',
254
-
255
- 'no-unused-expressions': 'off',
256
- '@typescript-eslint/no-unused-expressions': 'off',
257
-
258
- 'no-unused-vars': 'off',
259
- '@typescript-eslint/no-unused-vars': [
260
- 'error',
261
- {
262
- args: 'after-used',
263
- argsIgnorePattern: '^_',
264
- ignoreRestSiblings: true,
265
- varsIgnorePattern: '^ignored',
266
- },
267
- ],
268
-
269
- 'no-use-before-define': 'off',
270
- '@typescript-eslint/no-use-before-define': ['error', 'nofunc'],
1
+ import globals from 'globals'
2
+ import { config } from 'typescript-eslint'
3
+ import base from './configs/base.js'
4
+ import jest from './configs/jest.js'
5
+ import react from './configs/react.js'
6
+ import typescript from './configs/typescript.js'
7
+
8
+ const configs = {
9
+ all: [...base, ...react, ...jest, ...typescript],
10
+ base,
11
+ jest,
12
+ react,
13
+ typescript,
14
+ }
271
15
 
272
- '@typescript-eslint/array-type': ['error', { default: 'array-simple' }],
273
- '@typescript-eslint/class-methods-use-this': 'off',
274
- '@typescript-eslint/consistent-type-definitions': 'off',
275
- '@typescript-eslint/consistent-type-exports': [
276
- 'error',
277
- { fixMixedExportsWithInlineTypeSpecifier: true },
278
- ],
279
- 'import/consistent-type-specifier-style': 'off',
280
- '@typescript-eslint/consistent-type-imports': [
281
- 'error',
282
- { fixStyle: 'inline-type-imports' },
283
- ],
284
- '@typescript-eslint/explicit-function-return-type': 'off',
285
- '@typescript-eslint/explicit-member-accessibility': 'off',
286
- '@typescript-eslint/explicit-module-boundary-types': 'off',
287
- '@typescript-eslint/member-ordering': 'off',
288
- '@typescript-eslint/method-signature-style': 'off',
289
- '@typescript-eslint/naming-convention': 'off',
290
- '@typescript-eslint/no-base-to-string': 'warn',
291
- '@typescript-eslint/no-confusing-void-expression': [
292
- 'warn',
293
- { ignoreArrowShorthand: true, ignoreVoidOperator: true },
294
- ],
295
- '@typescript-eslint/no-empty-object-type': 'error',
296
- '@typescript-eslint/no-floating-promises': 'warn',
297
- '@typescript-eslint/no-import-type-side-effects': 'error',
298
- '@typescript-eslint/no-inferrable-types': 'off',
299
- '@typescript-eslint/no-invalid-void-type': 'warn',
300
- '@typescript-eslint/no-misused-promises': [
301
- 'warn',
302
- { checksVoidReturn: false },
303
- ],
304
- '@typescript-eslint/no-require-imports': 'off',
305
- '@typescript-eslint/no-restricted-imports': 'off',
306
- '@typescript-eslint/no-restricted-types': 'off',
307
- '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn',
308
- '@typescript-eslint/no-unnecessary-parameter-property-assignment':
309
- 'warn',
310
- '@typescript-eslint/no-unnecessary-qualifier': 'warn',
311
- '@typescript-eslint/no-unnecessary-type-arguments': 'warn',
312
- '@typescript-eslint/no-unsafe-assignment': 'warn',
313
- '@typescript-eslint/no-unsafe-call': 'warn',
314
- '@typescript-eslint/no-unsafe-member-access': 'warn',
315
- '@typescript-eslint/no-unsafe-return': 'warn',
316
- '@typescript-eslint/no-unsafe-unary-minus': 'error',
317
- '@typescript-eslint/no-useless-empty-export': 'error',
318
- '@typescript-eslint/parameter-properties': [
319
- 'error',
320
- { prefer: 'parameter-property' },
321
- ],
322
- '@typescript-eslint/prefer-destructuring': 'off',
323
- '@typescript-eslint/prefer-enum-initializers': 'error',
324
- '@typescript-eslint/prefer-find': 'warn',
325
- '@typescript-eslint/prefer-for-of': 'warn',
326
- '@typescript-eslint/prefer-function-type': 'warn',
327
- '@typescript-eslint/prefer-readonly': 'off',
328
- '@typescript-eslint/prefer-readonly-parameter-types': 'off',
329
- '@typescript-eslint/prefer-reduce-type-parameter': 'warn',
330
- '@typescript-eslint/prefer-regexp-exec': 'off',
331
- '@typescript-eslint/promise-function-async': 'off',
332
- '@typescript-eslint/require-array-sort-compare': 'off',
333
- '@typescript-eslint/return-await': 'off',
334
- '@typescript-eslint/strict-boolean-expressions': 'off',
335
- '@typescript-eslint/switch-exhaustiveness-check': 'error',
336
- '@typescript-eslint/typedef': 'off',
337
- '@typescript-eslint/unified-signatures': 'warn',
338
- },
339
- },
340
- ],
16
+ export default {
17
+ config,
18
+ configs,
19
+ globals,
341
20
  }
21
+ export { config, configs, globals }
package/package.json CHANGED
@@ -1,40 +1,40 @@
1
1
  {
2
2
  "name": "@mrpalmer/eslint-config",
3
- "version": "1.0.1",
3
+ "version": "2.0.0",
4
4
  "description": "Mike Palmer's personal ESLint rules",
5
5
  "license": "MIT",
6
+ "type": "module",
6
7
  "main": "index.js",
7
8
  "scripts": {
8
9
  "check-config": "run-p check-config:*",
9
- "check-config:jest": "validate-config -f component.test.js ./test/jest.js",
10
- "check-config:jest-ts": "validate-config -f component.test.ts ./test/jest.js",
11
- "check-config:js": "validate-config -f index.js ./index.js",
12
- "check-config:jsx-a11y": "validate-config -f component.jsx ./test/jsx-a11y.js",
13
- "check-config:react": "validate-config -f component.jsx ./test/react.js",
14
- "check-config:ts": "validate-config -f index.ts ./index.js",
15
- "lint": "eslint --config index.js .",
16
- "validate": "run-p lint check-config"
10
+ "check-config:jest": "cd test && validate-config -f component.test.js",
11
+ "check-config:jest-ts": "cd test && validate-config -f component.test.ts",
12
+ "check-config:js": "cd test && validate-config -f index.js",
13
+ "check-config:ts": "cd test && validate-config -f index.ts",
14
+ "dev": "cd test && eslint-config-inspector",
15
+ "validate": "npm run check-config"
17
16
  },
18
17
  "dependencies": {
19
- "@typescript-eslint/eslint-plugin": "^8.1.0",
20
- "@typescript-eslint/parser": "^8.1.0",
21
- "eslint-config-prettier": "^9.1.0",
22
- "eslint-plugin-import": "^2.29.1",
23
- "eslint-plugin-jest": "^28.8.0",
24
- "eslint-plugin-jest-dom": "^5.4.0",
25
- "eslint-plugin-jsx-a11y": "^6.9.0",
26
- "eslint-plugin-react": "^7.35.0",
27
- "eslint-plugin-react-hooks": "^4.6.2",
28
- "eslint-plugin-testing-library": "^6.3.0",
29
- "read-pkg-up": "^7.0.1",
30
- "semver": "^7.3.2"
18
+ "@eslint/js": "^9.20.0",
19
+ "@types/eslint__js": "^8.42.3",
20
+ "eslint-plugin-import": "^2.31.0",
21
+ "eslint-plugin-jest": "^28.11.0",
22
+ "eslint-plugin-jest-dom": "^5.5.0",
23
+ "eslint-plugin-jsx-a11y": "^6.10.2",
24
+ "eslint-plugin-react": "^7.37.4",
25
+ "eslint-plugin-react-hooks": "^5.1.0",
26
+ "eslint-plugin-testing-library": "^7.1.1",
27
+ "globals": "^15.14.0",
28
+ "read-package-up": "^11.0.0",
29
+ "semver": "^7.3.2",
30
+ "typescript-eslint": "^8.23.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@testing-library/dom": "*",
34
34
  "@testing-library/jest-dom": "*",
35
35
  "@testing-library/react": "*",
36
- "eslint": "^8.0.0",
37
- "typescript": "^4.0.0 || ^5.0.0"
36
+ "eslint": "^9.0.0",
37
+ "typescript": "^5.0.0"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@testing-library/dom": {
@@ -51,8 +51,8 @@
51
51
  }
52
52
  },
53
53
  "engines": {
54
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0",
55
- "npm": ">=6",
54
+ "node": ">=20",
55
+ "npm": ">=8",
56
56
  "yarn": ">=1"
57
57
  }
58
58
  }
@@ -0,0 +1,41 @@
1
+ import { readPackageUpSync } from 'read-package-up'
2
+ import * as semver from 'semver'
3
+
4
+ /** @typedef {Record<string, string>} Dependencies */
5
+
6
+ /**
7
+ * Get all dependencies from the current project
8
+ * @returns {Dependencies}
9
+ */
10
+ export function getAllDependencies() {
11
+ try {
12
+ const result = readPackageUpSync() ?? {}
13
+ return {
14
+ ...result.packageJson?.peerDependencies,
15
+ ...result.packageJson?.devDependencies,
16
+ ...result.packageJson?.dependencies,
17
+ }
18
+ } catch {
19
+ return {}
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Get the installed version of a dependency
25
+ * @param {Dependencies} allDeps
26
+ * @param {string} depName
27
+ * @returns {string | undefined}
28
+ */
29
+ export function getMinimumSupportedVersion(allDeps, depName) {
30
+ if (!allDeps[depName]) {
31
+ return undefined
32
+ }
33
+
34
+ const versions = semver
35
+ .validRange(allDeps[depName])
36
+ .replace(/[>=<|]/g, ' ')
37
+ .split(' ')
38
+ .filter(Boolean)
39
+ .sort(semver.compare)
40
+ return versions[0]
41
+ }
package/import.js DELETED
@@ -1,74 +0,0 @@
1
- module.exports = {
2
- env: {
3
- es6: true,
4
- },
5
- parserOptions: {
6
- ecmaVersion: 2018,
7
- sourceType: 'module',
8
- },
9
- plugins: ['import'],
10
- settings: {
11
- 'import/ignore': ['node_modules', '.json$', '.(scss|less|css|styl)$'],
12
- },
13
- rules: {
14
- 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
15
- 'import/default': 'error',
16
- 'import/dynamic-import-chunkname': 'off',
17
- 'import/export': 'error',
18
- 'import/exports-last': 'off',
19
- 'import/extensions': 'off',
20
- 'import/first': 'error',
21
- 'import/group-exports': 'off',
22
- 'import/max-dependencies': 'off',
23
- 'import/named': 'error',
24
- 'import/namespace': 'error',
25
- 'import/newline-after-import': 'off',
26
- 'import/no-absolute-path': 'error',
27
- 'import/no-amd': 'error',
28
- 'import/no-anonymous-default-export': 'error',
29
- 'import/no-commonjs': 'off',
30
- 'import/no-cycle': 'off',
31
- 'import/no-default-export': 'off',
32
- 'import/no-deprecated': 'warn',
33
- 'import/no-duplicates': 'error',
34
- 'import/no-dynamic-require': 'off',
35
- 'import/no-empty-named-blocks': 'warn',
36
- 'import/no-extraneous-dependencies': 'error',
37
- 'import/no-import-module-exports': 'error',
38
- 'import/no-internal-modules': 'off',
39
- 'import/no-mutable-exports': 'error',
40
- 'import/no-named-as-default': 'error',
41
- 'import/no-named-as-default-member': 'error',
42
- 'import/no-named-default': 'error',
43
- 'import/no-named-export': 'off',
44
- 'import/no-namespace': 'off',
45
- 'import/no-nodejs-modules': 'off',
46
- 'import/no-relative-packages': 'warn',
47
- 'import/no-relative-parent-imports': 'off',
48
- 'import/no-restricted-paths': 'off',
49
- 'import/no-self-import': 'error',
50
- 'import/no-unassigned-import': 'off',
51
- 'import/no-unresolved': 'error',
52
- 'import/no-unused-modules': 'off',
53
- 'import/no-useless-path-segments': 'error',
54
- 'import/no-webpack-loader-syntax': 'error',
55
- 'import/order': 'off',
56
- 'import/prefer-default-export': 'off',
57
- 'import/unambiguous': 'off',
58
- },
59
- overrides: [
60
- {
61
- files: ['**/*.ts?(x)'],
62
- extends: 'plugin:import/typescript',
63
- parser: '@typescript-eslint/parser',
64
- parserOptions: {
65
- ecmaVersion: 2018,
66
- sourceType: 'module',
67
- },
68
- plugins: ['@typescript-eslint'],
69
- rules: {
70
- 'import/no-unresolved': 'off', // ts(2307)
71
- },
72
- },
73
- ],
74
- }
package/jest.js DELETED
@@ -1,119 +0,0 @@
1
- const readPkgUp = require('read-pkg-up')
2
-
3
- let hasJestDom = false
4
- let hasTestingLibraryDom = false
5
- let hasTestingLibraryReact = false
6
-
7
- try {
8
- const { packageJson } = readPkgUp.sync({ normalize: true })
9
- const allDeps = Object.keys({
10
- ...packageJson.peerDependencies,
11
- ...packageJson.devDependencies,
12
- ...packageJson.dependencies,
13
- })
14
-
15
- hasJestDom = allDeps.includes('@testing-library/jest-dom')
16
- hasTestingLibraryDom = allDeps.includes('@testing-library/dom')
17
- hasTestingLibraryReact = allDeps.includes('@testing-library/react')
18
- } catch (error) {
19
- // ignore error
20
- }
21
-
22
- const hasTestingLibrary = hasTestingLibraryDom || hasTestingLibraryReact
23
-
24
- module.exports = {
25
- env: {
26
- 'jest/globals': true,
27
- },
28
- plugins: [
29
- 'jest',
30
- hasJestDom && 'jest-dom',
31
- hasTestingLibrary && 'testing-library',
32
- ].filter(Boolean),
33
- overrides: [
34
- {
35
- files: [
36
- '**/__tests__/**/*.+(js|ts)?(x)',
37
- '**/*.{spec,test}.+(js|ts)?(x)',
38
- ],
39
- extends: [
40
- 'plugin:jest/recommended',
41
- 'plugin:jest/style',
42
- hasJestDom && 'plugin:jest-dom/recommended',
43
- hasTestingLibraryReact
44
- ? 'plugin:testing-library/react'
45
- : hasTestingLibraryDom
46
- ? 'plugin:testing-library/dom'
47
- : null,
48
- ].filter(Boolean),
49
- rules: {
50
- 'react/display-name': 'off', // we don't need a display name in test files
51
-
52
- 'jest/consistent-test-it': 'off',
53
- 'jest/max-expects': 'off',
54
- 'jest/max-nested-describe': 'error',
55
- 'jest/no-conditional-in-test': 'error',
56
- 'jest/no-confusing-set-timeout': 'error',
57
- 'jest/no-duplicate-hooks': 'off',
58
- 'jest/no-hooks': 'off',
59
- 'jest/no-large-snapshots': ['warn', { maxSize: 300 }],
60
- 'jest/no-restricted-jest-methods': 'off',
61
- 'jest/no-restricted-matchers': 'off',
62
- 'jest/no-test-return-statement': 'off',
63
- 'jest/no-untyped-mock-factory': 'error',
64
- 'jest/padding-around-after-all-blocks': 'off',
65
- 'jest/padding-around-after-each-blocks': 'off',
66
- 'jest/padding-around-all': 'off',
67
- 'jest/padding-around-before-all-blocks': 'off',
68
- 'jest/padding-around-before-each-blocks': 'off',
69
- 'jest/padding-around-describe-blocks': 'off',
70
- 'jest/padding-around-expect-groups': 'off',
71
- 'jest/padding-around-test-blocks': 'off',
72
- 'jest/prefer-called-with': 'error',
73
- 'jest/prefer-comparison-matcher': 'warn',
74
- 'jest/prefer-each': 'warn',
75
- 'jest/prefer-equality-matcher': 'warn',
76
- 'jest/prefer-expect-assertions': 'off',
77
- 'jest/prefer-expect-resolves': 'off',
78
- 'jest/prefer-hooks-in-order': 'error',
79
- 'jest/prefer-hooks-on-top': 'error',
80
- 'jest/prefer-importing-jest-globals': 'off',
81
- 'jest/prefer-jest-mocked': 'warn',
82
- 'jest/prefer-lowercase-title': 'off',
83
- 'jest/prefer-mock-promise-shorthand': 'warn',
84
- 'jest/prefer-snapshot-hint': ['error', 'multi'],
85
- 'jest/prefer-spy-on': 'off',
86
- 'jest/prefer-strict-equal': 'off',
87
- 'jest/prefer-todo': 'warn',
88
- 'jest/require-hook': 'off',
89
- 'jest/require-to-throw-message': 'off',
90
- 'jest/require-top-level-describe': 'off',
91
- 'jest/unbound-method': 'off',
92
-
93
- ...(hasTestingLibrary
94
- ? {
95
- 'testing-library/consistent-data-testid': 'off',
96
- 'testing-library/no-container': 'error',
97
- 'testing-library/no-debugging-utils': 'error',
98
- 'testing-library/no-dom-import': ['error', 'react'],
99
- 'testing-library/no-manual-cleanup': 'error',
100
- 'testing-library/no-render-in-lifecycle': 'error',
101
- 'testing-library/no-unnecessary-act': 'error',
102
- 'testing-library/prefer-explicit-assert': 'warn',
103
- 'testing-library/prefer-implicit-assert': 'off',
104
- 'testing-library/prefer-query-matchers': 'off',
105
- 'testing-library/prefer-user-event': 'error',
106
- 'testing-library/render-result-naming-convention': 'error',
107
- }
108
- : null),
109
- },
110
- },
111
- {
112
- files: ['**/__tests__/**/*.ts?(x)', '**/*.{spec,test}.ts?(x)'],
113
- rules: {
114
- '@typescript-eslint/unbound-method': 'off',
115
- 'jest/unbound-method': 'error',
116
- },
117
- },
118
- ],
119
- }