@gooddata/eslint-config 4.1.0 → 11.4.0-alpha.4

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