@fullstacksjs/eslint-config 13.9.0 → 13.11.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
@@ -51,7 +51,7 @@ You can fine-tune module detection by overriding it, the `defineConfig` function
51
51
  ```typescript
52
52
  interface Options {
53
53
  react?: boolean | { additionalEffectHooks?: string }; // controls react, react-hooks, jsx/a11y plugins
54
- typescript?: ParserOptions // https://typescript-eslint.io/packages/parser#configuration
54
+ typescript?: boolean | ParserOptions // https://typescript-eslint.io/packages/parser#configuration
55
55
  node?: boolean; // controls node plugin
56
56
  sort?: boolean; // controls perfectionist plugin
57
57
  strict?: boolean; // controls strict rules
package/cjs/index.d.ts CHANGED
@@ -93,7 +93,7 @@ export interface Options extends Linter.Config {
93
93
  * Controls [TypeScript plugin](https://www.npmjs.com/package/typescript-eslint).
94
94
  * @default true - If you have `typescript` in your dependencies.
95
95
  */
96
- typescript?: { projectService?: boolean | ProjectService; tsconfigRootDir?: string; cacheLifetime?: number };
96
+ typescript?: boolean | { projectService?: boolean | ProjectService; tsconfigRootDir?: string; cacheLifetime?: number };
97
97
  /**
98
98
  * Disables expensive rules.
99
99
  * @default false
@@ -111,7 +111,7 @@ export interface Options extends Linter.Config {
111
111
  gitignore?: string | false;
112
112
  /**
113
113
  * Controls regex plugin.
114
- * @default true
114
+ * @default { allowedCharacterRanges: ['all'] }
115
115
  */
116
116
  regex?: boolean | { allowedCharacterRanges: string[] };
117
117
  }
@@ -81,6 +81,7 @@ function base(options = {}) {
81
81
  'no-dupe-else-if': 'error',
82
82
  'no-dupe-keys': 'error',
83
83
  'no-duplicate-case': 'error',
84
+ 'no-duplicate-imports': 'error',
84
85
  'no-empty-character-class': 'error',
85
86
  'no-empty-function': 'warn',
86
87
  'no-empty-pattern': 'error',
@@ -161,6 +162,7 @@ function base(options = {}) {
161
162
  ignoreRestSiblings: true
162
163
  }],
163
164
  'no-use-before-define': ['error', 'nofunc'],
165
+ 'no-useless-assignment': 'warn',
164
166
  'no-useless-backreference': 'error',
165
167
  'no-useless-call': 'error',
166
168
  'no-useless-catch': 'error',
@@ -188,12 +190,17 @@ function base(options = {}) {
188
190
  'preserve-caught-error': (0, _conditions.strict)(options, ['warn', {
189
191
  requireCatchParameter: true
190
192
  }]),
193
+ 'prefer-destructuring': ['warn', {
194
+ object: true,
195
+ array: true
196
+ }],
191
197
  'prefer-exponentiation-operator': 'warn',
192
198
  'prefer-numeric-literals': 'error',
193
199
  'prefer-object-has-own': 'warn',
194
200
  'prefer-rest-params': 'error',
195
201
  'prefer-spread': 'error',
196
202
  'prefer-template': 'error',
203
+ 'prefer-promise-reject-errors': 'warn',
197
204
  'radix': 'error',
198
205
  'require-await': 'error',
199
206
  'require-yield': 'error',
@@ -208,6 +215,9 @@ function base(options = {}) {
208
215
  'grouped-accessor-pairs': 'warn',
209
216
  'no-extra-boolean-cast': 'warn',
210
217
  'no-param-reassign': 'warn',
218
+ 'no-plusplus': ['warn', {
219
+ allowForLoopAfterthoughts: true
220
+ }],
211
221
  'prefer-regex-literals': ['warn', {
212
222
  disallowRedundantWrapping: true
213
223
  }],
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
 
7
7
  var _eslintPluginJest = _interopRequireDefault(require("eslint-plugin-jest"));
8
+ var _globals = _interopRequireDefault(require("globals"));
8
9
  var _globs = require("../utils/globs.js");
9
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
11
  /**
@@ -16,6 +17,11 @@ function jest() {
16
17
  plugins: {
17
18
  jest: _eslintPluginJest.default
18
19
  },
20
+ languageOptions: {
21
+ globals: {
22
+ ..._globals.default.jest
23
+ }
24
+ },
19
25
  rules: {
20
26
  'jest/consistent-test-it': 'off',
21
27
  'jest/expect-expect': 'off',
@@ -69,7 +75,8 @@ function jest() {
69
75
  'jest/valid-expect-in-promise': 'error',
70
76
  'jest/valid-expect': 'error',
71
77
  'jest/valid-title': 'warn',
72
- 'jest/no-deprecated-functions': 'error'
78
+ 'jest/no-deprecated-functions': 'error',
79
+ 'jest/valid-mock-module-path': 'warn'
73
80
 
74
81
  // ...predicate(options.typescript, {
75
82
  // '@typescript-eslint/unbound-method': 'off',
@@ -16,7 +16,7 @@ function perfectionist() {
16
16
  },
17
17
  rules: {
18
18
  'perfectionist/sort-array-includes': 'warn',
19
- 'perfectionist/sort-classes': 'warn',
19
+ 'perfectionist/sort-classes': 'off',
20
20
  'perfectionist/sort-enums': 'off',
21
21
  'perfectionist/sort-exports': 'warn',
22
22
  'perfectionist/sort-imports': ['warn', {}],
@@ -15,9 +15,6 @@ function playwright() {
15
15
  },
16
16
  files: _globs.globs.e2e,
17
17
  rules: {
18
- 'jest/no-standalone-expect': ['error', {
19
- additionalTestBlockFunctions: ['test.jestPlaywrightDebug', 'it.jestPlaywrightDebug', 'test.jestPlaywrightSkip', 'it.jestPlaywrightSkip', 'test.jestPlaywrightConfig', 'it.jestPlaywrightConfig']
20
- }],
21
18
  'playwright/expect-expect': 'error',
22
19
  'playwright/missing-playwright-await': 'error',
23
20
  'playwright/max-nested-describe': ['warn', {
@@ -39,6 +36,7 @@ function playwright() {
39
36
  'playwright/no-useless-await': 'error',
40
37
  'playwright/no-unsafe-references': 'warn',
41
38
  'playwright/no-useless-not': 'warn',
39
+ 'playwright/no-unused-locators': 'warn',
42
40
  'playwright/no-wait-for-navigation': 'warn',
43
41
  'playwright/no-wait-for-selector': 'warn',
44
42
  'playwright/no-wait-for-timeout': 'warn',
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
 
7
7
  var _eslintPluginPromise = _interopRequireDefault(require("eslint-plugin-promise"));
8
+ var _conditions = require("../utils/conditions.js");
8
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
10
  /** @return { import('eslint').Linter.Config } */
10
- function promise() {
11
+ function promise(options = {}) {
11
12
  return {
12
13
  plugins: {
13
14
  promise: _eslintPluginPromise.default
@@ -26,8 +27,10 @@ function promise() {
26
27
  'promise/param-names': 'warn',
27
28
  'promise/prefer-await-to-callbacks': 'off',
28
29
  'promise/prefer-await-to-then': 'off',
30
+ 'promise/prefer-catch': (0, _conditions.strict)(options, 'warn'),
29
31
  'promise/valid-params': 'warn',
30
- 'promise/no-multiple-resolved': 'warn'
32
+ 'promise/no-multiple-resolved': 'warn',
33
+ 'promise/spec-only': 'warn'
31
34
  }
32
35
  };
33
36
  }
@@ -54,6 +54,7 @@ function react(options = {}) {
54
54
  '@eslint-react/dom/no-script-url': 'warn',
55
55
  '@eslint-react/dom/no-unsafe-iframe-sandbox': 'warn',
56
56
  '@eslint-react/dom/no-unsafe-target-blank': 'warn',
57
+ '@eslint-react/jsx-dollar': 'warn',
57
58
  '@eslint-react/jsx-key-before-spread': 'error',
58
59
  '@eslint-react/jsx-no-undef': 'off',
59
60
  '@eslint-react/jsx-no-iife': 'warn',
@@ -13,31 +13,25 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
13
13
  * @param { import('../index.js').Options } options
14
14
  * @return { import('eslint').Linter.Config }
15
15
  */
16
+
16
17
  function tests(options = {}) {
17
18
  return {
19
+ files: [..._globs.globs.test, ..._globs.globs.e2e],
18
20
  plugins: {
19
21
  vitest: _eslintPlugin.default
20
22
  },
21
- files: [..._globs.globs.test, ..._globs.globs.e2e],
22
23
  languageOptions: {
23
24
  globals: {
24
- ..._globals.default['shared-node-browser'],
25
- ..._globals.default.jest
25
+ ..._globals.default['shared-node-browser']
26
26
  }
27
27
  },
28
28
  rules: {
29
- 'vitest/padding-around-after-all-blocks': 'warn',
30
- 'vitest/padding-around-after-each-blocks': 'warn',
31
- 'vitest/padding-around-before-all-blocks': 'warn',
32
- 'vitest/padding-around-before-each-blocks': 'warn',
33
- 'vitest/padding-around-describe-blocks': 'warn',
34
- 'vitest/padding-around-expect-groups': 'warn',
35
- 'vitest/padding-around-test-blocks': 'warn',
36
29
  'max-lines-per-function': 'off',
37
30
  'no-sparse-arrays': 'off',
38
31
  'no-empty-function': 'off',
32
+ 'vitest/padding-around-all': 'warn',
39
33
  ...(0, _conditions.predicate)(options.react, {
40
- 'react/jsx-no-constructed-context-values': 'off'
34
+ '@eslint-react/no-unstable-context-value': 'off'
41
35
  }),
42
36
  ...(0, _conditions.predicate)(options.typescript, {
43
37
  '@typescript-eslint/method-signature-style': 'off',
@@ -103,7 +103,6 @@ function typescript(options = {}) {
103
103
  '@typescript-eslint/no-restricted-imports': 'off',
104
104
  '@typescript-eslint/no-shadow': 'error',
105
105
  '@typescript-eslint/no-this-alias': 'error',
106
- '@typescript-eslint/no-type-alias': 'off',
107
106
  '@typescript-eslint/no-unnecessary-type-constraint': 'warn',
108
107
  '@typescript-eslint/no-unsafe-argument': (0, _conditions.strict)(options, 'warn'),
109
108
  '@typescript-eslint/no-unsafe-assignment': (0, _conditions.strict)(options, 'warn'),
@@ -148,9 +147,8 @@ function typescript(options = {}) {
148
147
  '@typescript-eslint/prefer-readonly': 'off',
149
148
  '@typescript-eslint/prefer-readonlysemi': 'off',
150
149
  // Annoying with auto-fix on save.
151
- '@typescript-eslint/prefer-ts-expect-error': 'off',
152
- '@typescript-eslint/promise-function-async': 'off',
153
- '@typescript-eslint/restrict-plus-operands': 'off',
150
+ '@typescript-eslint/promise-function-async': 'error',
151
+ '@typescript-eslint/restrict-plus-operands': 'warn',
154
152
  '@typescript-eslint/strict-boolean-expressions': 'off',
155
153
  // Annoying
156
154
  '@typescript-eslint/space-before-blocks': 'off',
@@ -178,6 +176,7 @@ function typescript(options = {}) {
178
176
  }],
179
177
  // Annoying and conflict with @typescript-eslint/no-meaningless-void-operator
180
178
  '@typescript-eslint/no-duplicate-type-constituents': 'warn',
179
+ '@typescript-eslint/no-deprecated': 'error',
181
180
  '@typescript-eslint/no-for-in-array': 'error',
182
181
  '@typescript-eslint/no-implied-eval': 'error',
183
182
  '@typescript-eslint/no-meaningless-void-operator': ['warn', {
@@ -208,6 +207,7 @@ function typescript(options = {}) {
208
207
  '@typescript-eslint/no-unnecessary-type-arguments': 'error',
209
208
  '@typescript-eslint/no-unnecessary-type-assertion': 'error',
210
209
  '@typescript-eslint/no-unsafe-unary-minus': 'error',
210
+ '@typescript-eslint/no-unused-private-class-members': 'warn',
211
211
  '@typescript-eslint/non-nullable-type-assertion-style': 'warn',
212
212
  '@typescript-eslint/only-throw-error': ['warn', {
213
213
  allowRethrowing: true
@@ -247,6 +247,7 @@ function typescript(options = {}) {
247
247
  'consistent-return': 'off'
248
248
  }),
249
249
  // Conflicts with @typescript-eslint
250
+ 'no-unused-private-class-members': 'off',
250
251
  'no-empty-function': 'off',
251
252
  'default-case': 'off',
252
253
  'import/named': 'off',
@@ -95,11 +95,13 @@ function vitest() {
95
95
  'vitest/require-local-test-context-for-concurrent-snapshots': 'warn',
96
96
  'vitest/require-mock-type-parameters': 'off',
97
97
  'vitest/require-to-throw-message': 'warn',
98
- 'vitest/require-top-level-describe': 'warn',
98
+ 'vitest/require-top-level-describe': 'off',
99
99
  'vitest/valid-describe-callback': 'warn',
100
100
  'vitest/valid-expect': 'warn',
101
101
  'vitest/valid-expect-in-promise': 'warn',
102
- 'vitest/valid-title': 'warn',
102
+ 'vitest/valid-title': ['warn', {
103
+ allowArguments: true
104
+ }],
103
105
  'vitest/warn-todo': 'warn'
104
106
  }
105
107
  };
@@ -29,7 +29,7 @@ const globs = exports.globs = {
29
29
  html: '**/*.html',
30
30
  astro: '**/*.astro',
31
31
  graphql: '**/*.{gql,graphql}',
32
- storybook: ['**/*.stories.{js,jsx,ts,tsx}'],
32
+ storybook: ['**/*.stories.{js,mjs,cjs,jsx,ts,tsx}'],
33
33
  test: [`**/__tests__/*.${srcExt}`, `**/*.spec.${srcExt}`, `**/*.test.${srcExt}`],
34
34
  e2e: [`**/e2e/*.${srcExt}`]
35
35
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstacksjs/eslint-config",
3
- "version": "13.9.0",
3
+ "version": "13.11.0",
4
4
  "license": "MIT",
5
5
  "author": "fullstacks <fullstacksjs@gmail.com>",
6
6
  "description": "fullstacks eslint config",
@@ -35,44 +35,45 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@eslint-react/eslint-plugin": "2.2.3",
39
- "@eslint/compat": "1.4.0",
40
- "@next/eslint-plugin-next": "16.0.0",
41
- "@stylistic/eslint-plugin": "5.5.0",
42
- "@vitest/eslint-plugin": "1.3.24",
38
+ "@eslint-react/eslint-plugin": "2.3.9",
39
+ "@eslint/compat": "2.0.0",
40
+ "@next/eslint-plugin-next": "16.0.6",
41
+ "@stylistic/eslint-plugin": "5.6.1",
42
+ "@vitest/eslint-plugin": "1.5.1",
43
43
  "deepmerge": "4.3.1",
44
- "eslint-plugin-better-tailwindcss": "3.7.10",
44
+ "eslint-plugin-better-tailwindcss": "3.7.11",
45
45
  "eslint-plugin-cypress": "5.2.0",
46
46
  "eslint-plugin-import-x": "4.16.1",
47
- "eslint-plugin-jest": "29.0.1",
47
+ "eslint-plugin-jest": "29.2.1",
48
48
  "eslint-plugin-jsx-a11y": "6.10.2",
49
49
  "eslint-plugin-n": "17.23.1",
50
50
  "eslint-plugin-perfectionist": "4.15.1",
51
- "eslint-plugin-playwright": "2.2.2",
51
+ "eslint-plugin-playwright": "2.3.0",
52
52
  "eslint-plugin-prettier": "5.5.4",
53
53
  "eslint-plugin-promise": "7.2.1",
54
54
  "eslint-plugin-react-hooks": "7.0.1",
55
55
  "eslint-plugin-regexp": "2.10.0",
56
- "eslint-plugin-storybook": "0.12.0",
57
- "globals": "16.4.0",
56
+ "eslint-plugin-storybook": "10.1.2",
57
+ "globals": "16.5.0",
58
58
  "local-pkg": "1.1.2",
59
- "typescript-eslint": "8.46.2"
59
+ "typescript-eslint": "8.48.0"
60
60
  },
61
61
  "devDependencies": {
62
- "@eslint/eslintrc": "3.3.1",
63
- "@eslint/js": "9.38.0",
64
- "@semantic-release/github": "12.0.0",
65
- "@semantic-release/npm": "13.1.1",
62
+ "@eslint/eslintrc": "3.3.3",
63
+ "@eslint/js": "9.39.1",
64
+ "@semantic-release/github": "12.0.2",
65
+ "@semantic-release/npm": "13.1.2",
66
66
  "@semantic-release/release-notes-generator": "14.1.0",
67
67
  "@types/eslint": "9.6.1",
68
- "cspell": "9.2.2",
69
- "eslint": "9.38.0",
68
+ "cspell": "9.4.0",
69
+ "eslint": "9.39.1",
70
70
  "husky": "9.1.7",
71
71
  "jest": "30.2.0",
72
- "lint-staged": "16.2.6",
72
+ "lint-staged": "16.2.7",
73
73
  "pinst": "3.0.0",
74
- "prettier": "3.6.2",
75
- "semantic-release": "25.0.1",
74
+ "prettier": "3.7.3",
75
+ "semantic-release": "25.0.2",
76
+ "storybook": "10.1.2",
76
77
  "typescript": "5.9.3",
77
78
  "unbuild": "3.6.1"
78
79
  },
package/src/index.d.ts CHANGED
@@ -93,7 +93,7 @@ export interface Options extends Linter.Config {
93
93
  * Controls [TypeScript plugin](https://www.npmjs.com/package/typescript-eslint).
94
94
  * @default true - If you have `typescript` in your dependencies.
95
95
  */
96
- typescript?: { projectService?: boolean | ProjectService; tsconfigRootDir?: string; cacheLifetime?: number };
96
+ typescript?: boolean | { projectService?: boolean | ProjectService; tsconfigRootDir?: string; cacheLifetime?: number };
97
97
  /**
98
98
  * Disables expensive rules.
99
99
  * @default false
@@ -111,7 +111,7 @@ export interface Options extends Linter.Config {
111
111
  gitignore?: string | false;
112
112
  /**
113
113
  * Controls regex plugin.
114
- * @default true
114
+ * @default { allowedCharacterRanges: ['all'] }
115
115
  */
116
116
  regex?: boolean | { allowedCharacterRanges: string[] };
117
117
  }
@@ -69,6 +69,7 @@ function base(options = {}) {
69
69
  'no-dupe-else-if': 'error',
70
70
  'no-dupe-keys': 'error',
71
71
  'no-duplicate-case': 'error',
72
+ 'no-duplicate-imports': 'error',
72
73
  'no-empty-character-class': 'error',
73
74
  'no-empty-function': 'warn',
74
75
  'no-empty-pattern': 'error',
@@ -142,6 +143,7 @@ function base(options = {}) {
142
143
  { argsIgnorePattern: '^_', varsIgnorePattern: '^ignore(d)?', args: 'after-used', ignoreRestSiblings: true },
143
144
  ],
144
145
  'no-use-before-define': ['error', 'nofunc'],
146
+ 'no-useless-assignment': 'warn',
145
147
  'no-useless-backreference': 'error',
146
148
  'no-useless-call': 'error',
147
149
  'no-useless-catch': 'error',
@@ -163,12 +165,14 @@ function base(options = {}) {
163
165
  requireCatchParameter: true,
164
166
  },
165
167
  ]),
168
+ 'prefer-destructuring': ['warn', { object: true, array: true }],
166
169
  'prefer-exponentiation-operator': 'warn',
167
170
  'prefer-numeric-literals': 'error',
168
171
  'prefer-object-has-own': 'warn',
169
172
  'prefer-rest-params': 'error',
170
173
  'prefer-spread': 'error',
171
174
  'prefer-template': 'error',
175
+ 'prefer-promise-reject-errors': 'warn',
172
176
  'radix': 'error',
173
177
  'require-await': 'error',
174
178
  'require-yield': 'error',
@@ -184,6 +188,7 @@ function base(options = {}) {
184
188
  'grouped-accessor-pairs': 'warn',
185
189
  'no-extra-boolean-cast': 'warn',
186
190
  'no-param-reassign': 'warn',
191
+ 'no-plusplus': ['warn', { allowForLoopAfterthoughts: true }],
187
192
  'prefer-regex-literals': ['warn', { disallowRedundantWrapping: true }],
188
193
 
189
194
  'no-console': strict(options, 'warn'),
@@ -1,4 +1,5 @@
1
1
  import plugin from 'eslint-plugin-jest';
2
+ import globals from 'globals';
2
3
 
3
4
  import { globs } from '../utils/globs.mjs';
4
5
 
@@ -9,6 +10,11 @@ function jest() {
9
10
  return {
10
11
  files: globs.test,
11
12
  plugins: { jest: plugin },
13
+ languageOptions: {
14
+ globals: {
15
+ ...globals.jest,
16
+ },
17
+ },
12
18
  rules: {
13
19
  'jest/consistent-test-it': 'off',
14
20
  'jest/expect-expect': 'off',
@@ -59,6 +65,7 @@ function jest() {
59
65
  'jest/valid-expect': 'error',
60
66
  'jest/valid-title': 'warn',
61
67
  'jest/no-deprecated-functions': 'error',
68
+ 'jest/valid-mock-module-path': 'warn',
62
69
 
63
70
  // ...predicate(options.typescript, {
64
71
  // '@typescript-eslint/unbound-method': 'off',
@@ -8,7 +8,7 @@ function perfectionist() {
8
8
  plugins: { perfectionist: plugin },
9
9
  rules: {
10
10
  'perfectionist/sort-array-includes': 'warn',
11
- 'perfectionist/sort-classes': 'warn',
11
+ 'perfectionist/sort-classes': 'off',
12
12
  'perfectionist/sort-enums': 'off',
13
13
  'perfectionist/sort-exports': 'warn',
14
14
  'perfectionist/sort-imports': ['warn', {}],
@@ -8,19 +8,6 @@ function playwright() {
8
8
  plugins: { playwright: plugin },
9
9
  files: globs.e2e,
10
10
  rules: {
11
- 'jest/no-standalone-expect': [
12
- 'error',
13
- {
14
- additionalTestBlockFunctions: [
15
- 'test.jestPlaywrightDebug',
16
- 'it.jestPlaywrightDebug',
17
- 'test.jestPlaywrightSkip',
18
- 'it.jestPlaywrightSkip',
19
- 'test.jestPlaywrightConfig',
20
- 'it.jestPlaywrightConfig',
21
- ],
22
- },
23
- ],
24
11
  'playwright/expect-expect': 'error',
25
12
  'playwright/missing-playwright-await': 'error',
26
13
  'playwright/max-nested-describe': ['warn', { max: 5 }],
@@ -40,6 +27,7 @@ function playwright() {
40
27
  'playwright/no-useless-await': 'error',
41
28
  'playwright/no-unsafe-references': 'warn',
42
29
  'playwright/no-useless-not': 'warn',
30
+ 'playwright/no-unused-locators': 'warn',
43
31
  'playwright/no-wait-for-navigation': 'warn',
44
32
  'playwright/no-wait-for-selector': 'warn',
45
33
  'playwright/no-wait-for-timeout': 'warn',
@@ -1,7 +1,9 @@
1
1
  import plugin from 'eslint-plugin-promise';
2
2
 
3
+ import { strict } from '../utils/conditions.mjs';
4
+
3
5
  /** @return { import('eslint').Linter.Config } */
4
- function promise() {
6
+ function promise(options = {}) {
5
7
  return {
6
8
  plugins: { promise: plugin },
7
9
  rules: {
@@ -18,8 +20,10 @@ function promise() {
18
20
  'promise/param-names': 'warn',
19
21
  'promise/prefer-await-to-callbacks': 'off',
20
22
  'promise/prefer-await-to-then': 'off',
23
+ 'promise/prefer-catch': strict(options, 'warn'),
21
24
  'promise/valid-params': 'warn',
22
25
  'promise/no-multiple-resolved': 'warn',
26
+ 'promise/spec-only': 'warn',
23
27
  },
24
28
  };
25
29
  }
@@ -49,6 +49,7 @@ function react(options = {}) {
49
49
  '@eslint-react/dom/no-unsafe-iframe-sandbox': 'warn',
50
50
  '@eslint-react/dom/no-unsafe-target-blank': 'warn',
51
51
 
52
+ '@eslint-react/jsx-dollar': 'warn',
52
53
  '@eslint-react/jsx-key-before-spread': 'error',
53
54
  '@eslint-react/jsx-no-undef': 'off',
54
55
  '@eslint-react/jsx-no-iife': 'warn',
@@ -8,28 +8,23 @@ import { globs } from '../utils/globs.mjs';
8
8
  * @param { import('..').Options } options
9
9
  * @return { import('eslint').Linter.Config }
10
10
  */
11
+
11
12
  function tests(options = {}) {
12
13
  return {
13
- plugins: { vitest: plugin },
14
14
  files: [...globs.test, ...globs.e2e],
15
+ plugins: { vitest: plugin },
15
16
  languageOptions: {
16
- globals: { ...globals['shared-node-browser'], ...globals.jest },
17
+ globals: { ...globals['shared-node-browser'] },
17
18
  },
18
19
  rules: {
19
- 'vitest/padding-around-after-all-blocks': 'warn',
20
- 'vitest/padding-around-after-each-blocks': 'warn',
21
- 'vitest/padding-around-before-all-blocks': 'warn',
22
- 'vitest/padding-around-before-each-blocks': 'warn',
23
- 'vitest/padding-around-describe-blocks': 'warn',
24
- 'vitest/padding-around-expect-groups': 'warn',
25
- 'vitest/padding-around-test-blocks': 'warn',
26
-
27
20
  'max-lines-per-function': 'off',
28
21
  'no-sparse-arrays': 'off',
29
22
  'no-empty-function': 'off',
30
23
 
24
+ 'vitest/padding-around-all': 'warn',
25
+
31
26
  ...predicate(options.react, {
32
- 'react/jsx-no-constructed-context-values': 'off',
27
+ '@eslint-react/no-unstable-context-value': 'off',
33
28
  }),
34
29
 
35
30
  ...predicate(options.typescript, {
@@ -94,7 +94,6 @@ function typescript(options = {}) {
94
94
  '@typescript-eslint/no-restricted-imports': 'off',
95
95
  '@typescript-eslint/no-shadow': 'error',
96
96
  '@typescript-eslint/no-this-alias': 'error',
97
- '@typescript-eslint/no-type-alias': 'off',
98
97
  '@typescript-eslint/no-unnecessary-type-constraint': 'warn',
99
98
  '@typescript-eslint/no-unsafe-argument': strict(options, 'warn'),
100
99
  '@typescript-eslint/no-unsafe-assignment': strict(options, 'warn'),
@@ -132,9 +131,8 @@ function typescript(options = {}) {
132
131
  ], // I'm not sure...
133
132
  '@typescript-eslint/prefer-readonly': 'off',
134
133
  '@typescript-eslint/prefer-readonlysemi': 'off', // Annoying with auto-fix on save.
135
- '@typescript-eslint/prefer-ts-expect-error': 'off',
136
- '@typescript-eslint/promise-function-async': 'off',
137
- '@typescript-eslint/restrict-plus-operands': 'off',
134
+ '@typescript-eslint/promise-function-async': 'error',
135
+ '@typescript-eslint/restrict-plus-operands': 'warn',
138
136
  '@typescript-eslint/strict-boolean-expressions': 'off', // Annoying
139
137
  '@typescript-eslint/space-before-blocks': 'off',
140
138
 
@@ -158,6 +156,7 @@ function typescript(options = {}) {
158
156
  '@typescript-eslint/no-base-to-string': 'error',
159
157
  '@typescript-eslint/no-confusing-void-expression': ['off', { ignoreArrowShorthand: true, ignoreVoidOperator: true }], // Annoying and conflict with @typescript-eslint/no-meaningless-void-operator
160
158
  '@typescript-eslint/no-duplicate-type-constituents': 'warn',
159
+ '@typescript-eslint/no-deprecated': 'error',
161
160
  '@typescript-eslint/no-for-in-array': 'error',
162
161
  '@typescript-eslint/no-implied-eval': 'error',
163
162
  '@typescript-eslint/no-meaningless-void-operator': ['warn', { checkNever: false }],
@@ -183,6 +182,7 @@ function typescript(options = {}) {
183
182
  '@typescript-eslint/no-unnecessary-type-arguments': 'error',
184
183
  '@typescript-eslint/no-unnecessary-type-assertion': 'error',
185
184
  '@typescript-eslint/no-unsafe-unary-minus': 'error',
185
+ '@typescript-eslint/no-unused-private-class-members': 'warn',
186
186
  '@typescript-eslint/non-nullable-type-assertion-style': 'warn',
187
187
  '@typescript-eslint/only-throw-error': ['warn', { allowRethrowing: true }],
188
188
  '@typescript-eslint/prefer-includes': 'warn',
@@ -217,6 +217,7 @@ function typescript(options = {}) {
217
217
  }),
218
218
 
219
219
  // Conflicts with @typescript-eslint
220
+ 'no-unused-private-class-members': 'off',
220
221
  'no-empty-function': 'off',
221
222
  'default-case': 'off',
222
223
  'import/named': 'off',
@@ -58,6 +58,7 @@ function vitest() {
58
58
  'vitest/no-standalone-expect': 'warn',
59
59
  'vitest/no-test-prefixes': 'warn',
60
60
  'vitest/no-test-return-statement': 'warn',
61
+
61
62
  'vitest/prefer-called-once': 'warn',
62
63
  'vitest/prefer-called-times': 'off',
63
64
  'vitest/prefer-called-with': 'warn',
@@ -88,11 +89,11 @@ function vitest() {
88
89
  'vitest/require-local-test-context-for-concurrent-snapshots': 'warn',
89
90
  'vitest/require-mock-type-parameters': 'off',
90
91
  'vitest/require-to-throw-message': 'warn',
91
- 'vitest/require-top-level-describe': 'warn',
92
+ 'vitest/require-top-level-describe': 'off',
92
93
  'vitest/valid-describe-callback': 'warn',
93
94
  'vitest/valid-expect': 'warn',
94
95
  'vitest/valid-expect-in-promise': 'warn',
95
- 'vitest/valid-title': 'warn',
96
+ 'vitest/valid-title': ['warn', { allowArguments: true }],
96
97
  'vitest/warn-todo': 'warn',
97
98
  },
98
99
  };
@@ -28,7 +28,7 @@ export const globs = {
28
28
  astro: '**/*.astro',
29
29
  graphql: '**/*.{gql,graphql}',
30
30
 
31
- storybook: ['**/*.stories.{js,jsx,ts,tsx}'],
31
+ storybook: ['**/*.stories.{js,mjs,cjs,jsx,ts,tsx}'],
32
32
 
33
33
  test: [`**/__tests__/*.${srcExt}`, `**/*.spec.${srcExt}`, `**/*.test.${srcExt}`],
34
34
  e2e: [`**/e2e/*.${srcExt}`],