@jsimck/eslint-config 2.0.0 → 2.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsimck/eslint-config",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Very opinionated eslint config I use on my projects, includes: prettier, TS, jest, sonarqube and unicorn. And many others.",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -0,0 +1,100 @@
1
+ import globals from 'globals';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ ignores: [
8
+ '**/out/**',
9
+ '**/*.gen.ts',
10
+ '**/node_modules/**',
11
+ '**/.next/**',
12
+ '**/.expo/**',
13
+ '**/dist/**',
14
+ '**/build/**',
15
+ '**/docs/**',
16
+ '**/storybook-static/**',
17
+ '**/.docusaurus/**',
18
+ '**/coverage/**',
19
+ ],
20
+ },
21
+ {
22
+ files: [...files.js, ...files.ts],
23
+ languageOptions: {
24
+ globals: {
25
+ ...globals.browser,
26
+ ...globals.node,
27
+ },
28
+ parserOptions: {
29
+ ecmaVersion: 'latest',
30
+ sourceType: 'module',
31
+ },
32
+ },
33
+ rules: {
34
+ // Stylistic has to be migrated -->>
35
+ // Lines between class member methods
36
+ 'lines-between-class-members': [
37
+ 'error',
38
+ 'always',
39
+ {
40
+ exceptAfterSingleLine: true,
41
+ },
42
+ ],
43
+
44
+ // Line spacing
45
+ 'padding-line-between-statements': [
46
+ 'error',
47
+ {
48
+ blankLine: 'always',
49
+ next: 'class',
50
+ prev: '*',
51
+ },
52
+ {
53
+ blankLine: 'always',
54
+ next: '*',
55
+ prev: 'class',
56
+ },
57
+ {
58
+ blankLine: 'always',
59
+ next: 'return',
60
+ prev: '*',
61
+ },
62
+ {
63
+ blankLine: 'always',
64
+ next: 'case',
65
+ prev: '*',
66
+ },
67
+ {
68
+ blankLine: 'always',
69
+ next: 'default',
70
+ prev: '*',
71
+ },
72
+ {
73
+ blankLine: 'always',
74
+ next: 'export',
75
+ prev: '*',
76
+ },
77
+ {
78
+ blankLine: 'any',
79
+ next: 'case',
80
+ prev: 'case',
81
+ },
82
+ {
83
+ blankLine: 'any',
84
+ next: 'export',
85
+ prev: 'export',
86
+ },
87
+ {
88
+ blankLine: 'always',
89
+ next: '*',
90
+ prev: 'import',
91
+ },
92
+ {
93
+ blankLine: 'any',
94
+ next: 'import',
95
+ prev: 'import',
96
+ },
97
+ ],
98
+ },
99
+ },
100
+ ];
@@ -0,0 +1,62 @@
1
+ import importPlugin from 'eslint-plugin-import-x';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.js, ...files.ts],
8
+ plugins: { 'import-x': importPlugin },
9
+ settings: {
10
+ 'import-x/parsers': {
11
+ espree: ['.js', '.cjs', '.mjs', '.jsx'],
12
+ },
13
+ 'import-x/resolver': {
14
+ typescript: true,
15
+ node: true,
16
+ },
17
+ },
18
+ rules: {
19
+ ...importPlugin.configs.recommended.rules,
20
+ 'import-x/no-duplicates': ['error', { 'prefer-inline': true }],
21
+ 'import-x/newline-after-import': ['error', { considerComments: false }],
22
+ 'import-x/no-unresolved': [
23
+ 'warn',
24
+ {
25
+ ignore: [
26
+ String.raw`^@/`, // ignore @/* aliases
27
+ '@(docusaurus|theme)',
28
+ ],
29
+ },
30
+ ],
31
+ 'import-x/order': [
32
+ 'error',
33
+ {
34
+ groups: ['builtin', 'external', 'internal'],
35
+ pathGroups: [
36
+ {
37
+ pattern: '{preact|react|svelte|docusaurus|theme}{/**,**}',
38
+ group: 'external',
39
+ position: 'before',
40
+ },
41
+ {
42
+ pattern: '@/**',
43
+ group: 'internal',
44
+ position: 'after',
45
+ },
46
+ {
47
+ pattern: '*.{css,less,json,html,txt,csv,png,jpg,svg}',
48
+ group: 'object',
49
+ patternOptions: { matchBase: true },
50
+ position: 'after',
51
+ },
52
+ ],
53
+ 'newlines-between': 'always',
54
+ alphabetize: {
55
+ order: 'asc',
56
+ caseInsensitive: true,
57
+ },
58
+ },
59
+ ],
60
+ },
61
+ },
62
+ ];
@@ -0,0 +1,9 @@
1
+ export const base: [];
2
+ export const imprt: [];
3
+ export const jest: [];
4
+ export const next: [];
5
+ export const prettier: [];
6
+ export const react: [];
7
+ export const typescript: [];
8
+ export const unusedImports: [];
9
+ export const typescriptTypeChecked: [];
@@ -0,0 +1,13 @@
1
+ export { default as base } from './base.js';
2
+ export { default as javascript } from './javascript.js';
3
+ export { default as imprt } from './import.js';
4
+ export { default as jest } from './jest.js';
5
+ export { default as next } from './next.js';
6
+ export { default as prettier } from './prettier.js';
7
+ export { default as react } from './react.js';
8
+ export { default as typescript } from './typescript.js';
9
+ export { default as unusedImports } from './unusedImports.js';
10
+ export { default as typescriptTypeChecked } from './typescriptTypeChecked.js';
11
+ export { default as sonarjs } from './sonarjs.js';
12
+ export { default as unicorn } from './unicorn.js';
13
+ export { default as sortClassMembers } from './sortClassMembers.js';
@@ -0,0 +1,32 @@
1
+ import js from '@eslint/js';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.js],
8
+ ...js.configs.recommended,
9
+ rules: {
10
+ ...js.configs.recommended.rules,
11
+ 'no-return-await': 'error',
12
+ 'no-console': [
13
+ 'warn',
14
+ {
15
+ allow: ['warn', 'error'],
16
+ },
17
+ ],
18
+ curly: ['error', 'all'],
19
+ 'dot-notation': ['error'],
20
+ 'no-unused-vars': [
21
+ 'error',
22
+ {
23
+ argsIgnorePattern: '^_',
24
+ varsIgnorePattern: '^_',
25
+ destructuredArrayIgnorePattern: '^_',
26
+ ignoreRestSiblings: true,
27
+ args: 'none',
28
+ },
29
+ ],
30
+ },
31
+ },
32
+ ];
@@ -0,0 +1,66 @@
1
+ import jest from 'eslint-plugin-jest';
2
+ import jestFormatting from 'eslint-plugin-jest-formatting';
3
+ import globals from 'globals';
4
+
5
+ import { files } from '../utils/helpers.js';
6
+
7
+ export default [
8
+ {
9
+ files: files.test,
10
+ plugins: {
11
+ jest,
12
+ 'jest-formatting': jestFormatting,
13
+ },
14
+ languageOptions: {
15
+ globals: {
16
+ ...globals.jest,
17
+ },
18
+ },
19
+ rules: {
20
+ // Jest plugin customization
21
+ ...jest.configs.recommended.rules,
22
+ ...jest.configs.style.rules,
23
+ 'jest/consistent-test-it': ['error', { fn: 'it' }],
24
+ 'jest/max-nested-describe': [
25
+ 'error',
26
+ {
27
+ max: 3,
28
+ },
29
+ ],
30
+ 'jest/no-duplicate-hooks': 'error',
31
+ 'jest/no-conditional-in-test': 'warn',
32
+ 'jest/no-done-callback': 'warn',
33
+ 'jest/no-large-snapshots': ['warn', { maxSize: 100, inlineMaxSize: 20 }],
34
+ 'jest/no-mocks-import': 'off',
35
+ 'jest/no-test-return-statement': 'warn',
36
+ 'jest/prefer-expect-resolves': 'error',
37
+ 'jest/prefer-strict-equal': 'warn',
38
+ 'jest/prefer-spy-on': 'off',
39
+ 'jest/prefer-hooks-on-top': 'error',
40
+ 'jest/prefer-todo': 'error',
41
+ 'jest/require-hook': 'warn',
42
+ 'jest/prefer-called-with': 'warn',
43
+ 'jest/no-conditional-expect': 'warn',
44
+ 'jest/no-identical-title': 'warn',
45
+ 'jest/prefer-each': 'error',
46
+ 'jest/prefer-equality-matcher': 'error',
47
+ 'jest/prefer-comparison-matcher': 'error',
48
+ 'jest/prefer-mock-promise-shorthand': 'error',
49
+ 'jest/prefer-lowercase-title': [
50
+ 'error',
51
+ {
52
+ ignore: ['describe'],
53
+ },
54
+ ],
55
+
56
+ // Jest-formatting plugin customization
57
+ 'jest-formatting/padding-around-after-all-blocks': 'error',
58
+ 'jest-formatting/padding-around-after-each-blocks': 'error',
59
+ 'jest-formatting/padding-around-before-all-blocks': 'error',
60
+ 'jest-formatting/padding-around-before-each-blocks': 'error',
61
+ 'jest-formatting/padding-around-expect-groups': 'error',
62
+ 'jest-formatting/padding-around-describe-blocks': 'error',
63
+ 'jest-formatting/padding-around-test-blocks': 'error',
64
+ },
65
+ },
66
+ ];
@@ -0,0 +1,13 @@
1
+ import next from '@next/eslint-plugin-next';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.js, ...files.ts],
8
+ plugins: { '@next/next': next },
9
+ rules: {
10
+ ...next.configs.recommended.rules,
11
+ },
12
+ },
13
+ ];
@@ -0,0 +1,30 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+
4
+ import { FlatCompat } from '@eslint/eslintrc';
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ const compat = new FlatCompat({
10
+ baseDirectory: __dirname,
11
+ });
12
+
13
+ export default [
14
+ ...compat.extends('plugin:prettier/recommended'),
15
+ {
16
+ rules: {
17
+ 'prettier/prettier': [
18
+ 'error',
19
+ {
20
+ singleQuote: true,
21
+ semi: true,
22
+ trailingComma: 'all',
23
+ jsxSingleQuote: true,
24
+ bracketSameLine: false,
25
+ arrowParens: 'avoid',
26
+ },
27
+ ],
28
+ },
29
+ },
30
+ ];
@@ -0,0 +1,176 @@
1
+ import jsxAlly from 'eslint-plugin-jsx-a11y';
2
+ import reactPlugin from 'eslint-plugin-react';
3
+ import hooksPlugin from 'eslint-plugin-react-hooks';
4
+ import reactRefresh from 'eslint-plugin-react-refresh';
5
+
6
+ import { files } from '../utils/helpers.js';
7
+
8
+ export default [
9
+ {
10
+ files: files.jsx,
11
+ plugins: {
12
+ react: reactPlugin,
13
+ 'jsx-a11y': jsxAlly,
14
+ 'react-refresh': reactRefresh,
15
+ },
16
+ settings: {
17
+ react: {
18
+ version: '18',
19
+ },
20
+ },
21
+ rules: {
22
+ ...reactPlugin.configs.recommended.rules,
23
+ ...reactPlugin.configs['jsx-runtime'].rules,
24
+ 'react-refresh/only-export-components': 'warn',
25
+ 'react/boolean-prop-naming': 'off',
26
+ // 'react/boolean-prop-naming': [
27
+ // 'error',
28
+ // {
29
+ // message:
30
+ // 'Invalid boolean prop name, use one of (is|has|show|hide) prefixes.',
31
+ // propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
32
+ // rule: '^(is|has|show|hide)[A-Z]([A-Za-z0-9]?)+',
33
+ // },
34
+ // ],
35
+ 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
36
+ 'react/default-props-match-prop-types': 'off',
37
+ 'react/display-name': ['off'],
38
+ 'react/function-component-definition': [
39
+ 'error',
40
+ {
41
+ namedComponents: 'function-declaration',
42
+ unnamedComponents: 'arrow-function',
43
+ },
44
+ ],
45
+ 'react/hook-use-state': ['warn', { allowDestructuredState: true }],
46
+ 'react/no-access-state-in-setstate': 'error',
47
+ 'react/no-adjacent-inline-elements': 'error',
48
+ 'react/no-array-index-key': 'warn',
49
+ 'react/no-arrow-function-lifecycle': 'error',
50
+ 'react/no-did-update-set-state': 'error',
51
+ 'react/no-find-dom-node': 'error',
52
+ 'react/no-multi-comp': 'error',
53
+ 'react/no-namespace': 'error',
54
+ 'react/no-redundant-should-component-update': 'error',
55
+ 'react/no-invalid-html-attribute': 'error',
56
+ 'react/no-this-in-sfc': 'error',
57
+ 'react/no-typos': 'error',
58
+ 'react/no-unsafe': 'error',
59
+ 'react/no-unstable-nested-components': ['warn', { allowAsProps: true }],
60
+ 'react/no-unused-class-component-methods': 'warn',
61
+ 'react/no-unused-prop-types': 'off',
62
+ 'react/no-unused-state': 'error',
63
+ 'react/no-will-update-set-state': 'error',
64
+ 'react/prefer-es6-class': ['error', 'always'],
65
+ 'react/prefer-stateless-function': 'error',
66
+ 'react/prop-types': 'off',
67
+ 'react/require-render-return': 'error',
68
+ 'react/no-unknown-property': 'warn',
69
+ 'react/self-closing-comp': 'error',
70
+ 'react/state-in-constructor': ['error', 'always'],
71
+ 'react/static-property-placement': [
72
+ 'error',
73
+ 'property assignment',
74
+ {
75
+ childContextTypes: 'static getter',
76
+ contextType: 'static getter',
77
+ contextTypes: 'static getter',
78
+ defaultProps: 'static getter',
79
+ displayName: 'static getter',
80
+ propTypes: 'static getter',
81
+ },
82
+ ],
83
+ 'react/style-prop-object': 'error',
84
+ 'react/void-dom-elements-no-children': 'error',
85
+
86
+ // jsx specifics
87
+ 'react/jsx-boolean-value': [
88
+ 'error',
89
+ 'never',
90
+ {
91
+ always: [],
92
+ },
93
+ ],
94
+ 'react/jsx-child-element-spacing': 'error',
95
+ 'react/jsx-closing-bracket-location': ['error', 'tag-aligned'],
96
+ 'react/jsx-closing-tag-location': 'error',
97
+ 'react/jsx-curly-brace-presence': [
98
+ 'error',
99
+ {
100
+ children: 'never',
101
+ props: 'never',
102
+ },
103
+ ],
104
+ 'react/jsx-curly-newline': [
105
+ 'error',
106
+ {
107
+ multiline: 'consistent',
108
+ singleline: 'consistent',
109
+ },
110
+ ],
111
+ 'react/jsx-filename-extension': [
112
+ 'error',
113
+ {
114
+ extensions: ['.jsx', '.tsx'],
115
+ },
116
+ ],
117
+ 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
118
+ 'react/jsx-fragments': ['error', 'syntax'],
119
+ 'react/jsx-handler-names': [
120
+ 'warn',
121
+ {
122
+ eventHandlerPrefix: 'handle',
123
+ eventHandlerPropPrefix: 'on',
124
+ checkLocalVariables: false,
125
+ checkInlineFunction: false,
126
+ },
127
+ ],
128
+ 'react/jsx-max-props-per-line': [
129
+ 'error',
130
+ {
131
+ maximum: 1,
132
+ when: 'multiline',
133
+ },
134
+ ],
135
+ 'react/jsx-newline': ['error', { prevent: true }],
136
+ 'react/jsx-no-constructed-context-values': 'error',
137
+ 'react/jsx-no-script-url': 'error',
138
+ 'react/jsx-one-expression-per-line': [
139
+ 'error',
140
+ {
141
+ allow: 'single-child',
142
+ },
143
+ ],
144
+ 'react/jsx-pascal-case': [
145
+ 'error',
146
+ {
147
+ allowAllCaps: true,
148
+ ignore: [],
149
+ },
150
+ ],
151
+ 'react/jsx-props-no-multi-spaces': 'error',
152
+ 'react/jsx-wrap-multilines': [
153
+ 'error',
154
+ {
155
+ arrow: 'parens-new-line',
156
+ assignment: 'parens-new-line',
157
+ condition: 'parens-new-line',
158
+ declaration: 'parens-new-line',
159
+ logical: 'parens-new-line',
160
+ prop: 'parens-new-line',
161
+ return: 'parens-new-line',
162
+ },
163
+ ],
164
+ },
165
+ },
166
+ {
167
+ // Hooks are usually defined in non-jsx extension files
168
+ files: [...files.ts, ...files.js],
169
+ plugins: {
170
+ 'react-hooks': hooksPlugin,
171
+ },
172
+ rules: {
173
+ ...hooksPlugin.configs.recommended.rules,
174
+ },
175
+ },
176
+ ];
@@ -0,0 +1,25 @@
1
+ import sonarjs from 'eslint-plugin-sonarjs';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.ts, ...files.js],
8
+ plugins: { sonarjs },
9
+ rules: {
10
+ ...sonarjs.configs.recommended.rules,
11
+ 'sonarjs/cognitive-complexity': 'warn',
12
+ 'sonarjs/no-identical-functions': ['warn', 3],
13
+ 'sonarjs/no-duplicate-string': ['warn', { threshold: 10 }],
14
+ 'sonarjs/no-nested-template-literals': 'off',
15
+ 'sonarjs/no-useless-catch': 'warn',
16
+ 'sonarjs/no-inverted-boolean-check': 'warn',
17
+ },
18
+ },
19
+ {
20
+ files: files.test,
21
+ rules: {
22
+ 'sonarjs/no-duplicate-string': 'off',
23
+ },
24
+ },
25
+ ];
@@ -0,0 +1,28 @@
1
+ import sortClassMembers from 'eslint-plugin-sort-class-members';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.js, ...files.ts],
8
+ ...sortClassMembers.configs['flat/recommended'],
9
+ rules: {
10
+ ...sortClassMembers.configs['flat/recommended'].rules,
11
+ 'sort-class-members/sort-class-members': [
12
+ 'error',
13
+ {
14
+ order: [
15
+ '[static-properties]',
16
+ '[static-methods]',
17
+ '[properties]',
18
+ '[conventional-private-properties]',
19
+ 'constructor',
20
+ '[methods]',
21
+ '[conventional-private-methods]',
22
+ ],
23
+ accessorPairPositioning: 'together',
24
+ },
25
+ ],
26
+ },
27
+ },
28
+ ];
@@ -0,0 +1,58 @@
1
+ import tsEslint from 'typescript-eslint';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: files.ts,
8
+ languageOptions: {
9
+ parser: tsEslint.parser,
10
+ parserOptions: {
11
+ ecmaVersion: 'latest',
12
+ sourceType: 'module',
13
+ jsDocParsingMode: 'none',
14
+ jsxPragma: null,
15
+ },
16
+ },
17
+ plugins: {
18
+ '@typescript-eslint': tsEslint.plugin,
19
+ },
20
+ rules: {
21
+ ...tsEslint.configs.eslintRecommended.rules,
22
+ ...tsEslint.configs.recommended.rules,
23
+ ...tsEslint.configs.stylistic.rules,
24
+ '@typescript-eslint/prefer-nullish-coalescing': 'off',
25
+ 'default-param-last': 'off',
26
+ '@typescript-eslint/default-param-last': 'error',
27
+ '@typescript-eslint/method-signature-style': ['error', 'property'],
28
+ 'dot-notation': 'off',
29
+ '@typescript-eslint/no-require-imports': 'error',
30
+ '@typescript-eslint/no-useless-empty-export': 'error',
31
+ '@typescript-eslint/consistent-type-definitions': 'off',
32
+ '@typescript-eslint/no-import-type-side-effects': 'error',
33
+ '@typescript-eslint/consistent-type-imports': [
34
+ 'error',
35
+ { prefer: 'type-imports' },
36
+ ],
37
+ '@typescript-eslint/no-non-null-assertion': 'off',
38
+ '@typescript-eslint/no-explicit-any': 'warn',
39
+ '@typescript-eslint/ban-ts-comment': [
40
+ 'error',
41
+ { 'ts-expect-error': 'allow-with-description' },
42
+ ],
43
+ '@typescript-eslint/no-unused-vars': [
44
+ 'error',
45
+ {
46
+ argsIgnorePattern: '^_',
47
+ varsIgnorePattern: '^_',
48
+ destructuredArrayIgnorePattern: '^_',
49
+ ignoreRestSiblings: true,
50
+ args: 'none',
51
+ },
52
+ ],
53
+ '@typescript-eslint/no-namespace': ['error', { allowDeclarations: true }],
54
+ // turn off eslint undef
55
+ 'no-undef': 'off',
56
+ },
57
+ },
58
+ ];
@@ -0,0 +1,18 @@
1
+ import tsEslint from 'typescript-eslint';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: files.ts,
8
+ languageOptions: {
9
+ parserOptions: { projectService: true },
10
+ },
11
+ rules: {
12
+ ...tsEslint.configs.recommendedTypeChecked.rules,
13
+ ...tsEslint.configs.stylisticTypeChecked.rules,
14
+ '@typescript-eslint/consistent-type-exports': 'error',
15
+ 'no-undef': 'off',
16
+ },
17
+ },
18
+ ];
@@ -0,0 +1,57 @@
1
+ import unicorn from 'eslint-plugin-unicorn';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.ts, ...files.js],
8
+ ...unicorn.configs['flat/recommended'],
9
+ rules: {
10
+ ...unicorn.configs['flat/recommended'].rules,
11
+ 'unicorn/filename-case': 'off',
12
+ 'unicorn/no-array-callback-reference': 'off',
13
+ 'unicorn/no-array-for-each': 'off',
14
+ 'unicorn/no-array-reduce': 'off',
15
+ 'unicorn/no-document-cookie': 'warn',
16
+ 'unicorn/no-null': 'off',
17
+ 'unicorn/no-static-only-class': 'off',
18
+ 'unicorn/no-unused-properties': 'warn',
19
+ 'unicorn/numeric-separators-style': [
20
+ 'error',
21
+ { onlyIfContainsSeparator: true },
22
+ ],
23
+ 'unicorn/prefer-export-from': ['error', { ignoreUsedVariables: true }],
24
+ 'unicorn/prefer-module': 'warn',
25
+ 'unicorn/switch-case-braces': ['error', 'avoid'],
26
+ 'unicorn/prefer-object-from-entries': 'warn',
27
+ 'unicorn/catch-error-name': 'off',
28
+ 'unicorn/prevent-abbreviations': 'off',
29
+ 'unicorn/relative-url-style': ['error', 'always'],
30
+ 'unicorn/consistent-function-scoping': 'warn',
31
+ 'unicorn/prefer-spread': 'off',
32
+ 'unicorn/no-negated-condition': 'warn',
33
+ 'unicorn/no-typeof-undefined': ['error', { checkGlobalVariables: false }],
34
+ 'unicorn/no-await-expression-member': 'off',
35
+ 'unicorn/explicit-length-check': 'off',
36
+ 'unicorn/prefer-logical-operator-over-ternary': 'warn',
37
+ 'unicorn/consistent-destructuring': 'warn',
38
+ 'unicorn/no-unreadable-iife': 'warn',
39
+ 'unicorn/prefer-event-target': 'warn',
40
+ 'unicorn/prefer-query-selector': 'off',
41
+ 'unicorn/prefer-string-slice': 'off',
42
+ 'unicorn/no-useless-undefined': ['error', { checkArguments: false }],
43
+
44
+ // Style rules turned off due to prettier
45
+ 'unicorn/empty-brace-spaces': 'off',
46
+
47
+ // This causes issues with some frameworks but is really rare to use
48
+ 'unicorn/no-array-method-this-argument': 'off',
49
+ },
50
+ },
51
+ {
52
+ files: files.test,
53
+ rules: {
54
+ 'unicorn/no-duplicate-string': 'off',
55
+ },
56
+ },
57
+ ];
@@ -0,0 +1,24 @@
1
+ import unusedImportsPlugin from 'eslint-plugin-unused-imports';
2
+
3
+ import { files } from '../utils/helpers.js';
4
+
5
+ export default [
6
+ {
7
+ files: [...files.js, ...files.ts],
8
+ plugins: { 'unused-imports': unusedImportsPlugin },
9
+ rules: {
10
+ 'no-unused-vars': 'off',
11
+ 'unused-imports/no-unused-imports': 'error',
12
+ 'unused-imports/no-unused-vars': [
13
+ 'error',
14
+ {
15
+ argsIgnorePattern: '^_',
16
+ varsIgnorePattern: '^_',
17
+ destructuredArrayIgnorePattern: '^_',
18
+ ignoreRestSiblings: true,
19
+ args: 'none',
20
+ },
21
+ ],
22
+ },
23
+ },
24
+ ];
@@ -0,0 +1,20 @@
1
+ /**
2
+ * File extensions for specific file types.
3
+ */
4
+ export const files = {
5
+ ts: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],
6
+ js: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
7
+ jsx: ['**/*.tsx', '**/*.jsx'],
8
+ test: [
9
+ '**/*.test.*',
10
+ '**/*_test.*',
11
+ '**/*Test.*',
12
+ '**/*.spec.*',
13
+ '**/*_spec.*',
14
+ '**/*Spec.*',
15
+ '**/__tests__/**/*',
16
+ '**/__integration__/**/*',
17
+ '**/__regression__/**/*',
18
+ '**/__mocks__/**/*',
19
+ ],
20
+ };