@dmitryrechkin/eslint-standard 1.2.0 → 1.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/eslint.config.mjs +491 -50
- package/package.json +54 -33
package/eslint.config.mjs
CHANGED
|
@@ -8,6 +8,15 @@ import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
|
|
|
8
8
|
import perfectionistPlugin from 'eslint-plugin-perfectionist';
|
|
9
9
|
import jsdocIndentPlugin from './src/plugins/jsdoc-indent.mjs';
|
|
10
10
|
import interfaceBracePlugin from './src/plugins/interface-brace.mjs';
|
|
11
|
+
import securityPlugin from 'eslint-plugin-security';
|
|
12
|
+
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
|
|
13
|
+
import promisePlugin from 'eslint-plugin-promise';
|
|
14
|
+
import importPlugin from 'eslint-plugin-import';
|
|
15
|
+
import sonarjsPlugin from 'eslint-plugin-sonarjs';
|
|
16
|
+
import unicornPlugin from 'eslint-plugin-unicorn';
|
|
17
|
+
import noSecretsPlugin from 'eslint-plugin-no-secrets';
|
|
18
|
+
import regexpPlugin from 'eslint-plugin-regexp';
|
|
19
|
+
import functionalPlugin from 'eslint-plugin-functional';
|
|
11
20
|
|
|
12
21
|
export default function ({
|
|
13
22
|
tsconfigPath = './tsconfig.json',
|
|
@@ -39,6 +48,15 @@ export default function ({
|
|
|
39
48
|
'perfectionist': perfectionistPlugin,
|
|
40
49
|
'jsdoc-indent': jsdocIndentPlugin,
|
|
41
50
|
'interface-brace': interfaceBracePlugin,
|
|
51
|
+
'security': securityPlugin,
|
|
52
|
+
'jsx-a11y': jsxA11yPlugin,
|
|
53
|
+
'promise': promisePlugin,
|
|
54
|
+
'import': importPlugin,
|
|
55
|
+
'sonarjs': sonarjsPlugin,
|
|
56
|
+
'unicorn': unicornPlugin,
|
|
57
|
+
'no-secrets': noSecretsPlugin,
|
|
58
|
+
'regexp': regexpPlugin,
|
|
59
|
+
'functional': functionalPlugin,
|
|
42
60
|
...plugins,
|
|
43
61
|
},
|
|
44
62
|
rules: {
|
|
@@ -63,56 +81,7 @@ export default function ({
|
|
|
63
81
|
'comma-dangle': 'off', // Disabled in favor of @stylistic/comma-dangle
|
|
64
82
|
'@stylistic/comma-dangle': ['error', 'never'],
|
|
65
83
|
|
|
66
|
-
//
|
|
67
|
-
'@typescript-eslint/naming-convention': [
|
|
68
|
-
'error',
|
|
69
|
-
{
|
|
70
|
-
selector: 'variableLike',
|
|
71
|
-
format: ['camelCase'],
|
|
72
|
-
leadingUnderscore: 'forbid',
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
selector: 'function',
|
|
76
|
-
format: ['camelCase'],
|
|
77
|
-
leadingUnderscore: 'forbid',
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
selector: 'class',
|
|
81
|
-
format: ['PascalCase'],
|
|
82
|
-
leadingUnderscore: 'forbid',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
selector: 'parameter',
|
|
86
|
-
format: ['camelCase'],
|
|
87
|
-
leadingUnderscore: 'forbid',
|
|
88
|
-
custom: {
|
|
89
|
-
regex: '^_',
|
|
90
|
-
match: false,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
selector: 'parameter',
|
|
95
|
-
format: null,
|
|
96
|
-
leadingUnderscore: 'require',
|
|
97
|
-
modifiers: ['unused'],
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
selector: 'memberLike',
|
|
101
|
-
format: ['camelCase'],
|
|
102
|
-
leadingUnderscore: 'forbid',
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
selector: 'property',
|
|
106
|
-
modifiers: ['readonly'],
|
|
107
|
-
format: ['camelCase', 'UPPER_CASE'],
|
|
108
|
-
leadingUnderscore: 'forbid',
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
selector: 'enumMember',
|
|
112
|
-
format: ['UPPER_CASE'],
|
|
113
|
-
leadingUnderscore: 'forbid',
|
|
114
|
-
},
|
|
115
|
-
],
|
|
84
|
+
// Comprehensive naming conventions based on coding standards
|
|
116
85
|
|
|
117
86
|
// Original unused-imports rules
|
|
118
87
|
'unused-imports/no-unused-imports': 'error',
|
|
@@ -202,6 +171,181 @@ export default function ({
|
|
|
202
171
|
// Enhanced: Interface brace style
|
|
203
172
|
'interface-brace/interface-brace-style': 'error',
|
|
204
173
|
|
|
174
|
+
// Additional naming conventions based on coding standards
|
|
175
|
+
'@typescript-eslint/naming-convention': [
|
|
176
|
+
'warn',
|
|
177
|
+
// Existing rules remain the same...
|
|
178
|
+
{
|
|
179
|
+
selector: 'variableLike',
|
|
180
|
+
format: ['camelCase'],
|
|
181
|
+
leadingUnderscore: 'forbid',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
selector: 'variable',
|
|
185
|
+
modifiers: ['const'],
|
|
186
|
+
format: ['camelCase', 'UPPER_CASE'],
|
|
187
|
+
leadingUnderscore: 'forbid',
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
selector: 'variable',
|
|
191
|
+
format: ['camelCase'],
|
|
192
|
+
leadingUnderscore: 'forbid',
|
|
193
|
+
custom: {
|
|
194
|
+
regex: '^(data|info|item|obj|object|val|value|temp|tmp|res|result|ret|param|params|arg|args|opt|options|config|cfg|ctx|context|e|err|error|cb|callback|fn|func|handler|util|utils|helper|helpers|mgr|manager|svc|service|ctrl|controller|comp|component|elem|element|str|string|num|number|bool|boolean|arr|array|list|items|dict|map|hash|i|j|k|n|x|y|z)$',
|
|
195
|
+
match: false
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
selector: 'function',
|
|
200
|
+
format: ['camelCase'],
|
|
201
|
+
leadingUnderscore: 'forbid',
|
|
202
|
+
custom: {
|
|
203
|
+
regex: '^(create|make|get|set|update|delete|remove|add|init|load|save|fetch|find|search|check|validate|handle|process|execute|run|start|stop|open|close|read|write|parse|format|convert|transform|build|render|draw|calculate|compute|generate|send|receive|submit|cancel|reset|clear|test|log|debug|trace|info|warn|error|show|hide|enable|disable|toggle|select|click|focus|blur|scroll|resize|move|copy|paste|cut|undo|redo|forward|back|up|down|left|right|first|last|next|prev|push|pop|shift|unshift|splice|slice|concat|join|split|replace|trim|pad|truncate|wrap|unwrap|escape|unescape|encode|decode|encrypt|decrypt|compress|decompress|serialize|deserialize|clone|merge|extend|assign|bind|unbind|on|off|once|emit|trigger|listen|unlisten|subscribe|unsubscribe|publish|unpublish|attach|detach|append|prepend|insert|inject|extract|filter|map|reduce|forEach|some|every|find|findIndex|indexOf|lastIndexOf|includes|contains|has|is|equals|compare|match|test|verify|assert|ensure|require|expect|should|must|can|may|might|will|shall|would|could)$',
|
|
204
|
+
match: false
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
selector: 'method',
|
|
209
|
+
format: ['camelCase'],
|
|
210
|
+
leadingUnderscore: 'forbid',
|
|
211
|
+
custom: {
|
|
212
|
+
regex: '^(create|make|get|set|update|delete|remove|add|init|load|save|fetch|find|search|check|validate|handle|process|execute|run|start|stop|open|close|read|write|parse|format|convert|transform|build|render|draw|calculate|compute|generate|send|receive|submit|cancel|reset|clear|test|log|debug|trace|info|warn|error|show|hide|enable|disable|toggle|select|click|focus|blur|scroll|resize|move|copy|paste|cut|undo|redo|forward|back|up|down|left|right|first|last|next|prev|push|pop|shift|unshift|splice|slice|concat|join|split|replace|trim|pad|truncate|wrap|unwrap|escape|unescape|encode|decode|encrypt|decrypt|compress|decompress|serialize|deserialize|clone|merge|extend|assign|bind|unbind|on|off|once|emit|trigger|listen|unlisten|subscribe|unsubscribe|publish|unpublish|attach|detach|append|prepend|insert|inject|extract|filter|map|reduce|forEach|some|every|find|findIndex|indexOf|lastIndexOf|includes|contains|has|is|equals|compare|match|test|verify|assert|ensure|require|expect|should|must|can|may|might|will|shall|would|could)$',
|
|
213
|
+
match: false
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
selector: 'method',
|
|
218
|
+
modifiers: ['public'],
|
|
219
|
+
format: ['camelCase'],
|
|
220
|
+
leadingUnderscore: 'forbid'
|
|
221
|
+
// Allow generic names for public methods
|
|
222
|
+
},
|
|
223
|
+
// Services must end with 'Service'
|
|
224
|
+
{
|
|
225
|
+
selector: 'class',
|
|
226
|
+
filter: {
|
|
227
|
+
regex: 'Service$',
|
|
228
|
+
match: true
|
|
229
|
+
},
|
|
230
|
+
format: ['PascalCase'],
|
|
231
|
+
custom: {
|
|
232
|
+
regex: '^[A-Z][a-zA-Z]*Service$',
|
|
233
|
+
match: true
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
// Repositories must end with 'Repository'
|
|
237
|
+
{
|
|
238
|
+
selector: 'class',
|
|
239
|
+
filter: {
|
|
240
|
+
regex: 'Repository$',
|
|
241
|
+
match: true
|
|
242
|
+
},
|
|
243
|
+
format: ['PascalCase'],
|
|
244
|
+
custom: {
|
|
245
|
+
regex: '^[A-Z][a-zA-Z]*(Command|Query)?Repository$',
|
|
246
|
+
match: true
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
// Helpers must end with 'Helper'
|
|
250
|
+
{
|
|
251
|
+
selector: 'class',
|
|
252
|
+
filter: {
|
|
253
|
+
regex: 'Helper$',
|
|
254
|
+
match: true
|
|
255
|
+
},
|
|
256
|
+
format: ['PascalCase'],
|
|
257
|
+
custom: {
|
|
258
|
+
regex: '^[A-Z][a-zA-Z]*Helper$',
|
|
259
|
+
match: true
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
// Factories must end with 'Factory'
|
|
263
|
+
{
|
|
264
|
+
selector: 'class',
|
|
265
|
+
filter: {
|
|
266
|
+
regex: 'Factory$',
|
|
267
|
+
match: true
|
|
268
|
+
},
|
|
269
|
+
format: ['PascalCase'],
|
|
270
|
+
custom: {
|
|
271
|
+
regex: '^[A-Z][a-zA-Z]*Factory$',
|
|
272
|
+
match: true
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
// General class naming (excluding specific patterns above)
|
|
276
|
+
{
|
|
277
|
+
selector: 'class',
|
|
278
|
+
format: ['PascalCase'],
|
|
279
|
+
leadingUnderscore: 'forbid',
|
|
280
|
+
custom: {
|
|
281
|
+
regex: '^(Base|Abstract|Main|App|Application|Component|Element|Item|Object|Entity|Model|View|Controller|Service|Manager|Handler|Helper|Util|Utils|Factory|Builder|Provider|Container|Wrapper|Adapter|Proxy|Decorator|Observer|Listener|Event|Action|Command|Request|Response|Result|Error|Exception|Interface|Type|Class|Struct|Enum|Module|Package|Library|Framework|System|Core|Common|Shared|Global|Default|Generic|Simple|Basic|Standard|Custom|Internal|External|Public|Private|Static|Dynamic|Singleton|Instance|Collection|List|Array|Map|Set|Dictionary|Queue|Stack|Tree|Graph|Node|Edge|Link|Data|Info|Config|Settings|Options|Parameters|Arguments|Properties|Attributes|State|Status|Context|Environment|Session|Transaction|Process|Thread|Task|Job|Worker|Pool|Cache|Buffer|Stream|Channel|Connection|Client|Server|Database|Repository|Store|Resource|Asset|File|Folder|Directory|Path|Route|Endpoint|Api|Rest|Http|Https|Tcp|Udp|Socket|Port|Host|Domain|Url|Uri|Query|Param|Header|Body|Content|Message|Packet|Frame|Byte|Bit|Flag|Token|Key|Value|Pair|Entry|Record|Row|Column|Field|Cell|Table|Index|Page|Form|Input|Output|Button|Label|Text|Image|Icon|Media|Audio|Video|Document|Template|Layout|Style|Theme|Color|Font|Size|Position|Location|Coordinate|Point|Vector|Matrix|Shape|Line|Circle|Rectangle|Polygon|Curve|Surface|Volume|Space|Time|Date|Duration|Period|Interval|Range|Sequence|Series|Pattern|Format|Encoder|Decoder|Parser|Formatter|Validator|Converter|Transformer|Filter|Mapper|Reducer|Sorter|Comparator|Iterator|Generator|Consumer|Producer|Publisher|Subscriber|Emitter|Receiver|Sender|Dispatcher|Router|Gateway|Bridge|Tunnel|Pipeline|Chain|Link|Hook|Plugin|Extension|Addon|Feature|Capability|Function|Method|Procedure|Routine|Algorithm|Strategy|Policy|Rule|Constraint|Condition|Requirement|Specification|Definition|Declaration|Implementation|Execution|Operation|Instruction|Statement|Expression|Variable|Constant|Parameter|Argument|Return|Result|Output|Input|IO|UI|GUI|CLI|API|SDK|IDE|OS|VM|CPU|GPU|RAM|ROM|HDD|SSD|DB|SQL|NoSQL|ORM|ODM|DTO|DAO|POJO|POCO|VO|BO|DO|PO|TO|SO|MO|NO)$',
|
|
282
|
+
match: false
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
selector: 'interface',
|
|
287
|
+
format: ['PascalCase'],
|
|
288
|
+
leadingUnderscore: 'forbid',
|
|
289
|
+
custom: {
|
|
290
|
+
regex: 'Interface$',
|
|
291
|
+
match: true
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
selector: 'typeAlias',
|
|
296
|
+
format: ['PascalCase'],
|
|
297
|
+
leadingUnderscore: 'forbid',
|
|
298
|
+
custom: {
|
|
299
|
+
regex: '^Type[A-Z]',
|
|
300
|
+
match: true
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
selector: 'parameter',
|
|
305
|
+
format: ['camelCase'],
|
|
306
|
+
leadingUnderscore: 'forbid',
|
|
307
|
+
custom: {
|
|
308
|
+
regex: '^_',
|
|
309
|
+
match: false,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
selector: 'parameter',
|
|
314
|
+
format: null,
|
|
315
|
+
leadingUnderscore: 'require',
|
|
316
|
+
modifiers: ['unused'],
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
selector: 'memberLike',
|
|
320
|
+
format: ['camelCase'],
|
|
321
|
+
leadingUnderscore: 'forbid',
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
selector: 'property',
|
|
325
|
+
modifiers: ['readonly'],
|
|
326
|
+
format: ['camelCase', 'UPPER_CASE'],
|
|
327
|
+
leadingUnderscore: 'forbid',
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
selector: 'enumMember',
|
|
331
|
+
format: ['camelCase', 'UPPER_CASE'],
|
|
332
|
+
leadingUnderscore: 'forbid',
|
|
333
|
+
},
|
|
334
|
+
// Schema table files must end with 'Table'
|
|
335
|
+
{
|
|
336
|
+
selector: 'variable',
|
|
337
|
+
filter: {
|
|
338
|
+
regex: 'Table$',
|
|
339
|
+
match: true
|
|
340
|
+
},
|
|
341
|
+
format: ['camelCase'],
|
|
342
|
+
custom: {
|
|
343
|
+
regex: '[a-z][a-zA-Z]*Table$',
|
|
344
|
+
match: true
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
],
|
|
348
|
+
|
|
205
349
|
// Code Complexity Rules (industry standards)
|
|
206
350
|
'complexity': ['error', 10], // Cyclomatic complexity - max 10 paths through a function
|
|
207
351
|
'max-lines-per-function': ['error', {
|
|
@@ -321,6 +465,303 @@ export default function ({
|
|
|
321
465
|
ignoreClassFieldInitialValues: true
|
|
322
466
|
}], // Named constants for magic numbers
|
|
323
467
|
|
|
468
|
+
// Identifier length rules
|
|
469
|
+
'id-length': ['warn', {
|
|
470
|
+
min: 3,
|
|
471
|
+
exceptions: ['i', 'j', 'k', 'x', 'y', 'z', 'id', 'db', 'fs', 'os', 'io', 'ui', 'vm', '_', 'idx'],
|
|
472
|
+
properties: 'never' // Don't apply to object properties
|
|
473
|
+
}],
|
|
474
|
+
|
|
475
|
+
// Security plugin rules
|
|
476
|
+
'security/detect-eval-with-expression': 'error',
|
|
477
|
+
'security/detect-non-literal-fs-filename': 'warn',
|
|
478
|
+
'security/detect-non-literal-regexp': 'warn',
|
|
479
|
+
'security/detect-unsafe-regex': 'error',
|
|
480
|
+
'security/detect-buffer-noassert': 'error',
|
|
481
|
+
'security/detect-child-process': 'warn',
|
|
482
|
+
'security/detect-disable-mustache-escape': 'error',
|
|
483
|
+
'security/detect-no-csrf-before-method-override': 'error',
|
|
484
|
+
'security/detect-object-injection': 'warn',
|
|
485
|
+
'security/detect-possible-timing-attacks': 'warn',
|
|
486
|
+
'security/detect-pseudoRandomBytes': 'error',
|
|
487
|
+
|
|
488
|
+
// Promise plugin rules
|
|
489
|
+
'promise/always-return': 'error',
|
|
490
|
+
'promise/no-return-wrap': 'error',
|
|
491
|
+
'promise/param-names': 'error',
|
|
492
|
+
'promise/catch-or-return': 'error',
|
|
493
|
+
'promise/no-native': 'off',
|
|
494
|
+
'promise/no-nesting': 'warn',
|
|
495
|
+
'promise/no-promise-in-callback': 'warn',
|
|
496
|
+
'promise/no-callback-in-promise': 'warn',
|
|
497
|
+
'promise/avoid-new': 'off',
|
|
498
|
+
'promise/no-new-statics': 'error',
|
|
499
|
+
'promise/no-return-in-finally': 'error',
|
|
500
|
+
'promise/valid-params': 'error',
|
|
501
|
+
'promise/prefer-await-to-then': 'warn',
|
|
502
|
+
'promise/prefer-await-to-callbacks': 'warn',
|
|
503
|
+
|
|
504
|
+
// Import plugin rules
|
|
505
|
+
'import/no-unresolved': 'error',
|
|
506
|
+
'import/named': 'error',
|
|
507
|
+
'import/default': 'error',
|
|
508
|
+
'import/namespace': 'error',
|
|
509
|
+
'import/no-restricted-paths': 'off',
|
|
510
|
+
'import/no-absolute-path': 'error',
|
|
511
|
+
'import/no-dynamic-require': 'error',
|
|
512
|
+
'import/no-internal-modules': 'off',
|
|
513
|
+
'import/no-webpack-loader-syntax': 'error',
|
|
514
|
+
'import/no-self-import': 'error',
|
|
515
|
+
'import/no-cycle': ['error', { maxDepth: 3 }],
|
|
516
|
+
'import/no-useless-path-segments': 'error',
|
|
517
|
+
'import/no-relative-parent-imports': 'off',
|
|
518
|
+
'import/export': 'error',
|
|
519
|
+
'import/no-named-as-default': 'error',
|
|
520
|
+
'import/no-named-as-default-member': 'error',
|
|
521
|
+
'import/no-deprecated': 'warn',
|
|
522
|
+
'import/no-extraneous-dependencies': ['error', {
|
|
523
|
+
devDependencies: ['**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}', '**/test/**', '**/tests/**', '**/__tests__/**']
|
|
524
|
+
}],
|
|
525
|
+
'import/no-mutable-exports': 'error',
|
|
526
|
+
'import/no-unused-modules': 'off', // Disabled due to .eslintrc requirement in flat config
|
|
527
|
+
'import/unambiguous': 'off',
|
|
528
|
+
'import/no-commonjs': 'off',
|
|
529
|
+
'import/no-amd': 'error',
|
|
530
|
+
'import/no-nodejs-modules': 'off',
|
|
531
|
+
'import/first': 'error',
|
|
532
|
+
'import/exports-last': 'off',
|
|
533
|
+
'import/no-duplicates': 'error',
|
|
534
|
+
'import/no-namespace': 'off',
|
|
535
|
+
'import/extensions': ['error', 'ignorePackages', {
|
|
536
|
+
js: 'never',
|
|
537
|
+
jsx: 'never',
|
|
538
|
+
ts: 'never',
|
|
539
|
+
tsx: 'never'
|
|
540
|
+
}],
|
|
541
|
+
'import/newline-after-import': 'error',
|
|
542
|
+
'import/prefer-default-export': 'off',
|
|
543
|
+
'import/max-dependencies': ['warn', { max: 20 }],
|
|
544
|
+
'import/no-unassigned-import': 'off',
|
|
545
|
+
'import/no-named-default': 'error',
|
|
546
|
+
'import/no-default-export': 'off',
|
|
547
|
+
'import/no-named-export': 'off',
|
|
548
|
+
'import/no-anonymous-default-export': 'warn',
|
|
549
|
+
'import/group-exports': 'off',
|
|
550
|
+
'import/dynamic-import-chunkname': 'off',
|
|
551
|
+
|
|
552
|
+
// JSX A11y plugin rules (only active for React/JSX files)
|
|
553
|
+
'jsx-a11y/alt-text': 'error',
|
|
554
|
+
'jsx-a11y/anchor-has-content': 'error',
|
|
555
|
+
'jsx-a11y/anchor-is-valid': 'error',
|
|
556
|
+
'jsx-a11y/aria-props': 'error',
|
|
557
|
+
'jsx-a11y/aria-role': 'error',
|
|
558
|
+
'jsx-a11y/aria-unsupported-elements': 'error',
|
|
559
|
+
'jsx-a11y/click-events-have-key-events': 'warn',
|
|
560
|
+
'jsx-a11y/heading-has-content': 'error',
|
|
561
|
+
'jsx-a11y/html-has-lang': 'error',
|
|
562
|
+
'jsx-a11y/iframe-has-title': 'error',
|
|
563
|
+
'jsx-a11y/img-redundant-alt': 'error',
|
|
564
|
+
'jsx-a11y/interactive-supports-focus': 'error',
|
|
565
|
+
'jsx-a11y/label-has-associated-control': 'error',
|
|
566
|
+
'jsx-a11y/media-has-caption': 'warn',
|
|
567
|
+
'jsx-a11y/mouse-events-have-key-events': 'warn',
|
|
568
|
+
'jsx-a11y/no-access-key': 'error',
|
|
569
|
+
'jsx-a11y/no-autofocus': 'warn',
|
|
570
|
+
'jsx-a11y/no-distracting-elements': 'error',
|
|
571
|
+
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'error',
|
|
572
|
+
'jsx-a11y/no-noninteractive-element-interactions': 'warn',
|
|
573
|
+
'jsx-a11y/no-noninteractive-element-to-interactive-role': 'error',
|
|
574
|
+
'jsx-a11y/no-redundant-roles': 'error',
|
|
575
|
+
'jsx-a11y/no-static-element-interactions': 'warn',
|
|
576
|
+
'jsx-a11y/role-has-required-aria-props': 'error',
|
|
577
|
+
'jsx-a11y/role-supports-aria-props': 'error',
|
|
578
|
+
'jsx-a11y/scope': 'error',
|
|
579
|
+
'jsx-a11y/tabindex-no-positive': 'error',
|
|
580
|
+
|
|
581
|
+
// SonarJS plugin rules - Code smells and cognitive complexity
|
|
582
|
+
'sonarjs/cognitive-complexity': ['error', 15], // More sophisticated than cyclomatic
|
|
583
|
+
'sonarjs/no-identical-expressions': 'error',
|
|
584
|
+
'sonarjs/no-identical-functions': 'error',
|
|
585
|
+
'sonarjs/no-duplicate-string': ['error', { threshold: 3 }],
|
|
586
|
+
'sonarjs/prefer-immediate-return': 'error',
|
|
587
|
+
'sonarjs/prefer-object-literal': 'error',
|
|
588
|
+
'sonarjs/prefer-single-boolean-return': 'error',
|
|
589
|
+
'sonarjs/no-redundant-boolean': 'error',
|
|
590
|
+
'sonarjs/no-unused-collection': 'error',
|
|
591
|
+
'sonarjs/no-useless-catch': 'error',
|
|
592
|
+
'sonarjs/prefer-while': 'error',
|
|
593
|
+
'sonarjs/max-switch-cases': ['error', 30],
|
|
594
|
+
'sonarjs/no-nested-switch': 'error',
|
|
595
|
+
'sonarjs/no-nested-template-literals': 'error',
|
|
596
|
+
'sonarjs/no-redundant-jump': 'error',
|
|
597
|
+
'sonarjs/no-same-line-conditional': 'error',
|
|
598
|
+
'sonarjs/non-existent-operator': 'error',
|
|
599
|
+
|
|
600
|
+
// Unicorn plugin rules - Modern JavaScript best practices
|
|
601
|
+
'unicorn/better-regex': 'error',
|
|
602
|
+
'unicorn/catch-error-name': 'error',
|
|
603
|
+
'unicorn/consistent-destructuring': 'error',
|
|
604
|
+
'unicorn/consistent-function-scoping': 'error',
|
|
605
|
+
'unicorn/custom-error-definition': 'error',
|
|
606
|
+
'unicorn/error-message': 'error',
|
|
607
|
+
'unicorn/escape-case': 'error',
|
|
608
|
+
'unicorn/expiring-todo-comments': 'error',
|
|
609
|
+
'unicorn/explicit-length-check': 'error',
|
|
610
|
+
'unicorn/filename-case': ['warn', {
|
|
611
|
+
cases: {
|
|
612
|
+
camelCase: true, // For folders: userAuth, licenseActivation
|
|
613
|
+
pascalCase: true, // For class files: UserService.ts
|
|
614
|
+
}
|
|
615
|
+
}],
|
|
616
|
+
'unicorn/import-style': 'error',
|
|
617
|
+
'unicorn/new-for-builtins': 'error',
|
|
618
|
+
'unicorn/no-abusive-eslint-disable': 'error',
|
|
619
|
+
'unicorn/no-array-callback-reference': 'error',
|
|
620
|
+
'unicorn/no-array-for-each': 'error',
|
|
621
|
+
'unicorn/no-array-method-this-argument': 'error',
|
|
622
|
+
'unicorn/no-array-push-push': 'error',
|
|
623
|
+
'unicorn/no-array-reduce': 'warn',
|
|
624
|
+
'unicorn/no-await-expression-member': 'error',
|
|
625
|
+
'unicorn/no-console-spaces': 'error',
|
|
626
|
+
'unicorn/no-document-cookie': 'error',
|
|
627
|
+
'unicorn/no-empty-file': 'error',
|
|
628
|
+
'unicorn/no-for-loop': 'error',
|
|
629
|
+
'unicorn/no-hex-escape': 'error',
|
|
630
|
+
'unicorn/no-instanceof-array': 'error',
|
|
631
|
+
'unicorn/no-invalid-remove-event-listener': 'error',
|
|
632
|
+
'unicorn/no-keyword-prefix': 'off',
|
|
633
|
+
'unicorn/no-lonely-if': 'error',
|
|
634
|
+
'unicorn/no-nested-ternary': 'error',
|
|
635
|
+
'unicorn/no-new-array': 'error',
|
|
636
|
+
'unicorn/no-new-buffer': 'error',
|
|
637
|
+
'unicorn/no-null': 'error', // Use undefined instead of null per coding standards
|
|
638
|
+
'unicorn/no-object-as-default-parameter': 'error',
|
|
639
|
+
'unicorn/no-process-exit': 'error',
|
|
640
|
+
'unicorn/no-static-only-class': 'error',
|
|
641
|
+
'unicorn/no-thenable': 'error',
|
|
642
|
+
'unicorn/no-this-assignment': 'error',
|
|
643
|
+
'unicorn/no-typeof-undefined': 'error',
|
|
644
|
+
'unicorn/no-unnecessary-await': 'error',
|
|
645
|
+
'unicorn/no-unreadable-array-destructuring': 'error',
|
|
646
|
+
'unicorn/no-unreadable-iife': 'error',
|
|
647
|
+
'unicorn/no-unsafe-regex': 'error',
|
|
648
|
+
'unicorn/no-unused-properties': 'off',
|
|
649
|
+
'unicorn/no-useless-fallback-in-spread': 'error',
|
|
650
|
+
'unicorn/no-useless-length-check': 'error',
|
|
651
|
+
'unicorn/no-useless-promise-resolve-reject': 'error',
|
|
652
|
+
'unicorn/no-useless-spread': 'error',
|
|
653
|
+
'unicorn/no-useless-switch-case': 'error',
|
|
654
|
+
'unicorn/no-zero-fractions': 'error',
|
|
655
|
+
'unicorn/number-literal-case': 'error',
|
|
656
|
+
'unicorn/numeric-separators-style': 'error',
|
|
657
|
+
'unicorn/prefer-add-event-listener': 'error',
|
|
658
|
+
'unicorn/prefer-array-find': 'error',
|
|
659
|
+
'unicorn/prefer-array-flat': 'error',
|
|
660
|
+
'unicorn/prefer-array-flat-map': 'error',
|
|
661
|
+
'unicorn/prefer-array-index-of': 'error',
|
|
662
|
+
'unicorn/prefer-array-some': 'error',
|
|
663
|
+
'unicorn/prefer-at': 'error',
|
|
664
|
+
'unicorn/prefer-code-point': 'error',
|
|
665
|
+
'unicorn/prefer-date-now': 'error',
|
|
666
|
+
'unicorn/prefer-default-parameters': 'error',
|
|
667
|
+
'unicorn/prefer-dom-node-append': 'error',
|
|
668
|
+
'unicorn/prefer-dom-node-dataset': 'error',
|
|
669
|
+
'unicorn/prefer-dom-node-remove': 'error',
|
|
670
|
+
'unicorn/prefer-dom-node-text-content': 'error',
|
|
671
|
+
'unicorn/prefer-includes': 'error',
|
|
672
|
+
'unicorn/prefer-json-parse-buffer': 'off',
|
|
673
|
+
'unicorn/prefer-keyboard-event-key': 'error',
|
|
674
|
+
'unicorn/prefer-logical-operator-over-ternary': 'error',
|
|
675
|
+
'unicorn/prefer-math-trunc': 'error',
|
|
676
|
+
'unicorn/prefer-modern-dom-apis': 'error',
|
|
677
|
+
'unicorn/prefer-modern-math-apis': 'error',
|
|
678
|
+
'unicorn/prefer-module': 'error',
|
|
679
|
+
'unicorn/prefer-native-coercion-functions': 'error',
|
|
680
|
+
'unicorn/prefer-negative-index': 'error',
|
|
681
|
+
'unicorn/prefer-node-protocol': 'error',
|
|
682
|
+
'unicorn/prefer-number-properties': 'error',
|
|
683
|
+
'unicorn/prefer-object-from-entries': 'error',
|
|
684
|
+
'unicorn/prefer-optional-catch-binding': 'error',
|
|
685
|
+
'unicorn/prefer-prototype-methods': 'error',
|
|
686
|
+
'unicorn/prefer-query-selector': 'error',
|
|
687
|
+
'unicorn/prefer-reflect-apply': 'error',
|
|
688
|
+
'unicorn/prefer-regexp-test': 'error',
|
|
689
|
+
'unicorn/prefer-set-has': 'error',
|
|
690
|
+
'unicorn/prefer-set-size': 'error',
|
|
691
|
+
'unicorn/prefer-spread': 'error',
|
|
692
|
+
'unicorn/prefer-string-replace-all': 'error',
|
|
693
|
+
'unicorn/prefer-string-slice': 'error',
|
|
694
|
+
'unicorn/prefer-string-starts-ends-with': 'error',
|
|
695
|
+
'unicorn/prefer-string-trim-start-end': 'error',
|
|
696
|
+
'unicorn/prefer-switch': 'error',
|
|
697
|
+
'unicorn/prefer-ternary': 'error',
|
|
698
|
+
'unicorn/prefer-top-level-await': 'error',
|
|
699
|
+
'unicorn/prefer-type-error': 'error',
|
|
700
|
+
'unicorn/prevent-abbreviations': 'off', // Too aggressive for existing code
|
|
701
|
+
'unicorn/relative-url-style': 'error',
|
|
702
|
+
'unicorn/require-array-join-separator': 'error',
|
|
703
|
+
'unicorn/require-number-to-fixed-digits-argument': 'error',
|
|
704
|
+
'unicorn/require-post-message-target-origin': 'error',
|
|
705
|
+
'unicorn/string-content': 'off',
|
|
706
|
+
'unicorn/switch-case-braces': 'error',
|
|
707
|
+
'unicorn/template-indent': 'warn',
|
|
708
|
+
'unicorn/text-encoding-identifier-case': 'error',
|
|
709
|
+
'unicorn/throw-new-error': 'error',
|
|
710
|
+
|
|
711
|
+
// No Secrets plugin rules - Prevent secrets in code
|
|
712
|
+
'no-secrets/no-secrets': ['error', {
|
|
713
|
+
tolerance: 4.2,
|
|
714
|
+
ignoreContent: '^CHANGE ME$',
|
|
715
|
+
ignoreModules: true,
|
|
716
|
+
ignoreIdentifiers: ['BASE64_CHARS', 'HEX_CHARS'],
|
|
717
|
+
additionalRegexes: {
|
|
718
|
+
'AWS Access Key': 'AKIA[0-9A-Z]{16}',
|
|
719
|
+
'GitHub Token': 'ghp_[a-zA-Z0-9]{36}',
|
|
720
|
+
'JWT Token': 'eyJ[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*\\.[a-zA-Z0-9_-]*'
|
|
721
|
+
}
|
|
722
|
+
}],
|
|
723
|
+
|
|
724
|
+
// RegExp plugin rules - Essential RegExp safety (conservative set for v2.9.0)
|
|
725
|
+
'regexp/no-control-character': 'error',
|
|
726
|
+
'regexp/no-empty-character-class': 'error',
|
|
727
|
+
'regexp/no-empty-group': 'error',
|
|
728
|
+
'regexp/no-invalid-regexp': 'error',
|
|
729
|
+
'regexp/no-misleading-capturing-group': 'error',
|
|
730
|
+
'regexp/no-misleading-unicode-character': 'error',
|
|
731
|
+
'regexp/no-super-linear-backtracking': 'error', // Prevents ReDoS
|
|
732
|
+
'regexp/no-unused-capturing-group': 'error',
|
|
733
|
+
'regexp/no-useless-character-class': 'error',
|
|
734
|
+
'regexp/no-useless-escape': 'error',
|
|
735
|
+
'regexp/no-useless-flag': 'error',
|
|
736
|
+
'regexp/no-useless-quantifier': 'error',
|
|
737
|
+
'regexp/no-useless-range': 'error',
|
|
738
|
+
'regexp/prefer-character-class': 'error',
|
|
739
|
+
'regexp/prefer-d': 'error',
|
|
740
|
+
'regexp/prefer-plus-quantifier': 'error',
|
|
741
|
+
'regexp/prefer-star-quantifier': 'error',
|
|
742
|
+
'regexp/prefer-w': 'error',
|
|
743
|
+
|
|
744
|
+
// Functional plugin rules - Immutability and functional programming
|
|
745
|
+
'functional/no-let': 'warn', // Encourage const
|
|
746
|
+
'functional/prefer-readonly-type': 'warn', // Readonly arrays/objects
|
|
747
|
+
'functional/no-method-signature': 'off', // Allow method signatures in interfaces
|
|
748
|
+
'functional/no-expression-statements': 'off', // Too restrictive for most code
|
|
749
|
+
'functional/functional-parameters': 'off', // Too restrictive
|
|
750
|
+
'functional/no-return-void': 'off', // Allow void returns
|
|
751
|
+
'functional/no-conditional-statements': 'off', // Too restrictive
|
|
752
|
+
'functional/no-loop-statements': 'warn', // Encourage functional alternatives
|
|
753
|
+
'functional/immutable-data': ['warn', {
|
|
754
|
+
ignoreImmediateMutation: true,
|
|
755
|
+
ignoreAccessorPattern: ['**.current', '**.ref']
|
|
756
|
+
}],
|
|
757
|
+
'functional/no-throw-statements': 'off', // Allow throwing errors
|
|
758
|
+
'functional/no-try-statements': 'off', // Allow try-catch
|
|
759
|
+
'functional/no-promise-reject': 'off', // Allow promise rejection
|
|
760
|
+
|
|
761
|
+
// Custom rules for coding standards compliance
|
|
762
|
+
'unicorn/prefer-query-selector': 'off', // Allow different DOM query methods
|
|
763
|
+
'unicorn/prevent-abbreviations': 'off', // Allow abbreviations for domain-specific terms
|
|
764
|
+
|
|
324
765
|
// Allow custom rules to be added
|
|
325
766
|
...rules,
|
|
326
767
|
},
|
package/package.json
CHANGED
|
@@ -1,50 +1,71 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dmitryrechkin/eslint-standard",
|
|
3
3
|
"description": "This package provides a shared ESLint configuration which includes TypeScript support and a set of specific linting rules designed to ensure high-quality and consistent code style across projects.",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"main": "eslint.config.mjs",
|
|
6
6
|
"bin": {
|
|
7
|
-
|
|
7
|
+
"eslint-standard": "./src/cli/index.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
"eslint.config.mjs",
|
|
11
|
+
"src/",
|
|
12
|
+
"docs/",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
"postinstall": "node src/cli/postinstall.mjs",
|
|
18
|
+
"package:publish": "npm publish --access public",
|
|
19
|
+
"test": "node tests/test-all-rules.js",
|
|
20
|
+
"test:all": "node tests/test-all-rules.js",
|
|
21
|
+
"test:formatting": "node tests/test-runner.js",
|
|
22
|
+
"test:complexity": "node tests/test-complexity-rules.js",
|
|
23
|
+
"test:safety": "node tests/test-safety-rules.js",
|
|
24
|
+
"test:security": "node tests/test-security-rules.js",
|
|
25
|
+
"test:sonarjs": "node tests/test-sonarjs-rules.js",
|
|
26
|
+
"test:unicorn": "node tests/test-unicorn-rules.js",
|
|
27
|
+
"test:cli": "node tests/test-cli.js",
|
|
28
|
+
"test:install": "node tests/test-install-simulation.js"
|
|
26
29
|
},
|
|
27
30
|
"keywords": [],
|
|
28
31
|
"author": "",
|
|
29
32
|
"license": "MIT",
|
|
30
33
|
"peerDependencies": {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
"@stylistic/eslint-plugin": "^5.0.0",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
36
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
37
|
+
"eslint": "^9.0.0",
|
|
38
|
+
"eslint-plugin-functional": "^7.0.0",
|
|
39
|
+
"eslint-plugin-import": "^2.0.0",
|
|
40
|
+
"eslint-plugin-jsdoc": "^50.0.0",
|
|
41
|
+
"eslint-plugin-jsx-a11y": "^6.0.0",
|
|
42
|
+
"eslint-plugin-no-secrets": "^1.0.0",
|
|
43
|
+
"eslint-plugin-perfectionist": "^4.0.0",
|
|
44
|
+
"eslint-plugin-promise": "^7.0.0",
|
|
45
|
+
"eslint-plugin-regexp": "^2.0.0",
|
|
46
|
+
"eslint-plugin-security": "^3.0.0",
|
|
47
|
+
"eslint-plugin-simple-import-sort": "^12.0.0",
|
|
48
|
+
"eslint-plugin-sonarjs": "^3.0.0",
|
|
49
|
+
"eslint-plugin-unicorn": "^56.0.0",
|
|
50
|
+
"eslint-plugin-unused-imports": "^4.0.0"
|
|
39
51
|
},
|
|
40
52
|
"devDependencies": {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
"@stylistic/eslint-plugin": "^5.2.2",
|
|
54
|
+
"@typescript-eslint/eslint-plugin": "^8.38.0",
|
|
55
|
+
"@typescript-eslint/parser": "^8.38.0",
|
|
56
|
+
"eslint": "^9.32.0",
|
|
57
|
+
"eslint-plugin-functional": "^7.3.0",
|
|
58
|
+
"eslint-plugin-import": "^2.32.0",
|
|
59
|
+
"eslint-plugin-jsdoc": "^50.8.0",
|
|
60
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
61
|
+
"eslint-plugin-no-secrets": "^1.1.2",
|
|
62
|
+
"eslint-plugin-perfectionist": "^4.15.0",
|
|
63
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
64
|
+
"eslint-plugin-regexp": "^2.9.0",
|
|
65
|
+
"eslint-plugin-security": "^3.0.1",
|
|
66
|
+
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
67
|
+
"eslint-plugin-sonarjs": "^3.0.4",
|
|
68
|
+
"eslint-plugin-unicorn": "^56.0.1",
|
|
69
|
+
"eslint-plugin-unused-imports": "^4.1.4"
|
|
49
70
|
}
|
|
50
|
-
|
|
71
|
+
}
|