@foray1010/eslint-config 14.0.1 → 15.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/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [15.0.1](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@15.0.0...@foray1010/eslint-config@15.0.1) (2025-03-13)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **eslint-config:** fix types ([28e3bfa](https://github.com/foray1010/common-presets/commit/28e3bfabce71cd1d80b0186f1ac7f3158a049d33))
11
+
12
+ ## [15.0.0](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@14.0.1...@foray1010/eslint-config@15.0.0) (2025-03-13)
13
+
14
+ ### ⚠ BREAKING CHANGES
15
+
16
+ - drop applyConfig utils
17
+ - require eslint ^9.22.0
18
+
19
+ ### Features
20
+
21
+ - migrate to eslint defineConfig utils ([faf0aa7](https://github.com/foray1010/common-presets/commit/faf0aa74048b2536e188a45b8371ebe416dcb851))
22
+
6
23
  ## [14.0.1](https://github.com/foray1010/common-presets/compare/@foray1010/eslint-config@14.0.0...@foray1010/eslint-config@14.0.1) (2025-03-11)
7
24
 
8
25
  ### Bug Fixes
package/README.md CHANGED
@@ -29,8 +29,9 @@ Z for looser rules
29
29
  eslintIgnoresConfig,
30
30
  eslintNodeConfig,
31
31
  } from '@foray1010/eslint-config'
32
+ import { defineConfig } from 'eslint/config'
32
33
 
33
- const config = [...eslintIgnoresConfig, ...eslintNodeConfig]
34
+ const config = defineConfig(eslintIgnoresConfig, eslintNodeConfig)
34
35
  export default config
35
36
  ```
36
37
 
@@ -41,8 +42,9 @@ Z for looser rules
41
42
  eslintIgnoresConfig,
42
43
  eslintBrowserConfig,
43
44
  } from '@foray1010/eslint-config'
45
+ import { defineConfig } from 'eslint/config'
44
46
 
45
- const config = [...eslintIgnoresConfig, ...eslintBrowserConfig]
47
+ const config = defineConfig(eslintIgnoresConfig, eslintBrowserConfig)
46
48
  export default config
47
49
  ```
48
50
 
@@ -53,8 +55,9 @@ Z for looser rules
53
55
  eslintIgnoresConfig,
54
56
  eslintReactConfig,
55
57
  } from '@foray1010/eslint-config'
58
+ import { defineConfig } from 'eslint/config'
56
59
 
57
- const config = [...eslintIgnoresConfig, ...eslintReactConfig]
60
+ const config = defineConfig(eslintIgnoresConfig, eslintReactConfig)
58
61
  export default config
59
62
  ```
60
63
 
@@ -62,28 +65,23 @@ Z for looser rules
62
65
 
63
66
  ```js
64
67
  import {
65
- applyConfig,
66
68
  eslintIgnoresConfig,
67
69
  eslintNodeConfig,
68
70
  eslintReactConfig,
69
71
  } from '@foray1010/eslint-config'
72
+ import { defineConfig } from 'eslint/config'
70
73
 
71
- const config = [
72
- ...eslintIgnoresConfig,
73
- ...applyConfig(
74
- {
75
- filePrefixes: '.',
76
- ignores: ['src/**'],
77
- },
78
- eslintNodeConfig,
79
- ),
80
- ...applyConfig(
81
- {
82
- filePrefixes: ['src'],
83
- },
84
- eslintReactConfig,
85
- ),
86
- ]
74
+ const config = defineConfig(
75
+ eslintIgnoresConfig,
76
+ {
77
+ ignores: ['src/**'],
78
+ extends: [eslintNodeConfig],
79
+ },
80
+ {
81
+ files: ['src/**'],
82
+ extends: [eslintReactConfig],
83
+ },
84
+ )
87
85
  export default config
88
86
  ```
89
87
 
package/bases/base.mjs CHANGED
@@ -1,6 +1,9 @@
1
1
  import js from '@eslint/js'
2
- import eslintPluginEslintComments from '@eslint-community/eslint-plugin-eslint-comments'
2
+ // eslint-disable-next-line import-x/extensions
3
+ import eslintPluginEslintCommentsConfigs from '@eslint-community/eslint-plugin-eslint-comments/configs'
3
4
  import { hasDep, isESM } from '@foray1010/common-presets-utils'
5
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
6
+ import { defineConfig } from 'eslint/config'
4
7
  import eslintPluginImportX from 'eslint-plugin-import-x'
5
8
  import eslintPluginJest from 'eslint-plugin-jest'
6
9
  import eslintPluginRegexp from 'eslint-plugin-regexp'
@@ -14,23 +17,22 @@ import {
14
17
  typeScriptTestFileGlobs,
15
18
  } from '../constants.mjs'
16
19
 
17
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
18
-
19
- /** @returns {Promise<EslintConfig>} */
20
20
  async function generateTypeScriptConfig() {
21
21
  // typescript plugins are depended on `typescript` package
22
- if (!hasDep('typescript')) return []
22
+ if (!hasDep('typescript')) return defineConfig({})
23
23
 
24
24
  // eslint-disable-next-line import-x/no-unresolved
25
25
  const tseslint = (await import('typescript-eslint')).default
26
26
 
27
- return [
28
- // @ts-expect-error `Type 'Config' is not assignable to type 'Readonly<FlatConfig<RulesRecord>>' with 'exactOptionalPropertyTypes: true'`
29
- ...tseslint.config({
27
+ return defineConfig(
28
+ {
30
29
  files: typeScriptFileGlobs,
31
30
  extends: [
31
+ // @ts-expect-error tseslint interface does not align with eslint
32
32
  tseslint.configs.eslintRecommended,
33
- ...tseslint.configs.recommendedTypeChecked,
33
+ // @ts-expect-error tseslint interface does not align with eslint
34
+ tseslint.configs.recommendedTypeChecked,
35
+ eslintPluginImportX.configs['typescript'],
34
36
  esmConfig,
35
37
  ],
36
38
  languageOptions: {
@@ -42,13 +44,7 @@ async function generateTypeScriptConfig() {
42
44
  project: ['./tsconfig*.json', './packages/*/tsconfig*.json'],
43
45
  },
44
46
  },
45
- settings: {
46
- 'import-x/resolver': {
47
- typescript: true,
48
- },
49
- },
50
47
  rules: {
51
- ...eslintPluginImportX.configs['typescript']?.rules,
52
48
  // separate type exports which allow certain optimizations within compilers
53
49
  '@typescript-eslint/consistent-type-exports': [
54
50
  'error',
@@ -136,8 +132,7 @@ async function generateTypeScriptConfig() {
136
132
  // It is disabled in recommended config but re-enabled here to enforce a subset of global variables that supported by both node.js and browsers
137
133
  'no-undef': 'error',
138
134
  },
139
- }),
140
- // @ts-expect-error As previous item's type is not correct, this item is affected too
135
+ },
141
136
  {
142
137
  files: typeScriptTestFileGlobs,
143
138
  rules: {
@@ -149,11 +144,10 @@ async function generateTypeScriptConfig() {
149
144
  'jest/unbound-method': ['error', { ignoreStatic: true }],
150
145
  },
151
146
  },
152
- ]
147
+ )
153
148
  }
154
149
 
155
- /** @type {EslintConfig[number]} */
156
- const cjsConfig = {
150
+ const cjsConfig = defineConfig({
157
151
  languageOptions: {
158
152
  globals: globals.commonjs,
159
153
  sourceType: 'script',
@@ -162,10 +156,9 @@ const cjsConfig = {
162
156
  // commonjs must use strict mode
163
157
  strict: ['error', 'global'],
164
158
  },
165
- }
159
+ })
166
160
 
167
- /** @type {EslintConfig[number]} */
168
- const esmConfig = {
161
+ const esmConfig = defineConfig({
169
162
  languageOptions: {
170
163
  sourceType: 'module',
171
164
  },
@@ -178,16 +171,31 @@ const esmConfig = {
178
171
  // auto sort import statements
179
172
  'simple-import-sort/imports': 'error',
180
173
  },
181
- }
174
+ })
182
175
 
183
- /** @type {EslintConfig} */
184
- const baseConfig = [
176
+ const baseConfig = defineConfig(
185
177
  js.configs.recommended,
186
- eslintPluginRegexp.configs['flat/recommended'],
187
178
  {
188
- ...eslintPluginImportX.flatConfigs.recommended,
179
+ extends: [
180
+ // @ts-expect-error no official types
181
+ eslintPluginEslintCommentsConfigs['recommended'],
182
+ ],
183
+ rules: {
184
+ // allow disable eslint rules for whole file without re-enable it in the end of the file
185
+ '@eslint-community/eslint-comments/disable-enable-pair': [
186
+ 'error',
187
+ { allowWholeFile: true },
188
+ ],
189
+ // make sure every eslint-disable comments are in use
190
+ '@eslint-community/eslint-comments/no-unused-disable': 'error',
191
+ },
192
+ },
193
+ {
194
+ extends: [
195
+ // @ts-expect-error eslint-plugin-import-x interface does not align with eslint
196
+ eslintPluginImportX.flatConfigs.recommended,
197
+ ],
189
198
  rules: {
190
- ...eslintPluginImportX.flatConfigs.recommended.rules,
191
199
  // this rule doesn't support commonjs, some dependencies are using commonjs
192
200
  'import-x/default': 'off',
193
201
  // Does not work after upgrading to eslint-plugin-import-x v4, got this error message: `sourceType 'module' is not supported when ecmaVersion < 2015. Consider adding `{ ecmaVersion: 2015 }` to the parser options. (undefined:undefined)`
@@ -262,27 +270,17 @@ const baseConfig = [
262
270
  },
263
271
  },
264
272
  {
265
- linterOptions: {
266
- reportUnusedDisableDirectives: 'error',
267
- reportUnusedInlineConfigs: 'error',
268
- },
269
- languageOptions: {
270
- ecmaVersion: 2023,
271
- globals: {
272
- ...globals.es2023,
273
- /* Not using `node` to explicitly import node.js only built-in modules, e.g.
274
- * import { Buffer } from 'node:buffer'
275
- * import process from 'node:process'
276
- */
277
- ...globals['shared-node-browser'],
278
- },
273
+ extends: [eslintPluginRegexp.configs['flat/recommended']],
274
+ rules: {
275
+ // enable regexp strict mode (use `v` flag instead when it is widely supported)
276
+ 'regexp/require-unicode-regexp': 'error',
279
277
  },
278
+ },
279
+ {
280
280
  plugins: {
281
- '@eslint-community/eslint-comments': eslintPluginEslintComments,
282
281
  unicorn: eslintPluginUnicorn,
283
282
  },
284
283
  rules: {
285
- ...eslintPluginEslintComments.configs['recommended']?.rules,
286
284
  ...Object.fromEntries(
287
285
  Object.entries(
288
286
  eslintPluginUnicorn.configs['flat/recommended']?.rules ?? {},
@@ -294,13 +292,40 @@ const baseConfig = [
294
292
  )
295
293
  }),
296
294
  ),
297
- // allow disable eslint rules for whole file without re-enable it in the end of the file
298
- '@eslint-community/eslint-comments/disable-enable-pair': [
299
- 'error',
300
- { allowWholeFile: true },
301
- ],
302
- // make sure every eslint-disable comments are in use
303
- '@eslint-community/eslint-comments/no-unused-disable': 'error',
295
+ // use with `unicorn/throw-new-error`
296
+ // disallow builtins to be created without `new` operator, to be consistent with es6 class syntax
297
+ 'unicorn/new-for-builtins': 'error',
298
+ // some legacy projects still use commonjs
299
+ 'unicorn/prefer-module': 'off',
300
+ // `querySelector` is slower than `getElementById`
301
+ 'unicorn/prefer-query-selector': 'off',
302
+ // `Array.from(iterable)` is more readable than `[...iterable]`
303
+ 'unicorn/prefer-spread': 'off',
304
+ // sometimes it is less readable using ternary expressions
305
+ 'unicorn/prefer-ternary': 'off',
306
+ // webpack support on `top level await` is still experimental, and some legacy projects still use commonjs
307
+ 'unicorn/prefer-top-level-await': 'off',
308
+ // use with `unicorn/new-for-builtins`
309
+ 'unicorn/throw-new-error': 'error',
310
+ },
311
+ },
312
+ {
313
+ linterOptions: {
314
+ reportUnusedDisableDirectives: 'error',
315
+ reportUnusedInlineConfigs: 'error',
316
+ },
317
+ languageOptions: {
318
+ ecmaVersion: 2023,
319
+ globals: {
320
+ ...globals.es2023,
321
+ /* Not using `node` to explicitly import node.js only built-in modules, e.g.
322
+ * import { Buffer } from 'node:buffer'
323
+ * import process from 'node:process'
324
+ */
325
+ ...globals['shared-node-browser'],
326
+ },
327
+ },
328
+ rules: {
304
329
  // always use named function for easier to debug via stack trace
305
330
  'func-names': ['error', 'as-needed'],
306
331
  // prefer explicitly convert type for readability
@@ -317,49 +342,31 @@ const baseConfig = [
317
342
  destructuring: 'all',
318
343
  },
319
344
  ],
320
- // enable regexp strict mode (use `v` flag instead when it is widely supported)
321
- 'regexp/require-unicode-regexp': 'error',
322
- // use with `unicorn/throw-new-error`
323
- // disallow builtins to be created without `new` operator, to be consistent with es6 class syntax
324
- 'unicorn/new-for-builtins': 'error',
325
- // some legacy projects still use commonjs
326
- 'unicorn/prefer-module': 'off',
327
- // `querySelector` is slower than `getElementById`
328
- 'unicorn/prefer-query-selector': 'off',
329
- // `Array.from(iterable)` is more readable than `[...iterable]`
330
- 'unicorn/prefer-spread': 'off',
331
- // sometimes it is less readable using ternary expressions
332
- 'unicorn/prefer-ternary': 'off',
333
- // webpack support on `top level await` is still experimental, and some legacy projects still use commonjs
334
- 'unicorn/prefer-top-level-await': 'off',
335
- // use with `unicorn/new-for-builtins`
336
- 'unicorn/throw-new-error': 'error',
337
345
  },
338
346
  },
339
347
  {
340
348
  files: ['**/*.js'],
341
- ...(isESM() ? esmConfig : cjsConfig),
349
+ extends: [isESM() ? esmConfig : cjsConfig],
342
350
  },
343
351
  {
344
352
  files: ['**/*.cjs'],
345
- ...cjsConfig,
353
+ extends: [cjsConfig],
346
354
  },
347
355
  {
348
356
  files: ['**/*.mjs'],
349
- ...esmConfig,
350
- },
351
- {
352
- files: testFileGlobs,
353
- ...eslintPluginJest.configs['flat/recommended'],
354
- ...eslintPluginJest.configs['flat/style'],
357
+ extends: [esmConfig],
355
358
  },
356
359
  {
357
360
  files: testFileGlobs,
361
+ extends: [
362
+ eslintPluginJest.configs['flat/recommended'],
363
+ eslintPluginJest.configs['flat/style'],
364
+ ],
358
365
  rules: {
359
366
  // make sure lifecycle hooks on the top for readability
360
367
  'jest/prefer-hooks-on-top': 'error',
361
368
  },
362
369
  },
363
- ...(await generateTypeScriptConfig()),
364
- ]
370
+ await generateTypeScriptConfig(),
371
+ )
365
372
  export default baseConfig
package/bases/browser.mjs CHANGED
@@ -1,30 +1,26 @@
1
1
  import { hasDep } from '@foray1010/common-presets-utils'
2
2
  import restrictedGlobals from 'confusing-browser-globals'
3
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
4
+ import { defineConfig } from 'eslint/config'
3
5
  import eslintPluginCompat from 'eslint-plugin-compat'
4
6
  import eslintPluginTestingLibrary from 'eslint-plugin-testing-library'
5
7
  import globals from 'globals'
6
8
 
7
9
  import { testFileGlobs } from '../constants.mjs'
8
10
 
9
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
10
-
11
- /** @returns {Promise<EslintConfig>} */
12
11
  async function generateJestDomConfig() {
13
12
  // `eslint-plugin-jest-dom` depends on `@testing-library/dom` package
14
- if (!hasDep('@testing-library/dom')) return []
13
+ if (!hasDep('@testing-library/dom')) return defineConfig({})
15
14
 
16
15
  const eslintPluginJestDom = (await import('eslint-plugin-jest-dom')).default
17
16
 
18
- return [
19
- {
20
- files: testFileGlobs,
21
- ...eslintPluginJestDom.configs['flat/recommended'],
22
- },
23
- ]
17
+ return defineConfig({
18
+ files: testFileGlobs,
19
+ extends: [eslintPluginJestDom.configs['flat/recommended']],
20
+ })
24
21
  }
25
22
 
26
- /** @type {EslintConfig} */
27
- const browserConfig = [
23
+ const browserConfig = defineConfig(
28
24
  {
29
25
  languageOptions: {
30
26
  globals: {
@@ -44,22 +40,14 @@ const browserConfig = [
44
40
  'no-restricted-globals': ['error', ...restrictedGlobals],
45
41
  },
46
42
  },
47
- ...(await generateJestDomConfig()),
48
- {
49
- files: testFileGlobs,
50
- plugins: {
51
- 'testing-library': eslintPluginTestingLibrary,
52
- },
53
- rules: {
54
- ...eslintPluginTestingLibrary.configs['flat/dom']?.rules,
55
- },
56
- },
43
+ await generateJestDomConfig(),
57
44
  {
58
45
  files: testFileGlobs,
46
+ extends: [eslintPluginTestingLibrary.configs['flat/dom']],
59
47
  rules: {
60
48
  // allow to use nodejs modules in tests
61
49
  'import-x/no-nodejs-modules': 'off',
62
50
  },
63
51
  },
64
- ]
52
+ )
65
53
  export default browserConfig
package/bases/ignores.mjs CHANGED
@@ -1,16 +1,13 @@
1
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
1
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
2
+ import { defineConfig, globalIgnores } from 'eslint/config'
2
3
 
3
- /** @type {EslintConfig} */
4
- const ignoresConfig = [
5
- {
6
- // replace `.eslintignore`
7
- ignores: [
8
- '**/.yarn/**',
9
- '**/build/**',
10
- '**/coverage/**',
11
- '**/dist/**',
12
- '**/node_modules/**',
13
- ],
14
- },
15
- ]
4
+ const ignoresConfig = defineConfig(
5
+ globalIgnores([
6
+ '**/.yarn/**',
7
+ '**/build/**',
8
+ '**/coverage/**',
9
+ '**/dist/**',
10
+ '**/node_modules/**',
11
+ ]),
12
+ )
16
13
  export default ignoresConfig
package/bases/node.mjs CHANGED
@@ -1,20 +1,18 @@
1
1
  import { isESM } from '@foray1010/common-presets-utils'
2
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
3
+ import { defineConfig } from 'eslint/config'
2
4
  import eslintPluginN from 'eslint-plugin-n'
3
5
 
4
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
5
-
6
- /** @type {EslintConfig[number]} */
7
- const cjsConfig = {
6
+ const cjsConfig = defineConfig({
8
7
  languageOptions: {
9
8
  globals: {
10
9
  __dirname: 'readonly',
11
10
  __filename: 'readonly',
12
11
  },
13
12
  },
14
- }
13
+ })
15
14
 
16
- /** @type {EslintConfig} */
17
- const nodeConfig = [
15
+ const nodeConfig = defineConfig(
18
16
  {
19
17
  plugins: {
20
18
  n: eslintPluginN,
@@ -67,12 +65,12 @@ const nodeConfig = [
67
65
  : [
68
66
  {
69
67
  files: ['**/*.js'],
70
- ...cjsConfig,
68
+ extends: [cjsConfig],
71
69
  },
72
70
  ]),
73
71
  {
74
72
  files: ['**/*.{cjs,cts}'],
75
- ...cjsConfig,
73
+ extends: [cjsConfig],
76
74
  },
77
- ]
75
+ )
78
76
  export default nodeConfig
@@ -1,12 +1,11 @@
1
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
2
+ import { defineConfig } from 'eslint/config'
1
3
  // eslint-disable-next-line import-x/extensions
2
4
  import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
3
5
 
4
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
5
-
6
- /** @type {EslintConfig} */
7
6
  // should be placed at the end to override other configs
8
- const prettierConfig = [
7
+ const prettierConfig = defineConfig(
9
8
  // This includes `eslint-config-prettier` as peer dependency
10
9
  eslintPluginPrettierRecommended,
11
- ]
10
+ )
12
11
  export default prettierConfig
package/bases/react.mjs CHANGED
@@ -1,26 +1,24 @@
1
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
2
+ import { defineConfig } from 'eslint/config'
1
3
  import eslintPluginReact from 'eslint-plugin-react'
2
4
  import eslintPluginReactHooks from 'eslint-plugin-react-hooks'
3
5
  import eslintPluginTestingLibrary from 'eslint-plugin-testing-library'
4
6
 
5
7
  import { testFileGlobs } from '../constants.mjs'
6
8
 
7
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
8
-
9
- /** @type {EslintConfig} */
10
- const reactConfig = [
11
- eslintPluginReact.configs.flat.recommended,
12
- eslintPluginReact.configs.flat['jsx-runtime'],
9
+ const reactConfig = defineConfig(
13
10
  {
14
11
  settings: {
15
12
  react: {
16
13
  version: 'detect',
17
14
  },
18
15
  },
19
- plugins: {
20
- 'react-hooks': eslintPluginReactHooks,
21
- },
16
+ extends: [
17
+ eslintPluginReact.configs.flat.recommended,
18
+ eslintPluginReact.configs.flat['jsx-runtime'],
19
+ eslintPluginReactHooks.configs['recommended-latest'],
20
+ ],
22
21
  rules: {
23
- ...eslintPluginReactHooks.configs['recommended']?.rules,
24
22
  // avoid unexpected form submits
25
23
  'react/button-has-type': 'error',
26
24
  'react/jsx-no-useless-fragment': [
@@ -61,13 +59,7 @@ const reactConfig = [
61
59
  },
62
60
  {
63
61
  files: testFileGlobs,
64
- rules: {
65
- // Do not use flat config directly as eslint v9 does not support duplicated plugins (already defined in browser.mjs)
66
- ...eslintPluginTestingLibrary.configs['flat/react']?.rules,
67
- },
68
- },
69
- {
70
- files: testFileGlobs,
62
+ extends: [eslintPluginTestingLibrary.configs['flat/react']],
71
63
  rules: {
72
64
  // avoid using unnecessary `await` as workaround for `not wrapped in act(...)` warnings
73
65
  'testing-library/no-await-sync-events': [
@@ -82,5 +74,5 @@ const reactConfig = [
82
74
  'testing-library/prefer-user-event': 'error',
83
75
  },
84
76
  },
85
- ]
77
+ )
86
78
  export default reactConfig
package/index.mjs CHANGED
@@ -1,33 +1,29 @@
1
+ // eslint-disable-next-line import-x/extensions, import-x/no-unresolved
2
+ import { defineConfig } from 'eslint/config'
3
+
1
4
  import baseConfig from './bases/base.mjs'
2
5
  import browserConfig from './bases/browser.mjs'
3
6
  import nodeConfig from './bases/node.mjs'
4
7
  import prettierConfig from './bases/prettier.mjs'
5
8
  import reactConfig from './bases/react.mjs'
6
9
 
7
- export * from './utils/applyConfig.mjs'
8
-
9
- /** @typedef {import('./types/internal.d.ts').EslintConfig} EslintConfig */
10
-
11
- /** @type {EslintConfig} */
12
- export const eslintBrowserConfig = [
13
- ...baseConfig,
14
- ...browserConfig,
15
- ...prettierConfig,
16
- ]
10
+ export const eslintBrowserConfig = defineConfig(
11
+ baseConfig,
12
+ browserConfig,
13
+ prettierConfig,
14
+ )
17
15
 
18
- /** @type {EslintConfig} */
19
- export const eslintNodeConfig = [
20
- ...baseConfig,
21
- ...nodeConfig,
22
- ...prettierConfig,
23
- ]
16
+ export const eslintNodeConfig = defineConfig(
17
+ baseConfig,
18
+ nodeConfig,
19
+ prettierConfig,
20
+ )
24
21
 
25
- /** @type {EslintConfig} */
26
- export const eslintReactConfig = [
27
- ...baseConfig,
28
- ...browserConfig,
29
- ...reactConfig,
30
- ...prettierConfig,
31
- ]
22
+ export const eslintReactConfig = defineConfig(
23
+ baseConfig,
24
+ browserConfig,
25
+ reactConfig,
26
+ prettierConfig,
27
+ )
32
28
 
33
29
  export { default as eslintIgnoresConfig } from './bases/ignores.mjs'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@foray1010/eslint-config",
4
- "version": "14.0.1",
4
+ "version": "15.0.1",
5
5
  "homepage": "https://github.com/foray1010/common-presets/tree/master/packages/eslint-config#readme",
6
6
  "bugs": "https://github.com/foray1010/common-presets/issues",
7
7
  "repository": {
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@testing-library/dom": "^10.0.0",
50
- "eslint": "^9.21.0",
50
+ "eslint": "^9.22.0",
51
51
  "prettier": "^3.0.0",
52
52
  "typescript": "^5.0.2"
53
53
  },
@@ -65,5 +65,5 @@
65
65
  "publishConfig": {
66
66
  "access": "public"
67
67
  },
68
- "gitHead": "c636af09fd413eaa3c2936b2e2b4d32daac1ef0c"
68
+ "gitHead": "df7fe29d7a74d9a61415c61074e5663db3e56044"
69
69
  }
@@ -1,72 +0,0 @@
1
- import path from 'node:path'
2
-
3
- import { supportedFilesGlob } from '../constants.mjs'
4
-
5
- /** @typedef {import('../types/internal.d.ts').EslintConfig} EslintConfig */
6
-
7
- /**
8
- * Extend the flat configs with default files and ignores
9
- * @param {{
10
- * readonly filePrefixes: string | string[],
11
- * readonly ignores?: string[] | undefined
12
- * }} options
13
- * @param {EslintConfig} eslintConfig
14
- * @returns {EslintConfig}
15
- */
16
- export function applyConfig(options, eslintConfig) {
17
- const filePrefixes = [options.filePrefixes].flat()
18
- if (filePrefixes.length === 0) {
19
- throw new TypeError('filePrefixes must not be empty')
20
- }
21
-
22
- // Do not allow string such as "eslint:recommended" because it cannot be overridden by files/ignores
23
- for (const config of eslintConfig) {
24
- if (typeof config === 'string') {
25
- throw new TypeError(
26
- `Cannot extend ${config} with files/ignores, use \`@eslint/js\` instead`,
27
- )
28
- }
29
-
30
- if (Object.keys(config).includes('ignores')) {
31
- throw new TypeError('Do not use `ignores` in config')
32
- }
33
- }
34
-
35
- return eslintConfig.map((config) => {
36
- const files = generateCombinations(filePrefixes, config.files)
37
- return {
38
- ...config,
39
- ...(files ? { files } : {}),
40
- ...(options.ignores ? { ignores: options.ignores } : {}),
41
- }
42
- })
43
- }
44
-
45
- /**
46
- * @param {string[]} prefixes
47
- * @param {EslintConfig[number]['files']} originalGlobs
48
- * @returns {string[] | undefined}
49
- */
50
- function generateCombinations(prefixes, originalGlobs) {
51
- if (!originalGlobs || originalGlobs.length === 0) {
52
- return prefixes.map((prefix) => path.join(prefix, supportedFilesGlob))
53
- }
54
-
55
- const verifiedOriginalGlobs = originalGlobs.filter(
56
- /** @returns {originalGlob is string} */
57
- (originalGlob) => typeof originalGlob === 'string',
58
- )
59
- if (originalGlobs.length !== verifiedOriginalGlobs.length) {
60
- throw new TypeError(
61
- `Do not support using non-string value in files/ignores`,
62
- )
63
- }
64
-
65
- return prefixes.flatMap((prefix) => {
66
- return verifiedOriginalGlobs.flatMap((originalGlob) => {
67
- const signRegexp = /^!/u
68
- const sign = originalGlob.match(signRegexp)?.[0] ?? ''
69
- return sign + path.join(prefix, originalGlob.replace(signRegexp, ''))
70
- })
71
- })
72
- }