@gooddata/eslint-config 4.1.1 → 11.4.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.
@@ -0,0 +1,801 @@
1
+ {
2
+ "plugins": [
3
+ "header",
4
+ "import",
5
+ "no-only-tests",
6
+ "sonarjs",
7
+ "tsdoc",
8
+ "eslint-comments",
9
+ "react",
10
+ "react-hooks",
11
+ "import-esm",
12
+ "cypress",
13
+ "chai-friendly"
14
+ ],
15
+ "extends": [
16
+ "eslint:recommended",
17
+ "plugin:import/errors",
18
+ "plugin:prettier/recommended",
19
+ "plugin:regexp/recommended",
20
+ "plugin:sonarjs/recommended",
21
+ "plugin:react-hooks/recommended",
22
+ "plugin:import-esm/recommended",
23
+ "plugin:cypress/recommended"
24
+ ],
25
+ "rules": {
26
+ "no-console": [
27
+ 2,
28
+ {
29
+ "allow": [
30
+ "warn",
31
+ "error"
32
+ ]
33
+ }
34
+ ],
35
+ "no-duplicate-imports": "error",
36
+ "no-restricted-imports": [
37
+ "error",
38
+ {
39
+ "paths": [
40
+ {
41
+ "name": "react",
42
+ "importNames": [
43
+ "default"
44
+ ],
45
+ "message": "Default import from React is not allowed. Use named imports instead."
46
+ }
47
+ ],
48
+ "patterns": [
49
+ {
50
+ "group": [
51
+ "lodash-es"
52
+ ],
53
+ "importNames": [
54
+ "get",
55
+ "getOr"
56
+ ],
57
+ "message": "Please use the ?. and ?? operators instead."
58
+ },
59
+ {
60
+ "group": [
61
+ "lodash-es"
62
+ ],
63
+ "importNames": [
64
+ "keys"
65
+ ],
66
+ "message": "Please use Object.keys() instead."
67
+ },
68
+ {
69
+ "group": [
70
+ "lodash-es"
71
+ ],
72
+ "importNames": [
73
+ "values"
74
+ ],
75
+ "message": "Please use Object.values() instead."
76
+ },
77
+ {
78
+ "group": [
79
+ "lodash-es"
80
+ ],
81
+ "importNames": [
82
+ "entries",
83
+ "toPairs"
84
+ ],
85
+ "message": "Please use Object.entries() instead."
86
+ },
87
+ {
88
+ "group": [
89
+ "lodash-es"
90
+ ],
91
+ "importNames": [
92
+ "map"
93
+ ],
94
+ "message": "Please use Array.prototype.map() instead."
95
+ },
96
+ {
97
+ "group": [
98
+ "lodash-es"
99
+ ],
100
+ "importNames": [
101
+ "flatMap"
102
+ ],
103
+ "message": "Please use Array.prototype.flatMap() instead."
104
+ },
105
+ {
106
+ "group": [
107
+ "lodash-es"
108
+ ],
109
+ "importNames": [
110
+ "filter"
111
+ ],
112
+ "message": "Please use Array.prototype.filter() instead."
113
+ },
114
+ {
115
+ "group": [
116
+ "lodash-es"
117
+ ],
118
+ "importNames": [
119
+ "find"
120
+ ],
121
+ "message": "Please use Array.prototype.find() instead."
122
+ },
123
+ {
124
+ "group": [
125
+ "lodash-es"
126
+ ],
127
+ "importNames": [
128
+ "findIndex"
129
+ ],
130
+ "message": "Please use Array.prototype.findIndex() instead."
131
+ },
132
+ {
133
+ "group": [
134
+ "lodash-es"
135
+ ],
136
+ "importNames": [
137
+ "includes"
138
+ ],
139
+ "message": "Please use Array.prototype.includes() instead."
140
+ },
141
+ {
142
+ "group": [
143
+ "lodash-es"
144
+ ],
145
+ "importNames": [
146
+ "some"
147
+ ],
148
+ "message": "Please use Array.prototype.some() instead."
149
+ },
150
+ {
151
+ "group": [
152
+ "lodash-es"
153
+ ],
154
+ "importNames": [
155
+ "every"
156
+ ],
157
+ "message": "Please use Array.prototype.every() instead."
158
+ },
159
+ {
160
+ "group": [
161
+ "lodash-es"
162
+ ],
163
+ "importNames": [
164
+ "concat"
165
+ ],
166
+ "message": "Please use Array.prototype.concat() or spread [...arr1, ...arr2] instead."
167
+ },
168
+ {
169
+ "group": [
170
+ "lodash-es"
171
+ ],
172
+ "importNames": [
173
+ "reverse"
174
+ ],
175
+ "message": "Please use Array.prototype.reverse() instead."
176
+ },
177
+ {
178
+ "group": [
179
+ "lodash-es"
180
+ ],
181
+ "importNames": [
182
+ "slice"
183
+ ],
184
+ "message": "Please use Array.prototype.slice() instead."
185
+ },
186
+ {
187
+ "group": [
188
+ "lodash-es"
189
+ ],
190
+ "importNames": [
191
+ "indexOf"
192
+ ],
193
+ "message": "Please use Array.prototype.indexOf() instead."
194
+ },
195
+ {
196
+ "group": [
197
+ "lodash-es"
198
+ ],
199
+ "importNames": [
200
+ "lastIndexOf"
201
+ ],
202
+ "message": "Please use Array.prototype.lastIndexOf() instead."
203
+ },
204
+ {
205
+ "group": [
206
+ "lodash-es"
207
+ ],
208
+ "importNames": [
209
+ "fill"
210
+ ],
211
+ "message": "Please use Array.prototype.fill() instead."
212
+ },
213
+ {
214
+ "group": [
215
+ "lodash-es"
216
+ ],
217
+ "importNames": [
218
+ "startsWith"
219
+ ],
220
+ "message": "Please use String.prototype.startsWith() instead."
221
+ },
222
+ {
223
+ "group": [
224
+ "lodash-es"
225
+ ],
226
+ "importNames": [
227
+ "endsWith"
228
+ ],
229
+ "message": "Please use String.prototype.endsWith() instead."
230
+ },
231
+ {
232
+ "group": [
233
+ "lodash-es"
234
+ ],
235
+ "importNames": [
236
+ "repeat"
237
+ ],
238
+ "message": "Please use String.prototype.repeat() instead."
239
+ },
240
+ {
241
+ "group": [
242
+ "lodash-es"
243
+ ],
244
+ "importNames": [
245
+ "padStart"
246
+ ],
247
+ "message": "Please use String.prototype.padStart() instead."
248
+ },
249
+ {
250
+ "group": [
251
+ "lodash-es"
252
+ ],
253
+ "importNames": [
254
+ "padEnd"
255
+ ],
256
+ "message": "Please use String.prototype.padEnd() instead."
257
+ },
258
+ {
259
+ "group": [
260
+ "lodash-es"
261
+ ],
262
+ "importNames": [
263
+ "trim"
264
+ ],
265
+ "message": "Please use String.prototype.trim() instead."
266
+ },
267
+ {
268
+ "group": [
269
+ "lodash-es"
270
+ ],
271
+ "importNames": [
272
+ "trimStart",
273
+ "trimLeft"
274
+ ],
275
+ "message": "Please use String.prototype.trimStart() instead."
276
+ },
277
+ {
278
+ "group": [
279
+ "lodash-es"
280
+ ],
281
+ "importNames": [
282
+ "trimEnd",
283
+ "trimRight"
284
+ ],
285
+ "message": "Please use String.prototype.trimEnd() instead."
286
+ },
287
+ {
288
+ "group": [
289
+ "lodash-es"
290
+ ],
291
+ "importNames": [
292
+ "toUpper"
293
+ ],
294
+ "message": "Please use String.prototype.toUpperCase() instead."
295
+ },
296
+ {
297
+ "group": [
298
+ "lodash-es"
299
+ ],
300
+ "importNames": [
301
+ "toLower"
302
+ ],
303
+ "message": "Please use String.prototype.toLowerCase() instead."
304
+ },
305
+ {
306
+ "group": [
307
+ "lodash-es"
308
+ ],
309
+ "importNames": [
310
+ "isArray"
311
+ ],
312
+ "message": "Please use Array.isArray() instead."
313
+ },
314
+ {
315
+ "group": [
316
+ "lodash-es"
317
+ ],
318
+ "importNames": [
319
+ "isNaN"
320
+ ],
321
+ "message": "Please use Number.isNaN() instead."
322
+ },
323
+ {
324
+ "group": [
325
+ "lodash-es"
326
+ ],
327
+ "importNames": [
328
+ "isFinite"
329
+ ],
330
+ "message": "Please use Number.isFinite() instead."
331
+ },
332
+ {
333
+ "group": [
334
+ "lodash-es"
335
+ ],
336
+ "importNames": [
337
+ "isInteger"
338
+ ],
339
+ "message": "Please use Number.isInteger() instead."
340
+ },
341
+ {
342
+ "group": [
343
+ "lodash-es"
344
+ ],
345
+ "importNames": [
346
+ "isNull"
347
+ ],
348
+ "message": "Please use value === null instead."
349
+ },
350
+ {
351
+ "group": [
352
+ "lodash-es"
353
+ ],
354
+ "importNames": [
355
+ "isUndefined"
356
+ ],
357
+ "message": "Please use value === undefined instead."
358
+ },
359
+ {
360
+ "group": [
361
+ "lodash-es"
362
+ ],
363
+ "importNames": [
364
+ "defaultTo"
365
+ ],
366
+ "message": "Please use value ?? defaultValue instead."
367
+ },
368
+ {
369
+ "group": [
370
+ "lodash-es"
371
+ ],
372
+ "importNames": [
373
+ "assign"
374
+ ],
375
+ "message": "Please use Object.assign() or spread syntax {...obj} instead."
376
+ },
377
+ {
378
+ "group": [
379
+ "lodash-es"
380
+ ],
381
+ "importNames": [
382
+ "flatten"
383
+ ],
384
+ "message": "Please use Array.prototype.flat() instead."
385
+ },
386
+ {
387
+ "group": [
388
+ "lodash-es"
389
+ ],
390
+ "importNames": [
391
+ "flattenDeep"
392
+ ],
393
+ "message": "Please use Array.prototype.flat(Infinity) instead."
394
+ },
395
+ {
396
+ "group": [
397
+ "lodash-es"
398
+ ],
399
+ "importNames": [
400
+ "isNil"
401
+ ],
402
+ "message": "Please use value === null || value === undefined instead."
403
+ },
404
+ {
405
+ "group": [
406
+ "lodash-es"
407
+ ],
408
+ "importNames": [
409
+ "noop"
410
+ ],
411
+ "message": "Please use () => {} instead."
412
+ },
413
+ {
414
+ "group": [
415
+ "lodash-es"
416
+ ],
417
+ "importNames": [
418
+ "identity"
419
+ ],
420
+ "message": "Please use x => x instead."
421
+ },
422
+ {
423
+ "group": [
424
+ "lodash-es"
425
+ ],
426
+ "importNames": [
427
+ "first",
428
+ "head"
429
+ ],
430
+ "message": "Please use Array.prototype.at(0) instead."
431
+ },
432
+ {
433
+ "group": [
434
+ "lodash-es"
435
+ ],
436
+ "importNames": [
437
+ "last"
438
+ ],
439
+ "message": "Please use Array.prototype.at(-1) instead."
440
+ },
441
+ {
442
+ "group": [
443
+ "lodash-es"
444
+ ],
445
+ "importNames": [
446
+ "forEach"
447
+ ],
448
+ "message": "Please use Array.prototype.forEach() instead."
449
+ },
450
+ {
451
+ "group": [
452
+ "lodash-es"
453
+ ],
454
+ "importNames": [
455
+ "fromPairs"
456
+ ],
457
+ "message": "Please use Object.fromEntries() instead."
458
+ },
459
+ {
460
+ "group": [
461
+ "lodash-es"
462
+ ],
463
+ "importNames": [
464
+ "join"
465
+ ],
466
+ "message": "Please use Array.prototype.join() instead."
467
+ },
468
+ {
469
+ "group": [
470
+ "lodash-es"
471
+ ],
472
+ "importNames": [
473
+ "isDate"
474
+ ],
475
+ "message": "Please use val instanceof Date instead."
476
+ },
477
+ {
478
+ "group": [
479
+ "lodash-es"
480
+ ],
481
+ "importNames": [
482
+ "isFunction"
483
+ ],
484
+ "message": "Please use typeof val === 'function' instead."
485
+ },
486
+ {
487
+ "group": [
488
+ "lodash-es"
489
+ ],
490
+ "importNames": [
491
+ "isNumber"
492
+ ],
493
+ "message": "Please use typeof val === 'number' instead."
494
+ },
495
+ {
496
+ "group": [
497
+ "lodash-es"
498
+ ],
499
+ "importNames": [
500
+ "isObject"
501
+ ],
502
+ "message": "Please use val !== null && typeof val === 'object' instead."
503
+ },
504
+ {
505
+ "group": [
506
+ "lodash-es"
507
+ ],
508
+ "importNames": [
509
+ "isString"
510
+ ],
511
+ "message": "Please use typeof val === 'string' instead."
512
+ },
513
+ {
514
+ "group": [
515
+ "lodash-es"
516
+ ],
517
+ "importNames": [
518
+ "toString"
519
+ ],
520
+ "message": "Please use String(val) instead."
521
+ },
522
+ {
523
+ "group": [
524
+ "lodash-es"
525
+ ],
526
+ "importNames": [
527
+ "flow",
528
+ "flowRight"
529
+ ],
530
+ "message": "Please refactor your code instead."
531
+ }
532
+ ]
533
+ }
534
+ ],
535
+ "no-restricted-syntax": [
536
+ "error",
537
+ {
538
+ "selector": "MemberExpression[object.name='React']",
539
+ "message": "Do not use `React.*`. Use named imports instead."
540
+ }
541
+ ],
542
+ "sort-imports": [
543
+ "error",
544
+ {
545
+ "ignoreCase": false,
546
+ "ignoreDeclarationSort": true,
547
+ "ignoreMemberSort": false
548
+ }
549
+ ],
550
+ "no-useless-escape": "off",
551
+ "no-negated-condition": "error",
552
+ "no-unneeded-ternary": [
553
+ "error",
554
+ {
555
+ "defaultAssignment": false
556
+ }
557
+ ],
558
+ "no-extra-boolean-cast": "error",
559
+ "no-unexpected-multiline": "off",
560
+ "header/header": [
561
+ 2,
562
+ "line",
563
+ {
564
+ "pattern": "^ \\(C\\) \\d{4}(-\\d{4})? GoodData Corporation$",
565
+ "template": " (C) 2025 GoodData Corporation"
566
+ }
567
+ ],
568
+ "import/order": [
569
+ "error",
570
+ {
571
+ "pathGroups": [
572
+ {
573
+ "pattern": "react",
574
+ "group": "external",
575
+ "position": "before"
576
+ },
577
+ {
578
+ "pattern": "@gooddata/**",
579
+ "group": "external",
580
+ "position": "after"
581
+ }
582
+ ],
583
+ "groups": [
584
+ "builtin",
585
+ "external",
586
+ "internal",
587
+ [
588
+ "parent",
589
+ "sibling",
590
+ "index"
591
+ ]
592
+ ],
593
+ "pathGroupsExcludedImportTypes": [
594
+ "react"
595
+ ],
596
+ "alphabetize": {
597
+ "order": "asc",
598
+ "caseInsensitive": true
599
+ },
600
+ "newlines-between": "always"
601
+ }
602
+ ],
603
+ "import/no-unassigned-import": "error",
604
+ "no-only-tests/no-only-tests": [
605
+ "error",
606
+ {
607
+ "block": [
608
+ "fixture"
609
+ ],
610
+ "focus": [
611
+ "only"
612
+ ]
613
+ }
614
+ ],
615
+ "regexp/prefer-d": "off",
616
+ "regexp/prefer-w": "off",
617
+ "sonarjs/no-duplicate-string": "off",
618
+ "sonarjs/cognitive-complexity": "warn",
619
+ "tsdoc/syntax": "error",
620
+ "eslint-comments/no-unused-disable": "error",
621
+ "no-caller": 2,
622
+ "no-eval": 2,
623
+ "no-delete-var": 2,
624
+ "no-octal-escape": 2,
625
+ "react/no-danger": "error",
626
+ "react/prop-types": "off",
627
+ "react/function-component-definition": [
628
+ "error",
629
+ {
630
+ "namedComponents": "function-declaration",
631
+ "unnamedComponents": "arrow-function"
632
+ }
633
+ ],
634
+ "react/jsx-no-leaked-render": [
635
+ "warn",
636
+ {
637
+ "validStrategies": [
638
+ "ternary",
639
+ "coerce"
640
+ ]
641
+ }
642
+ ],
643
+ "react/jsx-boolean-value": [
644
+ "error",
645
+ "never"
646
+ ],
647
+ "react/react-in-jsx-scope": "off",
648
+ "react-hooks/rules-of-hooks": "error",
649
+ "react-hooks/exhaustive-deps": "error",
650
+ "cypress/no-unnecessary-waiting": "warn",
651
+ "cypress/no-assigning-return-values": "warn",
652
+ "cypress/unsafe-to-chain-command": "warn",
653
+ "no-unused-expressions": "off",
654
+ "chai-friendly/no-unused-expressions": "error"
655
+ },
656
+ "overrides": [
657
+ {
658
+ "parser": "@typescript-eslint/parser",
659
+ "files": [
660
+ "**/*.ts",
661
+ "**/*.tsx"
662
+ ],
663
+ "extends": [
664
+ "plugin:@typescript-eslint/recommended-type-checked"
665
+ ],
666
+ "parserOptions": {
667
+ "ecmaVersion": 2022,
668
+ "sourceType": "module"
669
+ },
670
+ "rules": {
671
+ "@typescript-eslint/explicit-function-return-type": 0,
672
+ "@typescript-eslint/no-use-before-define": 0,
673
+ "@typescript-eslint/no-empty-function": 0,
674
+ "@typescript-eslint/naming-convention": [
675
+ "error",
676
+ {
677
+ "selector": "interface",
678
+ "format": [
679
+ "PascalCase"
680
+ ],
681
+ "custom": {
682
+ "regex": "^I[A-Z]",
683
+ "match": true
684
+ }
685
+ }
686
+ ],
687
+ "@typescript-eslint/no-unused-vars": [
688
+ 2,
689
+ {
690
+ "varsIgnorePattern": "^_.*$",
691
+ "argsIgnorePattern": "^_.*$"
692
+ }
693
+ ],
694
+ "@typescript-eslint/no-explicit-any": 0,
695
+ "@typescript-eslint/array-type": "off",
696
+ "@typescript-eslint/ban-ts-comment": [
697
+ "error",
698
+ {
699
+ "ts-expect-error": "allow-with-description"
700
+ }
701
+ ],
702
+ "@typescript-eslint/no-wrapper-object-types": "error",
703
+ "@typescript-eslint/no-unsafe-function-type": "error",
704
+ "@typescript-eslint/no-restricted-types": [
705
+ "error",
706
+ {
707
+ "types": {
708
+ "String": {
709
+ "message": "Use 'string' instead",
710
+ "fixWith": "string"
711
+ },
712
+ "Number": {
713
+ "message": "Use 'number' instead",
714
+ "fixWith": "number"
715
+ },
716
+ "Boolean": {
717
+ "message": "Use 'boolean' instead",
718
+ "fixWith": "boolean"
719
+ },
720
+ "Symbol": {
721
+ "message": "Use 'symbol' instead",
722
+ "fixWith": "symbol"
723
+ }
724
+ }
725
+ }
726
+ ],
727
+ "@typescript-eslint/consistent-type-exports": [
728
+ "error",
729
+ {
730
+ "fixMixedExportsWithInlineTypeSpecifier": false
731
+ }
732
+ ],
733
+ "@typescript-eslint/explicit-member-accessibility": "off",
734
+ "@typescript-eslint/interface-name-prefix": "off",
735
+ "@typescript-eslint/member-ordering": "off",
736
+ "@typescript-eslint/no-inferrable-types": "off",
737
+ "@typescript-eslint/no-non-null-assertion": "off",
738
+ "@typescript-eslint/prefer-optional-chain": "error",
739
+ "no-restricted-syntax": [
740
+ "error",
741
+ {
742
+ "selector": "MemberExpression[object.name='React']",
743
+ "message": "Do not use `React.*`. Use named imports instead."
744
+ },
745
+ {
746
+ "selector": "TSTypeReference[typeName.type='TSQualifiedName'][typeName.left.name='React']",
747
+ "message": "Do not use `React.*` types. Use named imports instead."
748
+ }
749
+ ]
750
+ }
751
+ },
752
+ {
753
+ "parser": "@typescript-eslint/parser",
754
+ "files": [
755
+ "**/*.ts",
756
+ "**/*.tsx"
757
+ ],
758
+ "extends": [
759
+ "plugin:import/typescript"
760
+ ]
761
+ },
762
+ {
763
+ "files": [
764
+ "*.test.ts",
765
+ "*.test.tsx",
766
+ "*.spec.ts"
767
+ ],
768
+ "rules": {
769
+ "sonarjs/no-identical-functions": "off"
770
+ }
771
+ },
772
+ {
773
+ "parser": "@typescript-eslint/parser",
774
+ "files": [
775
+ "**/*.ts",
776
+ "**/*.tsx"
777
+ ],
778
+ "rules": {
779
+ "@typescript-eslint/no-unused-expressions": "off"
780
+ }
781
+ }
782
+ ],
783
+ "settings": {
784
+ "react": {
785
+ "version": "detect"
786
+ }
787
+ },
788
+ "env": {
789
+ "node": true,
790
+ "es2022": true,
791
+ "browser": true
792
+ },
793
+ "ignorePatterns": [
794
+ "**/dist/**/*.*",
795
+ "**/esm/**/*.*"
796
+ ],
797
+ "parserOptions": {
798
+ "ecmaVersion": 2022,
799
+ "sourceType": "module"
800
+ }
801
+ }