@mikey-pro/eslint-config 9.0.7 → 10.0.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
@@ -26,7 +26,7 @@ export { default } from '@mikey-pro/eslint-config';
26
26
 
27
27
  ## Supported File Types
28
28
 
29
- JavaScript, TypeScript, JSON, YAML, TOML, HTML, CSS, SCSS
29
+ JavaScript, TypeScript, JSON, YAML, TOML, HTML, CSS, SCSS, Shell Scripts (.sh, .bash, .zsh), .env files
30
30
 
31
31
  ## Customization
32
32
 
package/base-config.js ADDED
@@ -0,0 +1,432 @@
1
+ // Base configuration for Mikey Pro ESLint
2
+ import js from '@eslint/js';
3
+ import html from '@html-eslint/eslint-plugin';
4
+ import htmlParser from '@html-eslint/parser';
5
+ import markdown from '@eslint/markdown';
6
+ import tsPlugin from '@typescript-eslint/eslint-plugin';
7
+ import tsParser from '@typescript-eslint/parser';
8
+ import boundaries from 'eslint-plugin-boundaries';
9
+ import compat from 'eslint-plugin-compat';
10
+ import cypress from 'eslint-plugin-cypress';
11
+ import importX from 'eslint-plugin-import-x';
12
+ import jest from 'eslint-plugin-jest';
13
+ import jestDom from 'eslint-plugin-jest-dom';
14
+ import jsonc from 'eslint-plugin-jsonc';
15
+ import nPlugin from 'eslint-plugin-n';
16
+ import noOnlyTests from 'eslint-plugin-no-only-tests';
17
+ import noSecrets from 'eslint-plugin-no-secrets';
18
+
19
+ import perfectionist from 'eslint-plugin-perfectionist';
20
+ import prettier from 'eslint-plugin-prettier';
21
+ import promise from 'eslint-plugin-promise';
22
+ import regexp from 'eslint-plugin-regexp';
23
+ import security from 'eslint-plugin-security';
24
+ import importSort from 'eslint-plugin-simple-import-sort';
25
+ import sonarjs from 'eslint-plugin-sonarjs';
26
+ import sortDestructureKeys from 'eslint-plugin-sort-destructure-keys';
27
+ import testingLibrary from 'eslint-plugin-testing-library';
28
+ import toml from 'eslint-plugin-toml';
29
+ import unicorn from 'eslint-plugin-unicorn';
30
+ import yml from 'eslint-plugin-yml';
31
+ import globals from 'globals';
32
+
33
+ // Global plugin registration — available to all config objects
34
+ // No `files` restriction so plugins are accessible everywhere
35
+ export const globalPlugins = {
36
+ plugins: {
37
+ '@html-eslint': html,
38
+ '@typescript-eslint': tsPlugin,
39
+ boundaries,
40
+ compat,
41
+ cypress,
42
+ 'import-x': importX,
43
+ jest,
44
+ 'jest-dom': jestDom,
45
+ jsonc,
46
+ markdown,
47
+ n: nPlugin,
48
+ 'no-only-tests': noOnlyTests,
49
+ 'no-secrets': noSecrets,
50
+ perfectionist,
51
+ prettier,
52
+ promise,
53
+ regexp,
54
+ security,
55
+ 'simple-import-sort': importSort,
56
+ sonarjs,
57
+ 'sort-destructure-keys': sortDestructureKeys,
58
+ 'testing-library': testingLibrary,
59
+ toml,
60
+ unicorn,
61
+ yml,
62
+ },
63
+ };
64
+
65
+ export const baseConfig = {
66
+ files: ['**/*.{js,jsx,ts,tsx,mjs,cjs}'],
67
+ languageOptions: {
68
+ ecmaVersion: 'latest',
69
+ globals: {
70
+ ...globals.browser,
71
+ ...globals.node,
72
+ ...globals.es2022,
73
+ },
74
+ sourceType: 'module',
75
+ },
76
+ linterOptions: {
77
+ noInlineConfig: true,
78
+ reportUnusedDisableDirectives: true,
79
+ },
80
+ rules: {
81
+ // Core ESLint rules
82
+ ...js.configs.recommended.rules,
83
+
84
+ // Core ESLint best practices
85
+ 'accessor-pairs': 'error',
86
+ 'array-callback-return': 'error',
87
+ 'block-scoped-var': 'error',
88
+ 'consistent-return': 'error',
89
+ curly: ['error', 'all'],
90
+ 'default-case': 'error',
91
+ 'default-case-last': 'error',
92
+ 'default-param-last': 'error',
93
+ 'dot-notation': 'warn',
94
+ eqeqeq: ['error', 'always', { null: 'ignore' }],
95
+ 'grouped-accessor-pairs': 'error',
96
+ 'guard-for-in': 'error',
97
+
98
+ // Import/Export rules
99
+ 'import-x/consistent-type-specifier-style': ['error', 'prefer-top-level'],
100
+ 'import-x/default': 'off',
101
+ 'import-x/export': 'error',
102
+ 'import-x/extensions': [
103
+ 'error',
104
+ 'ignorePackages',
105
+ { ts: 'never', tsx: 'never' },
106
+ ],
107
+ 'import-x/first': 'error',
108
+ 'import-x/named': 'off',
109
+ 'import-x/namespace': 'off',
110
+ 'import-x/newline-after-import': 'error',
111
+ 'import-x/no-absolute-path': 'error',
112
+ 'import-x/no-cycle': ['error', { ignoreExternal: true, maxDepth: 1 }],
113
+ 'import-x/no-duplicates': ['error', { 'prefer-inline': true }],
114
+ 'import-x/no-dynamic-require': 'error',
115
+ 'import-x/no-empty-named-blocks': 'error',
116
+ 'import-x/no-extraneous-dependencies': [
117
+ 'error',
118
+ {
119
+ devDependencies: [
120
+ '**/*.test.{js,ts}',
121
+ '**/*.spec.{js,ts}',
122
+ '**/test/**',
123
+ ],
124
+ },
125
+ ],
126
+ 'import-x/no-import-module-exports': 'error',
127
+ 'import-x/no-mutable-exports': 'error',
128
+ 'import-x/no-named-as-default-member': 'off',
129
+ 'import-x/no-named-default': 'error',
130
+ 'import-x/no-namespace': 'error',
131
+ 'import-x/no-relative-packages': 'error',
132
+ 'import-x/no-relative-parent-imports': [
133
+ 'error',
134
+ { ignore: ['@/components', '@/utils', '@/types'] },
135
+ ],
136
+ 'import-x/no-self-import': 'error',
137
+ 'import-x/no-unresolved': [
138
+ 'error',
139
+ { amd: true, commonjs: true, ignore: ['^node:'] },
140
+ ],
141
+ 'import-x/no-useless-path-segments': 'error',
142
+ 'import-x/no-webpack-loader-syntax': 'error',
143
+ 'import-x/order': [
144
+ 'error',
145
+ {
146
+ alphabetize: { order: 'asc' },
147
+ 'newlines-between': 'always',
148
+ pathGroups: [
149
+ {
150
+ group: 'builtin',
151
+ pattern: 'node:*',
152
+ position: 'before',
153
+ },
154
+ {
155
+ group: 'external',
156
+ pattern: '@*',
157
+ position: 'after',
158
+ },
159
+ {
160
+ group: 'internal',
161
+ pattern: '@/**',
162
+ position: 'after',
163
+ },
164
+ ],
165
+ pathGroupsExcludedImportTypes: ['builtin'],
166
+ },
167
+ ],
168
+ 'simple-import-sort/exports': 'error',
169
+ 'simple-import-sort/imports': 'error',
170
+
171
+ // Unicorn rules for modern JavaScript
172
+ ...unicorn.configs.all.rules,
173
+ // Compatibility rules
174
+ 'compat/compat': 'warn',
175
+
176
+ // Code quality rules
177
+ complexity: ['error', { max: 12 }],
178
+ 'max-classes-per-file': ['error', 1],
179
+ 'max-depth': ['error', 3],
180
+ 'max-lines': [
181
+ 'error',
182
+ { max: 300, skipBlankLines: true, skipComments: true },
183
+ ],
184
+ 'max-lines-per-function': [
185
+ 'error',
186
+ { max: 50, skipBlankLines: true, skipComments: true },
187
+ ],
188
+ 'max-params': ['error', 3],
189
+ // Node.js rules
190
+ 'n/no-unsupported-features/es-syntax': [
191
+ 'error',
192
+ {
193
+ ignores: ['modules', 'dynamicImport'],
194
+ version: '>=20.0.0',
195
+ },
196
+ ],
197
+
198
+ 'no-alert': 'warn',
199
+ 'no-array-constructor': 'error',
200
+ 'no-await-in-loop': 'warn',
201
+ 'no-bitwise': 'error',
202
+ 'no-caller': 'warn',
203
+ 'no-console': 'warn',
204
+ 'no-constant-binary-expression': 'error',
205
+ 'no-constant-condition': 'error',
206
+ 'no-constructor-return': 'error',
207
+ 'no-continue': 'error',
208
+ 'no-div-regex': 'error',
209
+ 'no-duplicate-imports': 'error',
210
+ 'no-else-return': 'warn',
211
+ 'no-empty': 'off',
212
+ 'no-empty-pattern': 'off',
213
+ 'no-eq-null': 'error',
214
+ 'no-eval': 'error',
215
+ 'no-extend-native': 'error',
216
+ 'no-extra-bind': 'warn',
217
+ 'no-floating-decimal': 'warn',
218
+ 'no-implicit-coercion': [
219
+ 'error',
220
+ { boolean: false, number: true, string: true },
221
+ ],
222
+ 'no-implicit-globals': 'error',
223
+ 'no-implied-eval': 'error',
224
+ 'no-iterator': 'warn',
225
+ 'no-lone-blocks': 'error',
226
+ 'no-lonely-if': 'warn',
227
+ 'no-loop-func': 'error',
228
+ 'no-multi-assign': 'error',
229
+ 'no-multi-str': 'warn',
230
+ 'no-nested-ternary': 'error',
231
+ 'no-new': 'error',
232
+ 'no-new-func': 'error',
233
+ 'no-new-object': 'error',
234
+ 'no-new-wrappers': 'warn',
235
+ 'no-octal-escape': 'error',
236
+ // Other quality rules
237
+ 'no-only-tests/no-only-tests': 'warn',
238
+ 'no-param-reassign': 'warn',
239
+ 'no-promise-executor-return': ['error', { allowVoid: true }],
240
+ 'no-proto': 'warn',
241
+ 'no-restricted-syntax': [
242
+ 'warn',
243
+ {
244
+ message:
245
+ 'for..in loops iterate over the entire prototype chain. Use Object.{keys,values,entries} instead.',
246
+ selector: 'ForInStatement',
247
+ },
248
+ {
249
+ message: 'Labels are a form of GOTO; using them makes code confusing.',
250
+ selector: 'LabeledStatement',
251
+ },
252
+ {
253
+ message: '`with` is disallowed in strict mode.',
254
+ selector: 'WithStatement',
255
+ },
256
+ {
257
+ message: 'Provide initialValue to reduce.',
258
+ selector:
259
+ "CallExpression[callee.property.name='reduce'][arguments.length<2]",
260
+ },
261
+ ],
262
+ 'no-return-assign': 'error',
263
+ 'no-return-await': 'error',
264
+ 'no-script-url': 'error',
265
+ 'no-secrets/no-secrets': ['warn', { tolerance: 4.5 }],
266
+ 'no-self-compare': 'error',
267
+ 'no-sequences': 'error',
268
+ 'no-template-curly-in-string': 'error',
269
+ 'no-throw-literal': 'error',
270
+ 'no-unmodified-loop-condition': 'error',
271
+ 'no-unreachable-loop': 'error',
272
+ 'no-unused-expressions': 'error',
273
+ 'no-unused-private-class-members': 'warn',
274
+ 'no-useless-call': 'warn',
275
+ 'no-useless-computed-key': 'warn',
276
+ 'no-useless-concat': 'warn',
277
+ 'no-useless-constructor': 'warn',
278
+ 'no-useless-escape': 'warn',
279
+ 'no-useless-rename': 'warn',
280
+ 'no-useless-return': 'warn',
281
+ 'no-var': 'error',
282
+ 'no-void': 'error',
283
+ 'no-warning-comments': 'warn',
284
+ 'no-with': 'warn',
285
+ 'object-shorthand': 'warn',
286
+ 'one-var': ['error', 'never'],
287
+ // Perfectionist rules for consistent ordering
288
+ 'perfectionist/sort-named-imports': [
289
+ 'error',
290
+ {
291
+ ignoreCase: true,
292
+ order: 'asc',
293
+ type: 'natural',
294
+ },
295
+ ],
296
+ 'perfectionist/sort-objects': [
297
+ 'error',
298
+ {
299
+ order: 'asc',
300
+ type: 'natural',
301
+ },
302
+ ],
303
+ 'prefer-arrow-callback': 'warn',
304
+ 'prefer-const': 'warn',
305
+ 'prefer-destructuring': ['warn', { array: false, object: true }],
306
+ 'prefer-exponentiation-operator': 'error',
307
+ 'prefer-object-has-own': 'error',
308
+ 'prefer-rest-params': 'warn',
309
+ 'prefer-spread': 'warn',
310
+ 'prefer-template': 'warn',
311
+ // Prettier integration
312
+ 'prettier/prettier': [
313
+ 'warn',
314
+ {
315
+ endOfLine: 'lf',
316
+ parser: 'babel',
317
+ singleQuote: true,
318
+ trailingComma: 'all',
319
+ },
320
+ ],
321
+ // Promise rules
322
+ 'promise/always-return': 'warn',
323
+ 'promise/catch-or-return': 'warn',
324
+ 'promise/no-callback-in-promise': 'warn',
325
+ 'promise/no-multiple-resolved': 'error',
326
+ 'promise/no-nesting': 'warn',
327
+ 'promise/no-new-statics': 'error',
328
+ 'promise/no-promise-in-callback': 'warn',
329
+ 'promise/no-return-in-finally': 'warn',
330
+ 'promise/no-return-wrap': 'warn',
331
+ 'promise/param-names': 'warn',
332
+ 'promise/prefer-await-to-callbacks': 'warn',
333
+ 'promise/prefer-await-to-then': 'warn',
334
+ 'promise/valid-params': 'warn',
335
+ radix: 'warn',
336
+ 'regexp/no-missing-g-flag': 'error',
337
+ 'regexp/no-useless-flag': 'error',
338
+ 'regexp/prefer-d': 'error',
339
+ 'regexp/prefer-plus-quantifier': 'error',
340
+ 'regexp/prefer-question-quantifier': 'error',
341
+ 'regexp/prefer-star-quantifier': 'error',
342
+ 'require-atomic-updates': ['error', { allowProperties: false }],
343
+ 'require-unicode-regexp': 'error',
344
+ // Security rules
345
+ 'security/detect-buffer-noassert': 'error',
346
+ 'security/detect-child-process': 'warn',
347
+ 'security/detect-disable-mustache-escape': 'error',
348
+ 'security/detect-eval-with-expression': 'error',
349
+ 'security/detect-new-buffer': 'error',
350
+ 'security/detect-no-csrf-before-method-override': 'error',
351
+ 'security/detect-non-literal-fs-filename': 'error',
352
+ 'security/detect-non-literal-regexp': 'error',
353
+ 'security/detect-non-literal-require': 'error',
354
+ 'security/detect-object-injection': 'warn',
355
+ 'security/detect-possible-timing-attacks': 'error',
356
+ 'security/detect-pseudoRandomBytes': 'error',
357
+ 'security/detect-unsafe-regex': 'error',
358
+ 'sonarjs/cognitive-complexity': ['warn', 12],
359
+ 'sonarjs/max-switch-cases': ['warn', 10],
360
+ 'sonarjs/no-all-duplicated-branches': 'warn',
361
+ 'sonarjs/no-collapsible-if': 'warn',
362
+ 'sonarjs/no-collection-size-mischeck': 'warn',
363
+ 'sonarjs/no-duplicate-string': ['warn', { threshold: 5 }],
364
+ 'sonarjs/no-duplicated-branches': 'warn',
365
+ 'sonarjs/no-identical-conditions': 'warn',
366
+ 'sonarjs/no-identical-expressions': 'warn',
367
+ 'sonarjs/no-inverted-boolean-check': 'warn',
368
+ 'sonarjs/no-nested-switch': 'warn',
369
+ 'sonarjs/no-nested-template-literals': 'warn',
370
+ 'sonarjs/no-redundant-boolean': 'warn',
371
+ 'sonarjs/no-redundant-jump': 'warn',
372
+ 'sonarjs/no-small-switch': 'warn',
373
+ 'sonarjs/no-unused-collection': 'warn',
374
+ 'sonarjs/no-use-of-empty-return-value': 'warn',
375
+ 'sonarjs/no-useless-catch': 'warn',
376
+ 'sonarjs/prefer-immediate-return': 'warn',
377
+ 'sonarjs/prefer-object-literal': 'warn',
378
+ 'sonarjs/prefer-single-boolean-return': 'warn',
379
+ 'sonarjs/prefer-while': 'warn',
380
+ 'sort-destructure-keys/sort-destructure-keys': 'warn',
381
+ 'sort-imports': 'off',
382
+
383
+ 'sort-vars': 'warn',
384
+ 'spaced-comment': ['warn', 'always'],
385
+ strict: ['error', 'never'],
386
+ 'symbol-description': 'error',
387
+
388
+ 'unicorn/expiring-todo-comments': 'off',
389
+ 'unicorn/filename-case': [
390
+ 'error',
391
+ {
392
+ cases: { camelCase: true, pascalCase: true },
393
+ ignore: ['.*.md'],
394
+ },
395
+ ],
396
+ 'unicorn/no-array-callback-reference': 'off',
397
+ 'unicorn/no-useless-undefined': ['error', { checkArguments: true }],
398
+ 'unicorn/prefer-array-flat': ['error', { functions: ['flatten'] }],
399
+ 'unicorn/prefer-at': 'error',
400
+ 'unicorn/prefer-blob-reading-methods': 'error',
401
+ 'unicorn/prefer-string-replace-all': 'error',
402
+ 'unicorn/prefer-string-slice': 'error',
403
+ 'unicorn/prefer-type-error': 'error',
404
+ 'unicorn/prevent-abbreviations': [
405
+ 'warn',
406
+ {
407
+ allowList: { e2e: true, params: true, props: true, ref: true },
408
+ ignore: [/e2e/],
409
+ },
410
+ ],
411
+ 'unicorn/require-post-message-target-origin': 'error',
412
+
413
+ yoda: 'error',
414
+ },
415
+ settings: {
416
+ 'import-x/extensions': ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'],
417
+ 'import-x/parsers': {
418
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.mts', '.cts'],
419
+ },
420
+ 'import-x/resolver': {
421
+ node: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'] },
422
+ },
423
+ jest: { version: 29 },
424
+ 'json/json-with-comments-files': [],
425
+ polyfills: [
426
+ 'Promise',
427
+ 'fetch',
428
+ 'URLSearchParams',
429
+ 'Array.prototype.includes',
430
+ ],
431
+ },
432
+ };
package/flat.js CHANGED
@@ -1,7 +1,8 @@
1
- // Modern ESLint 9 Flat Configuration for Mikey Pro
2
- // Ultimate coding style guide for excellence
1
+ // Modern ESLint 10 Flat Configuration for Mikey Pro
2
+ // Simplified flat config entry point
3
3
 
4
- import { baseConfig } from './base-config.js';
4
+ import { baseConfig, globalPlugins } from './base-config.js';
5
+ import { baseOverrides } from './overrides.js';
5
6
 
6
7
  export default [
7
8
  // Global ignores
@@ -30,7 +31,6 @@ export default [
30
31
  '*.psd',
31
32
  '*.ai',
32
33
  '*.ase',
33
- '*.sh',
34
34
  '*.bat',
35
35
  '*.cmd',
36
36
  'package-lock.json',
@@ -40,9 +40,16 @@ export default [
40
40
  'CNAME',
41
41
  '*.min.js',
42
42
  '*.min.css',
43
+ '**/*.npmrc',
43
44
  ],
44
45
  },
45
46
 
46
- // Base configuration
47
+ // Global plugin registration (available to all config objects)
48
+ globalPlugins,
49
+
50
+ // Base configuration for JS/TS files
47
51
  baseConfig,
52
+
53
+ // File-specific overrides
54
+ ...baseOverrides,
48
55
  ];
package/index.js CHANGED
@@ -1,52 +1,57 @@
1
- // Modern ESLint 9 configuration for Mikey Pro
2
- // This is the main entry point that exports the flat config
1
+ // Modern ESLint 10 configuration for Mikey Pro
2
+ // Ultimate coding style guide for excellence
3
3
 
4
- import { baseConfig } from './base-config.js';
4
+ import { baseConfig, globalPlugins } from './base-config.js';
5
5
  import { baseOverrides } from './overrides.js';
6
6
 
7
+ // Global ignores — files excluded from all linting
8
+ const globalIgnores = {
9
+ ignores: [
10
+ '**/dist/**/*',
11
+ '**/vendor/**/*',
12
+ '**/node_modules/**/*',
13
+ '**/coverage/**/*',
14
+ '**/.next/**/*',
15
+ '**/.nuxt/**/*',
16
+ '**/.output/**/*',
17
+ '**/.vite/**/*',
18
+ '**/build/**/*',
19
+ '**/out/**/*',
20
+ '*.properties',
21
+ '*.cclibs',
22
+ '*.svg',
23
+ '*.png',
24
+ '*.jpg',
25
+ '*.jpeg',
26
+ '*.gif',
27
+ '*.ico',
28
+ '*.webp',
29
+ '*.aco',
30
+ '*.psd',
31
+ '*.ai',
32
+ '*.ase',
33
+ '*.bat',
34
+ '*.cmd',
35
+ 'package-lock.json',
36
+ 'yarn.lock',
37
+ 'pnpm-lock.yaml',
38
+ 'LICENSE',
39
+ 'CNAME',
40
+ '*.min.js',
41
+ '*.min.css',
42
+ '**/*.npmrc',
43
+ ],
44
+ };
45
+
7
46
  // Export the modern flat configuration
8
47
  export default [
9
48
  // Global ignores
10
- {
11
- ignores: [
12
- '**/dist/**/*',
13
- '**/vendor/**/*',
14
- '**/node_modules/**/*',
15
- '**/coverage/**/*',
16
- '**/.next/**/*',
17
- '**/.nuxt/**/*',
18
- '**/.output/**/*',
19
- '**/.vite/**/*',
20
- '**/build/**/*',
21
- '**/out/**/*',
22
- '*.properties',
23
- '*.cclibs',
24
- '*.svg',
25
- '*.png',
26
- '*.jpg',
27
- '*.jpeg',
28
- '*.gif',
29
- '*.ico',
30
- '*.webp',
31
- '*.aco',
32
- '*.psd',
33
- '*.ai',
34
- '*.ase',
35
- '*.sh',
36
- '*.bat',
37
- '*.cmd',
38
- 'package-lock.json',
39
- 'yarn.lock',
40
- 'pnpm-lock.yaml',
41
- 'LICENSE',
42
- 'CNAME',
43
- '*.min.js',
44
- '*.min.css',
45
- '**/*.md', // Markdown files require special processor configuration
46
- ],
47
- },
49
+ globalIgnores,
50
+
51
+ // Global plugin registration (available to all config objects)
52
+ globalPlugins,
48
53
 
49
- // Base configuration
54
+ // Base configuration for JS/TS files
50
55
  baseConfig,
51
56
 
52
57
  // File-specific overrides
@@ -54,6 +59,5 @@ export default [
54
59
  ];
55
60
 
56
61
  // Export individual components for advanced usage
57
- export { baseConfig } from './base-config.js';
62
+ export { baseConfig, globalPlugins } from './base-config.js';
58
63
  export { baseOverrides } from './overrides.js';
59
- export { baseRules } from './rules.js';