@agilebot/eslint-plugin 0.3.8 → 0.3.10
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +9 -9
- package/LICENSE.tpl +8 -8
- package/README.md +9 -9
- package/dist/index.js +148 -94
- package/package.json +5 -5
package/LICENSE
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2024 Agilebot, Inc.
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
-
|
7
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
-
|
9
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Agilebot, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/LICENSE.tpl
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
/**
|
2
|
-
* @license %(name)s v%(version)s
|
3
|
-
*
|
4
|
-
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
|
-
*
|
6
|
-
* This source code is licensed under the MIT license found in the
|
7
|
-
* LICENSE file in the root directory of this source tree.
|
8
|
-
*/
|
1
|
+
/**
|
2
|
+
* @license %(name)s v%(version)s
|
3
|
+
*
|
4
|
+
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
|
+
*
|
6
|
+
* This source code is licensed under the MIT license found in the
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
8
|
+
*/
|
package/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# @agilebot/eslint-plugin
|
2
|
-
|
3
|
-
Agilebot extended ESLint rules. For @agilebot/eslint-config.
|
4
|
-
|
5
|
-
### Usage
|
6
|
-
|
7
|
-
```bash
|
8
|
-
npm install --save-dev eslint @agilebot/eslint-plugin
|
9
|
-
```
|
1
|
+
# @agilebot/eslint-plugin
|
2
|
+
|
3
|
+
Agilebot extended ESLint rules. For @agilebot/eslint-config.
|
4
|
+
|
5
|
+
### Usage
|
6
|
+
|
7
|
+
```bash
|
8
|
+
npm install --save-dev eslint @agilebot/eslint-plugin
|
9
|
+
```
|
package/dist/index.js
CHANGED
@@ -1,17 +1,16 @@
|
|
1
|
-
/**
|
2
|
-
* @license @agilebot/eslint-plugin v0.3.
|
3
|
-
*
|
4
|
-
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
|
-
*
|
6
|
-
* This source code is licensed under the MIT license found in the
|
7
|
-
* LICENSE file in the root directory of this source tree.
|
8
|
-
*/
|
1
|
+
/**
|
2
|
+
* @license @agilebot/eslint-plugin v0.3.10
|
3
|
+
*
|
4
|
+
* Copyright (c) Agilebot, Inc. and its affiliates.
|
5
|
+
*
|
6
|
+
* This source code is licensed under the MIT license found in the
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
8
|
+
*/
|
9
9
|
'use strict';
|
10
10
|
|
11
11
|
var eslintUtils = require('@agilebot/eslint-utils');
|
12
12
|
var fs = require('node:fs');
|
13
13
|
var path = require('node:path');
|
14
|
-
var utils = require('@typescript-eslint/utils');
|
15
14
|
|
16
15
|
function _interopNamespaceDefault(e) {
|
17
16
|
var n = Object.create(null);
|
@@ -33,12 +32,12 @@ function _interopNamespaceDefault(e) {
|
|
33
32
|
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
34
33
|
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
35
34
|
|
36
|
-
var enforceMuiIconAlias = {
|
35
|
+
var enforceMuiIconAlias = eslintUtils.createESLintRule({
|
37
36
|
meta: {
|
38
37
|
type: 'problem',
|
39
38
|
docs: {
|
40
39
|
description: 'Enforce alias for @mui/icons-material imports',
|
41
|
-
recommended:
|
40
|
+
recommended: 'recommended'
|
42
41
|
},
|
43
42
|
fixable: 'code',
|
44
43
|
schema: [],
|
@@ -46,6 +45,7 @@ var enforceMuiIconAlias = {
|
|
46
45
|
iconAlias: 'Import for {{ name }} should be aliased.'
|
47
46
|
}
|
48
47
|
},
|
48
|
+
defaultOptions: [],
|
49
49
|
create(context) {
|
50
50
|
return {
|
51
51
|
ImportDeclaration(node) {
|
@@ -70,10 +70,11 @@ var enforceMuiIconAlias = {
|
|
70
70
|
}
|
71
71
|
};
|
72
72
|
}
|
73
|
-
};
|
73
|
+
});
|
74
74
|
|
75
|
-
var funcNaming = {
|
75
|
+
var funcNaming = eslintUtils.createESLintRule({
|
76
76
|
meta: {
|
77
|
+
type: 'problem',
|
77
78
|
docs: {
|
78
79
|
description: 'Enforce function naming convention'
|
79
80
|
},
|
@@ -81,6 +82,7 @@ var funcNaming = {
|
|
81
82
|
type: 'object',
|
82
83
|
properties: {
|
83
84
|
format: {
|
85
|
+
type: 'string',
|
84
86
|
"enum": ['camelCase', 'PascalCase']
|
85
87
|
}
|
86
88
|
}
|
@@ -90,6 +92,7 @@ var funcNaming = {
|
|
90
92
|
invalidReactFCNaming: 'Invalid naming convention for React functional component, expected PascalCase'
|
91
93
|
}
|
92
94
|
},
|
95
|
+
defaultOptions: [],
|
93
96
|
create(context) {
|
94
97
|
if (!context.options[0]) {
|
95
98
|
throw new Error('Missing options');
|
@@ -162,14 +165,15 @@ var funcNaming = {
|
|
162
165
|
}
|
163
166
|
},
|
164
167
|
VariableDeclarator(node) {
|
165
|
-
if (node.init && ['FunctionExpression', 'ArrowFunctionExpression'].includes(node.init.type)) {
|
168
|
+
if (node.id && node.init && ['FunctionExpression', 'ArrowFunctionExpression'].includes(node.init.type)) {
|
166
169
|
const fnName = node.id.name;
|
167
170
|
let isReactComponent = checkJSXElement(node.init.body);
|
168
171
|
if (node.id.typeAnnotation && node.id.typeAnnotation.typeAnnotation) {
|
169
172
|
const typeAnnotation = node.id.typeAnnotation.typeAnnotation;
|
170
173
|
if (typeAnnotation.type === 'TSTypeReference' && typeAnnotation.typeName.type === 'Identifier') {
|
171
174
|
const typeName = typeAnnotation.typeName.name;
|
172
|
-
|
175
|
+
const typeNameLast = typeName.split('.').pop();
|
176
|
+
if (['FC', 'FunctionComponent', 'VFC', 'VoidFunctionComponent'].includes(typeNameLast)) {
|
173
177
|
isReactComponent = true;
|
174
178
|
}
|
175
179
|
}
|
@@ -187,7 +191,7 @@ var funcNaming = {
|
|
187
191
|
}
|
188
192
|
};
|
189
193
|
}
|
190
|
-
};
|
194
|
+
});
|
191
195
|
|
192
196
|
function getSetting(context, name) {
|
193
197
|
return context.settings["agilebot/".concat(name)];
|
@@ -202,12 +206,12 @@ function warnOnce(message) {
|
|
202
206
|
console.warn("Warning: ".concat(message));
|
203
207
|
}
|
204
208
|
|
205
|
-
var importMonorepo = {
|
209
|
+
var importMonorepo = eslintUtils.createESLintRule({
|
206
210
|
meta: {
|
207
211
|
type: 'problem',
|
208
212
|
docs: {
|
209
213
|
description: 'Enforce import styles for monorepo',
|
210
|
-
recommended:
|
214
|
+
recommended: 'recommended'
|
211
215
|
},
|
212
216
|
fixable: 'code',
|
213
217
|
schema: [],
|
@@ -215,6 +219,7 @@ var importMonorepo = {
|
|
215
219
|
monorepoImport: 'Import for {{ module }} should not contains src folder.'
|
216
220
|
}
|
217
221
|
},
|
222
|
+
defaultOptions: [],
|
218
223
|
create(context) {
|
219
224
|
return {
|
220
225
|
ImportDeclaration(node) {
|
@@ -247,7 +252,7 @@ var importMonorepo = {
|
|
247
252
|
}
|
248
253
|
};
|
249
254
|
}
|
250
|
-
};
|
255
|
+
});
|
251
256
|
|
252
257
|
function findFormatMessageAttrNode(node, attrName) {
|
253
258
|
if (node.type === 'CallExpression' && (node.callee.name === 'formatMessage' || node.callee.name === '$t') && node.arguments.length > 0 && node.arguments[0].properties) {
|
@@ -317,15 +322,20 @@ function getIntlIds(context) {
|
|
317
322
|
return results;
|
318
323
|
}
|
319
324
|
|
320
|
-
var intlIdMissing = {
|
325
|
+
var intlIdMissing = eslintUtils.createESLintRule({
|
321
326
|
meta: {
|
327
|
+
type: 'problem',
|
322
328
|
docs: {
|
323
|
-
description: 'Validates intl message ids are in locale file'
|
324
|
-
category: 'Intl'
|
329
|
+
description: 'Validates intl message ids are in locale file'
|
325
330
|
},
|
326
|
-
|
327
|
-
|
331
|
+
schema: [],
|
332
|
+
messages: {
|
333
|
+
missingId: 'Missing id: {{value}}',
|
334
|
+
missingIdPattern: 'Missing id pattern: {{value}}',
|
335
|
+
disallowInvoke: 'Do not invoke intl by {{value}}'
|
336
|
+
}
|
328
337
|
},
|
338
|
+
defaultOptions: [],
|
329
339
|
create: function (context) {
|
330
340
|
const translatedIds = getIntlIds(context);
|
331
341
|
const translatedIdSet = new Set(translatedIds);
|
@@ -339,7 +349,10 @@ var intlIdMissing = {
|
|
339
349
|
if (!isLiteralTranslated(node.value)) {
|
340
350
|
context.report({
|
341
351
|
node: node,
|
342
|
-
|
352
|
+
messageId: 'missingId',
|
353
|
+
data: {
|
354
|
+
value: node.value
|
355
|
+
}
|
343
356
|
});
|
344
357
|
}
|
345
358
|
}
|
@@ -349,7 +362,10 @@ var intlIdMissing = {
|
|
349
362
|
if (!isTemplateTranslated(re)) {
|
350
363
|
context.report({
|
351
364
|
node: node,
|
352
|
-
|
365
|
+
messageId: 'missingIdPattern',
|
366
|
+
data: {
|
367
|
+
value: templateLiteralDisplayStr(node)
|
368
|
+
}
|
353
369
|
});
|
354
370
|
}
|
355
371
|
}
|
@@ -365,7 +381,10 @@ var intlIdMissing = {
|
|
365
381
|
}
|
366
382
|
context.report({
|
367
383
|
node: node,
|
368
|
-
|
384
|
+
messageId: 'disallowInvoke',
|
385
|
+
data: {
|
386
|
+
value: node.value.type
|
387
|
+
}
|
369
388
|
});
|
370
389
|
}
|
371
390
|
return {
|
@@ -389,19 +408,19 @@ var intlIdMissing = {
|
|
389
408
|
}
|
390
409
|
};
|
391
410
|
}
|
392
|
-
};
|
411
|
+
});
|
393
412
|
|
394
|
-
var intlIdNaming = {
|
413
|
+
var intlIdNaming = eslintUtils.createESLintRule({
|
395
414
|
meta: {
|
415
|
+
type: 'problem',
|
396
416
|
docs: {
|
397
|
-
description: 'Validates intl message ids naming convention'
|
398
|
-
category: 'Intl'
|
417
|
+
description: 'Validates intl message ids naming convention'
|
399
418
|
},
|
400
|
-
fixable: undefined,
|
401
419
|
schema: [{
|
402
420
|
type: 'object',
|
403
421
|
properties: {
|
404
422
|
format: {
|
423
|
+
type: 'string',
|
405
424
|
"enum": ['camelCase', 'PascalCase']
|
406
425
|
}
|
407
426
|
}
|
@@ -410,6 +429,7 @@ var intlIdNaming = {
|
|
410
429
|
invalidIdNaming: "Invalid id naming, expected {{format}}"
|
411
430
|
}
|
412
431
|
},
|
432
|
+
defaultOptions: [],
|
413
433
|
create: function (context) {
|
414
434
|
if (!context.options[0]) {
|
415
435
|
throw new Error('Missing options');
|
@@ -481,22 +501,25 @@ var intlIdNaming = {
|
|
481
501
|
}
|
482
502
|
};
|
483
503
|
}
|
484
|
-
};
|
504
|
+
});
|
485
505
|
|
486
|
-
var intlIdPrefix = {
|
506
|
+
var intlIdPrefix = eslintUtils.createESLintRule({
|
487
507
|
meta: {
|
508
|
+
type: 'problem',
|
488
509
|
docs: {
|
489
|
-
description: 'Validates intl message ids has correct prefixes'
|
490
|
-
category: 'Intl'
|
510
|
+
description: 'Validates intl message ids has correct prefixes'
|
491
511
|
},
|
492
|
-
fixable: undefined,
|
493
512
|
schema: [{
|
494
513
|
type: 'array',
|
495
514
|
items: {
|
496
515
|
type: 'string'
|
497
516
|
}
|
498
|
-
}]
|
517
|
+
}],
|
518
|
+
messages: {
|
519
|
+
invalidIdPrefix: 'Invalid id prefix: {{value}}'
|
520
|
+
}
|
499
521
|
},
|
522
|
+
defaultOptions: [],
|
500
523
|
create: function (context) {
|
501
524
|
if (context.options[0].length === 0) {
|
502
525
|
throw new Error('Prefixes are required in settings');
|
@@ -506,7 +529,10 @@ var intlIdPrefix = {
|
|
506
529
|
if (!hasPrefix(value)) {
|
507
530
|
context.report({
|
508
531
|
node: node,
|
509
|
-
|
532
|
+
messageId: 'invalidIdPrefix',
|
533
|
+
data: {
|
534
|
+
value
|
535
|
+
}
|
510
536
|
});
|
511
537
|
}
|
512
538
|
}
|
@@ -549,18 +575,19 @@ var intlIdPrefix = {
|
|
549
575
|
}
|
550
576
|
};
|
551
577
|
}
|
552
|
-
};
|
578
|
+
});
|
553
579
|
|
554
580
|
const usedIds = new Map();
|
555
|
-
var intlIdUnused = {
|
581
|
+
var intlIdUnused = eslintUtils.createESLintRule({
|
556
582
|
meta: {
|
583
|
+
type: 'problem',
|
557
584
|
docs: {
|
558
|
-
description: 'Finds unused intl message ids in locale file'
|
559
|
-
category: 'Intl'
|
585
|
+
description: 'Finds unused intl message ids in locale file'
|
560
586
|
},
|
561
|
-
|
562
|
-
|
587
|
+
schema: [],
|
588
|
+
messages: {}
|
563
589
|
},
|
590
|
+
defaultOptions: [],
|
564
591
|
create: function (context) {
|
565
592
|
const projectRoot = getSetting(context, 'project-root');
|
566
593
|
if (!projectRoot) {
|
@@ -625,22 +652,25 @@ var intlIdUnused = {
|
|
625
652
|
}
|
626
653
|
};
|
627
654
|
}
|
628
|
-
};
|
655
|
+
});
|
629
656
|
|
630
|
-
var intlNoDefault = {
|
657
|
+
var intlNoDefault = eslintUtils.createESLintRule({
|
631
658
|
meta: {
|
659
|
+
type: 'problem',
|
632
660
|
docs: {
|
633
|
-
description: 'Validates defaultMessage is not used with react-intl'
|
634
|
-
category: 'Intl'
|
661
|
+
description: 'Validates defaultMessage is not used with react-intl'
|
635
662
|
},
|
636
|
-
|
637
|
-
|
663
|
+
schema: [],
|
664
|
+
messages: {
|
665
|
+
noDefaultMessage: 'Do not use defaultMessage'
|
666
|
+
}
|
638
667
|
},
|
668
|
+
defaultOptions: [],
|
639
669
|
create: function (context) {
|
640
670
|
function processAttrNode(node) {
|
641
671
|
context.report({
|
642
672
|
node: node,
|
643
|
-
|
673
|
+
messageId: 'noDefaultMessage'
|
644
674
|
});
|
645
675
|
}
|
646
676
|
return {
|
@@ -664,21 +694,21 @@ var intlNoDefault = {
|
|
664
694
|
}
|
665
695
|
};
|
666
696
|
}
|
667
|
-
};
|
697
|
+
});
|
668
698
|
|
669
|
-
var noAsyncArrayMethods = {
|
699
|
+
var noAsyncArrayMethods = eslintUtils.createESLintRule({
|
670
700
|
meta: {
|
701
|
+
type: 'problem',
|
671
702
|
docs: {
|
672
703
|
description: 'No async callback for Array methods forEach, map, filter, reduce, some, every, etc.',
|
673
|
-
|
674
|
-
recommended: true
|
704
|
+
recommended: 'recommended'
|
675
705
|
},
|
676
|
-
fixable: undefined,
|
677
706
|
schema: [],
|
678
707
|
messages: {
|
679
708
|
noAsyncArrayMethods: "No async function in method '{{ methodName }}'"
|
680
709
|
}
|
681
710
|
},
|
711
|
+
defaultOptions: [],
|
682
712
|
create: function (context) {
|
683
713
|
return {
|
684
714
|
ExpressionStatement: function (node) {
|
@@ -706,21 +736,21 @@ var noAsyncArrayMethods = {
|
|
706
736
|
}
|
707
737
|
};
|
708
738
|
}
|
709
|
-
};
|
739
|
+
});
|
710
740
|
|
711
|
-
var noImportCss = {
|
741
|
+
var noImportCss = eslintUtils.createESLintRule({
|
712
742
|
meta: {
|
713
743
|
type: 'problem',
|
714
744
|
docs: {
|
715
745
|
description: 'Prevent importing CSS',
|
716
|
-
recommended:
|
746
|
+
recommended: 'recommended'
|
717
747
|
},
|
718
|
-
fixable: 'code',
|
719
748
|
schema: [],
|
720
749
|
messages: {
|
721
750
|
noImportCSS: 'Do not import CSS files. Use CSS-in-JS instead.'
|
722
751
|
}
|
723
752
|
},
|
753
|
+
defaultOptions: [],
|
724
754
|
create(context) {
|
725
755
|
return {
|
726
756
|
ImportDeclaration(node) {
|
@@ -737,9 +767,9 @@ var noImportCss = {
|
|
737
767
|
}
|
738
768
|
};
|
739
769
|
}
|
740
|
-
};
|
770
|
+
});
|
741
771
|
|
742
|
-
var noThenCatchFinally = {
|
772
|
+
var noThenCatchFinally = eslintUtils.createESLintRule({
|
743
773
|
meta: {
|
744
774
|
type: 'suggestion',
|
745
775
|
docs: {
|
@@ -761,6 +791,7 @@ var noThenCatchFinally = {
|
|
761
791
|
forbiddenThenCatchFinally: "then()/catch()/finally() is forbidden when invoke {{ name }}()."
|
762
792
|
}
|
763
793
|
},
|
794
|
+
defaultOptions: [],
|
764
795
|
create(context) {
|
765
796
|
const configuration = context.options[0] || {};
|
766
797
|
const restrictedFunctions = configuration.restrictedFunctions || [];
|
@@ -791,14 +822,14 @@ var noThenCatchFinally = {
|
|
791
822
|
}
|
792
823
|
};
|
793
824
|
}
|
794
|
-
};
|
825
|
+
});
|
795
826
|
|
796
|
-
var noUnnecessaryTemplateLiterals = {
|
827
|
+
var noUnnecessaryTemplateLiterals = eslintUtils.createESLintRule({
|
797
828
|
meta: {
|
798
829
|
type: 'problem',
|
799
830
|
docs: {
|
800
831
|
description: 'Check if a template string contains only one ${}',
|
801
|
-
recommended:
|
832
|
+
recommended: 'recommended'
|
802
833
|
},
|
803
834
|
fixable: 'code',
|
804
835
|
schema: [],
|
@@ -806,6 +837,7 @@ var noUnnecessaryTemplateLiterals = {
|
|
806
837
|
unnecessaryTemplateString: 'Unnecessary template string with only one ${}.'
|
807
838
|
}
|
808
839
|
},
|
840
|
+
defaultOptions: [],
|
809
841
|
create(context) {
|
810
842
|
return {
|
811
843
|
TemplateLiteral(node) {
|
@@ -822,7 +854,7 @@ var noUnnecessaryTemplateLiterals = {
|
|
822
854
|
}
|
823
855
|
};
|
824
856
|
}
|
825
|
-
};
|
857
|
+
});
|
826
858
|
|
827
859
|
var reactBetterExhaustiveDeps = {
|
828
860
|
meta: {
|
@@ -2016,19 +2048,20 @@ function isAncestorNodeOf(a, b) {
|
|
2016
2048
|
}
|
2017
2049
|
|
2018
2050
|
const Components = require('eslint-plugin-react/lib/util/Components');
|
2019
|
-
var reactHookUseRef = {
|
2051
|
+
var reactHookUseRef = eslintUtils.createESLintRule({
|
2020
2052
|
meta: {
|
2053
|
+
type: 'suggestion',
|
2021
2054
|
docs: {
|
2022
2055
|
description: 'Ensure naming of useRef hook value.',
|
2023
|
-
recommended:
|
2056
|
+
recommended: 'recommended'
|
2024
2057
|
},
|
2025
2058
|
schema: [],
|
2026
|
-
type: 'suggestion',
|
2027
2059
|
hasSuggestions: true,
|
2028
2060
|
messages: {
|
2029
2061
|
useRefName: 'useRef call is not end with "Ref"'
|
2030
2062
|
}
|
2031
2063
|
},
|
2064
|
+
defaultOptions: [],
|
2032
2065
|
create: Components.detect((context, component, util) => ({
|
2033
2066
|
CallExpression(node) {
|
2034
2067
|
const isImmediateReturn = node.parent && node.parent.type === 'ReturnStatement';
|
@@ -2047,7 +2080,7 @@ var reactHookUseRef = {
|
|
2047
2080
|
}
|
2048
2081
|
}
|
2049
2082
|
}))
|
2050
|
-
};
|
2083
|
+
});
|
2051
2084
|
|
2052
2085
|
function* updateImportStatement(context, fixer, key) {
|
2053
2086
|
const sourceCode = context.sourceCode;
|
@@ -2066,20 +2099,21 @@ function* updateImportStatement(context, fixer, key) {
|
|
2066
2099
|
}
|
2067
2100
|
yield fixer.insertTextAfter([...importNode.specifiers].pop(), ", ".concat(key));
|
2068
2101
|
}
|
2069
|
-
var reactPreferNamedPropertyAccess =
|
2070
|
-
defaultOptions: [],
|
2102
|
+
var reactPreferNamedPropertyAccess = eslintUtils.createESLintRule({
|
2071
2103
|
meta: {
|
2072
|
-
type: '
|
2104
|
+
type: 'problem',
|
2073
2105
|
fixable: 'code',
|
2074
2106
|
docs: {
|
2075
2107
|
description: 'Enforce importing each member of React namespace separately instead of accessing them through React namespace',
|
2076
2108
|
recommended: 'recommended'
|
2077
2109
|
},
|
2078
2110
|
messages: {
|
2079
|
-
illegalReactPropertyAccess: 'Illegal React property access: {{name}}. Use named import instead.'
|
2111
|
+
illegalReactPropertyAccess: 'Illegal React property access: {{name}}. Use named import instead.',
|
2112
|
+
disallowImportReactEvent: 'Disallow importing React event types to avoid conflicts with global event types.'
|
2080
2113
|
},
|
2081
2114
|
schema: []
|
2082
2115
|
},
|
2116
|
+
defaultOptions: [],
|
2083
2117
|
create(context) {
|
2084
2118
|
return {
|
2085
2119
|
TSQualifiedName(node) {
|
@@ -2113,17 +2147,30 @@ var reactPreferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
|
|
2113
2147
|
yield* updateImportStatement(context, fixer, node.property.name);
|
2114
2148
|
}
|
2115
2149
|
});
|
2150
|
+
},
|
2151
|
+
ImportDeclaration(node) {
|
2152
|
+
if (node.source.value !== 'react' && node.source.value !== 'preact') {
|
2153
|
+
return;
|
2154
|
+
}
|
2155
|
+
node.specifiers.forEach(specifier => {
|
2156
|
+
if (specifier.type === 'ImportSpecifier' && specifier.imported.name && specifier.imported.name.endsWith('Event')) {
|
2157
|
+
context.report({
|
2158
|
+
node: specifier,
|
2159
|
+
messageId: 'disallowImportReactEvent'
|
2160
|
+
});
|
2161
|
+
}
|
2162
|
+
});
|
2116
2163
|
}
|
2117
2164
|
};
|
2118
2165
|
}
|
2119
2166
|
});
|
2120
2167
|
|
2121
|
-
var reactPreferSxProp = {
|
2168
|
+
var reactPreferSxProp = eslintUtils.createESLintRule({
|
2122
2169
|
meta: {
|
2170
|
+
type: 'problem',
|
2123
2171
|
docs: {
|
2124
2172
|
description: 'Prefer using sx prop instead of inline styles',
|
2125
|
-
|
2126
|
-
recommended: true
|
2173
|
+
recommended: 'recommended'
|
2127
2174
|
},
|
2128
2175
|
messages: {
|
2129
2176
|
preferSxProp: 'Avoid using inline styles, use sx prop or tss-react or styled-component instead'
|
@@ -2141,6 +2188,7 @@ var reactPreferSxProp = {
|
|
2141
2188
|
}
|
2142
2189
|
}]
|
2143
2190
|
},
|
2191
|
+
defaultOptions: [],
|
2144
2192
|
create(context) {
|
2145
2193
|
const configuration = context.options[0] || {};
|
2146
2194
|
const allowedFor = configuration.allowedFor || [];
|
@@ -2185,7 +2233,7 @@ var reactPreferSxProp = {
|
|
2185
2233
|
}
|
2186
2234
|
};
|
2187
2235
|
}
|
2188
|
-
};
|
2236
|
+
});
|
2189
2237
|
|
2190
2238
|
function getBasicIdentifier(node) {
|
2191
2239
|
if (node.type === 'Identifier') {
|
@@ -2276,18 +2324,19 @@ function loopStylesObj(node, callback) {
|
|
2276
2324
|
}
|
2277
2325
|
}
|
2278
2326
|
|
2279
|
-
var tssClassNaming = {
|
2327
|
+
var tssClassNaming = eslintUtils.createESLintRule({
|
2280
2328
|
meta: {
|
2281
2329
|
type: 'problem',
|
2282
2330
|
docs: {
|
2283
2331
|
description: 'Enforce camelCase class names in TSS',
|
2284
|
-
|
2285
|
-
recommended: true
|
2332
|
+
recommended: 'recommended'
|
2286
2333
|
},
|
2334
|
+
schema: [],
|
2287
2335
|
messages: {
|
2288
2336
|
camelCase: 'Class `{{ className }}` must be camelCase in TSS.'
|
2289
2337
|
}
|
2290
2338
|
},
|
2339
|
+
defaultOptions: [],
|
2291
2340
|
create: function rule(context) {
|
2292
2341
|
return {
|
2293
2342
|
CallExpression(node) {
|
@@ -2316,7 +2365,7 @@ var tssClassNaming = {
|
|
2316
2365
|
}
|
2317
2366
|
};
|
2318
2367
|
}
|
2319
|
-
};
|
2368
|
+
});
|
2320
2369
|
|
2321
2370
|
var colors = {
|
2322
2371
|
aliceblue: [240, 248, 255],
|
@@ -2469,17 +2518,19 @@ var colors = {
|
|
2469
2518
|
yellowgreen: [154, 205, 50]
|
2470
2519
|
};
|
2471
2520
|
|
2472
|
-
var tssNoColorName = {
|
2521
|
+
var tssNoColorName = eslintUtils.createESLintRule({
|
2473
2522
|
meta: {
|
2474
2523
|
type: 'suggestion',
|
2475
2524
|
docs: {
|
2476
2525
|
description: 'Enforce the use of color variables instead of color name within TSS',
|
2477
|
-
recommended:
|
2526
|
+
recommended: 'recommended'
|
2478
2527
|
},
|
2528
|
+
schema: [],
|
2479
2529
|
messages: {
|
2480
2530
|
disallowColorName: 'Disallowed color name. Use color from `@mui/material/colors` or `theme.palette`.'
|
2481
2531
|
}
|
2482
2532
|
},
|
2533
|
+
defaultOptions: [],
|
2483
2534
|
create: function (context) {
|
2484
2535
|
return {
|
2485
2536
|
CallExpression(node) {
|
@@ -2499,19 +2550,21 @@ var tssNoColorName = {
|
|
2499
2550
|
}
|
2500
2551
|
};
|
2501
2552
|
}
|
2502
|
-
};
|
2553
|
+
});
|
2503
2554
|
|
2504
|
-
var tssNoColorValue = {
|
2555
|
+
var tssNoColorValue = eslintUtils.createESLintRule({
|
2505
2556
|
meta: {
|
2506
2557
|
type: 'problem',
|
2507
2558
|
docs: {
|
2508
2559
|
description: 'Enforce the use of color variables instead of color codes within TSS',
|
2509
|
-
recommended:
|
2560
|
+
recommended: 'recommended'
|
2510
2561
|
},
|
2562
|
+
schema: [],
|
2511
2563
|
messages: {
|
2512
2564
|
preferMuiColor: 'Prefer use color from `@mui/material/colors` or `theme.palette`.'
|
2513
2565
|
}
|
2514
2566
|
},
|
2567
|
+
defaultOptions: [],
|
2515
2568
|
create: function (context) {
|
2516
2569
|
return {
|
2517
2570
|
CallExpression(node) {
|
@@ -2534,20 +2587,21 @@ var tssNoColorValue = {
|
|
2534
2587
|
}
|
2535
2588
|
};
|
2536
2589
|
}
|
2537
|
-
};
|
2590
|
+
});
|
2538
2591
|
|
2539
|
-
var tssUnusedClasses = {
|
2592
|
+
var tssUnusedClasses = eslintUtils.createESLintRule({
|
2540
2593
|
meta: {
|
2541
2594
|
type: 'suggestion',
|
2542
2595
|
docs: {
|
2543
2596
|
description: 'Disallow unused classes in tss',
|
2544
|
-
|
2545
|
-
recommended: true
|
2597
|
+
recommended: 'recommended'
|
2546
2598
|
},
|
2599
|
+
schema: [],
|
2547
2600
|
messages: {
|
2548
2601
|
unusedClass: 'Class `{{ className }}` is unused in JSX'
|
2549
2602
|
}
|
2550
2603
|
},
|
2604
|
+
defaultOptions: [],
|
2551
2605
|
create: function rule(context) {
|
2552
2606
|
const usedClasses = {};
|
2553
2607
|
const definedClasses = {};
|
@@ -2623,7 +2677,7 @@ var tssUnusedClasses = {
|
|
2623
2677
|
}
|
2624
2678
|
};
|
2625
2679
|
}
|
2626
|
-
};
|
2680
|
+
});
|
2627
2681
|
|
2628
2682
|
var ruleFiles = /*#__PURE__*/Object.freeze({
|
2629
2683
|
__proto__: null,
|
@@ -2669,7 +2723,7 @@ Object.keys(ruleFiles).forEach(key => {
|
|
2669
2723
|
const rule = ruleFiles[key];
|
2670
2724
|
plugin.rules[finalKey] = rule;
|
2671
2725
|
if (rule.meta && rule.meta.docs && rule.meta.docs.recommended) {
|
2672
|
-
plugin.configs.recommended.rules["@agilebot/".concat(finalKey)] = rule.meta.type === '
|
2726
|
+
plugin.configs.recommended.rules["@agilebot/".concat(finalKey)] = rule.meta.type === 'problem' ? 'error' : 'warn';
|
2673
2727
|
}
|
2674
2728
|
});
|
2675
2729
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@agilebot/eslint-plugin",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.10",
|
4
4
|
"description": "Agilebot's ESLint plugin",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"types": "dist/index.d.ts",
|
@@ -18,9 +18,8 @@
|
|
18
18
|
"node": "^18.18.0 || >=20.0.0"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"
|
22
|
-
"eslint-
|
23
|
-
"@agilebot/eslint-utils": "0.3.8"
|
21
|
+
"eslint-plugin-react": "^7.34.3",
|
22
|
+
"@agilebot/eslint-utils": "0.3.10"
|
24
23
|
},
|
25
24
|
"peerDependencies": {
|
26
25
|
"eslint": "^7.0.0 || ^8.0.0"
|
@@ -32,7 +31,8 @@
|
|
32
31
|
"@types/color-name": "^1.1.4",
|
33
32
|
"@types/estree": "^1.0.5",
|
34
33
|
"color-name": "^2.0.0",
|
35
|
-
"eslint-vitest-rule-tester": "^0.3.2"
|
34
|
+
"eslint-vitest-rule-tester": "^0.3.2",
|
35
|
+
"typescript-eslint": "^7.16.0"
|
36
36
|
},
|
37
37
|
"scripts": {
|
38
38
|
"build": "rollup -c rollup.config.mjs",
|