@mikey-pro/eslint-config 9.0.7 → 9.0.8

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,334 @@
1
+ // Base configuration for Mikey Pro ESLint
2
+ import js from '@eslint/js';
3
+ import html from '@html-eslint/eslint-plugin';
4
+ import boundaries from 'eslint-plugin-boundaries';
5
+ import compat from 'eslint-plugin-compat';
6
+ import cssModules from 'eslint-plugin-css-modules';
7
+ import cypress from 'eslint-plugin-cypress';
8
+ import filenames from 'eslint-plugin-filenames';
9
+ import importPlugin from 'eslint-plugin-import';
10
+ import jest from 'eslint-plugin-jest';
11
+ import jestDom from 'eslint-plugin-jest-dom';
12
+ import jsonc from 'eslint-plugin-jsonc';
13
+ import markdownlint from 'eslint-plugin-markdownlint';
14
+ import markdown from '@eslint/markdown';
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
+ import onlyWarn from 'eslint-plugin-only-warn';
19
+ import optimizeRegex from 'eslint-plugin-optimize-regex';
20
+ import perfectionist from 'eslint-plugin-perfectionist';
21
+ import prettier from 'eslint-plugin-prettier';
22
+ import promise from 'eslint-plugin-promise';
23
+ import regexp from 'eslint-plugin-regexp';
24
+ import security from 'eslint-plugin-security';
25
+ import importSort from 'eslint-plugin-simple-import-sort';
26
+ import sonarjs from 'eslint-plugin-sonarjs';
27
+ import sortDestructureKeys from 'eslint-plugin-sort-destructure-keys';
28
+ import testingLibrary from 'eslint-plugin-testing-library';
29
+ import toml from 'eslint-plugin-toml';
30
+ import unicorn from 'eslint-plugin-unicorn';
31
+ import writeGoodComments from 'eslint-plugin-write-good-comments';
32
+ import yml from 'eslint-plugin-yml';
33
+ import globals from 'globals';
34
+
35
+ export const baseConfig = {
36
+ files: ['**/*.{js,jsx,ts,tsx,mjs,cjs}'],
37
+ languageOptions: {
38
+ ecmaVersion: 'latest',
39
+ globals: {
40
+ ...globals.browser,
41
+ ...globals.node,
42
+ ...globals.es2022,
43
+ },
44
+ sourceType: 'module',
45
+ },
46
+ linterOptions: {
47
+ noInlineConfig: true,
48
+ reportUnusedDisableDirectives: true,
49
+ },
50
+ plugins: {
51
+ boundaries,
52
+ compat,
53
+ 'css-modules': cssModules,
54
+ cypress,
55
+ filenames,
56
+ html,
57
+ import: importPlugin,
58
+ jest,
59
+ 'jest-dom': jestDom,
60
+ jsonc,
61
+ markdown,
62
+ markdownlint,
63
+ n: nPlugin,
64
+ 'no-only-tests': noOnlyTests,
65
+ 'no-secrets': noSecrets,
66
+ 'only-warn': onlyWarn,
67
+ 'optimize-regex': optimizeRegex,
68
+ perfectionist,
69
+ prettier,
70
+ promise,
71
+ regexp,
72
+ security,
73
+ 'simple-import-sort': importSort,
74
+ sonarjs,
75
+ 'sort-destructure-keys': sortDestructureKeys,
76
+ testing: testingLibrary,
77
+ toml,
78
+ unicorn,
79
+ 'write-good-comments': writeGoodComments,
80
+ yml,
81
+ },
82
+ rules: {
83
+ // Core ESLint rules
84
+ ...js.configs.recommended.rules,
85
+
86
+ // Import/Export rules
87
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
88
+ 'import/default': 'off',
89
+ 'import/extensions': [
90
+ 'error',
91
+ 'ignorePackages',
92
+ { ts: 'never', tsx: 'never' },
93
+ ],
94
+ 'import/first': 'error',
95
+ 'import/named': 'off',
96
+ 'import/namespace': 'off',
97
+ 'import/no-absolute-path': 'error',
98
+ 'import/no-cycle': ['error', { ignoreExternal: true, maxDepth: 1 }],
99
+ 'import/no-duplicates': ['error', { 'prefer-inline': true }],
100
+ 'import/no-dynamic-require': 'error',
101
+ 'import/no-empty-named-blocks': 'error',
102
+ 'import/no-extraneous-dependencies': [
103
+ 'error',
104
+ {
105
+ devDependencies: [
106
+ '**/*.test.{js,ts}',
107
+ '**/*.spec.{js,ts}',
108
+ '**/test/**',
109
+ ],
110
+ },
111
+ ],
112
+ 'import/no-import-module-exports': 'error',
113
+ 'import/no-named-as-default-member': 'off',
114
+ 'import/no-namespace': 'error',
115
+ 'import/no-relative-packages': 'error',
116
+ 'import/no-relative-parent-imports': [
117
+ 'error',
118
+ { ignore: ['@/components', '@/utils', '@/types'] },
119
+ ],
120
+ 'import/no-self-import': 'error',
121
+ 'import/no-unresolved': [
122
+ 'error',
123
+ { amd: true, commonjs: true, ignore: ['^node:'] },
124
+ ],
125
+ 'import/order': [
126
+ 'error',
127
+ {
128
+ alphabetize: { order: 'asc' },
129
+ 'newlines-between': 'always',
130
+ pathGroups: [
131
+ {
132
+ group: 'builtin',
133
+ pattern: 'node:*',
134
+ position: 'before',
135
+ },
136
+ {
137
+ group: 'external',
138
+ pattern: '@*',
139
+ position: 'after',
140
+ },
141
+ {
142
+ group: 'internal',
143
+ pattern: '@/**',
144
+ position: 'after',
145
+ },
146
+ ],
147
+ pathGroupsExcludedImportTypes: ['builtin'],
148
+ },
149
+ ],
150
+ 'simple-import-sort/exports': 'error',
151
+ 'simple-import-sort/imports': 'error',
152
+
153
+ // Unicorn rules for modern JavaScript
154
+ ...unicorn.configs.all.rules,
155
+ // Code quality rules
156
+ complexity: ['error', { max: 15 }],
157
+ 'max-classes-per-file': ['error', 1],
158
+ 'max-depth': ['error', 4],
159
+ 'max-lines': [
160
+ 'error',
161
+ { max: 500, skipBlankLines: true, skipComments: true },
162
+ ],
163
+ 'max-lines-per-function': [
164
+ 'error',
165
+ { max: 50, skipBlankLines: true, skipComments: true },
166
+ ],
167
+ 'max-params': ['error', 4],
168
+ 'no-array-constructor': 'error',
169
+ 'no-await-in-loop': 'warn',
170
+ 'no-caller': 'warn',
171
+ 'no-constant-binary-expression': 'error',
172
+ 'no-constant-condition': 'error',
173
+ 'no-constructor-return': 'error',
174
+
175
+ 'no-duplicate-imports': 'error',
176
+ 'no-else-return': 'warn',
177
+ 'no-empty': 'off',
178
+ 'no-empty-pattern': 'off',
179
+ 'no-eval': 'error',
180
+ 'no-extend-native': 'error',
181
+ 'no-extra-bind': 'warn',
182
+ 'no-floating-decimal': 'warn',
183
+
184
+ 'no-implicit-coercion': [
185
+ 'error',
186
+ { boolean: false, number: true, string: true },
187
+ ],
188
+ 'no-iterator': 'warn',
189
+ 'no-lonely-if': 'warn',
190
+ 'no-multi-str': 'warn',
191
+ 'no-new-object': 'error',
192
+ 'no-new-wrappers': 'warn',
193
+ 'no-octal-escape': 'error',
194
+ // Other quality rules
195
+ 'no-only-tests/no-only-tests': 'warn',
196
+ 'no-param-reassign': 'warn',
197
+ 'no-promise-executor-return': ['error', { allowVoid: true }],
198
+ 'no-proto': 'warn',
199
+ 'no-return-assign': 'error',
200
+ 'no-return-await': 'error',
201
+ 'no-secrets/no-secrets': ['warn', { tolerance: 4.5 }],
202
+ 'no-self-compare': 'error',
203
+ 'no-sequences': 'error',
204
+ 'no-throw-literal': 'error',
205
+ 'no-unmodified-loop-condition': 'error',
206
+ 'no-unreachable-loop': 'error',
207
+ 'no-unused-expressions': 'error',
208
+ 'no-unused-private-class-members': 'warn',
209
+ 'no-useless-call': 'warn',
210
+ 'no-useless-computed-key': 'warn',
211
+ 'no-useless-concat': 'warn',
212
+ 'no-useless-constructor': 'warn',
213
+ 'no-useless-escape': 'warn',
214
+ 'no-useless-rename': 'warn',
215
+ 'no-useless-return': 'warn',
216
+ 'no-var': 'error',
217
+ 'no-void': 'error',
218
+ 'no-with': 'warn',
219
+ 'optimize-regex/optimize-regex': 'warn',
220
+ // Perfectionist rules for consistent ordering
221
+ 'perfectionist/sort-named-imports': [
222
+ 'error',
223
+ {
224
+ ignoreCase: true,
225
+ order: 'asc',
226
+ type: 'natural',
227
+ },
228
+ ],
229
+ 'perfectionist/sort-objects': [
230
+ 'error',
231
+ {
232
+ order: 'asc',
233
+ type: 'natural',
234
+ },
235
+ ],
236
+ 'prefer-arrow-callback': 'warn',
237
+ 'prefer-const': 'warn',
238
+ 'prefer-destructuring': ['warn', { array: false, object: true }],
239
+ 'prefer-exponentiation-operator': 'error',
240
+ 'prefer-object-has-own': 'error',
241
+ 'prefer-rest-params': 'warn',
242
+ 'prefer-spread': 'warn',
243
+ 'prefer-template': 'warn',
244
+ // Prettier integration
245
+ 'prettier/prettier': [
246
+ 'warn',
247
+ {
248
+ endOfLine: 'lf',
249
+ parser: 'babel',
250
+ singleQuote: true,
251
+ trailingComma: 'all',
252
+ },
253
+ ],
254
+ // Promise rules
255
+ 'promise/always-return': 'warn',
256
+ 'promise/catch-or-return': 'warn',
257
+ 'promise/no-multiple-resolved': 'error',
258
+ 'promise/no-nesting': 'warn',
259
+ 'promise/no-return-wrap': 'warn',
260
+ 'promise/param-names': 'warn',
261
+ 'promise/prefer-await-to-callbacks': 'warn',
262
+ 'promise/prefer-await-to-then': 'warn',
263
+ radix: 'warn',
264
+ 'regexp/no-missing-g-flag': 'error',
265
+ 'require-atomic-updates': ['error', { allowProperties: false }],
266
+ // Security rules
267
+ 'security/detect-buffer-noassert': 'error',
268
+ 'security/detect-child-process': 'warn',
269
+ 'security/detect-disable-mustache-escape': 'error',
270
+ 'security/detect-non-literal-fs-filename': 'error',
271
+ 'security/detect-non-literal-regexp': 'error',
272
+ 'security/detect-non-literal-require': 'error',
273
+ 'security/detect-possible-timing-attacks': 'error',
274
+ 'security/detect-unsafe-regex': 'error',
275
+ 'sonarjs/cognitive-complexity': ['warn', 15],
276
+
277
+ 'sonarjs/max-switch-cases': ['warn', 10],
278
+ 'sonarjs/no-duplicate-string': ['warn', { threshold: 5 }],
279
+ 'sonarjs/no-duplicated-branches': 'warn',
280
+ 'sonarjs/no-redundant-boolean': 'warn',
281
+ 'sonarjs/no-small-switch': 'warn',
282
+ 'sonarjs/prefer-immediate-return': 'warn',
283
+ 'sort-destructure-keys/sort-destructure-keys': 'warn',
284
+ 'sort-imports': 'off',
285
+
286
+ 'sort-vars': 'warn',
287
+ strict: ['error', 'never'],
288
+
289
+ 'unicorn/expiring-todo-comments': 'off',
290
+ 'unicorn/filename-case': [
291
+ 'error',
292
+ {
293
+ cases: { camelCase: true, pascalCase: true },
294
+ ignore: ['.*.md'],
295
+ },
296
+ ],
297
+ 'unicorn/no-array-callback-reference': 'off',
298
+ 'unicorn/no-useless-undefined': ['error', { checkArguments: true }],
299
+ 'unicorn/prefer-array-flat': ['error', { functions: ['flatten'] }],
300
+ 'unicorn/prefer-at': 'error',
301
+ 'unicorn/prefer-blob-reading-methods': 'error',
302
+ 'unicorn/prefer-string-replace-all': 'error',
303
+ 'unicorn/prefer-string-slice': 'error',
304
+ 'unicorn/prefer-type-error': 'error',
305
+ 'unicorn/prevent-abbreviations': [
306
+ 'warn',
307
+ {
308
+ allowList: { e2e: true, params: true, props: true, ref: true },
309
+ ignore: [/e2e/],
310
+ },
311
+ ],
312
+ 'unicorn/require-post-message-target-origin': 'error',
313
+ 'write-good-comments/write-good-comments': 'warn',
314
+
315
+ yoda: 'error',
316
+ },
317
+ settings: {
318
+ 'import/extensions': ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'],
319
+ 'import/parsers': {
320
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.mts', '.cts'],
321
+ },
322
+ 'import/resolver': {
323
+ node: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'] },
324
+ },
325
+ jest: { version: 29 },
326
+ 'json/json-with-comments-files': [],
327
+ polyfills: [
328
+ 'Promise',
329
+ 'fetch',
330
+ 'URLSearchParams',
331
+ 'Array.prototype.includes',
332
+ ],
333
+ },
334
+ };
package/flat.js CHANGED
@@ -30,7 +30,6 @@ export default [
30
30
  '*.psd',
31
31
  '*.ai',
32
32
  '*.ase',
33
- '*.sh',
34
33
  '*.bat',
35
34
  '*.cmd',
36
35
  'package-lock.json',
package/index.js CHANGED
@@ -32,7 +32,6 @@ export default [
32
32
  '*.psd',
33
33
  '*.ai',
34
34
  '*.ase',
35
- '*.sh',
36
35
  '*.bat',
37
36
  '*.cmd',
38
37
  'package-lock.json',
package/overrides.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // Modern overrides for different file types and frameworks
2
2
  import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
3
 
5
4
  import html from '@html-eslint/eslint-plugin';
6
5
  import htmlParser from '@html-eslint/parser';
@@ -9,8 +8,8 @@ import tsParser from '@typescript-eslint/parser';
9
8
  import cypress from 'eslint-plugin-cypress';
10
9
  import importPlugin from 'eslint-plugin-import';
11
10
  import jest from 'eslint-plugin-jest';
12
- import markdownlint from 'eslint-plugin-markdownlint';
13
11
  import prettier from 'eslint-plugin-prettier';
12
+ import shell, { parserPlain } from 'eslint-plugin-shell';
14
13
  import yml from 'eslint-plugin-yml';
15
14
  import jsoncParser from 'jsonc-eslint-parser';
16
15
  import tomlParser from 'toml-eslint-parser';
@@ -405,6 +404,39 @@ export const cypressConfig = {
405
404
  },
406
405
  };
407
406
 
407
+ // Shell scripts (bash, sh, zsh)
408
+ export const shellConfig = {
409
+ files: ['**/*.sh', '**/*.bash', '**/*.zsh'],
410
+ languageOptions: {
411
+ parser: parserPlain,
412
+ },
413
+ plugins: {
414
+ shell,
415
+ },
416
+ rules: {
417
+ // Basic shell script linting rules
418
+ // Note: Full shell script linting may require shellcheck (external tool)
419
+ 'shell/shell': 'warn',
420
+ },
421
+ };
422
+
423
+ // .env files
424
+ export const envFilesConfig = {
425
+ files: ['**/.env', '**/.env.*', '**/*.env'],
426
+ languageOptions: {
427
+ parser: parserPlain,
428
+ },
429
+ plugins: {
430
+ shell,
431
+ },
432
+ rules: {
433
+ // Relax JavaScript-specific variable rules for .env files
434
+ // Note: .env formatting and validation should be handled by external tools
435
+ 'no-undef': 'off',
436
+ 'no-unused-vars': 'off',
437
+ },
438
+ };
439
+
408
440
  // Export all overrides
409
441
  export const baseOverrides = [
410
442
  ts,
@@ -421,4 +453,6 @@ export const baseOverrides = [
421
453
  jestJs,
422
454
  jestTs,
423
455
  cypressConfig,
456
+ shellConfig,
457
+ envFilesConfig,
424
458
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikey-pro/eslint-config",
3
- "version": "9.0.7",
3
+ "version": "9.0.8",
4
4
  "description": "Mikey Pro ESLint configuration - Ultimate coding style guide for excellence",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -39,6 +39,7 @@
39
39
  "eslint-plugin-promise": "^7.2.1",
40
40
  "eslint-plugin-regexp": "^2.10.0",
41
41
  "eslint-plugin-security": "^3.0.1",
42
+ "eslint-plugin-shell": "^0.0.1",
42
43
  "eslint-plugin-simple-import-sort": "^12.1.1",
43
44
  "eslint-plugin-sonarjs": "^3.0.5",
44
45
  "eslint-plugin-sort-destructure-keys": "^2.0.0",
@@ -68,6 +69,7 @@
68
69
  },
69
70
  "files": [
70
71
  "index.js",
72
+ "base-config.js",
71
73
  "flat.js",
72
74
  "rules.js",
73
75
  "overrides.js",