@fullstacksjs/eslint-config 11.4.0 → 11.6.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
@@ -18,7 +18,7 @@ $ npm install --save-dev @fullstacksjs/eslint-config eslint prettier
18
18
 
19
19
  ## Usage
20
20
 
21
- To use the configuration all you need is exporting generated config by `init` function. The configuration reads the metadata from your root `package.json` file and automatically adds the rules and plugins that are needed.
21
+ To use the configuration, all you need is to export the generated config by the `init` function. The configuration reads the metadata from your root `package.json` file and automatically adds the rules and plugins that are needed.
22
22
 
23
23
  ### ESM
24
24
 
@@ -38,7 +38,7 @@ module.exports = init();
38
38
 
39
39
  ## Modules API
40
40
 
41
- You can fine tune module detection by overriding it, `init` function accepts options as its first argument to control enabled modules.
41
+ You can fine-tune module detection by overriding it, the `init` function accepts options as its first argument to control enabled modules.
42
42
 
43
43
  ```typescript
44
44
  interface Options {
@@ -80,7 +80,7 @@ export default init(
80
80
  {
81
81
  typescript: true,
82
82
  // You can pass extends here
83
- rules {
83
+ rules: {
84
84
  'no-console': 'error'
85
85
  }
86
86
  },
@@ -95,7 +95,7 @@ export default init(
95
95
 
96
96
  ## Speed Optimization!
97
97
 
98
- It's crucial to balance the benefits of linting rules against their performance impact. Below is a table highlighting the most resource-intensive linting rules encountered in a real-world React project:
98
+ Balancing the benefits of linting rules against their performance impact is crucial. Below is a table highlighting the most resource-intensive linting rules encountered in a real-world React project:
99
99
 
100
100
  | Rule | Time (ms) | Relative |
101
101
  | -------------------------------------- | --------- | -------- |
@@ -108,7 +108,7 @@ As illustrated, certain rules significantly increase linting time, potentially h
108
108
 
109
109
  To conditionally disable expensive linting rules, you can modify your configuration as follows:
110
110
 
111
- list of expensiveRules to be effected:
111
+ List of `expensiveRules` to be affected:
112
112
 
113
113
  ```
114
114
  @typescript-eslint/no-floating-promises
@@ -129,19 +129,17 @@ export default init({
129
129
  });
130
130
  ```
131
131
 
132
- This approach ensures a smoother development experience while still enforcing rigorous code quality checks in environments where performance is less of a concern.
132
+ ## Migration Guide
133
133
 
134
- ## Migration Guid
134
+ ### To v11
135
135
 
136
- ### to v10
137
-
138
- v10 drops support for ESLint v8 configuration and only ESLint v9 is supported, which means you should migrate to [ESlint Flat Config](https://eslint.org/docs/latest/extend/plugin-migration-flat-config):
136
+ v11 drops support for ESLint v8 configuration and only ESLint v9 is supported, which means you should migrate to [ESlint Flat Config](https://eslint.org/docs/latest/extend/plugin-migration-flat-config):
139
137
 
140
138
  1. Move your configs to `eslint.config.js` file.
141
139
  2. Use init API.
142
140
  ```diff
143
141
  -const { init } = require('@fullstacksjs/eslint-config/init');
144
- +import { init } from '@fullstacksjs/eslint-config/init'
142
+ +import { init } from '@fullstacksjs/eslint-config';
145
143
 
146
144
  -module.exports = init({
147
145
  - modules: {
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
 
7
+ var _eslintImportResolverTypescript = require("eslint-import-resolver-typescript");
7
8
  var _eslintPluginImportX = _interopRequireDefault(require("eslint-plugin-import-x"));
8
9
  var _conditions = require("../utils/conditions.js");
9
10
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -35,9 +36,10 @@ function imports(options = {}) {
35
36
  'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],
36
37
  'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json)$'],
37
38
  ...(0, _conditions.predicate)(options.typescript, {
38
- 'import-x/resolver': {
39
- typescript: true
40
- },
39
+ 'import-x/resolver-next': [(0, _eslintImportResolverTypescript.createTypeScriptImportResolver)({
40
+ alwaysTryTypes: true,
41
+ project: options.typescript.projects
42
+ })],
41
43
  'import-x/parsers': {
42
44
  '@typescript-eslint/parser': tsExtensions
43
45
  },
@@ -38,13 +38,11 @@ function perfectionist() {
38
38
  'perfectionist/sort-object-types': 'off',
39
39
  'perfectionist/sort-objects': 'off',
40
40
  'perfectionist/sort-sets': 'warn',
41
- 'perfectionist/sort-svelte-attributes': 'warn',
42
41
  'perfectionist/sort-switch-case': 'off',
43
42
  'perfectionist/sort-union-types': ['warn', {
44
43
  groups: ['conditional', 'function', 'import', 'intersection', 'keyword', 'literal', 'named', 'object', 'operator', 'tuple', 'union', 'nullish']
45
44
  }],
46
- 'perfectionist/sort-variable-declarations': 'warn',
47
- 'perfectionist/sort-vue-attributes': 'warn'
45
+ 'perfectionist/sort-variable-declarations': 'warn'
48
46
  }
49
47
  };
50
48
  }
@@ -19,7 +19,8 @@ function playwright() {
19
19
  additionalTestBlockFunctions: ['test.jestPlaywrightDebug', 'it.jestPlaywrightDebug', 'test.jestPlaywrightSkip', 'it.jestPlaywrightSkip', 'test.jestPlaywrightConfig', 'it.jestPlaywrightConfig']
20
20
  }],
21
21
  'playwright/missing-playwright-await': 'error',
22
- 'playwright/no-page-pause': 'warn'
22
+ 'playwright/no-page-pause': 'warn',
23
+ 'playwright/no-slowed-test': 'warn'
23
24
  }
24
25
  };
25
26
  }
@@ -73,6 +73,7 @@ function react() {
73
73
  '@eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks': 'warn',
74
74
  '@eslint-react/hooks-extra/ensure-use-memo-has-non-empty-deps': 'warn',
75
75
  '@eslint-react/hooks-extra/prefer-use-state-lazy-initialization': 'warn',
76
+ '@eslint-react/hooks-extra/no-useless-custom-hooks': 'warn',
76
77
  '@eslint-react/naming-convention/component-name': 'warn',
77
78
  '@eslint-react/naming-convention/filename': 'off',
78
79
  '@eslint-react/naming-convention/filename-extension': ['warn', {
@@ -39,7 +39,7 @@ function tests(options = {}) {
39
39
  }),
40
40
  ...(0, _conditions.predicate)(options.typescript, {
41
41
  '@typescript-eslint/method-signature-style': 'off',
42
- '@typescript-eslint/no-namespace ': 'off',
42
+ '@typescript-eslint/no-namespace': 'off',
43
43
  '@typescript-eslint/unbound-method': 'off',
44
44
  '@typescript-eslint/no-empty-function': 'off',
45
45
  '@typescript-eslint/no-floating-promises': 'off'
@@ -196,6 +196,7 @@ function typescript(options = {}) {
196
196
  }
197
197
  }]
198
198
  }),
199
+ '@typescript-eslint/no-misused-spread': 'error',
199
200
  '@typescript-eslint/no-mixed-enums': 'error',
200
201
  '@typescript-eslint/no-redundant-type-constituents': 'warn',
201
202
  // '@typescript-eslint/no-throw-literal': ['warn', { allowThrowingUnknown: false }],
@@ -206,10 +207,10 @@ function typescript(options = {}) {
206
207
  allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false
207
208
  }],
208
209
  '@typescript-eslint/no-unnecessary-qualifier': 'error',
210
+ '@typescript-eslint/no-unnecessary-template-expression': 'warn',
209
211
  '@typescript-eslint/no-unnecessary-type-arguments': 'error',
210
212
  '@typescript-eslint/no-unnecessary-type-assertion': 'error',
211
213
  '@typescript-eslint/no-unsafe-unary-minus': 'error',
212
- '@typescript-eslint/no-unnecessary-template-expression': 'warn',
213
214
  '@typescript-eslint/non-nullable-type-assertion-style': 'warn',
214
215
  '@typescript-eslint/prefer-includes': 'warn',
215
216
  '@typescript-eslint/prefer-optional-chain': 'warn',
@@ -232,6 +233,7 @@ function typescript(options = {}) {
232
233
  allowRegExp: false,
233
234
  allowNever: false
234
235
  }],
236
+ '@typescript-eslint/related-getter-setter-pairs': 'error',
235
237
  '@typescript-eslint/require-array-sort-compare': ['error', {
236
238
  ignoreStringArrays: true
237
239
  }],
package/cjs/option.d.ts CHANGED
@@ -7,7 +7,7 @@ export interface Options extends Linter.Config {
7
7
  tailwind?: boolean | { callees: string[] };
8
8
  node?: boolean;
9
9
  strict?: boolean;
10
- import?: { internalRegExp?: string; lifetime?: number; projects?: string | string[] } | boolean;
10
+ import?: boolean | { internalRegExp?: string; lifetime?: number; projects?: string | string[] };
11
11
  esm?: boolean;
12
12
  test?: boolean;
13
13
  jest?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstacksjs/eslint-config",
3
- "version": "11.4.0",
3
+ "version": "11.6.0",
4
4
  "license": "MIT",
5
5
  "author": "fullstacks <fullstacksjs@gmail.com>",
6
6
  "description": "fullstacks eslint config",
@@ -34,48 +34,48 @@
34
34
  }
35
35
  },
36
36
  "dependencies": {
37
- "@eslint-react/eslint-plugin": "1.15.0",
38
- "@next/eslint-plugin-next": "14.2.15",
37
+ "@eslint-react/eslint-plugin": "1.28.0",
38
+ "@next/eslint-plugin-next": "15.1.7",
39
39
  "deepmerge": "4.3.1",
40
- "eslint-import-resolver-typescript": "3.6.3",
41
- "eslint-plugin-cypress": "4.0.0",
42
- "eslint-plugin-import-x": "4.3.1",
43
- "eslint-plugin-jest": "28.8.3",
40
+ "eslint-import-resolver-typescript": "3.8.3",
41
+ "eslint-plugin-cypress": "4.1.0",
42
+ "eslint-plugin-import-x": "4.6.1",
43
+ "eslint-plugin-jest": "28.11.0",
44
44
  "eslint-plugin-jest-formatting": "3.1.0",
45
- "eslint-plugin-jsx-a11y": "6.10.0",
46
- "eslint-plugin-n": "17.11.1",
47
- "eslint-plugin-perfectionist": "3.9.1",
48
- "eslint-plugin-playwright": "1.7.0",
49
- "eslint-plugin-prettier": "5.2.1",
50
- "eslint-plugin-promise": "7.1.0",
51
- "eslint-plugin-react-hooks": "5.0.0",
52
- "eslint-plugin-storybook": "0.9.0",
53
- "eslint-plugin-tailwindcss": "3.17.5",
45
+ "eslint-plugin-jsx-a11y": "6.10.2",
46
+ "eslint-plugin-n": "17.15.1",
47
+ "eslint-plugin-perfectionist": "4.9.0",
48
+ "eslint-plugin-playwright": "2.2.0",
49
+ "eslint-plugin-prettier": "5.2.3",
50
+ "eslint-plugin-promise": "7.2.1",
51
+ "eslint-plugin-react-hooks": "5.1.0",
52
+ "eslint-plugin-storybook": "0.11.3",
53
+ "eslint-plugin-tailwindcss": "3.18.0",
54
54
  "eslint-plugin-vitest": "0.5.4",
55
- "globals": "15.11.0",
56
- "local-pkg": "0.5.0",
57
- "typescript-eslint": "8.10.0"
55
+ "globals": "16.0.0",
56
+ "local-pkg": "1.0.0",
57
+ "typescript-eslint": "8.25.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@eslint/eslintrc": "3.1.0",
61
- "@eslint/js": "9.12.0",
62
- "@semantic-release/github": "11.0.0",
60
+ "@eslint/eslintrc": "3.3.0",
61
+ "@eslint/js": "9.21.0",
62
+ "@semantic-release/github": "11.0.1",
63
63
  "@semantic-release/npm": "12.0.1",
64
- "@semantic-release/release-notes-generator": "14.0.1",
64
+ "@semantic-release/release-notes-generator": "14.0.3",
65
65
  "@types/eslint": "9.6.1",
66
- "cspell": "8.15.3",
67
- "eslint": "9.12.0",
68
- "eslint-find-rules": "4.2.0",
69
- "husky": "9.1.6",
66
+ "cspell": "8.17.5",
67
+ "eslint": "9.21.0",
68
+ "eslint-find-rules": "5.0.0",
69
+ "husky": "9.1.7",
70
70
  "jest": "29.7.0",
71
- "lint-staged": "15.2.10",
72
- "np": "10.0.7",
71
+ "lint-staged": "15.4.3",
72
+ "np": "10.2.0",
73
73
  "npm-run-all": "4.1.5",
74
74
  "pinst": "3.0.0",
75
- "prettier": "3.3.3",
76
- "semantic-release": "24.1.2",
77
- "typescript": "^5.4",
78
- "unbuild": "2.0.0"
75
+ "prettier": "3.5.2",
76
+ "semantic-release": "24.2.3",
77
+ "typescript": "5.7.3",
78
+ "unbuild": "3.5.0"
79
79
  },
80
80
  "peerDependencies": {
81
81
  "cypress": ">=8",
@@ -1,3 +1,4 @@
1
+ import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript';
1
2
  import plugin from 'eslint-plugin-import-x';
2
3
 
3
4
  import { predicate } from '../utils/conditions.mjs';
@@ -31,7 +32,12 @@ function imports(options = {}) {
31
32
  'import-x/external-module-folders': ['node_modules', 'node_modules/@types'],
32
33
  'import-x/ignore': ['node_modules', '\\.(scss|css|svg|json)$'],
33
34
  ...predicate(options.typescript, {
34
- 'import-x/resolver': { typescript: true },
35
+ 'import-x/resolver-next': [
36
+ createTypeScriptImportResolver({
37
+ alwaysTryTypes: true,
38
+ project: options.typescript.projects,
39
+ }),
40
+ ],
35
41
  'import-x/parsers': { '@typescript-eslint/parser': tsExtensions },
36
42
  'import-x/extensions': allExtensions,
37
43
  }),
@@ -45,7 +45,6 @@ function perfectionist() {
45
45
  'perfectionist/sort-object-types': 'off',
46
46
  'perfectionist/sort-objects': 'off',
47
47
  'perfectionist/sort-sets': 'warn',
48
- 'perfectionist/sort-svelte-attributes': 'warn',
49
48
  'perfectionist/sort-switch-case': 'off',
50
49
  'perfectionist/sort-union-types': [
51
50
  'warn',
@@ -67,7 +66,6 @@ function perfectionist() {
67
66
  },
68
67
  ],
69
68
  'perfectionist/sort-variable-declarations': 'warn',
70
- 'perfectionist/sort-vue-attributes': 'warn',
71
69
  },
72
70
  };
73
71
  }
@@ -23,6 +23,7 @@ function playwright() {
23
23
  ],
24
24
  'playwright/missing-playwright-await': 'error',
25
25
  'playwright/no-page-pause': 'warn',
26
+ 'playwright/no-slowed-test': 'warn',
26
27
  },
27
28
  };
28
29
  }
@@ -69,6 +69,7 @@ function react() {
69
69
  '@eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks': 'warn',
70
70
  '@eslint-react/hooks-extra/ensure-use-memo-has-non-empty-deps': 'warn',
71
71
  '@eslint-react/hooks-extra/prefer-use-state-lazy-initialization': 'warn',
72
+ '@eslint-react/hooks-extra/no-useless-custom-hooks': 'warn',
72
73
 
73
74
  '@eslint-react/naming-convention/component-name': 'warn',
74
75
  '@eslint-react/naming-convention/filename': 'off',
@@ -32,7 +32,7 @@ function tests(options = {}) {
32
32
 
33
33
  ...predicate(options.typescript, {
34
34
  '@typescript-eslint/method-signature-style': 'off',
35
- '@typescript-eslint/no-namespace ': 'off',
35
+ '@typescript-eslint/no-namespace': 'off',
36
36
  '@typescript-eslint/unbound-method': 'off',
37
37
  '@typescript-eslint/no-empty-function': 'off',
38
38
  '@typescript-eslint/no-floating-promises': 'off',
@@ -169,6 +169,7 @@ function typescript(options = {}) {
169
169
  '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
170
170
  '@typescript-eslint/no-misused-promises': ['warn', { checksVoidReturn: { attributes: false } }],
171
171
  }),
172
+ '@typescript-eslint/no-misused-spread': 'error',
172
173
  '@typescript-eslint/no-mixed-enums': 'error',
173
174
  '@typescript-eslint/no-redundant-type-constituents': 'warn',
174
175
  // '@typescript-eslint/no-throw-literal': ['warn', { allowThrowingUnknown: false }],
@@ -182,10 +183,10 @@ function typescript(options = {}) {
182
183
  },
183
184
  ],
184
185
  '@typescript-eslint/no-unnecessary-qualifier': 'error',
186
+ '@typescript-eslint/no-unnecessary-template-expression': 'warn',
185
187
  '@typescript-eslint/no-unnecessary-type-arguments': 'error',
186
188
  '@typescript-eslint/no-unnecessary-type-assertion': 'error',
187
189
  '@typescript-eslint/no-unsafe-unary-minus': 'error',
188
- '@typescript-eslint/no-unnecessary-template-expression': 'warn',
189
190
  '@typescript-eslint/non-nullable-type-assertion-style': 'warn',
190
191
  '@typescript-eslint/prefer-includes': 'warn',
191
192
  '@typescript-eslint/prefer-optional-chain': 'warn',
@@ -207,6 +208,7 @@ function typescript(options = {}) {
207
208
  'warn',
208
209
  { allowNumber: true, allowBoolean: false, allowAny: false, allowNullish: false, allowRegExp: false, allowNever: false },
209
210
  ],
211
+ '@typescript-eslint/related-getter-setter-pairs': 'error',
210
212
  '@typescript-eslint/require-array-sort-compare': ['error', { ignoreStringArrays: true }],
211
213
  '@typescript-eslint/require-await': 'error',
212
214
  '@typescript-eslint/return-await': 'error',
package/src/option.d.ts CHANGED
@@ -7,7 +7,7 @@ export interface Options extends Linter.Config {
7
7
  tailwind?: boolean | { callees: string[] };
8
8
  node?: boolean;
9
9
  strict?: boolean;
10
- import?: { internalRegExp?: string; lifetime?: number; projects?: string | string[] } | boolean;
10
+ import?: boolean | { internalRegExp?: string; lifetime?: number; projects?: string | string[] };
11
11
  esm?: boolean;
12
12
  test?: boolean;
13
13
  jest?: boolean;