@agilebot/eslint-plugin 0.7.4 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- /**
2
- * @license @agilebot/eslint-plugin v0.7.4
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.8.1
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 utils = require('@typescript-eslint/utils');
@@ -38,9 +38,9 @@ const hasDocs = typeof ["enforce-mui-icon-alias","intl-id-missing","intl-id-pref
38
38
  ["enforce-mui-icon-alias","intl-id-missing","intl-id-prefix","intl-no-default","react-better-exhaustive-deps"] : [];
39
39
  const createRule = utils.ESLintUtils.RuleCreator(name => hasDocs.includes(name) ? "".concat(docBaseUrl).concat(name, ".md") : "".concat(docBaseUrl).concat(name, ".test.js"));
40
40
 
41
- const RULE_NAME$j = 'enforce-mui-icon-alias';
41
+ const RULE_NAME$h = 'enforce-mui-icon-alias';
42
42
  var enforceMuiIconAlias = createRule({
43
- name: RULE_NAME$j,
43
+ name: RULE_NAME$h,
44
44
  meta: {
45
45
  type: 'problem',
46
46
  docs: {
@@ -61,7 +61,7 @@ var enforceMuiIconAlias = createRule({
61
61
  return;
62
62
  }
63
63
  for (const specifier of node.specifiers) {
64
- if (specifier.type !== 'ImportSpecifier') {
64
+ if (specifier.type !== utils.AST_NODE_TYPES.ImportSpecifier) {
65
65
  return;
66
66
  }
67
67
  if (specifier.imported.name === specifier.local.name || !specifier.local.name.endsWith('Icon')) {
@@ -84,18 +84,9 @@ function getSetting(context, name) {
84
84
  return context.settings["agilebot/".concat(name)];
85
85
  }
86
86
 
87
- const warned = new Set();
88
- function warnOnce(message) {
89
- if (warned.has(message)) {
90
- return;
91
- }
92
- warned.add(message);
93
- console.warn("Warning: ".concat(message));
94
- }
95
-
96
- const RULE_NAME$i = 'import-monorepo';
87
+ const RULE_NAME$g = 'import-monorepo';
97
88
  var importMonorepo = createRule({
98
- name: RULE_NAME$i,
89
+ name: RULE_NAME$g,
99
90
  meta: {
100
91
  type: 'problem',
101
92
  docs: {
@@ -114,7 +105,6 @@ var importMonorepo = createRule({
114
105
  ImportDeclaration(node) {
115
106
  let prefix = getSetting(context, 'monorepo-scope');
116
107
  if (!prefix) {
117
- warnOnce('agilebot/monorepo-scope is not set.');
118
108
  return;
119
109
  }
120
110
  prefix = "".concat(prefix, "/");
@@ -144,25 +134,25 @@ var importMonorepo = createRule({
144
134
  });
145
135
 
146
136
  function findFormatMessageAttrNode(node, attrName) {
147
- if (node.type === 'CallExpression' && (node.callee.name === 'formatMessage' || node.callee.name === '$t') && node.arguments.length > 0 && node.arguments[0].properties) {
137
+ if (node.type === utils.AST_NODE_TYPES.CallExpression && (node.callee.name === 'formatMessage' || node.callee.name === '$t') && node.arguments.length > 0 && node.arguments[0].properties) {
148
138
  return node.arguments[0].properties.find(a => a.key && a.key.name === attrName);
149
139
  }
150
- if (node.type === 'CallExpression' && node.callee.type === 'MemberExpression' && (node.callee.object.name === 'intl' || node.callee.object.name && node.callee.object.name.endsWith('Intl')) && (node.callee.property.name === 'formatMessage' || node.callee.property.name === '$t')) {
140
+ if (node.type === utils.AST_NODE_TYPES.CallExpression && node.callee.type === utils.AST_NODE_TYPES.MemberExpression && (node.callee.object.name === 'intl' || node.callee.object.name && node.callee.object.name.endsWith('Intl')) && (node.callee.property.name === 'formatMessage' || node.callee.property.name === '$t')) {
151
141
  return node.arguments[0].properties.find(a => a.key && a.key.name === attrName);
152
142
  }
153
143
  }
154
144
  function findFormattedMessageAttrNode(node, attrName) {
155
- if (node.type === 'JSXIdentifier' && node.name === 'FormattedMessage' && node.parent && node.parent.type === 'JSXOpeningElement') {
145
+ if (node.type === utils.AST_NODE_TYPES.JSXIdentifier && node.name === 'FormattedMessage' && node.parent && node.parent.type === utils.AST_NODE_TYPES.JSXOpeningElement) {
156
146
  return node.parent.attributes.find(a => a.name && a.name.name === attrName);
157
147
  }
158
148
  }
159
149
  function findAttrNodeInDefineMessages(node, attrName) {
160
- if (node.type === 'Property' && node.key.name === attrName && node.parent && node.parent.parent && node.parent.parent.parent && node.parent.parent.parent.parent && node.parent.parent.parent.parent.type === 'CallExpression' && node.parent.parent.parent.parent.callee.name === 'defineMessages') {
150
+ if (node.type === 'Property' && node.key.name === attrName && node.parent && node.parent.parent && node.parent.parent.parent && node.parent.parent.parent.parent && node.parent.parent.parent.parent.type === utils.AST_NODE_TYPES.CallExpression && node.parent.parent.parent.parent.callee.name === 'defineMessages') {
161
151
  return node;
162
152
  }
163
153
  }
164
154
  function findAttrNodeInDefineMessage(node, attrName) {
165
- if (node.type === 'Property' && node.key.name === attrName && node.parent && node.parent.parent && node.parent.parent.type === 'CallExpression' && node.parent.parent.callee.name === 'defineMessage') {
155
+ if (node.type === 'Property' && node.key.name === attrName && node.parent && node.parent.parent && node.parent.parent.type === utils.AST_NODE_TYPES.CallExpression && node.parent.parent.callee.name === 'defineMessage') {
166
156
  return node;
167
157
  }
168
158
  }
@@ -211,9 +201,9 @@ function getIntlIds(context) {
211
201
  return results;
212
202
  }
213
203
 
214
- const RULE_NAME$h = 'intl-id-missing';
204
+ const RULE_NAME$f = 'intl-id-missing';
215
205
  var intlIdMissing = createRule({
216
- name: RULE_NAME$h,
206
+ name: RULE_NAME$f,
217
207
  meta: {
218
208
  type: 'problem',
219
209
  docs: {
@@ -261,13 +251,13 @@ var intlIdMissing = createRule({
261
251
  }
262
252
  }
263
253
  function processAttrNode(node) {
264
- if (node.value.type === 'Literal') {
254
+ if (node.value.type === utils.AST_NODE_TYPES.Literal) {
265
255
  return processLiteral(node.value);
266
256
  }
267
- if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
257
+ if (node.value.type === utils.AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === utils.AST_NODE_TYPES.TemplateLiteral) {
268
258
  return processTemplateLiteral(node.value.expression);
269
259
  }
270
- if (node.value.type === 'TemplateLiteral') {
260
+ if (node.value.type === utils.AST_NODE_TYPES.TemplateLiteral) {
271
261
  return processTemplateLiteral(node.value);
272
262
  }
273
263
  context.report({
@@ -301,9 +291,9 @@ var intlIdMissing = createRule({
301
291
  }
302
292
  });
303
293
 
304
- const RULE_NAME$g = 'intl-id-naming';
294
+ const RULE_NAME$e = 'intl-id-naming';
305
295
  var intlIdNaming = createRule({
306
- name: RULE_NAME$g,
296
+ name: RULE_NAME$e,
307
297
  meta: {
308
298
  type: 'problem',
309
299
  docs: {
@@ -363,13 +353,13 @@ var intlIdNaming = createRule({
363
353
  report(node, displayStr);
364
354
  }
365
355
  function processAttrNode(node) {
366
- if (node.value.type === 'Literal') {
356
+ if (node.value.type === utils.AST_NODE_TYPES.Literal) {
367
357
  return processLiteral(node.value);
368
358
  }
369
- if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
359
+ if (node.value.type === utils.AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === utils.AST_NODE_TYPES.TemplateLiteral) {
370
360
  return processTemplateLiteral(node.value.expression);
371
361
  }
372
- if (node.value.type === 'TemplateLiteral') {
362
+ if (node.value.type === utils.AST_NODE_TYPES.TemplateLiteral) {
373
363
  return processTemplateLiteral(node.value);
374
364
  }
375
365
  }
@@ -396,9 +386,9 @@ var intlIdNaming = createRule({
396
386
  }
397
387
  });
398
388
 
399
- const RULE_NAME$f = 'intl-id-prefix';
389
+ const RULE_NAME$d = 'intl-id-prefix';
400
390
  var intlIdPrefix = createRule({
401
- name: RULE_NAME$f,
391
+ name: RULE_NAME$d,
402
392
  meta: {
403
393
  type: 'problem',
404
394
  docs: {
@@ -439,13 +429,13 @@ var intlIdPrefix = createRule({
439
429
  report(node, displayStr);
440
430
  }
441
431
  function processAttrNode(node) {
442
- if (node.value.type === 'Literal') {
432
+ if (node.value.type === utils.AST_NODE_TYPES.Literal) {
443
433
  return processLiteral(node.value);
444
434
  }
445
- if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
435
+ if (node.value.type === utils.AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === utils.AST_NODE_TYPES.TemplateLiteral) {
446
436
  return processTemplateLiteral(node.value.expression);
447
437
  }
448
- if (node.value.type === 'TemplateLiteral') {
438
+ if (node.value.type === utils.AST_NODE_TYPES.TemplateLiteral) {
449
439
  return processTemplateLiteral(node.value);
450
440
  }
451
441
  }
@@ -472,10 +462,10 @@ var intlIdPrefix = createRule({
472
462
  }
473
463
  });
474
464
 
475
- const RULE_NAME$e = 'intl-id-unused';
465
+ const RULE_NAME$c = 'intl-id-unused';
476
466
  const usedIds = new Map();
477
467
  var intlIdUnused = createRule({
478
- name: RULE_NAME$e,
468
+ name: RULE_NAME$c,
479
469
  meta: {
480
470
  type: 'problem',
481
471
  docs: {
@@ -513,13 +503,13 @@ var intlIdUnused = createRule({
513
503
  if (isTemplateTranslated(re)) ;
514
504
  }
515
505
  function processAttrNode(node) {
516
- if (node.value.type === 'Literal') {
506
+ if (node.value.type === utils.AST_NODE_TYPES.Literal) {
517
507
  return processLiteral(node.value);
518
508
  }
519
- if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
509
+ if (node.value.type === utils.AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === utils.AST_NODE_TYPES.TemplateLiteral) {
520
510
  return processTemplateLiteral(node.value.expression);
521
511
  }
522
- if (node.value.type === 'TemplateLiteral') {
512
+ if (node.value.type === utils.AST_NODE_TYPES.TemplateLiteral) {
523
513
  return processTemplateLiteral(node.value);
524
514
  }
525
515
  }
@@ -551,9 +541,9 @@ var intlIdUnused = createRule({
551
541
  }
552
542
  });
553
543
 
554
- const RULE_NAME$d = 'intl-no-default';
544
+ const RULE_NAME$b = 'intl-no-default';
555
545
  var intlNoDefault = createRule({
556
- name: RULE_NAME$d,
546
+ name: RULE_NAME$b,
557
547
  meta: {
558
548
  type: 'problem',
559
549
  docs: {
@@ -595,9 +585,9 @@ var intlNoDefault = createRule({
595
585
  }
596
586
  });
597
587
 
598
- const RULE_NAME$c = 'no-async-array-methods';
588
+ const RULE_NAME$a = 'no-async-array-methods';
599
589
  var noAsyncArrayMethods = createRule({
600
- name: RULE_NAME$c,
590
+ name: RULE_NAME$a,
601
591
  meta: {
602
592
  type: 'problem',
603
593
  docs: {
@@ -622,7 +612,7 @@ var noAsyncArrayMethods = createRule({
622
612
  }
623
613
  if (notAllowedArrayMethods.includes(callee.property.name)) {
624
614
  const functionArguments = node.expression.arguments.find(n => {
625
- return ['ArrowFunctionExpression', 'FunctionExpression'].includes(n.type);
615
+ return [utils.AST_NODE_TYPES.ArrowFunctionExpression, utils.AST_NODE_TYPES.FunctionExpression].includes(n.type);
626
616
  });
627
617
  if (functionArguments && functionArguments.async) {
628
618
  context.report({
@@ -639,9 +629,9 @@ var noAsyncArrayMethods = createRule({
639
629
  }
640
630
  });
641
631
 
642
- const RULE_NAME$b = 'no-extends-error';
632
+ const RULE_NAME$9 = 'no-extends-error';
643
633
  var noExtendsError = createRule({
644
- name: RULE_NAME$b,
634
+ name: RULE_NAME$9,
645
635
  meta: {
646
636
  type: 'problem',
647
637
  docs: {
@@ -657,7 +647,7 @@ var noExtendsError = createRule({
657
647
  create(context) {
658
648
  return {
659
649
  ClassDeclaration(node) {
660
- if (node.superClass && node.superClass.type === 'Identifier' && node.superClass.name === 'Error') {
650
+ if (node.superClass && node.superClass.type === utils.AST_NODE_TYPES.Identifier && node.superClass.name === 'Error') {
661
651
  context.report({
662
652
  node: node.superClass,
663
653
  messageId: 'noExtendsError'
@@ -668,9 +658,9 @@ var noExtendsError = createRule({
668
658
  }
669
659
  });
670
660
 
671
- const RULE_NAME$a = 'no-import-css';
661
+ const RULE_NAME$8 = 'no-import-css';
672
662
  var noImportCss = createRule({
673
- name: RULE_NAME$a,
663
+ name: RULE_NAME$8,
674
664
  meta: {
675
665
  type: 'problem',
676
666
  docs: {
@@ -701,9 +691,9 @@ var noImportCss = createRule({
701
691
  }
702
692
  });
703
693
 
704
- const RULE_NAME$9 = 'no-then-catch-finally';
694
+ const RULE_NAME$7 = 'no-then-catch-finally';
705
695
  var noThenCatchFinally = createRule({
706
- name: RULE_NAME$9,
696
+ name: RULE_NAME$7,
707
697
  meta: {
708
698
  type: 'suggestion',
709
699
  docs: {
@@ -741,7 +731,7 @@ var noThenCatchFinally = createRule({
741
731
  return node.property && (node.property.name === 'then' || node.property.name === 'catch' || node.property.name === 'finally');
742
732
  }
743
733
  return {
744
- 'CallExpression > MemberExpression.callee'(node) {
734
+ ["".concat(utils.AST_NODE_TYPES.CallExpression, " > ").concat(utils.AST_NODE_TYPES.MemberExpression, ".callee")]: node => {
745
735
  if (isTopLevelScoped(node)) {
746
736
  return;
747
737
  }
@@ -749,7 +739,7 @@ var noThenCatchFinally = createRule({
749
739
  return;
750
740
  }
751
741
  const callExpression = node.object;
752
- if (callExpression.type === 'CallExpression' && callExpression.callee.type === 'Identifier' && restrictedFunctions.includes(callExpression.callee.name)) {
742
+ if (callExpression.type === utils.AST_NODE_TYPES.CallExpression && callExpression.callee.type === utils.AST_NODE_TYPES.Identifier && restrictedFunctions.includes(callExpression.callee.name)) {
753
743
  context.report({
754
744
  node: node.property,
755
745
  messageId: 'forbiddenThenCatchFinally',
@@ -763,9 +753,9 @@ var noThenCatchFinally = createRule({
763
753
  }
764
754
  });
765
755
 
766
- const RULE_NAME$8 = 'no-unnecessary-template-literals';
756
+ const RULE_NAME$6 = 'no-unnecessary-template-literals';
767
757
  var noUnnecessaryTemplateLiterals = createRule({
768
- name: RULE_NAME$8,
758
+ name: RULE_NAME$6,
769
759
  meta: {
770
760
  type: 'problem',
771
761
  docs: {
@@ -857,7 +847,6 @@ var reactBetterExhaustiveDeps = {
857
847
  const checkMemoizedVariableIsStatic = context.options && context.options[0] && context.options[0].checkMemoizedVariableIsStatic || false;
858
848
  const options = {
859
849
  additionalHooks,
860
- enableDangerousAutofixThisMayCauseInfiniteLoops,
861
850
  customHooks,
862
851
  staticHooks,
863
852
  checkMemoizedVariableIsStatic
@@ -2066,9 +2055,9 @@ function isUseEffectEventIdentifier(node) {
2066
2055
  }
2067
2056
 
2068
2057
  const Components = require('eslint-plugin-react/lib/util/Components');
2069
- const RULE_NAME$7 = 'react-hook-use-ref';
2058
+ const RULE_NAME$5 = 'react-hook-use-ref';
2070
2059
  var reactHookUseRef = createRule({
2071
- name: RULE_NAME$7,
2060
+ name: RULE_NAME$5,
2072
2061
  meta: {
2073
2062
  type: 'suggestion',
2074
2063
  docs: {
@@ -2084,11 +2073,11 @@ var reactHookUseRef = createRule({
2084
2073
  defaultOptions: [],
2085
2074
  create: Components.detect((context, component, util) => ({
2086
2075
  CallExpression(node) {
2087
- const isImmediateReturn = node.parent && node.parent.type === 'ReturnStatement';
2076
+ const isImmediateReturn = node.parent && node.parent.type === utils.AST_NODE_TYPES.ReturnStatement;
2088
2077
  if (isImmediateReturn || !util.isReactHookCall(node, ['useRef'])) {
2089
2078
  return;
2090
2079
  }
2091
- if (node.parent.id.type !== 'Identifier') {
2080
+ if (node.parent.id.type !== utils.AST_NODE_TYPES.Identifier) {
2092
2081
  return;
2093
2082
  }
2094
2083
  const variable = node.parent.id.name;
@@ -2102,94 +2091,9 @@ var reactHookUseRef = createRule({
2102
2091
  }))
2103
2092
  });
2104
2093
 
2105
- const RULE_NAME$6 = 'react-prefer-named-property-access';
2106
- function* updateImportStatement(context, fixer, key) {
2107
- const sourceCode = context.sourceCode;
2108
- const importNode = sourceCode.ast.body.find(node => node.type === 'ImportDeclaration' && node.source.value === 'react');
2109
- if (!importNode) {
2110
- yield fixer.insertTextBefore(sourceCode.ast.body[0], "import { ".concat(key, " } from 'react';\n"));
2111
- return;
2112
- }
2113
- if (importNode.specifiers.length === 1 && importNode.specifiers[0].type === 'ImportDefaultSpecifier') {
2114
- yield fixer.insertTextAfter(importNode.specifiers[0], ", { ".concat(key, " }"));
2115
- return;
2116
- }
2117
- const alreadyImportedKeys = importNode.specifiers.filter(specifier => specifier.type === 'ImportSpecifier').map(specifier => specifier.imported.name);
2118
- if (alreadyImportedKeys.includes(key)) {
2119
- return;
2120
- }
2121
- yield fixer.insertTextAfter([...importNode.specifiers].pop(), ", ".concat(key));
2122
- }
2123
- var reactPreferNamedPropertyAccess = createRule({
2124
- name: RULE_NAME$6,
2125
- meta: {
2126
- type: 'problem',
2127
- fixable: 'code',
2128
- docs: {
2129
- description: 'Enforce importing each member of React namespace separately instead of accessing them through React namespace',
2130
- recommended: 'recommended'
2131
- },
2132
- messages: {
2133
- illegalReactPropertyAccess: 'Illegal React property access: {{name}}. Use named import instead.',
2134
- disallowImportReactEvent: 'Disallow importing React event types to avoid conflicts with global event types.'
2135
- },
2136
- schema: []
2137
- },
2138
- defaultOptions: [],
2139
- create(context) {
2140
- return {
2141
- TSQualifiedName(node) {
2142
- if ('name' in node.left && node.left.name !== 'React' || 'name' in node.right && node.right.name.endsWith('Event')) {
2143
- return;
2144
- }
2145
- context.report({
2146
- node,
2147
- messageId: 'illegalReactPropertyAccess',
2148
- data: {
2149
- name: node.right.name
2150
- },
2151
- *fix(fixer) {
2152
- yield fixer.replaceText(node, node.right.name);
2153
- yield* updateImportStatement(context, fixer, node.right.name);
2154
- }
2155
- });
2156
- },
2157
- MemberExpression(node) {
2158
- if (node.object.name !== 'React') {
2159
- return;
2160
- }
2161
- context.report({
2162
- node,
2163
- messageId: 'illegalReactPropertyAccess',
2164
- data: {
2165
- name: node.property.name
2166
- },
2167
- *fix(fixer) {
2168
- yield fixer.replaceText(node, node.property.name);
2169
- yield* updateImportStatement(context, fixer, node.property.name);
2170
- }
2171
- });
2172
- },
2173
- ImportDeclaration(node) {
2174
- if (node.source.value !== 'react' && node.source.value !== 'preact') {
2175
- return;
2176
- }
2177
- node.specifiers.forEach(specifier => {
2178
- if (specifier.type === 'ImportSpecifier' && specifier.imported.name && specifier.imported.name.endsWith('Event')) {
2179
- context.report({
2180
- node: specifier,
2181
- messageId: 'disallowImportReactEvent'
2182
- });
2183
- }
2184
- });
2185
- }
2186
- };
2187
- }
2188
- });
2189
-
2190
- const RULE_NAME$5 = 'react-prefer-sx-prop';
2094
+ const RULE_NAME$4 = 'react-prefer-sx-prop';
2191
2095
  var reactPreferSxProp = createRule({
2192
- name: RULE_NAME$5,
2096
+ name: RULE_NAME$4,
2193
2097
  meta: {
2194
2098
  type: 'problem',
2195
2099
  docs: {
@@ -2260,13 +2164,13 @@ var reactPreferSxProp = createRule({
2260
2164
  });
2261
2165
 
2262
2166
  function getBasicIdentifier(node) {
2263
- if (node.type === 'Identifier') {
2167
+ if (node.type === utils.AST_NODE_TYPES.Identifier) {
2264
2168
  return node.name;
2265
2169
  }
2266
- if (node.type === 'Literal') {
2170
+ if (node.type === utils.AST_NODE_TYPES.Literal) {
2267
2171
  return node.value;
2268
2172
  }
2269
- if (node.type === 'TemplateLiteral') {
2173
+ if (node.type === utils.AST_NODE_TYPES.TemplateLiteral) {
2270
2174
  if (node.expressions.length > 0) {
2271
2175
  return null;
2272
2176
  }
@@ -2276,15 +2180,15 @@ function getBasicIdentifier(node) {
2276
2180
  }
2277
2181
  function getBaseIdentifier(node) {
2278
2182
  switch (node.type) {
2279
- case 'Identifier':
2183
+ case utils.AST_NODE_TYPES.Identifier:
2280
2184
  {
2281
2185
  return node;
2282
2186
  }
2283
- case 'CallExpression':
2187
+ case utils.AST_NODE_TYPES.CallExpression:
2284
2188
  {
2285
2189
  return getBaseIdentifier(node.callee);
2286
2190
  }
2287
- case 'MemberExpression':
2191
+ case utils.AST_NODE_TYPES.MemberExpression:
2288
2192
  {
2289
2193
  return getBaseIdentifier(node.object);
2290
2194
  }
@@ -2293,7 +2197,7 @@ function getBaseIdentifier(node) {
2293
2197
  }
2294
2198
  function getStyesObj(node) {
2295
2199
  const isMakeStyles = node.callee.name === 'makeStyles';
2296
- const isModernApi = node.callee.type === 'MemberExpression' && node.callee.property.name === 'create' && getBaseIdentifier(node.callee.object) && getBaseIdentifier(node.callee.object).name === 'tss';
2200
+ const isModernApi = node.callee.type === utils.AST_NODE_TYPES.MemberExpression && node.callee.property.name === 'create' && getBaseIdentifier(node.callee.object) && getBaseIdentifier(node.callee.object).name === 'tss';
2297
2201
  if (!isMakeStyles && !isModernApi) {
2298
2202
  return;
2299
2203
  }
@@ -2309,21 +2213,21 @@ function getStyesObj(node) {
2309
2213
  return;
2310
2214
  }
2311
2215
  switch (styles.type) {
2312
- case 'ObjectExpression':
2216
+ case utils.AST_NODE_TYPES.ObjectExpression:
2313
2217
  return styles;
2314
- case 'ArrowFunctionExpression':
2218
+ case utils.AST_NODE_TYPES.ArrowFunctionExpression:
2315
2219
  {
2316
2220
  const {
2317
2221
  body
2318
2222
  } = styles;
2319
2223
  switch (body.type) {
2320
- case 'ObjectExpression':
2224
+ case utils.AST_NODE_TYPES.ObjectExpression:
2321
2225
  return body;
2322
- case 'BlockStatement':
2226
+ case utils.AST_NODE_TYPES.BlockStatement:
2323
2227
  {
2324
2228
  let stylesObj;
2325
2229
  body.body.forEach(bodyNode => {
2326
- if (bodyNode.type === 'ReturnStatement' && bodyNode.argument.type === 'ObjectExpression') {
2230
+ if (bodyNode.type === utils.AST_NODE_TYPES.ReturnStatement && bodyNode.argument.type === utils.AST_NODE_TYPES.ObjectExpression) {
2327
2231
  stylesObj = bodyNode.argument;
2328
2232
  }
2329
2233
  });
@@ -2335,10 +2239,10 @@ function getStyesObj(node) {
2335
2239
  }
2336
2240
  }
2337
2241
  function loopStylesObj(node, callback) {
2338
- if (node && node.type === 'ObjectExpression') {
2242
+ if (node && node.type === utils.AST_NODE_TYPES.ObjectExpression) {
2339
2243
  node.properties.forEach(property => {
2340
- if (property.type === 'Property' && property.value) {
2341
- if (property.value.type === 'ObjectExpression') {
2244
+ if (property.type === utils.AST_NODE_TYPES.Property && property.value) {
2245
+ if (property.value.type === utils.AST_NODE_TYPES.ObjectExpression) {
2342
2246
  loopStylesObj(property.value, callback);
2343
2247
  } else {
2344
2248
  callback(property.value);
@@ -2348,9 +2252,9 @@ function loopStylesObj(node, callback) {
2348
2252
  }
2349
2253
  }
2350
2254
 
2351
- const RULE_NAME$4 = 'tss-class-naming';
2255
+ const RULE_NAME$3 = 'tss-class-naming';
2352
2256
  var tssClassNaming = createRule({
2353
- name: RULE_NAME$4,
2257
+ name: RULE_NAME$3,
2354
2258
  meta: {
2355
2259
  type: 'problem',
2356
2260
  docs: {
@@ -2374,7 +2278,7 @@ var tssClassNaming = createRule({
2374
2278
  if (property.computed) {
2375
2279
  return;
2376
2280
  }
2377
- if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {
2281
+ if (property.type === 'ExperimentalSpreadProperty' || property.type === utils.AST_NODE_TYPES.SpreadElement) {
2378
2282
  return;
2379
2283
  }
2380
2284
  const className = property.key.value || property.key.name;
@@ -2544,9 +2448,9 @@ var colors = {
2544
2448
  yellowgreen: [154, 205, 50]
2545
2449
  };
2546
2450
 
2547
- const RULE_NAME$3 = 'tss-no-color-name';
2451
+ const RULE_NAME$2 = 'tss-no-color-name';
2548
2452
  var tssNoColorName = createRule({
2549
- name: RULE_NAME$3,
2453
+ name: RULE_NAME$2,
2550
2454
  meta: {
2551
2455
  type: 'suggestion',
2552
2456
  docs: {
@@ -2567,7 +2471,7 @@ var tssNoColorName = createRule({
2567
2471
  return;
2568
2472
  }
2569
2473
  function checkColorLiteral(value) {
2570
- if (value.type === 'Literal' && typeof value.value === 'string' && Object.keys(colors).includes(value.value.toLowerCase())) {
2474
+ if (value.type === utils.AST_NODE_TYPES.Literal && typeof value.value === 'string' && Object.keys(colors).includes(value.value.toLowerCase())) {
2571
2475
  context.report({
2572
2476
  node: value,
2573
2477
  messageId: 'disallowColorName'
@@ -2580,9 +2484,9 @@ var tssNoColorName = createRule({
2580
2484
  }
2581
2485
  });
2582
2486
 
2583
- const RULE_NAME$2 = 'tss-no-color-value';
2487
+ const RULE_NAME$1 = 'tss-no-color-value';
2584
2488
  var tssNoColorValue = createRule({
2585
- name: RULE_NAME$2,
2489
+ name: RULE_NAME$1,
2586
2490
  meta: {
2587
2491
  type: 'problem',
2588
2492
  docs: {
@@ -2603,7 +2507,7 @@ var tssNoColorValue = createRule({
2603
2507
  return;
2604
2508
  }
2605
2509
  function checkColorLiteral(value) {
2606
- if (value.type === 'Literal' && typeof value.value === 'string') {
2510
+ if (value.type === utils.AST_NODE_TYPES.Literal && typeof value.value === 'string') {
2607
2511
  const colorCodePattern = /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\?\(\s*(\d{1,3}\s*,\s*){2}\d{1,3}(?:\s*,\s*\d*(?:\.\d+)?)?\s*\)/g;
2608
2512
  if (colorCodePattern.test(value.value)) {
2609
2513
  context.report({
@@ -2619,9 +2523,9 @@ var tssNoColorValue = createRule({
2619
2523
  }
2620
2524
  });
2621
2525
 
2622
- const RULE_NAME$1 = 'tss-unused-classes';
2526
+ const RULE_NAME = 'tss-unused-classes';
2623
2527
  var tssUnusedClasses = createRule({
2624
- name: RULE_NAME$1,
2528
+ name: RULE_NAME,
2625
2529
  meta: {
2626
2530
  type: 'suggestion',
2627
2531
  docs: {
@@ -2647,14 +2551,14 @@ var tssUnusedClasses = createRule({
2647
2551
  if (property.computed) {
2648
2552
  return;
2649
2553
  }
2650
- if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {
2554
+ if (property.type === 'ExperimentalSpreadProperty' || property.type === utils.AST_NODE_TYPES.SpreadElement) {
2651
2555
  return;
2652
2556
  }
2653
2557
  definedClasses[property.key.value || property.key.name] = property;
2654
2558
  });
2655
2559
  },
2656
2560
  MemberExpression(node) {
2657
- if (node.object.type === 'Identifier' && node.object.name === 'classes') {
2561
+ if (node.object.type === utils.AST_NODE_TYPES.Identifier && node.object.name === 'classes') {
2658
2562
  const whichClass = getBasicIdentifier(node.property);
2659
2563
  if (whichClass) {
2660
2564
  usedClasses[whichClass] = true;
@@ -2671,22 +2575,22 @@ var tssUnusedClasses = createRule({
2671
2575
  const {
2672
2576
  parent
2673
2577
  } = node;
2674
- if (parent.type !== 'MemberExpression') {
2578
+ if (parent.type !== utils.AST_NODE_TYPES.MemberExpression) {
2675
2579
  return;
2676
2580
  }
2677
2581
  if (
2678
2582
  node.object.object &&
2679
- node.object.object.type !== 'ThisExpression') {
2583
+ node.object.object.type !== utils.AST_NODE_TYPES.ThisExpression) {
2680
2584
  return;
2681
2585
  }
2682
2586
  const propsIdentifier = getBasicIdentifier(parent.object);
2683
2587
  if (propsIdentifier && propsIdentifier !== 'props') {
2684
2588
  return;
2685
2589
  }
2686
- if (!propsIdentifier && parent.object.type !== 'MemberExpression') {
2590
+ if (!propsIdentifier && parent.object.type !== utils.AST_NODE_TYPES.MemberExpression) {
2687
2591
  return;
2688
2592
  }
2689
- if (parent.parent.type === 'MemberExpression') {
2593
+ if (parent.parent.type === utils.AST_NODE_TYPES.MemberExpression) {
2690
2594
  return;
2691
2595
  }
2692
2596
  const parentClassIdentifier = getBasicIdentifier(parent.property);
@@ -2711,254 +2615,6 @@ var tssUnusedClasses = createRule({
2711
2615
  }
2712
2616
  });
2713
2617
 
2714
- const RULE_NAME = 'var-naming';
2715
- const reactGlobalFuncs = new Set(['createContext', 'forwardRef', 'lazy', 'memo', 'combineProviders']);
2716
- const reactFCTypes = new Set(['FC', 'FunctionComponent', 'VFC', 'VoidFunctionComponent']);
2717
- const defaultExcludeTypes = ['StoryObj', 'StoryFn'];
2718
- const defaultExcludeNames = ['^(__dirname|__filename)$', '(.*)Event$'];
2719
- var varNaming = createRule({
2720
- name: RULE_NAME,
2721
- meta: {
2722
- type: 'problem',
2723
- docs: {
2724
- description: 'Enforce variable and function naming convention',
2725
- recommended: 'recommended'
2726
- },
2727
- schema: [{
2728
- type: 'object',
2729
- properties: {
2730
- funcFormat: {
2731
- type: 'array',
2732
- items: {
2733
- "enum": ['camelCase', 'PascalCase', 'UPPER_CASE']
2734
- }
2735
- },
2736
- varFormat: {
2737
- type: 'array',
2738
- items: {
2739
- "enum": ['camelCase', 'PascalCase', 'UPPER_CASE']
2740
- }
2741
- },
2742
- excludeNames: {
2743
- type: 'array',
2744
- items: {
2745
- type: 'string'
2746
- }
2747
- },
2748
- excludeFuncs: {
2749
- type: 'array',
2750
- items: {
2751
- type: 'string'
2752
- }
2753
- },
2754
- excludeTypes: {
2755
- type: 'array',
2756
- items: {
2757
- type: 'string'
2758
- }
2759
- }
2760
- }
2761
- }],
2762
- messages: {
2763
- invalidFuncNaming: 'Invalid function naming for non-React component, expected {{formats}}',
2764
- invalidReactFCNaming: 'Invalid naming convention for React functional component, expected PascalCase',
2765
- invalidVarNaming: 'Invalid variable naming, expected {{formats}}'
2766
- }
2767
- },
2768
- defaultOptions: [],
2769
- create(context) {
2770
- if (!context.options[0]) {
2771
- context.options[0] = {};
2772
- }
2773
- const funcFormat = context.options[0].funcFormat || ['camelCase'];
2774
- const varFormat = context.options[0].varFormat || ['camelCase', 'UPPER_CASE'];
2775
- let excludeNames = context.options[0].excludeNames || [];
2776
- excludeNames = [...defaultExcludeNames, ...excludeNames];
2777
- const excludeFuncs = context.options[0].excludeFuncs || [];
2778
- let excludeTypes = context.options[0].excludeTypes || [];
2779
- excludeTypes = [...defaultExcludeTypes, ...excludeTypes];
2780
- function validate(type, {
2781
- node,
2782
- name
2783
- }) {
2784
- let isPass = false;
2785
- let formats;
2786
- let messageId;
2787
- switch (type) {
2788
- case 'func':
2789
- formats = funcFormat;
2790
- messageId = 'invalidFuncNaming';
2791
- break;
2792
- case 'var':
2793
- formats = varFormat;
2794
- messageId = 'invalidVarNaming';
2795
- break;
2796
- }
2797
- for (const format of formats) {
2798
- switch (format) {
2799
- case 'camelCase':
2800
- if (eslintUtils.isCamelCase(name)) {
2801
- isPass = true;
2802
- }
2803
- break;
2804
- case 'PascalCase':
2805
- if (eslintUtils.isPascalCase(name)) {
2806
- isPass = true;
2807
- }
2808
- break;
2809
- case 'UPPER_CASE':
2810
- if (eslintUtils.isUpperCase(name)) {
2811
- isPass = true;
2812
- }
2813
- break;
2814
- }
2815
- }
2816
- if (!isPass) {
2817
- context.report({
2818
- node: node,
2819
- messageId: messageId,
2820
- data: {
2821
- formats: formats.join(', ')
2822
- }
2823
- });
2824
- }
2825
- }
2826
- function checkJSXElement(node) {
2827
- if (!node) {
2828
- return false;
2829
- }
2830
- if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
2831
- return true;
2832
- }
2833
- if (node.type === 'BlockStatement') {
2834
- for (const statement of node.body) {
2835
- if (statement.type === 'ReturnStatement') {
2836
- if (checkJSXElement(statement.argument)) {
2837
- return true;
2838
- }
2839
- } else if (checkJSXElement(statement)) {
2840
- return true;
2841
- }
2842
- }
2843
- }
2844
- if (node.type === 'ArrowFunctionExpression' || node.type === 'FunctionExpression') {
2845
- return checkJSXElement(node.body);
2846
- }
2847
- return false;
2848
- }
2849
- function getTypeReference(node) {
2850
- if (node.id.typeAnnotation && node.id.typeAnnotation.typeAnnotation) {
2851
- const typeAnnotation = node.id.typeAnnotation.typeAnnotation;
2852
- if (typeAnnotation.type === 'TSTypeReference' && typeAnnotation.typeName.type === 'Identifier') {
2853
- const typeName = typeAnnotation.typeName.name;
2854
- const typeNameLast = typeName.split('.').pop();
2855
- return typeNameLast;
2856
- }
2857
- }
2858
- }
2859
- return {
2860
- FunctionDeclaration(node) {
2861
- if (node.type === 'FunctionDeclaration' && node.id) {
2862
- const fnName = node.id.name;
2863
- const isReactComponent = checkJSXElement(node.body);
2864
- if (!isReactComponent) {
2865
- validate('func', {
2866
- node,
2867
- name: fnName
2868
- });
2869
- }
2870
- }
2871
- },
2872
- VariableDeclarator(node) {
2873
- if (node.id && node.init && ['FunctionExpression', 'ArrowFunctionExpression'].includes(node.init.type)) {
2874
- const fnName = node.id.name;
2875
- let isReactComponent = checkJSXElement(node.init.body);
2876
- const typeName = getTypeReference(node);
2877
- if (typeName && reactFCTypes.has(typeName)) {
2878
- isReactComponent = true;
2879
- }
2880
- if (!isReactComponent) {
2881
- validate('func', {
2882
- node,
2883
- name: fnName
2884
- });
2885
- }
2886
- } else if (node.id && node.init && node.init.type === 'LogicalExpression') {
2887
- const varName = node.id.name;
2888
- const parts = [node.init.left, node.init.right];
2889
- let partIsReactComponent = false;
2890
- for (const part of parts) {
2891
- if (['FunctionExpression', 'ArrowFunctionExpression'].includes(part.type)) {
2892
- const isReactComponent = checkJSXElement(part.body);
2893
- if (isReactComponent) {
2894
- partIsReactComponent = true;
2895
- }
2896
- }
2897
- }
2898
- if (!partIsReactComponent) {
2899
- validate('var', {
2900
- node,
2901
- name: varName
2902
- });
2903
- }
2904
- } else if (node.id) {
2905
- const varName = node.id.name;
2906
- for (const excludeRegex of excludeNames) {
2907
- if (new RegExp(excludeRegex).test(varName)) {
2908
- return;
2909
- }
2910
- }
2911
- const typeName = getTypeReference(node);
2912
- if (typeName) {
2913
- for (const excludeRegex of excludeTypes) {
2914
- if (new RegExp(excludeRegex).test(typeName)) {
2915
- return;
2916
- }
2917
- }
2918
- }
2919
- if (node.id.parent && node.id.parent.init) {
2920
- let calleeName;
2921
- let shouldCheckReact = false;
2922
- let initNode;
2923
- if (node.id.parent.init.type === 'CallExpression') {
2924
- initNode = node.id.parent.init;
2925
- } else if (node.id.parent.init.type === 'TSAsExpression' && node.id.parent.init.expression && node.id.parent.init.expression.callee) {
2926
- initNode = node.id.parent.init.expression;
2927
- }
2928
- if (initNode) {
2929
- shouldCheckReact = true;
2930
- if (initNode.callee.type === 'Identifier') {
2931
- calleeName = initNode.callee.name;
2932
- } else if (initNode.callee.type === 'MemberExpression') {
2933
- calleeName = initNode.callee.property.name;
2934
- }
2935
- }
2936
- if (calleeName) {
2937
- for (const excludeRegex of excludeFuncs) {
2938
- if (new RegExp(excludeRegex).test(calleeName)) {
2939
- return;
2940
- }
2941
- }
2942
- }
2943
- if (shouldCheckReact) {
2944
- if (!calleeName) {
2945
- return;
2946
- }
2947
- if (reactGlobalFuncs.has(calleeName) || reactGlobalFuncs.has(calleeName.split('.').pop())) {
2948
- return;
2949
- }
2950
- }
2951
- }
2952
- validate('var', {
2953
- node,
2954
- name: varName
2955
- });
2956
- }
2957
- }
2958
- };
2959
- }
2960
- });
2961
-
2962
2618
  var ruleFiles = /*#__PURE__*/Object.freeze({
2963
2619
  __proto__: null,
2964
2620
  rules_enforce_mui_icon_alias: enforceMuiIconAlias,
@@ -2975,13 +2631,11 @@ var ruleFiles = /*#__PURE__*/Object.freeze({
2975
2631
  rules_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals,
2976
2632
  rules_react_better_exhaustive_deps: reactBetterExhaustiveDeps,
2977
2633
  rules_react_hook_use_ref: reactHookUseRef,
2978
- rules_react_prefer_named_property_access: reactPreferNamedPropertyAccess,
2979
2634
  rules_react_prefer_sx_prop: reactPreferSxProp,
2980
2635
  rules_tss_class_naming: tssClassNaming,
2981
2636
  rules_tss_no_color_name: tssNoColorName,
2982
2637
  rules_tss_no_color_value: tssNoColorValue,
2983
- rules_tss_unused_classes: tssUnusedClasses,
2984
- rules_var_naming: varNaming
2638
+ rules_tss_unused_classes: tssUnusedClasses
2985
2639
  });
2986
2640
 
2987
2641
  const plugin = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agilebot/eslint-plugin",
3
- "version": "0.7.4",
3
+ "version": "0.8.1",
4
4
  "description": "Agilebot's ESLint plugin",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,10 +18,9 @@
18
18
  "node": "^18.18.0 || >=20.0.0"
19
19
  },
20
20
  "dependencies": {
21
- "@eslint/compat": "^1.2.3",
22
21
  "@typescript-eslint/utils": "~8.25.0",
23
22
  "eslint-plugin-react": "^7.37.2",
24
- "@agilebot/eslint-utils": "0.7.4"
23
+ "@agilebot/eslint-utils": "0.8.1"
25
24
  },
26
25
  "peerDependencies": {
27
26
  "eslint": "^8.57.0 || ^9.0.0"
@@ -33,7 +32,7 @@
33
32
  "@types/color-name": "^1.1.4",
34
33
  "@types/estree": "^1.0.5",
35
34
  "color-name": "^2.0.0",
36
- "eslint-vitest-rule-tester": "^0.6.1",
35
+ "eslint-vitest-rule-tester": "^2.2.0",
37
36
  "typescript-eslint": "~8.25.0"
38
37
  },
39
38
  "scripts": {
package/LICENSE.tpl DELETED
@@ -1,8 +0,0 @@
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
- */