@alexlit/config-eslint 84.2.0 → 84.3.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,379 +1,17 @@
1
- /* eslint-disable sonarjs/no-duplicate-string, import/order, no-undef */
1
+ const { FlatCompat } = require('@eslint/eslintrc');
2
2
 
3
- const { defineConfig } = require('eslint-define-config');
4
3
  const { extendSpellChecker } = require('./utils/extend-spell-checker');
4
+ const { createConfig } = require('./utils/create-config');
5
5
 
6
- const DEFAULT_PLUGINS = {
7
- /** @see [eslint-plugin-array-func](https://github.com/freaktechnik/eslint-plugin-array-func) */
8
- 'array-func': true,
6
+ const compat = new FlatCompat({
7
+ baseDirectory: __dirname,
8
+ });
9
9
 
10
- /** @see [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat) */
11
- compat: true,
10
+ const createFlatConfig = () => [
11
+ ...compat.extends('./legacy.js'),
12
+ {
13
+ ignores: ['.gitignore', '.eslintignore', '.prettierignore'],
14
+ },
15
+ ];
12
16
 
13
- /** @see [eslint-plugin-decorator-position](https://github.com/NullVoxPopuli/eslint-plugin-decorator-position) */
14
- 'decorator-position': true,
15
-
16
- /** @see [eslint-plugin-eslint-comments](hhttps://github.com/mysticatea/eslint-plugin-eslint-comments) */
17
- 'eslint-comments': true,
18
-
19
- /** @see [eslint-plugin-etc](https://github.com/cartant/eslint-plugin-etc) */
20
- etc: true,
21
-
22
- /** @see [eslint-plugin-ext](https://github.com/jiangfengming/eslint-plugin-ext) */
23
- ext: true,
24
-
25
- /** @see [eslint-plugin-filenames](https://github.com/selaux/eslint-plugin-filenames) */
26
- filenames: true,
27
-
28
- /**
29
- * @see [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import)
30
- * @see [eslint-import-resolver-alias](https://github.com/johvin/eslint-import-resolver-alias)
31
- */
32
- import: true,
33
-
34
- /** @see [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) */
35
- jsdoc: true,
36
-
37
- /** @see [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) */
38
- 'jsx-a11y': true,
39
-
40
- /** @see [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) */
41
- lit: true,
42
-
43
- /** @see [eslint-plugin-lit-a11y](https://www.npmjs.com/package/eslint-plugin-lit-a11y) */
44
- 'lit-a11y': true,
45
-
46
- /** @see [eslint-plugin-more](https://github.com/WebbyLab/eslint-plugin-more) */
47
- more: true,
48
-
49
- /** @see [eslint-plugin-no-await-in-promise](https://github.com/hugo-vrijswijk/eslint-plugin-no-await-in-promise/) */
50
- 'no-await-in-promise': true,
51
-
52
- /** @see [eslint-plugin-no-constructor-bind](https://github.com/markalfred/eslint-plugin-no-constructor-bind) */
53
- 'no-constructor-bind': true,
54
-
55
- /** @see [eslint-plugin-no-explicit-type-exports](https://github.com/intuit/eslint-plugin-no-explicit-type-exports) */
56
- 'no-explicit-type-exports': true,
57
-
58
- /** @see [eslint-plugin-no-loops](https://github.com/buildo/eslint-plugin-no-loops) */
59
- 'no-loops': true,
60
-
61
- /** @see [eslint-plugin-no-secrets](https://github.com/nickdeis/eslint-plugin-no-secrets) */
62
- 'no-secrets': true,
63
-
64
- /** @see [eslint-plugin-no-use-extend-native](https://github.com/dustinspecker/eslint-plugin-no-use-extend-native) */
65
- 'no-use-extend-native': true,
66
-
67
- /** @see [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise) */
68
- promise: true,
69
-
70
- /** @see [eslint-plugin-regexp](https://github.com/ota-meshi/eslint-plugin-regexp) */
71
- regexp: true,
72
-
73
- /** @see [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort) */
74
- 'simple-import-sort': true,
75
-
76
- /** @see [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs) */
77
- sonar: true,
78
-
79
- /** @see [eslint-plugin-sort-class-members](https://github.com/bryanrsmith/eslint-plugin-sort-class-members) */
80
- 'sort-class-members': true,
81
-
82
- /** @see [eslint-plugin-sort-destructure-keys](https://github.com/mthadley/eslint-plugin-sort-destructure-keys) */
83
- 'sort-destructure-keys': true,
84
-
85
- /** @see [eslint-plugin-sort-keys-fix](https://github.com/leo-buneev/eslint-plugin-sort-keys-fix) */
86
- 'sort-keys-fix': true,
87
-
88
- /** @see [eslint-plugin-spellcheck](https://github.com/aotaduy/eslint-plugin-spellcheck) */
89
- spellcheck: true,
90
-
91
- /** @see [eslint-plugin-sql](https://github.com/gajus/eslint-plugin-sql) */
92
- sql: true,
93
-
94
- /** @see [@tanstack/query](https://tanstack.com/query/v4/docs/react/eslint/eslint-plugin-query) */
95
- 'tanstack-query': true,
96
-
97
- /** @see [eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library) */
98
- 'testing-library': true,
99
-
100
- /** @see [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) */
101
- typescript: true,
102
-
103
- /** @see [eslint-plugin-typescript-sort-keys](https://github.com/infctr/eslint-plugin-typescript-sort-keys) */
104
- 'typescript-sort-keys': true,
105
-
106
- /** @see [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) */
107
- unicorn: true,
108
-
109
- /** @see [eslint-plugin-unused-imports](https://github.com/sweepline/eslint-plugin-unused-imports) */
110
- 'unused-imports': true,
111
-
112
- /** @see [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) */
113
- vitest: true,
114
-
115
- /** @see [eslint-plugin-vue](https://eslint.vuejs.org/rules/) */
116
- vue: true,
117
-
118
- /** @see [eslint-plugin-vue-i18n](https://eslint-plugin-vue-i18n.intlify.dev/) */
119
- 'vue-i18n': true,
120
-
121
- /** @see [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility) */
122
- 'vuejs-accessibility': true,
123
-
124
- /** @see [eslint-plugin-wc](https://github.com/43081j/eslint-plugin-wc) */
125
- wc: true,
126
-
127
- /** @see [eslint-plugin-write-good-comments](https://github.com/kantord/eslint-plugin-write-good-comments) */
128
- 'write-good-comments': true,
129
- };
130
-
131
- const OPTIONAL_PLUGINS = {
132
- /** @see [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) */
133
- node: false,
134
-
135
- /** @see [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) */
136
- security: false,
137
- };
138
-
139
- const CODESTYLE_PLUGINS = {
140
- /** @see [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) */
141
- prettier: true,
142
- };
143
-
144
- const PLUGINS = {
145
- ...DEFAULT_PLUGINS,
146
- ...OPTIONAL_PLUGINS,
147
- ...CODESTYLE_PLUGINS,
148
- };
149
-
150
- /**
151
- * Create "extends" field
152
- *
153
- * @param {PLUGINS} plugins Enabled/disabled plugins list
154
- */
155
- const createPluginsList = (plugins = {}) => {
156
- const pluginsList = [];
157
-
158
- Object.entries({ ...PLUGINS, ...plugins })?.forEach(([name, isActive]) => {
159
- if (isActive) {
160
- pluginsList.push(require.resolve(`./plugins/${name}`));
161
- }
162
- });
163
-
164
- return pluginsList;
165
- };
166
-
167
- /**
168
- * Create eslint config
169
- *
170
- * @param {PLUGINS} plugins Enabled/disabled plugins list
171
- * @param {import('eslint-define-config').defineConfig} options Eslint options
172
- */
173
- const createConfig = (plugins = {}, options = {}) =>
174
- defineConfig({
175
- ...options,
176
-
177
- env: {
178
- browser: true,
179
- node: true,
180
-
181
- ...options.env,
182
- },
183
-
184
- extends: [
185
- /** @see [eslint-config-airbnb-base](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base) */
186
- 'airbnb-base',
187
-
188
- ...createPluginsList(plugins),
189
-
190
- ...(options.extends ?? []),
191
- ],
192
-
193
- ignorePatterns: [
194
- '.*',
195
- 'build',
196
- 'dist',
197
- 'docs',
198
- 'node_modules',
199
- 'storybook-*',
200
- 'sw.js',
201
- '!.*.js',
202
- '!.node',
203
- '!.storybook',
204
-
205
- ...(options.ignorePatterns ?? []),
206
- ],
207
-
208
- overrides: [
209
- {
210
- files: ['.*.cjs', '.*.js'],
211
-
212
- rules: {
213
- 'global-require': 'off',
214
- },
215
- },
216
- {
217
- files: ['**/store/**/*', '**/vuex/**/*', '**/pinia/**/*'],
218
-
219
- rules: {
220
- 'no-param-reassign': 'off',
221
- },
222
- },
223
-
224
- ...(options.overrides ?? []),
225
- ],
226
-
227
- parserOptions: {
228
- ecmaFeatures: { jsx: true },
229
- extraFileExtensions: ['.vue'],
230
- parser: '@typescript-eslint/parser',
231
- project: ['./tsconfig.json'],
232
-
233
- ...options.parserOptions,
234
- },
235
-
236
- root: options.root ?? true,
237
-
238
- rules: {
239
- 'class-methods-use-this': 'off',
240
- curly: 'error',
241
- 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
242
- 'grouped-accessor-pairs': ['error', 'getBeforeSet'],
243
- indent: 'off',
244
-
245
- 'lines-around-comment': [
246
- 'warn',
247
- {
248
- afterBlockComment: false,
249
- afterLineComment: false,
250
-
251
- allowArrayEnd: true,
252
- allowArrayStart: true,
253
-
254
- allowBlockEnd: true,
255
- allowBlockStart: true,
256
-
257
- allowClassEnd: true,
258
- allowClassStart: true,
259
-
260
- allowObjectEnd: true,
261
- allowObjectStart: true,
262
-
263
- beforeBlockComment: true,
264
- beforeLineComment: false,
265
- },
266
- ],
267
-
268
- 'no-console': 'warn',
269
-
270
- 'no-implicit-coercion': 'error',
271
-
272
- 'no-param-reassign': ['error', { props: false }],
273
-
274
- 'no-restricted-exports': [
275
- 'error',
276
- {
277
- restrictedNamedExports: [
278
- 'then', // this will cause tons of confusion when your module is dynamically `import()`ed, and will break in most node ESM versions
279
- ],
280
- },
281
- ],
282
-
283
- 'no-restricted-imports': [
284
- 'error',
285
- {
286
- patterns: [
287
- {
288
- group: ['.', '..', '*/..'],
289
- message: 'Use absolute path instead',
290
- },
291
- ],
292
- },
293
- ],
294
-
295
- 'no-return-await': 'off',
296
-
297
- 'no-shadow': 'off',
298
-
299
- 'no-underscore-dangle': 'off',
300
-
301
- 'no-unused-vars': 'off',
302
-
303
- // delegate to eslint-plugin-unused-imports
304
- 'no-use-before-define': 'off',
305
-
306
- 'nonblock-statement-body-position': ['error', 'below'],
307
-
308
- 'padding-line-between-statements': [
309
- 'warn',
310
- // always
311
- { blankLine: 'always', next: '*', prev: 'block-like' },
312
- { blankLine: 'always', next: '*', prev: 'case' },
313
- { blankLine: 'always', next: '*', prev: 'cjs-export' },
314
- { blankLine: 'always', next: '*', prev: 'cjs-import' },
315
- { blankLine: 'always', next: '*', prev: 'class' },
316
- { blankLine: 'always', next: '*', prev: 'default' },
317
- { blankLine: 'always', next: '*', prev: 'directive' },
318
- { blankLine: 'always', next: '*', prev: 'expression' },
319
- { blankLine: 'always', next: '*', prev: 'iife' },
320
- { blankLine: 'always', next: '*', prev: 'multiline-block-like' },
321
- { blankLine: 'always', next: '*', prev: 'multiline-const' },
322
- { blankLine: 'always', next: '*', prev: 'multiline-expression' },
323
- { blankLine: 'always', next: '*', prev: 'multiline-let' },
324
- { blankLine: 'always', next: '*', prev: 'multiline-var' },
325
- { blankLine: 'always', next: '*', prev: 'singleline-const' },
326
- { blankLine: 'always', next: '*', prev: 'singleline-let' },
327
- { blankLine: 'always', next: '*', prev: 'singleline-var' },
328
- { blankLine: 'always', next: 'block-like', prev: '*' },
329
- { blankLine: 'always', next: 'cjs-export', prev: '*' },
330
- { blankLine: 'always', next: 'cjs-import', prev: '*' },
331
- { blankLine: 'always', next: 'class', prev: '*' },
332
- { blankLine: 'always', next: 'expression', prev: '*' },
333
- { blankLine: 'always', next: 'function', prev: '*' },
334
- { blankLine: 'always', next: 'iife', prev: '*' },
335
- { blankLine: 'always', next: 'multiline-block-like', prev: '*' },
336
- { blankLine: 'always', next: 'multiline-const', prev: '*' },
337
- { blankLine: 'always', next: 'multiline-expression', prev: '*' },
338
- { blankLine: 'always', next: 'multiline-let', prev: '*' },
339
- { blankLine: 'always', next: 'multiline-var', prev: '*' },
340
- { blankLine: 'always', next: 'return', prev: '*' },
341
- { blankLine: 'always', next: 'switch', prev: '*' },
342
- // any
343
- { blankLine: 'any', next: 'expression', prev: 'expression' },
344
- {
345
- blankLine: 'any',
346
- next: 'singleline-const',
347
- prev: 'singleline-const',
348
- },
349
- { blankLine: 'any', next: 'singleline-let', prev: 'singleline-let' },
350
- { blankLine: 'any', next: 'singleline-var', prev: 'singleline-var' },
351
- // never
352
- { blankLine: 'never', next: 'cjs-export', prev: 'cjs-export' },
353
- { blankLine: 'never', next: 'cjs-import', prev: 'cjs-import' },
354
- { blankLine: 'never', next: 'directive', prev: 'directive' },
355
- ],
356
-
357
- quotes: ['error', 'single'],
358
- 'require-await': 'off',
359
-
360
- 'sort-imports': [
361
- 'warn',
362
- {
363
- allowSeparatedGroups: true,
364
- ignoreCase: true,
365
- ignoreDeclarationSort: true,
366
- ignoreMemberSort: false,
367
- memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
368
- },
369
- ],
370
-
371
- 'sort-keys': 'off', // delegate to sort-keys-fix
372
-
373
- 'sort-vars': 'warn',
374
-
375
- ...options.rules,
376
- },
377
- });
378
-
379
- module.exports = { createConfig, extendSpellChecker };
17
+ module.exports = { createConfig, extendSpellChecker, createFlatConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexlit/config-eslint",
3
- "version": "84.2.0",
3
+ "version": "84.3.0",
4
4
  "private": false,
5
5
  "description": "Eslint config",
6
6
  "keywords": [
@@ -37,6 +37,8 @@
37
37
  "up": "../../scripts/up.sh"
38
38
  },
39
39
  "dependencies": {
40
+ "@babel/eslint-parser": "^7.24.5",
41
+ "@eslint/eslintrc": "^3.1.0",
40
42
  "@intlify/eslint-plugin-vue-i18n": "^2.0.0",
41
43
  "@tanstack/eslint-plugin-query": "^5.35.6",
42
44
  "@typescript-eslint/eslint-plugin": "^7.9.0",
@@ -54,12 +56,12 @@
54
56
  "eslint-plugin-ext": "^0.1.0",
55
57
  "eslint-plugin-filenames": "^1.3.2",
56
58
  "eslint-plugin-import": "^2.29.1",
57
- "eslint-plugin-jsdoc": "^48.2.4",
59
+ "eslint-plugin-jsdoc": "^48.2.5",
58
60
  "eslint-plugin-jsx-a11y": "^6.8.0",
59
61
  "eslint-plugin-lit": "^1.13.0",
60
62
  "eslint-plugin-lit-a11y": "^4.1.2",
61
63
  "eslint-plugin-more": "^1.0.5",
62
- "eslint-plugin-no-await-in-promise": "^1.1.6",
64
+ "eslint-plugin-no-await-in-promise": "^2.0.0",
63
65
  "eslint-plugin-no-constructor-bind": "^2.0.4",
64
66
  "eslint-plugin-no-explicit-type-exports": "^0.12.1",
65
67
  "eslint-plugin-no-loops": "^0.3.0",
@@ -89,11 +91,11 @@
89
91
  "typescript": "^5.4.5"
90
92
  },
91
93
  "engines": {
92
- "node": ">=18"
94
+ "node": ">=18.18"
93
95
  },
94
96
  "overrides": {
95
97
  "eslint": "^8.57.0",
96
98
  "eslint-plugin-array-func": "^4.0.0",
97
99
  "eslint-plugin-vitest": "^0.5.4"
98
100
  }
99
- }
101
+ }
@@ -1,5 +1,5 @@
1
1
  module.exports = {
2
- extends: ['plugin:no-await-in-promise/recommended'],
2
+ extends: ['plugin:no-await-in-promise/recommended-legacy'],
3
3
 
4
- plugins: ['eslint-plugin-no-await-in-promise'],
4
+ plugins: ['no-await-in-promise'],
5
5
  };
@@ -0,0 +1,378 @@
1
+ /* eslint-disable sonarjs/no-duplicate-string, import/order, no-undef */
2
+
3
+ const { defineConfig } = require('eslint-define-config');
4
+
5
+ const DEFAULT_PLUGINS = {
6
+ /** @see [eslint-plugin-array-func](https://github.com/freaktechnik/eslint-plugin-array-func) */
7
+ 'array-func': true,
8
+
9
+ /** @see [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat) */
10
+ compat: true,
11
+
12
+ /** @see [eslint-plugin-decorator-position](https://github.com/NullVoxPopuli/eslint-plugin-decorator-position) */
13
+ 'decorator-position': true,
14
+
15
+ /** @see [eslint-plugin-eslint-comments](hhttps://github.com/mysticatea/eslint-plugin-eslint-comments) */
16
+ 'eslint-comments': true,
17
+
18
+ /** @see [eslint-plugin-etc](https://github.com/cartant/eslint-plugin-etc) */
19
+ etc: true,
20
+
21
+ /** @see [eslint-plugin-ext](https://github.com/jiangfengming/eslint-plugin-ext) */
22
+ ext: true,
23
+
24
+ /** @see [eslint-plugin-filenames](https://github.com/selaux/eslint-plugin-filenames) */
25
+ filenames: true,
26
+
27
+ /**
28
+ * @see [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import)
29
+ * @see [eslint-import-resolver-alias](https://github.com/johvin/eslint-import-resolver-alias)
30
+ */
31
+ import: true,
32
+
33
+ /** @see [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) */
34
+ jsdoc: true,
35
+
36
+ /** @see [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) */
37
+ 'jsx-a11y': true,
38
+
39
+ /** @see [eslint-plugin-lit](https://github.com/43081j/eslint-plugin-lit) */
40
+ lit: true,
41
+
42
+ /** @see [eslint-plugin-lit-a11y](https://www.npmjs.com/package/eslint-plugin-lit-a11y) */
43
+ 'lit-a11y': true,
44
+
45
+ /** @see [eslint-plugin-more](https://github.com/WebbyLab/eslint-plugin-more) */
46
+ more: true,
47
+
48
+ /** @see [eslint-plugin-no-await-in-promise](https://github.com/hugo-vrijswijk/eslint-plugin-no-await-in-promise/) */
49
+ 'no-await-in-promise': true,
50
+
51
+ /** @see [eslint-plugin-no-constructor-bind](https://github.com/markalfred/eslint-plugin-no-constructor-bind) */
52
+ 'no-constructor-bind': true,
53
+
54
+ /** @see [eslint-plugin-no-explicit-type-exports](https://github.com/intuit/eslint-plugin-no-explicit-type-exports) */
55
+ 'no-explicit-type-exports': true,
56
+
57
+ /** @see [eslint-plugin-no-loops](https://github.com/buildo/eslint-plugin-no-loops) */
58
+ 'no-loops': true,
59
+
60
+ /** @see [eslint-plugin-no-secrets](https://github.com/nickdeis/eslint-plugin-no-secrets) */
61
+ 'no-secrets': true,
62
+
63
+ /** @see [eslint-plugin-no-use-extend-native](https://github.com/dustinspecker/eslint-plugin-no-use-extend-native) */
64
+ 'no-use-extend-native': true,
65
+
66
+ /** @see [eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise) */
67
+ promise: true,
68
+
69
+ /** @see [eslint-plugin-regexp](https://github.com/ota-meshi/eslint-plugin-regexp) */
70
+ regexp: true,
71
+
72
+ /** @see [eslint-plugin-simple-import-sort](https://github.com/lydell/eslint-plugin-simple-import-sort) */
73
+ 'simple-import-sort': true,
74
+
75
+ /** @see [eslint-plugin-sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs) */
76
+ sonar: true,
77
+
78
+ /** @see [eslint-plugin-sort-class-members](https://github.com/bryanrsmith/eslint-plugin-sort-class-members) */
79
+ 'sort-class-members': true,
80
+
81
+ /** @see [eslint-plugin-sort-destructure-keys](https://github.com/mthadley/eslint-plugin-sort-destructure-keys) */
82
+ 'sort-destructure-keys': true,
83
+
84
+ /** @see [eslint-plugin-sort-keys-fix](https://github.com/leo-buneev/eslint-plugin-sort-keys-fix) */
85
+ 'sort-keys-fix': true,
86
+
87
+ /** @see [eslint-plugin-spellcheck](https://github.com/aotaduy/eslint-plugin-spellcheck) */
88
+ spellcheck: true,
89
+
90
+ /** @see [eslint-plugin-sql](https://github.com/gajus/eslint-plugin-sql) */
91
+ sql: true,
92
+
93
+ /** @see [@tanstack/query](https://tanstack.com/query/v4/docs/react/eslint/eslint-plugin-query) */
94
+ 'tanstack-query': true,
95
+
96
+ /** @see [eslint-plugin-testing-library](https://github.com/testing-library/eslint-plugin-testing-library) */
97
+ 'testing-library': true,
98
+
99
+ /** @see [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) */
100
+ typescript: true,
101
+
102
+ /** @see [eslint-plugin-typescript-sort-keys](https://github.com/infctr/eslint-plugin-typescript-sort-keys) */
103
+ 'typescript-sort-keys': true,
104
+
105
+ /** @see [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) */
106
+ unicorn: true,
107
+
108
+ /** @see [eslint-plugin-unused-imports](https://github.com/sweepline/eslint-plugin-unused-imports) */
109
+ 'unused-imports': true,
110
+
111
+ /** @see [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) */
112
+ vitest: true,
113
+
114
+ /** @see [eslint-plugin-vue](https://eslint.vuejs.org/rules/) */
115
+ vue: true,
116
+
117
+ /** @see [eslint-plugin-vue-i18n](https://eslint-plugin-vue-i18n.intlify.dev/) */
118
+ 'vue-i18n': true,
119
+
120
+ /** @see [eslint-plugin-vuejs-accessibility](https://github.com/vue-a11y/eslint-plugin-vuejs-accessibility) */
121
+ 'vuejs-accessibility': true,
122
+
123
+ /** @see [eslint-plugin-wc](https://github.com/43081j/eslint-plugin-wc) */
124
+ wc: true,
125
+
126
+ /** @see [eslint-plugin-write-good-comments](https://github.com/kantord/eslint-plugin-write-good-comments) */
127
+ 'write-good-comments': true,
128
+ };
129
+
130
+ const OPTIONAL_PLUGINS = {
131
+ /** @see [eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node) */
132
+ node: false,
133
+
134
+ /** @see [eslint-plugin-security](https://github.com/nodesecurity/eslint-plugin-security) */
135
+ security: false,
136
+ };
137
+
138
+ const CODESTYLE_PLUGINS = {
139
+ /** @see [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) */
140
+ prettier: true,
141
+ };
142
+
143
+ const PLUGINS = {
144
+ ...DEFAULT_PLUGINS,
145
+ ...OPTIONAL_PLUGINS,
146
+ ...CODESTYLE_PLUGINS,
147
+ };
148
+
149
+ /**
150
+ * Create "extends" field
151
+ *
152
+ * @param {PLUGINS} plugins Enabled/disabled plugins list
153
+ */
154
+ const createPluginsList = (plugins = {}) => {
155
+ const pluginsList = [];
156
+
157
+ Object.entries({ ...PLUGINS, ...plugins })?.forEach(([name, isActive]) => {
158
+ if (isActive) {
159
+ pluginsList.push(require.resolve(`../plugins/${name}`));
160
+ }
161
+ });
162
+
163
+ return pluginsList;
164
+ };
165
+
166
+ /**
167
+ * Create eslint config
168
+ *
169
+ * @param {PLUGINS} plugins Enabled/disabled plugins list
170
+ * @param {import('eslint-define-config').defineConfig} options Eslint options
171
+ */
172
+ const createConfig = (plugins = {}, options = {}) =>
173
+ defineConfig({
174
+ ...options,
175
+
176
+ env: {
177
+ browser: true,
178
+ node: true,
179
+
180
+ ...options.env,
181
+ },
182
+
183
+ extends: [
184
+ /** @see [eslint-config-airbnb-base](https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb-base) */
185
+ 'airbnb-base',
186
+
187
+ ...createPluginsList(plugins),
188
+
189
+ ...(options.extends ?? []),
190
+ ],
191
+
192
+ ignorePatterns: [
193
+ '.*',
194
+ 'build',
195
+ 'dist',
196
+ 'docs',
197
+ 'node_modules',
198
+ 'storybook-*',
199
+ 'sw.js',
200
+ '!.*.js',
201
+ '!.node',
202
+ '!.storybook',
203
+
204
+ ...(options.ignorePatterns ?? []),
205
+ ],
206
+
207
+ overrides: [
208
+ {
209
+ files: ['.*.cjs', '.*.js'],
210
+
211
+ rules: {
212
+ 'global-require': 'off',
213
+ },
214
+ },
215
+ {
216
+ files: ['**/store/**/*', '**/vuex/**/*', '**/pinia/**/*'],
217
+
218
+ rules: {
219
+ 'no-param-reassign': 'off',
220
+ },
221
+ },
222
+
223
+ ...(options.overrides ?? []),
224
+ ],
225
+
226
+ parserOptions: {
227
+ ecmaFeatures: { jsx: true },
228
+ extraFileExtensions: ['.vue'],
229
+ parser: '@typescript-eslint/parser',
230
+ project: ['./tsconfig.json'],
231
+
232
+ ...options.parserOptions,
233
+ },
234
+
235
+ root: options.root ?? true,
236
+
237
+ rules: {
238
+ 'class-methods-use-this': 'off',
239
+ curly: 'error',
240
+ 'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
241
+ 'grouped-accessor-pairs': ['error', 'getBeforeSet'],
242
+ indent: 'off',
243
+
244
+ 'lines-around-comment': [
245
+ 'warn',
246
+ {
247
+ afterBlockComment: false,
248
+ afterLineComment: false,
249
+
250
+ allowArrayEnd: true,
251
+ allowArrayStart: true,
252
+
253
+ allowBlockEnd: true,
254
+ allowBlockStart: true,
255
+
256
+ allowClassEnd: true,
257
+ allowClassStart: true,
258
+
259
+ allowObjectEnd: true,
260
+ allowObjectStart: true,
261
+
262
+ beforeBlockComment: true,
263
+ beforeLineComment: false,
264
+ },
265
+ ],
266
+
267
+ 'no-console': 'warn',
268
+
269
+ 'no-implicit-coercion': 'error',
270
+
271
+ 'no-param-reassign': ['error', { props: false }],
272
+
273
+ 'no-restricted-exports': [
274
+ 'error',
275
+ {
276
+ restrictedNamedExports: [
277
+ 'then', // this will cause tons of confusion when your module is dynamically `import()`ed, and will break in most node ESM versions
278
+ ],
279
+ },
280
+ ],
281
+
282
+ 'no-restricted-imports': [
283
+ 'error',
284
+ {
285
+ patterns: [
286
+ {
287
+ group: ['.', '..', '*/..'],
288
+ message: 'Use absolute path instead',
289
+ },
290
+ ],
291
+ },
292
+ ],
293
+
294
+ 'no-return-await': 'off',
295
+
296
+ 'no-shadow': 'off',
297
+
298
+ 'no-underscore-dangle': 'off',
299
+
300
+ 'no-unused-vars': 'off',
301
+
302
+ // delegate to eslint-plugin-unused-imports
303
+ 'no-use-before-define': 'off',
304
+
305
+ 'nonblock-statement-body-position': ['error', 'below'],
306
+
307
+ 'padding-line-between-statements': [
308
+ 'warn',
309
+ // always
310
+ { blankLine: 'always', next: '*', prev: 'block-like' },
311
+ { blankLine: 'always', next: '*', prev: 'case' },
312
+ { blankLine: 'always', next: '*', prev: 'cjs-export' },
313
+ { blankLine: 'always', next: '*', prev: 'cjs-import' },
314
+ { blankLine: 'always', next: '*', prev: 'class' },
315
+ { blankLine: 'always', next: '*', prev: 'default' },
316
+ { blankLine: 'always', next: '*', prev: 'directive' },
317
+ { blankLine: 'always', next: '*', prev: 'expression' },
318
+ { blankLine: 'always', next: '*', prev: 'iife' },
319
+ { blankLine: 'always', next: '*', prev: 'multiline-block-like' },
320
+ { blankLine: 'always', next: '*', prev: 'multiline-const' },
321
+ { blankLine: 'always', next: '*', prev: 'multiline-expression' },
322
+ { blankLine: 'always', next: '*', prev: 'multiline-let' },
323
+ { blankLine: 'always', next: '*', prev: 'multiline-var' },
324
+ { blankLine: 'always', next: '*', prev: 'singleline-const' },
325
+ { blankLine: 'always', next: '*', prev: 'singleline-let' },
326
+ { blankLine: 'always', next: '*', prev: 'singleline-var' },
327
+ { blankLine: 'always', next: 'block-like', prev: '*' },
328
+ { blankLine: 'always', next: 'cjs-export', prev: '*' },
329
+ { blankLine: 'always', next: 'cjs-import', prev: '*' },
330
+ { blankLine: 'always', next: 'class', prev: '*' },
331
+ { blankLine: 'always', next: 'expression', prev: '*' },
332
+ { blankLine: 'always', next: 'function', prev: '*' },
333
+ { blankLine: 'always', next: 'iife', prev: '*' },
334
+ { blankLine: 'always', next: 'multiline-block-like', prev: '*' },
335
+ { blankLine: 'always', next: 'multiline-const', prev: '*' },
336
+ { blankLine: 'always', next: 'multiline-expression', prev: '*' },
337
+ { blankLine: 'always', next: 'multiline-let', prev: '*' },
338
+ { blankLine: 'always', next: 'multiline-var', prev: '*' },
339
+ { blankLine: 'always', next: 'return', prev: '*' },
340
+ { blankLine: 'always', next: 'switch', prev: '*' },
341
+ // any
342
+ { blankLine: 'any', next: 'expression', prev: 'expression' },
343
+ {
344
+ blankLine: 'any',
345
+ next: 'singleline-const',
346
+ prev: 'singleline-const',
347
+ },
348
+ { blankLine: 'any', next: 'singleline-let', prev: 'singleline-let' },
349
+ { blankLine: 'any', next: 'singleline-var', prev: 'singleline-var' },
350
+ // never
351
+ { blankLine: 'never', next: 'cjs-export', prev: 'cjs-export' },
352
+ { blankLine: 'never', next: 'cjs-import', prev: 'cjs-import' },
353
+ { blankLine: 'never', next: 'directive', prev: 'directive' },
354
+ ],
355
+
356
+ quotes: ['error', 'single'],
357
+ 'require-await': 'off',
358
+
359
+ 'sort-imports': [
360
+ 'warn',
361
+ {
362
+ allowSeparatedGroups: true,
363
+ ignoreCase: true,
364
+ ignoreDeclarationSort: true,
365
+ ignoreMemberSort: false,
366
+ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
367
+ },
368
+ ],
369
+
370
+ 'sort-keys': 'off', // delegate to sort-keys-fix
371
+
372
+ 'sort-vars': 'warn',
373
+
374
+ ...options.rules,
375
+ },
376
+ });
377
+
378
+ module.exports = { createConfig };