@mikey-pro/eslint-config 7.5.3 → 8.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.
Files changed (5) hide show
  1. package/index.d.ts +7 -0
  2. package/index.js +142 -70
  3. package/overrides.js +162 -49
  4. package/package.json +85 -27
  5. package/rules.js +238 -5
package/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { Linter } from 'eslint';
2
+
3
+ declare const config: Linter.Config[];
4
+ export default config;
5
+
6
+ export const baseRules: Linter.RulesRecord;
7
+ export const baseOverrides: Linter.ConfigOverride[];
package/index.js CHANGED
@@ -1,75 +1,147 @@
1
- const overrides = require('./overrides');
2
- const rules = require('./rules');
1
+ import babelParser from '@babel/eslint-parser';
2
+ import cypressJson from '@cypress/json';
3
+ import eslintJs from '@eslint/js';
4
+ import compatPlugin from 'eslint-plugin-compat';
5
+ import cssModules from 'eslint-plugin-css-modules';
6
+ import disableAutofix from 'eslint-plugin-disable-autofix';
7
+ import importPlugin from 'eslint-plugin-import';
8
+ import importRecommended from 'eslint-plugin-import/config/recommended';
9
+ import onlyWarn from 'eslint-plugin-only-warn';
10
+ import prettier from 'eslint-plugin-prettier';
11
+ import prettierRecommended from 'eslint-plugin-prettier/config/recommended';
12
+ import unicorn from 'eslint-plugin-unicorn';
13
+ import globals from 'globals';
14
+ import securityPlugin from 'eslint-plugin-security';
15
+ import promisePlugin from 'eslint-plugin-promise';
16
+ import importSortPlugin from 'eslint-plugin-simple-import-sort';
17
+ import perfectionistPlugin from 'eslint-plugin-perfectionist';
18
+ import noSecretsPlugin from 'eslint-plugin-no-secrets';
19
+ import noOnlyTestsPlugin from 'eslint-plugin-no-only-tests';
3
20
 
4
- module.exports = {
5
- env: {
6
- browser: true,
7
- commonjs: true,
8
- es2022: true,
9
- es6: true,
10
- node: true,
21
+ import { baseOverrides } from './overrides';
22
+ import { baseRules } from './rules';
23
+
24
+ /** @type {import('eslint').Linter.Config[]} */
25
+ const config = [
26
+ {
27
+ ignores: [
28
+ '**/dist/**/*',
29
+ '**/vendor/**/*',
30
+ '*.properties',
31
+ '*.cclibs',
32
+ '*.svg',
33
+ '*.png',
34
+ '*.aco',
35
+ '*.psd',
36
+ '*.ai',
37
+ '*.ase',
38
+ '*.sh',
39
+ '*.ico',
40
+ 'package-lock.json',
41
+ 'LICENSE',
42
+ 'CNAME',
43
+ ],
11
44
  },
12
- extends: [
13
- 'eslint:recommended',
14
- 'plugin:unicorn/all',
15
- 'plugin:compat/recommended',
16
- 'plugin:css-modules/recommended',
17
- 'plugin:import/recommended',
18
- 'plugin:prettier/recommended',
19
- ],
20
- ignorePatterns: [
21
- '**/dist/**/*',
22
- '**/vendor/**/*',
23
- '*.properties',
24
- '*.cclibs',
25
- '*.svg',
26
- '*.png',
27
- '*.aco',
28
- '*.psd',
29
- '*.ai',
30
- '*.ase',
31
- '*.sh',
32
- '*.ico',
33
- 'package-lock.json',
34
- 'LICENSE',
35
- 'CNAME',
36
- ],
37
- overrides: [...overrides.base],
38
- parser: '@babel/eslint-parser',
39
- parserOptions: {
40
- babelOptions: {
41
- presets: [
42
- [
43
- '@babel/preset-env',
44
- {
45
- targets: {
46
- node: 'current',
47
- },
48
- },
49
- ],
50
- ],
45
+ eslintJs.configs.recommended,
46
+ {
47
+ languageOptions: {
48
+ ecmaVersion: 'latest',
49
+ sourceType: 'module',
50
+ parser: babelParser,
51
+ parserOptions: {
52
+ babelOptions: {
53
+ presets: [
54
+ [
55
+ '@babel/preset-env',
56
+ {
57
+ targets: {
58
+ node: 'current',
59
+ },
60
+ },
61
+ ],
62
+ ],
63
+ },
64
+ requireConfigFile: false,
65
+ },
66
+ globals: {
67
+ ...globals.browser,
68
+ ...globals.commonjs,
69
+ ...globals.es2022,
70
+ ...globals.es6,
71
+ ...globals.node
72
+ },
51
73
  },
52
- ecmaVersion: 'latest',
53
- requireConfigFile: false,
54
- sourceType: 'module',
55
- },
56
- plugins: [
57
- 'prettier',
58
- 'css-modules',
59
- 'disable-autofix',
60
- '@babel',
61
- 'unicorn',
62
- 'only-warn',
63
- '@cypress/json',
64
- 'import',
65
- ],
66
- root: true,
67
- rules,
68
- settings: {
69
- 'json/json-with-comments-files': [],
70
- polyfills: ['Promise'],
71
- jest: {
72
- version: 29,
74
+ plugins: {
75
+ prettier,
76
+ unicorn,
77
+ 'css-modules': cssModules,
78
+ 'disable-autofix': disableAutofix,
79
+ 'only-warn': onlyWarn,
80
+ '@cypress/json': cypressJson,
81
+ import: importPlugin,
82
+ security: securityPlugin,
83
+ promise: promisePlugin,
84
+ 'simple-import-sort': importSortPlugin,
85
+ perfectionist: perfectionistPlugin,
86
+ 'no-secrets': noSecretsPlugin,
87
+ 'no-only-tests': noOnlyTestsPlugin,
88
+ },
89
+ rules: {
90
+ ...baseRules,
91
+ ...unicorn.configs.all.rules,
92
+ ...compatPlugin.configs.recommended.rules,
93
+ ...cssModules.configs.recommended.rules,
94
+ ...importRecommended.rules,
95
+ ...prettierRecommended.rules,
96
+ // Security
97
+ 'security/detect-object-injection': 'warn',
98
+ 'security/detect-possible-timing-attacks': 'warn',
99
+ 'security/detect-non-literal-regexp': 'warn',
100
+
101
+ // Promises
102
+ 'promise/always-return': 'warn',
103
+ 'promise/no-return-wrap': 'warn',
104
+ 'promise/param-names': 'error',
105
+ 'promise/catch-or-return': 'warn',
106
+
107
+ // Better import sorting
108
+ 'simple-import-sort/imports': 'warn',
109
+ 'simple-import-sort/exports': 'warn',
110
+
111
+ // Better code organization
112
+ 'perfectionist/sort-objects': ['warn', {
113
+ type: 'natural',
114
+ order: 'asc',
115
+ }],
116
+ 'perfectionist/sort-named-imports': 'warn',
117
+
118
+ // Security and testing
119
+ 'no-secrets/no-secrets': ['warn', { tolerance: 4.5 }],
120
+ 'no-only-tests/no-only-tests': 'warn',
121
+
122
+ // Enhanced import rules
123
+ 'import/no-cycle': 'warn',
124
+ 'import/no-useless-path-segments': 'warn',
125
+ 'import/no-anonymous-default-export': 'warn',
126
+ },
127
+ settings: {
128
+ 'json/json-with-comments-files': [],
129
+ polyfills: ['Promise', 'fetch', 'URLSearchParams'],
130
+ jest: {
131
+ version: 29,
132
+ },
133
+ 'import/parsers': {
134
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.mts', '.cts'],
135
+ },
73
136
  },
74
137
  },
75
- };
138
+ ...baseOverrides,
139
+ ];
140
+
141
+ export default config;
142
+ export { baseRules } from './rules.js';
143
+ export { baseOverrides } from './overrides.js';
144
+
145
+ if (typeof module !== 'undefined' && module.exports) {
146
+ module.exports = config;
147
+ }
package/overrides.js CHANGED
@@ -1,29 +1,40 @@
1
- const path = require('node:path');
1
+ import path from 'node:path';
2
+ import typescriptParser from '@typescript-eslint/parser';
3
+ import typeScriptPlugin from '@typescript-eslint/eslint-plugin';
4
+ import importPlugin from 'eslint-plugin-import';
5
+ import markdownPlugin from 'eslint-plugin-markdownlint';
2
6
 
3
7
  const ts = {
4
8
  files: ['*.ts', '*.tsx'],
5
- extends: [
6
- 'plugin:@typescript-eslint/all',
7
- 'plugin:@typescript-eslint/recommended-requiring-type-checking',
8
- 'plugin:import/typescript',
9
- ],
10
- parser: '@typescript-eslint/parser',
11
- parserOptions: {
12
- ecmaFeatures: {
13
- jsx: true,
9
+ languageOptions: {
10
+ parser: typescriptParser,
11
+ parserOptions: {
12
+ ecmaFeatures: {
13
+ jsx: true,
14
+ },
15
+ ecmaVersion: 'latest',
16
+ extraFileExtensions: ['.vue', '.svelte'],
17
+ sourceType: 'module',
18
+ project: 'tsconfig.json',
19
+ tsconfigRootDir: path.join(__dirname, '../../..'),
14
20
  },
15
- ecmaVersion: 'latest',
16
- extraFileExtensions: ['.vue', '.svelte'],
17
- sourceType: 'module',
18
- project: 'tsconfig.json',
19
- tsconfigRootDir: path.join(__dirname, '../../..'),
20
21
  },
21
- plugins: ['@typescript-eslint'],
22
+ plugins: {
23
+ '@typescript-eslint': typeScriptPlugin,
24
+ import: importPlugin,
25
+ },
22
26
  rules: {
27
+ ...typeScriptPlugin.configs.all.rules,
28
+ ...typeScriptPlugin.configs['recommended-requiring-type-checking'].rules,
29
+ ...importPlugin.configs.typescript.rules,
23
30
  '@typescript-eslint/class-methods-use-this': 'off',
24
31
  '@typescript-eslint/consistent-type-imports': [
25
- 'warn',
26
- { fixStyle: 'inline-type-imports' },
32
+ 'error',
33
+ {
34
+ prefer: 'type-imports',
35
+ fixStyle: 'separate-type-imports',
36
+ disallowTypeAnnotations: false,
37
+ },
27
38
  ],
28
39
  '@typescript-eslint/explicit-member-accessibility': [
29
40
  'warn',
@@ -62,7 +73,27 @@ const ts = {
62
73
  ],
63
74
  },
64
75
  ],
65
- '@typescript-eslint/naming-convention': 'off',
76
+ '@typescript-eslint/naming-convention': [
77
+ 'error',
78
+ {
79
+ selector: ['typeLike'],
80
+ format: ['PascalCase']
81
+ },
82
+ {
83
+ selector: ['typeParameter'],
84
+ format: ['PascalCase'],
85
+ prefix: ['T']
86
+ },
87
+ {
88
+ selector: ['interface'],
89
+ format: ['PascalCase'],
90
+ custom: {
91
+ regex: '^I[A-Z]',
92
+ match: false,
93
+ message: 'Interface name should not be prefixed with "I"'
94
+ }
95
+ }
96
+ ],
66
97
  '@typescript-eslint/no-extraneous-class': [
67
98
  'warn',
68
99
  {
@@ -75,18 +106,106 @@ const ts = {
75
106
  '@typescript-eslint/no-inferrable-types': 'off',
76
107
  '@typescript-eslint/no-magic-numbers': 'off',
77
108
  '@typescript-eslint/no-unnecessary-condition': 'off',
78
- '@typescript-eslint/parameter-properties': 'off',
109
+ '@typescript-eslint/parameter-properties': ['error', { prefer: 'parameter-property' }],
79
110
  '@typescript-eslint/prefer-nullish-coalescing': 'off',
80
111
  '@typescript-eslint/prefer-readonly': 'off',
81
112
  '@typescript-eslint/prefer-readonly-parameter-types': 'off',
82
113
  '@typescript-eslint/strict-boolean-expressions': 'off',
83
114
  '@typescript-eslint/unbound-method': 'off',
84
115
  '@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
116
+ '@typescript-eslint/consistent-type-assertions': [
117
+ 'error',
118
+ {
119
+ assertionStyle: 'as',
120
+ objectLiteralTypeAssertions: 'never',
121
+ },
122
+ ],
123
+ '@typescript-eslint/explicit-function-return-type': [
124
+ 'warn',
125
+ {
126
+ allowExpressions: true,
127
+ allowTypedFunctionExpressions: true,
128
+ },
129
+ ],
130
+ '@typescript-eslint/no-explicit-any': 'warn',
131
+ '@typescript-eslint/no-floating-promises': 'error',
132
+ '@typescript-eslint/no-for-in-array': 'error',
133
+ '@typescript-eslint/no-import-type-side-effects': 'error',
134
+ '@typescript-eslint/no-misused-promises': [
135
+ 'error',
136
+ {
137
+ checksVoidReturn: false,
138
+ },
139
+ ],
140
+ '@typescript-eslint/no-unnecessary-type-constraint': 'error',
141
+ '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
142
+ '@typescript-eslint/no-unnecessary-qualifier': 'error',
143
+ '@typescript-eslint/no-unsafe-declaration-merging': 'error',
144
+ '@typescript-eslint/no-unsafe-enum-comparison': 'error',
145
+ '@typescript-eslint/prefer-optional-chain': 'error',
146
+ '@typescript-eslint/prefer-reduce-type-parameter': 'error',
147
+ '@typescript-eslint/prefer-return-this-type': 'error',
148
+ 'deprecation/deprecation': 'warn',
85
149
  'prettier/prettier': ['warn', { parser: 'typescript' }],
150
+ '@typescript-eslint/consistent-indexed-object-style': ['error', 'record'],
151
+ '@typescript-eslint/consistent-generic-constructors': ['error', 'constructor'],
152
+ '@typescript-eslint/no-confusing-void-expression': [
153
+ 'error',
154
+ { ignoreArrowShorthand: true }
155
+ ],
156
+ '@typescript-eslint/prefer-return-this-type': 'error',
157
+ '@typescript-eslint/prefer-string-starts-ends-with': 'error',
158
+ '@typescript-eslint/promise-function-async': 'error',
159
+ '@typescript-eslint/require-array-sort-compare': [
160
+ 'error',
161
+ { ignoreStringArrays: true }
162
+ ],
163
+ '@typescript-eslint/strict-boolean-expressions': [
164
+ 'error',
165
+ {
166
+ allowString: false,
167
+ allowNumber: false,
168
+ allowNullableObject: false
169
+ }
170
+ ],
171
+ '@typescript-eslint/method-signature-style': ['error', 'property'],
172
+ '@typescript-eslint/prefer-enum-initializers': 'error',
173
+ '@typescript-eslint/prefer-literal-enum-member': 'error',
174
+ '@typescript-eslint/prefer-ts-expect-error': 'error',
175
+ '@typescript-eslint/sort-type-constituents': 'error',
176
+ '@typescript-eslint/switch-exhaustiveness-check': 'error',
177
+ '@typescript-eslint/prefer-optional-chain': ['error', {
178
+ checkAny: true,
179
+ checkUnknown: true,
180
+ checkString: true,
181
+ checkNumber: true,
182
+ checkBoolean: true,
183
+ checkBigInt: true
184
+ }],
185
+ '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
186
+ '@typescript-eslint/no-redundant-type-constituents': 'error',
187
+ '@typescript-eslint/no-unsafe-unary-minus': 'error',
188
+ '@typescript-eslint/no-useless-template-literals': 'error',
189
+ '@typescript-eslint/prefer-find': 'error',
190
+ '@typescript-eslint/consistent-type-exports': [
191
+ 'error',
192
+ { fixMixedExportsWithInlineTypeSpecifier: true }
193
+ ],
194
+ '@typescript-eslint/no-unnecessary-type-arguments': 'error',
195
+ '@typescript-eslint/no-unsafe-argument': 'error',
196
+ '@typescript-eslint/no-unsafe-member-access': 'error',
197
+ '@typescript-eslint/prefer-includes': 'error',
198
+ '@typescript-eslint/prefer-regexp-exec': 'error',
199
+ '@typescript-eslint/promise-function-async': ['error', {
200
+ checkArrowFunctions: true,
201
+ checkFunctionDeclarations: true,
202
+ checkFunctionExpressions: true,
203
+ checkMethodDeclarations: true
204
+ }]
86
205
  },
87
206
  settings: {
88
207
  'import/parsers': {
89
- '@typescript-eslint/parser': ['.ts', '.tsx'],
208
+ '@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'],
90
209
  },
91
210
  'import/resolver': {
92
211
  typescript: {
@@ -138,9 +257,14 @@ const toml = {
138
257
 
139
258
  const md = {
140
259
  files: ['*.md'],
141
- parser: 'eslint-plugin-markdownlint/parser',
142
- extends: ['plugin:markdownlint/recommended'],
260
+ languageOptions: {
261
+ parser: 'eslint-plugin-markdownlint/parser',
262
+ },
263
+ plugins: {
264
+ markdownlint: markdownPlugin,
265
+ },
143
266
  rules: {
267
+ ...markdownPlugin.configs.recommended.rules,
144
268
  'markdownlint/md033': 'off',
145
269
  'markdownlint/md041': 'off',
146
270
  'prettier/prettier': ['warn', { parser: 'markdown' }],
@@ -239,6 +363,12 @@ const jestJs = {
239
363
  rules: {
240
364
  'unicorn/no-array-callback-reference': 'off',
241
365
  'jest/unbound-method': 'off',
366
+ 'unicorn/prevent-abbreviations': [
367
+ 'warn',
368
+ {
369
+ ignore: [/e2e/],
370
+ }
371
+ ],
242
372
  },
243
373
  };
244
374
 
@@ -253,34 +383,23 @@ const jestTs = {
253
383
  rules: {
254
384
  'unicorn/no-array-callback-reference': 'off',
255
385
  'jest/unbound-method': 'off',
386
+ 'unicorn/prevent-abbreviations': [
387
+ 'warn',
388
+ {
389
+ ignore: [/e2e/],
390
+ }
391
+ ],
256
392
  },
257
393
  };
258
394
 
259
395
  const cypress = {
396
+ mdJson,
260
397
  files: ['*.cy.*'],
261
398
  plugins: ['cypress'],
262
399
  extends: ['plugin:cypress/recommended'],
263
400
  };
264
401
 
265
- const all = {
266
- ts,
267
- css,
268
- scss,
269
- less,
270
- yaml,
271
- toml,
272
- md,
273
- packageJson,
274
- mdJson,
275
- html,
276
- jsonc,
277
- json5,
278
- jestJs,
279
- jestTs,
280
- cypress,
281
- };
282
-
283
- const base = {
402
+ export const baseOverrides = [
284
403
  ts,
285
404
  css,
286
405
  scss,
@@ -296,10 +415,4 @@ const base = {
296
415
  jestJs,
297
416
  jestTs,
298
417
  cypress,
299
- };
300
-
301
- module.exports = {
302
- ...all,
303
- all: Object.values(all),
304
- base: Object.values(base),
305
- };
418
+ ];
package/package.json CHANGED
@@ -1,45 +1,91 @@
1
1
  {
2
2
  "name": "@mikey-pro/eslint-config",
3
- "version": "7.5.3",
3
+ "version": "8.0.1",
4
4
  "description": "Mikey Pro ESLint configuration",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "sideEffects": false,
6
8
  "dependencies": {
7
- "@babel/core": "^7.24.6",
8
- "@babel/eslint-parser": "^7.24",
9
- "@babel/eslint-plugin": "^7.24",
10
- "@babel/preset-env": "^7.24",
9
+ "@babel/core": "^7.26.7",
10
+ "@babel/eslint-parser": "^7.26.5",
11
+ "@babel/eslint-plugin": "^7.25",
12
+ "@babel/preset-env": "^7.26",
11
13
  "@cypress/eslint-plugin-json": "^3.2.3",
12
- "@html-eslint/eslint-plugin": "^0.24.1",
13
- "@html-eslint/parser": "^0.24.1",
14
- "@typescript-eslint/eslint-plugin": "^7.11.0",
15
- "@typescript-eslint/parser": "^7.11.0",
16
- "eslint-config-prettier": "^9.1",
17
- "eslint-import-resolver-typescript": "^3.6.1",
18
- "eslint-plugin-compat": "^4.2",
14
+ "@html-eslint/eslint-plugin": "^0.33.1",
15
+ "@html-eslint/parser": "^0.33.0",
16
+ "@typescript-eslint/eslint-plugin": "^8.22.0",
17
+ "@typescript-eslint/parser": "^8.22.0",
18
+ "eslint-config-prettier": "^10.0",
19
+ "eslint-import-resolver-typescript": "^3.7.0",
20
+ "eslint-plugin-compat": "^6.0",
19
21
  "eslint-plugin-css-modules": "^2.12",
20
- "eslint-plugin-cypress": "^3.3.0",
21
- "eslint-plugin-disable-autofix": "^5.0.0",
22
- "eslint-plugin-import": "^2.29.1",
23
- "eslint-plugin-jest": "^28.5.0",
24
- "eslint-plugin-jsonc": "^2.16.0",
22
+ "eslint-plugin-cypress": "^4.1.0",
23
+ "eslint-plugin-disable-autofix": "^5.0.1",
24
+ "eslint-plugin-import": "^2.31.0",
25
+ "eslint-plugin-jest": "^28.11.0",
26
+ "eslint-plugin-jsonc": "^2.19.1",
25
27
  "eslint-plugin-markdownlint": "^0.6.0",
26
- "eslint-plugin-n": "^17.7.0",
28
+ "eslint-plugin-n": "^17.15.1",
27
29
  "eslint-plugin-only-warn": "^1.1.0",
28
- "eslint-plugin-prettier": "^5.1",
29
- "eslint-plugin-promise": "^6.2.0",
30
- "eslint-plugin-toml": "^0.11.0",
31
- "eslint-plugin-unicorn": "^53.0.0",
32
- "eslint-plugin-yml": "^1.14.0",
33
- "postcss": "^8.4.38",
30
+ "eslint-plugin-perfectionist": "^4.7.0",
31
+ "eslint-plugin-no-secrets": "^2.1.1",
32
+ "eslint-plugin-no-only-tests": "^3.3.0",
33
+ "eslint-plugin-prettier": "^5.2",
34
+ "eslint-plugin-promise": "^7.2.1",
35
+ "eslint-plugin-security": "^3.0.1",
36
+ "eslint-plugin-simple-import-sort": "^12.1.1",
37
+ "eslint-plugin-toml": "^0.12.0",
38
+ "eslint-plugin-unicorn": "^56.0.1",
39
+ "eslint-plugin-yml": "^1.16.0",
40
+ "eslint-plugin-testing-library": "^7.1.1",
41
+ "eslint-plugin-jest-dom": "^5.5.0",
42
+ "eslint-plugin-deprecation": "^3.0.0",
43
+ "postcss": "^8.5.1",
34
44
  "postcss-scss": "^4.0.9",
35
- "yaml-eslint-parser": "^1.2.3"
45
+ "yaml-eslint-parser": "^1.2.3",
46
+ "eslint-plugin-sonarjs": "^3.0.1",
47
+ "eslint-plugin-regexp": "^2.7.0",
48
+ "eslint-plugin-etc": "^2.0.3",
49
+ "eslint-plugin-functional": "^8.0.0",
50
+ "eslint-plugin-typescript-sort-keys": "^3.3.0",
51
+ "eslint-plugin-sort-destructure-keys": "^2.0.0",
52
+ "eslint-plugin-write-good-comments": "^0.2.0",
53
+ "eslint-plugin-boundaries": "^5.0.1",
54
+ "eslint-plugin-immutable": "^1.0.0",
55
+ "eslint-plugin-radar": "^0.2.1",
56
+ "eslint-plugin-optimize-regex": "^1.2.1"
57
+ },
58
+ "peerDependencies": {
59
+ "eslint": "^8.57.0",
60
+ "typescript": "^5.3.0",
61
+ "prettier": "^3.2.0",
62
+ "@babel/core": "^7.24.0",
63
+ "@typescript-eslint/parser": "^7.0.0",
64
+ "eslint-plugin-import": "^2.31.0",
65
+ "eslint-plugin-n": "^17.0.0",
66
+ "eslint-plugin-prettier": "^5.0.0"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "typescript": {
70
+ "optional": true
71
+ },
72
+ "@typescript-eslint/parser": {
73
+ "optional": true
74
+ },
75
+ "eslint-plugin-import": {
76
+ "optional": false
77
+ },
78
+ "eslint-plugin-n": {
79
+ "optional": false
80
+ }
36
81
  },
37
82
  "files": [
38
83
  "index.js",
39
84
  "rules.js",
40
85
  "overrides.js",
41
86
  "README.md",
42
- "LICENSE"
87
+ "LICENSE",
88
+ "index.d.ts"
43
89
  ],
44
90
  "homepage": "https://github.com/chiefmikey/mikey-pro#readme",
45
91
  "repository": {
@@ -67,5 +113,17 @@
67
113
  "author": "Mikl Wolfe <wolfe@mikl.io> (https://mikl.io)",
68
114
  "browserslist": [
69
115
  "defaults"
70
- ]
116
+ ],
117
+ "type": "module",
118
+ "engines": {
119
+ "node": ">=18.0.0",
120
+ "npm": ">=9.0.0",
121
+ "pnpm": ">=8.0.0",
122
+ "yarn": ">=4.0.0"
123
+ },
124
+ "exports": {
125
+ ".": "./index.js",
126
+ "./rules": "./rules.js",
127
+ "./overrides": "./overrides.js"
128
+ }
71
129
  }
package/rules.js CHANGED
@@ -1,17 +1,25 @@
1
- module.exports = {
2
- camelcase: 'warn',
1
+ export const baseRules = {
2
+ camelcase: [
3
+ 'error',
4
+ {
5
+ properties: 'never',
6
+ ignoreDestructuring: true,
7
+ ignoreImports: true,
8
+ ignoreGlobals: true,
9
+ },
10
+ ],
3
11
  'class-methods-use-this': 'off',
4
12
  'constructor-super': 'warn',
5
13
  'dot-notation': 'warn',
6
14
  'func-names': 'off',
7
- 'import/extensions': ['warn', 'never', { ignorePackages: true }],
15
+ 'import/extensions': ['warn', 'ignorePackages', { ts: 'never' }],
8
16
  'import/no-commonjs': 'off',
9
17
  'import/default': 'off',
10
18
  'import/named': 'off',
11
19
  'import/namespace': 'off',
12
20
  'import/no-named-as-default-member': 'off',
13
21
  'import/no-unresolved': [
14
- 'warn',
22
+ 'error',
15
23
  { amd: true, commonjs: true, ignore: ['^node:'] },
16
24
  ],
17
25
  'import/order': [
@@ -115,7 +123,7 @@ module.exports = {
115
123
  ],
116
124
  radix: 'warn',
117
125
  'filenames/match-regex': 'off',
118
- 'require-atomic-updates': 'off',
126
+ 'require-atomic-updates': 'error',
119
127
  'sort-imports': 'off',
120
128
  'rest-spread-spacing': 'off',
121
129
  semi: 'off',
@@ -152,6 +160,231 @@ module.exports = {
152
160
  ignore: ['.*.md'],
153
161
  },
154
162
  ],
163
+ 'unicorn/prevent-abbreviations': [
164
+ 'warn',
165
+ {
166
+ allowList: {
167
+ e2e: true,
168
+ props: true,
169
+ ref: true,
170
+ params: true
171
+ },
172
+ ignore: [/e2e/]
173
+ }
174
+ ],
155
175
  'unicorn/import-index': ['warn', { ignoreImports: true }],
156
176
  'prettier/prettier': ['warn', { parser: 'babel' }],
177
+
178
+ // Error handling
179
+ 'no-await-in-loop': 'warn',
180
+ 'no-promise-executor-return': 'error',
181
+ 'no-unsafe-optional-chaining': 'error',
182
+
183
+ // Modern practices
184
+ 'logical-assignment-operators': ['warn', 'always', { enforceForIfStatements: true }],
185
+ 'no-constant-binary-expression': 'error',
186
+ 'no-unused-private-class-members': 'warn',
187
+
188
+ // Import rules
189
+ 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
190
+ 'import/no-empty-named-blocks': 'error',
191
+ 'import/no-reserved-dependencies': 'error',
192
+
193
+ // Better promises
194
+ 'promise/no-multiple-resolved': 'error',
195
+ 'promise/prefer-await-to-callbacks': 'warn',
196
+
197
+ // Security
198
+ 'security/detect-non-literal-fs-filename': 'warn',
199
+ 'security/detect-unsafe-regex': 'error',
200
+
201
+ // Better testing
202
+ 'jest/prefer-spy-on': 'warn',
203
+ 'jest/require-top-level-describe': 'error',
204
+
205
+ // Code Quality
206
+ 'sonarjs/cognitive-complexity': ['error', 15],
207
+ 'sonarjs/no-duplicate-string': ['error', 5],
208
+ 'sonarjs/no-redundant-boolean': 'error',
209
+ 'sonarjs/prefer-immediate-return': 'error',
210
+
211
+ // RegExp
212
+ 'regexp/no-missing-g-flag': 'error',
213
+ 'regexp/no-useless-flag': 'error',
214
+ 'regexp/prefer-quantifier': 'error',
215
+
216
+ // Enhanced TypeScript
217
+ 'etc/no-commented-out-code': 'warn',
218
+ 'etc/no-implicit-any-catch': 'error',
219
+ 'etc/prefer-interface': 'error',
220
+
221
+ // Enhanced Import Rules
222
+ 'import/no-relative-parent-imports': 'warn',
223
+ 'import/no-extraneous-dependencies': ['error', {
224
+ devDependencies: ['**/*.test.{js,ts}', '**/*.spec.{js,ts}', '**/test/**']
225
+ }],
226
+
227
+ // Better Promise Handling
228
+ 'promise/no-nesting': 'warn',
229
+ 'promise/prefer-await-to-then': 'warn',
230
+
231
+ // Security Enhancements
232
+ 'security/detect-buffer-noassert': 'error',
233
+ 'security/detect-child-process': 'warn',
234
+ 'security/detect-disable-mustache-escape': 'error',
235
+
236
+ // Functional Programming
237
+ 'functional/no-let': 'warn',
238
+ 'functional/prefer-readonly-type': 'warn',
239
+ 'functional/no-mixed-type': 'warn',
240
+
241
+ // Code Organization
242
+ 'typescript-sort-keys/interface': 'warn',
243
+ 'typescript-sort-keys/string-enum': 'warn',
244
+ 'sort-destructure-keys/sort-destructure-keys': 'warn',
245
+
246
+ // Code Quality
247
+ 'write-good-comments/write-good-comments': 'warn',
248
+ 'sonarjs/no-small-switch': 'warn',
249
+ 'sonarjs/no-duplicated-branches': 'error',
250
+ 'sonarjs/max-switch-cases': ['warn', 10],
251
+
252
+ // Additional Security
253
+ 'security/detect-possible-timing-attacks': ['error', { threshold: 10 }],
254
+ 'security/detect-non-literal-regexp': ['error', { report: 'error' }],
255
+ 'security/detect-non-literal-require': 'error',
256
+
257
+ // Better Type Safety
258
+ 'import/no-relative-packages': 'error',
259
+ 'import/no-self-import': 'error',
260
+
261
+ // Architecture Boundaries
262
+ 'boundaries/element-types': [
263
+ 'warn',
264
+ {
265
+ default: 'disallow',
266
+ rules: [
267
+ { from: 'utils', allow: ['utils'] },
268
+ { from: 'features', allow: ['features', 'shared', 'utils'] },
269
+ { from: 'shared', allow: ['shared', 'utils'] }
270
+ ]
271
+ }
272
+ ],
273
+
274
+ // Immutability
275
+ 'immutable/no-mutation': 'warn',
276
+ 'immutable/no-let': 'warn',
277
+
278
+ // Performance
279
+ 'optimize-regex/optimize-regex': 'warn',
280
+ 'radar/no-duplicate-string': ['warn', 5],
281
+ 'radar/cognitive-complexity': ['error', 15],
282
+
283
+ // Enhanced Security
284
+ 'security/detect-non-literal-fs-filename': ['error', { allowInlineConfig: false }],
285
+ 'security/detect-unsafe-regex': ['error', { allowDollarMatchAll: false }],
286
+ 'security/detect-buffer-noassert': 'error',
287
+
288
+ // Better Type Safety
289
+ 'import/no-cycle': ['error', { maxDepth: 1 }],
290
+ 'import/no-relative-packages': 'error',
291
+ 'unicorn/prefer-module': 'error',
292
+
293
+ // Code Style
294
+ 'perfectionist/sort-named-imports': [
295
+ 'warn',
296
+ {
297
+ type: 'natural',
298
+ order: 'asc',
299
+ 'ignore-case': true
300
+ }
301
+ ],
302
+
303
+ // Enhanced Security
304
+ 'security/detect-possible-timing-attacks': ['error', {
305
+ threshold: 8,
306
+ catchAliases: true
307
+ }],
308
+ 'security/detect-non-literal-regexp': ['error', {
309
+ report: 'error',
310
+ warnOnDynamicRegexp: true
311
+ }],
312
+ 'security/detect-unsafe-regex': ['error', {
313
+ maxLength: 50
314
+ }],
315
+
316
+ // Import Safety
317
+ 'import/no-import-module-exports': 'error',
318
+ 'import/no-relative-parent-imports': ['error', {
319
+ ignore: ['@/components', '@/utils', '@/types']
320
+ }],
321
+
322
+ // Better Code Organization
323
+ 'perfectionist/sort-objects': ['error', {
324
+ type: 'natural',
325
+ order: 'asc',
326
+ 'spread-last': true
327
+ }],
328
+ 'perfectionist/sort-named-imports': ['error', {
329
+ type: 'natural',
330
+ order: 'asc',
331
+ 'ignore-case': true
332
+ }],
333
+
334
+ // Advanced Performance
335
+ 'no-restricted-syntax': [
336
+ 'error',
337
+ {
338
+ selector: "CallExpression[callee.property.name='reduce'][arguments.length<2]",
339
+ message: 'Provide initialValue to reduce'
340
+ },
341
+ {
342
+ selector: "CallExpression[callee.property.name='forEach']",
343
+ message: 'Use for...of instead'
344
+ }
345
+ ],
346
+ 'require-atomic-updates': ['error', { allowProperties: false }],
347
+ 'no-constant-binary-expression': 'error',
348
+
349
+ // Better Error Handling
350
+ 'no-implicit-coercion': ['error', { boolean: false, number: true, string: true }],
351
+ 'unicorn/prefer-type-error': 'error',
352
+ 'unicorn/no-useless-undefined': ['error', { checkArguments: true }],
353
+
354
+ // Enhanced Import Safety
355
+ 'import/no-cycle': ['error', { maxDepth: 1, ignoreExternal: true }],
356
+ 'import/no-relative-packages': 'error',
357
+ 'import/no-self-import': 'error',
358
+
359
+ // Type Safety
360
+ 'unicorn/prefer-at': 'error',
361
+ 'unicorn/prefer-string-replace-all': 'error',
362
+ 'unicorn/require-post-message-target-origin': 'error',
363
+
364
+ // Security
365
+ 'n/no-unsupported-features/es-syntax': ['error', {
366
+ version: '>=18.0.0',
367
+ ignores: ['modules', 'dynamicImport']
368
+ }],
369
+
370
+ // Modern JavaScript Features
371
+ 'prefer-object-has-own': 'error',
372
+ 'unicorn/prefer-string-slice': 'error',
373
+ 'unicorn/prefer-array-flat': ['error', { functions: ['flatten'] }],
374
+ 'unicorn/prefer-blob-reading-methods': 'error',
375
+
376
+ // Memory Optimizations
377
+ 'no-array-constructor': 'error',
378
+ 'no-new-object': 'error',
379
+ 'prefer-exponentiation-operator': 'error',
380
+
381
+ // Better Error Handling
382
+ 'max-classes-per-file': ['error', 1],
383
+ 'no-promise-executor-return': ['error', { allowVoid: true }],
384
+ 'unicorn/catch-error-name': ['error', { name: 'error' }],
385
+
386
+ // Enhanced Import Safety
387
+ 'import/no-namespace': 'error',
388
+ 'import/no-empty-named-blocks': 'error',
389
+ 'import/no-duplicates': ['error', { 'prefer-inline': true }]
157
390
  };