@agilebot/eslint-plugin 0.3.4 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license @agilebot/eslint-plugin v0.3.4
2
+ * @license @agilebot/eslint-plugin v0.3.6
3
3
  *
4
4
  * Copyright (c) Agilebot, Inc. and its affiliates.
5
5
  *
@@ -33,7 +33,7 @@ function _interopNamespaceDefault(e) {
33
33
  var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
34
34
  var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
35
35
 
36
- var enforceIconAlias = {
36
+ var enforceMuiIconAlias = {
37
37
  meta: {
38
38
  type: 'problem',
39
39
  docs: {
@@ -49,10 +49,7 @@ var enforceIconAlias = {
49
49
  create(context) {
50
50
  return {
51
51
  ImportDeclaration(node) {
52
- if (
53
- node.source.value !== '@mui/icons-material' &&
54
- node.source.value !== 'mdi-material-ui'
55
- ) {
52
+ if (node.source.value !== '@mui/icons-material' && node.source.value !== 'mdi-material-ui') {
56
53
  return;
57
54
  }
58
55
  for (const specifier of node.specifiers) {
@@ -66,11 +63,7 @@ var enforceIconAlias = {
66
63
  data: {
67
64
  name: node.source.value
68
65
  },
69
- fix: fixer =>
70
- fixer.replaceText(
71
- specifier,
72
- `${specifier.imported.name} as ${specifier.imported.name}Icon`
73
- )
66
+ fix: fixer => fixer.replaceText(specifier, "".concat(specifier.imported.name, " as ").concat(specifier.imported.name, "Icon"))
74
67
  });
75
68
  }
76
69
  }
@@ -80,11 +73,11 @@ var enforceIconAlias = {
80
73
  };
81
74
 
82
75
  function getSetting(context, name) {
83
- return context.settings[`agilebot/${name}`];
76
+ return context.settings["agilebot/".concat(name)];
84
77
  }
85
78
 
86
79
  let warnedForMissingPrefix = false;
87
- var monorepo = {
80
+ var importMonorepo = {
88
81
  meta: {
89
82
  type: 'problem',
90
83
  docs: {
@@ -108,7 +101,7 @@ var monorepo = {
108
101
  }
109
102
  return;
110
103
  }
111
- prefix = `${prefix}/`;
104
+ prefix = "".concat(prefix, "/");
112
105
  if (typeof node.source.value !== 'string') {
113
106
  return;
114
107
  }
@@ -124,10 +117,8 @@ var monorepo = {
124
117
  module: node.source.value
125
118
  },
126
119
  fix: fixer => {
127
- const correctedPath = values
128
- .filter((_, index) => index !== 2)
129
- .join('/');
130
- return fixer.replaceText(node.source, `'${correctedPath}'`);
120
+ const correctedPath = values.filter((_, index) => index !== 2).join('/');
121
+ return fixer.replaceText(node.source, "'".concat(correctedPath, "'"));
131
122
  }
132
123
  });
133
124
  }
@@ -137,74 +128,33 @@ var monorepo = {
137
128
  };
138
129
 
139
130
  function findFormatMessageAttrNode(node, attrName) {
140
- if (
141
- node.type === 'CallExpression' &&
142
- (node.callee.name === 'formatMessage' || node.callee.name === '$t') &&
143
- node.arguments.length > 0 &&
144
- node.arguments[0].properties
145
- ) {
146
- return node.arguments[0].properties.find(
147
- a => a.key && a.key.name === attrName
148
- );
131
+ if (node.type === 'CallExpression' && (node.callee.name === 'formatMessage' || node.callee.name === '$t') && node.arguments.length > 0 && node.arguments[0].properties) {
132
+ return node.arguments[0].properties.find(a => a.key && a.key.name === attrName);
149
133
  }
150
- if (
151
- node.type === 'CallExpression' &&
152
- node.callee.type === 'MemberExpression' &&
153
- (node.callee.object.name === 'intl' ||
154
- (node.callee.object.name && node.callee.object.name.endsWith('Intl'))) &&
155
- (node.callee.property.name === 'formatMessage' ||
156
- node.callee.property.name === '$t')
157
- ) {
158
- return node.arguments[0].properties.find(
159
- a => a.key && a.key.name === attrName
160
- );
134
+ 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')) {
135
+ return node.arguments[0].properties.find(a => a.key && a.key.name === attrName);
161
136
  }
162
137
  }
163
138
  function findFormattedMessageAttrNode(node, attrName) {
164
- if (
165
- node.type === 'JSXIdentifier' &&
166
- node.name === 'FormattedMessage' &&
167
- node.parent &&
168
- node.parent.type === 'JSXOpeningElement'
169
- ) {
139
+ if (node.type === 'JSXIdentifier' && node.name === 'FormattedMessage' && node.parent && node.parent.type === 'JSXOpeningElement') {
170
140
  return node.parent.attributes.find(a => a.name && a.name.name === attrName);
171
141
  }
172
142
  }
173
143
  function findAttrNodeInDefineMessages(node, attrName) {
174
- if (
175
- node.type === 'Property' &&
176
- node.key.name === attrName &&
177
- node.parent &&
178
- node.parent.parent &&
179
- node.parent.parent.parent &&
180
- node.parent.parent.parent.parent &&
181
- node.parent.parent.parent.parent.type === 'CallExpression' &&
182
- node.parent.parent.parent.parent.callee.name === 'defineMessages'
183
- ) {
144
+ 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') {
184
145
  return node;
185
146
  }
186
147
  }
187
148
  function findAttrNodeInDefineMessage(node, attrName) {
188
- if (
189
- node.type === 'Property' &&
190
- node.key.name === attrName &&
191
- node.parent &&
192
- node.parent.parent &&
193
- node.parent.parent.type === 'CallExpression' &&
194
- node.parent.parent.callee.name === 'defineMessage'
195
- ) {
149
+ if (node.type === 'Property' && node.key.name === attrName && node.parent && node.parent.parent && node.parent.parent.type === 'CallExpression' && node.parent.parent.callee.name === 'defineMessage') {
196
150
  return node;
197
151
  }
198
152
  }
199
153
  function sortedTemplateElements(node) {
200
- return [...node.quasis, ...node.expressions].sort(
201
- (a, b) => a.range[0] - b.range[0]
202
- );
154
+ return [...node.quasis, ...node.expressions].sort((a, b) => a.range[0] - b.range[0]);
203
155
  }
204
156
  function templateLiteralDisplayStr(node) {
205
- return sortedTemplateElements(node)
206
- .map(e => (!e.value ? '*' : e.value.raw))
207
- .join('');
157
+ return sortedTemplateElements(node).map(e => !e.value ? '*' : e.value.raw).join('');
208
158
  }
209
159
 
210
160
  const localeFilesKeys = {};
@@ -218,22 +168,19 @@ function getIntlIds(context) {
218
168
  localeFiles.forEach(f => {
219
169
  const fullPath = projectRoot ? path__namespace.join(projectRoot, f) : f;
220
170
  const mtime = fs__namespace.lstatSync(fullPath).mtime.getTime();
221
- if (
222
- !localeFilesKeys[fullPath] ||
223
- mtime !== localeFilesKeys[fullPath].mtime
224
- ) {
171
+ if (!localeFilesKeys[fullPath] || mtime !== localeFilesKeys[fullPath].mtime) {
225
172
  let json;
226
173
  if (fullPath.endsWith('.json')) {
227
174
  json = JSON.parse(fs__namespace.readFileSync(fullPath, 'utf8'));
228
175
  } else if (fullPath.endsWith('.ts')) {
229
176
  json = eslintUtils.tsImport(fullPath);
230
- if (typeof json === 'object' && json.default) {
231
- json = json.default;
177
+ if (typeof json === 'object' && json["default"]) {
178
+ json = json["default"];
232
179
  }
233
180
  } else if (fullPath.endsWith('.js')) {
234
181
  json = require(fullPath);
235
- if (typeof json === 'object' && json.default) {
236
- json = json.default;
182
+ if (typeof json === 'object' && json["default"]) {
183
+ json = json["default"];
237
184
  }
238
185
  } else {
239
186
  throw new Error('unsupported file extension');
@@ -248,7 +195,7 @@ function getIntlIds(context) {
248
195
  return results;
249
196
  }
250
197
 
251
- var idMissing = {
198
+ var intlIdMissing = {
252
199
  meta: {
253
200
  docs: {
254
201
  description: 'Validates intl message ids are in locale file',
@@ -275,9 +222,7 @@ var idMissing = {
275
222
  }
276
223
  }
277
224
  function processTemplateLiteral(node) {
278
- const exStr = sortedTemplateElements(node)
279
- .map(e => (!e.value ? '.*' : e.value.raw))
280
- .join('');
225
+ const exStr = sortedTemplateElements(node).map(e => !e.value ? '.*' : e.value.raw).join('');
281
226
  const re = new RegExp(exStr);
282
227
  if (!isTemplateTranslated(re)) {
283
228
  context.report({
@@ -290,10 +235,7 @@ var idMissing = {
290
235
  if (node.value.type === 'Literal') {
291
236
  return processLiteral(node.value);
292
237
  }
293
- if (
294
- node.value.type === 'JSXExpressionContainer' &&
295
- node.value.expression.type === 'TemplateLiteral'
296
- ) {
238
+ if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
297
239
  return processTemplateLiteral(node.value.expression);
298
240
  }
299
241
  if (node.value.type === 'TemplateLiteral') {
@@ -318,9 +260,7 @@ var idMissing = {
318
260
  }
319
261
  },
320
262
  Property: function (node) {
321
- const attrNode =
322
- findAttrNodeInDefineMessages(node, 'id') ||
323
- findAttrNodeInDefineMessage(node, 'id');
263
+ const attrNode = findAttrNodeInDefineMessages(node, 'id') || findAttrNodeInDefineMessage(node, 'id');
324
264
  if (attrNode) {
325
265
  return processAttrNode(attrNode);
326
266
  }
@@ -329,33 +269,30 @@ var idMissing = {
329
269
  }
330
270
  };
331
271
 
332
- var idPrefix = {
272
+ var intlIdPrefix = {
333
273
  meta: {
334
274
  docs: {
335
275
  description: 'Validates intl message ids has correct prefixes',
336
276
  category: 'Intl'
337
277
  },
338
278
  fixable: undefined,
339
- schema: [
340
- {
341
- type: 'array',
342
- items: {
343
- type: 'string'
344
- }
279
+ schema: [{
280
+ type: 'array',
281
+ items: {
282
+ type: 'string'
345
283
  }
346
- ]
284
+ }]
347
285
  },
348
286
  create: function (context) {
349
287
  if (context.options[0].length === 0) {
350
288
  throw new Error('Prefixes are required in settings');
351
289
  }
352
- const hasPrefix = value =>
353
- context.options[0].some(p => value.startsWith(p));
290
+ const hasPrefix = value => context.options[0].some(p => value.startsWith(p));
354
291
  function report(node, value) {
355
292
  if (!hasPrefix(value)) {
356
293
  context.report({
357
294
  node: node,
358
- message: `Invalid id prefix: ${value}`
295
+ message: "Invalid id prefix: ".concat(value)
359
296
  });
360
297
  }
361
298
  }
@@ -370,10 +307,7 @@ var idPrefix = {
370
307
  if (node.value.type === 'Literal') {
371
308
  return processLiteral(node.value);
372
309
  }
373
- if (
374
- node.value.type === 'JSXExpressionContainer' &&
375
- node.value.expression.type === 'TemplateLiteral'
376
- ) {
310
+ if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
377
311
  return processTemplateLiteral(node.value.expression);
378
312
  }
379
313
  if (node.value.type === 'TemplateLiteral') {
@@ -394,9 +328,7 @@ var idPrefix = {
394
328
  }
395
329
  },
396
330
  Property: function (node) {
397
- const attrNode =
398
- findAttrNodeInDefineMessages(node, 'id') ||
399
- findAttrNodeInDefineMessage(node, 'id');
331
+ const attrNode = findAttrNodeInDefineMessages(node, 'id') || findAttrNodeInDefineMessage(node, 'id');
400
332
  if (attrNode) {
401
333
  return processAttrNode(attrNode);
402
334
  }
@@ -406,7 +338,7 @@ var idPrefix = {
406
338
  };
407
339
 
408
340
  const usedIds = new Map();
409
- var idUnused = {
341
+ var intlIdUnused = {
410
342
  meta: {
411
343
  docs: {
412
344
  description: 'Finds unused intl message ids in locale file',
@@ -438,9 +370,7 @@ var idUnused = {
438
370
  }
439
371
  }
440
372
  function processTemplateLiteral(node) {
441
- const exStr = sortedTemplateElements(node)
442
- .map(e => (!e.value ? '.*' : e.value.raw))
443
- .join('');
373
+ const exStr = sortedTemplateElements(node).map(e => !e.value ? '.*' : e.value.raw).join('');
444
374
  const re = new RegExp(exStr);
445
375
  if (isTemplateTranslated(re)) ;
446
376
  }
@@ -448,10 +378,7 @@ var idUnused = {
448
378
  if (node.value.type === 'Literal') {
449
379
  return processLiteral(node.value);
450
380
  }
451
- if (
452
- node.value.type === 'JSXExpressionContainer' &&
453
- node.value.expression.type === 'TemplateLiteral'
454
- ) {
381
+ if (node.value.type === 'JSXExpressionContainer' && node.value.expression.type === 'TemplateLiteral') {
455
382
  return processTemplateLiteral(node.value.expression);
456
383
  }
457
384
  if (node.value.type === 'TemplateLiteral') {
@@ -472,9 +399,7 @@ var idUnused = {
472
399
  }
473
400
  },
474
401
  Property: function (node) {
475
- const attrNode =
476
- findAttrNodeInDefineMessages(node, 'id') ||
477
- findAttrNodeInDefineMessage(node, 'id');
402
+ const attrNode = findAttrNodeInDefineMessages(node, 'id') || findAttrNodeInDefineMessage(node, 'id');
478
403
  if (attrNode) {
479
404
  return processAttrNode(attrNode);
480
405
  }
@@ -488,7 +413,7 @@ var idUnused = {
488
413
  }
489
414
  };
490
415
 
491
- var noDefault = {
416
+ var intlNoDefault = {
492
417
  meta: {
493
418
  docs: {
494
419
  description: 'Validates defaultMessage is not used with react-intl',
@@ -518,9 +443,7 @@ var noDefault = {
518
443
  }
519
444
  },
520
445
  Property: function (node) {
521
- const attrNode =
522
- findAttrNodeInDefineMessages(node, 'defaultMessage') ||
523
- findAttrNodeInDefineMessage(node, 'defaultMessage');
446
+ const attrNode = findAttrNodeInDefineMessages(node, 'defaultMessage') || findAttrNodeInDefineMessage(node, 'defaultMessage');
524
447
  if (attrNode) {
525
448
  return processAttrNode(attrNode);
526
449
  }
@@ -529,79 +452,213 @@ var noDefault = {
529
452
  }
530
453
  };
531
454
 
532
- var betterExhaustiveDeps = {
455
+ var noAsyncArrayMethods = {
456
+ meta: {
457
+ docs: {
458
+ description: 'No async callback for Array methods forEach, map, filter, reduce, some, every, etc.',
459
+ category: 'Array',
460
+ recommended: true
461
+ },
462
+ fixable: undefined,
463
+ schema: [],
464
+ messages: {
465
+ noAsyncArrayMethods: "No async function in method '{{ methodName }}'"
466
+ }
467
+ },
468
+ create: function (context) {
469
+ return {
470
+ ExpressionStatement: function (node) {
471
+ const notAllowedArrayMethods = ['forEach', 'filter', 'some', 'every', 'map', 'reduce', 'reduceRight', 'flatMap', 'find', 'findIndex', 'findLast', 'findLastIndex'];
472
+ const {
473
+ callee
474
+ } = node.expression;
475
+ if (!callee || !callee.property || !callee.property.name) {
476
+ return;
477
+ }
478
+ if (notAllowedArrayMethods.includes(callee.property.name)) {
479
+ const functionArguments = node.expression.arguments.find(n => {
480
+ return ['ArrowFunctionExpression', 'FunctionExpression'].includes(n.type);
481
+ });
482
+ if (functionArguments && functionArguments.async) {
483
+ context.report({
484
+ node,
485
+ messageId: 'noAsyncArrayMethods',
486
+ data: {
487
+ methodName: callee.property.name
488
+ }
489
+ });
490
+ }
491
+ }
492
+ }
493
+ };
494
+ }
495
+ };
496
+
497
+ var noImportCss = {
498
+ meta: {
499
+ type: 'problem',
500
+ docs: {
501
+ description: 'Prevent importing CSS',
502
+ recommended: true
503
+ },
504
+ fixable: 'code',
505
+ schema: [],
506
+ messages: {
507
+ noImportCSS: 'Do not import CSS files. Use CSS-in-JS instead.'
508
+ }
509
+ },
510
+ create(context) {
511
+ return {
512
+ ImportDeclaration(node) {
513
+ const ext = path.extname(node.source.value);
514
+ if (ext.startsWith('.css') || ext.startsWith('.scss') || ext.startsWith('.sass') || ext.startsWith('.less') || ext.startsWith('.styl')) {
515
+ context.report({
516
+ node,
517
+ messageId: 'noImportCSS',
518
+ data: {
519
+ path: node.source.value
520
+ }
521
+ });
522
+ }
523
+ }
524
+ };
525
+ }
526
+ };
527
+
528
+ var noThenCatchFinally = {
529
+ meta: {
530
+ type: 'suggestion',
531
+ docs: {
532
+ description: 'Disallow the use of then()/catch()/finally() when invoking specific functions.'
533
+ },
534
+ schema: [{
535
+ type: 'object',
536
+ properties: {
537
+ restrictedFunctions: {
538
+ type: 'array',
539
+ uniqueItems: true,
540
+ items: {
541
+ type: 'string'
542
+ }
543
+ }
544
+ }
545
+ }],
546
+ messages: {
547
+ forbiddenThenCatchFinally: "then()/catch()/finally() is forbidden when invoke {{ name }}()."
548
+ }
549
+ },
550
+ create(context) {
551
+ const configuration = context.options[0] || {};
552
+ const restrictedFunctions = configuration.restrictedFunctions || [];
553
+ function isTopLevelScoped() {
554
+ return context.getScope().block.type === 'Program';
555
+ }
556
+ function isThenCatchFinally(node) {
557
+ return node.property && (node.property.name === 'then' || node.property.name === 'catch' || node.property.name === 'finally');
558
+ }
559
+ return {
560
+ 'CallExpression > MemberExpression.callee'(node) {
561
+ if (isTopLevelScoped()) {
562
+ return;
563
+ }
564
+ if (!isThenCatchFinally(node)) {
565
+ return;
566
+ }
567
+ const callExpression = node.object;
568
+ if (callExpression.type === 'CallExpression' && callExpression.callee.type === 'Identifier' && restrictedFunctions.includes(callExpression.callee.name)) {
569
+ context.report({
570
+ node: node.property,
571
+ messageId: 'forbiddenThenCatchFinally',
572
+ data: {
573
+ name: callExpression.callee.name
574
+ }
575
+ });
576
+ }
577
+ }
578
+ };
579
+ }
580
+ };
581
+
582
+ var noUnnecessaryTemplateLiterals = {
583
+ meta: {
584
+ type: 'problem',
585
+ docs: {
586
+ description: 'Check if a template string contains only one ${}',
587
+ recommended: true
588
+ },
589
+ fixable: 'code',
590
+ schema: [],
591
+ messages: {
592
+ unnecessaryTemplateString: 'Unnecessary template string with only one ${}.'
593
+ }
594
+ },
595
+ create(context) {
596
+ return {
597
+ TemplateLiteral(node) {
598
+ const code = context.sourceCode.getText(node);
599
+ if (code.startsWith('`${') && code.endsWith('}`') && code.split('${').length === 2) {
600
+ context.report({
601
+ node,
602
+ messageId: 'unnecessaryTemplateString',
603
+ fix(fixer) {
604
+ return fixer.replaceText(node, code.substring(3, code.length - 2));
605
+ }
606
+ });
607
+ }
608
+ }
609
+ };
610
+ }
611
+ };
612
+
613
+ var reactBetterExhaustiveDeps = {
533
614
  meta: {
534
615
  type: 'suggestion',
535
616
  docs: {
536
- description:
537
- 'verifies the list of dependencies for Hooks like useEffect and similar',
617
+ description: 'verifies the list of dependencies for Hooks like useEffect and similar',
538
618
  url: 'https://github.com/facebook/react/issues/14920'
539
619
  },
540
620
  fixable: 'code',
541
621
  hasSuggestions: true,
542
- schema: [
543
- {
544
- type: 'object',
545
- additionalProperties: false,
546
- enableDangerousAutofixThisMayCauseInfiniteLoops: false,
547
- properties: {
548
- additionalHooks: {
549
- type: 'string'
550
- },
551
- enableDangerousAutofixThisMayCauseInfiniteLoops: {
552
- type: 'boolean'
553
- },
554
- staticHooks: {
555
- type: 'object',
556
- additionalProperties: {
557
- oneOf: [
558
- {
559
- type: 'boolean'
560
- },
561
- {
562
- type: 'array',
563
- items: {
564
- type: 'boolean'
565
- }
566
- },
567
- {
568
- type: 'object',
569
- additionalProperties: {
570
- type: 'boolean'
571
- }
572
- }
573
- ]
574
- }
575
- },
576
- checkMemoizedVariableIsStatic: {
577
- type: 'boolean'
622
+ schema: [{
623
+ type: 'object',
624
+ additionalProperties: false,
625
+ enableDangerousAutofixThisMayCauseInfiniteLoops: false,
626
+ properties: {
627
+ additionalHooks: {
628
+ type: 'string'
629
+ },
630
+ enableDangerousAutofixThisMayCauseInfiniteLoops: {
631
+ type: 'boolean'
632
+ },
633
+ staticHooks: {
634
+ type: 'object',
635
+ additionalProperties: {
636
+ oneOf: [{
637
+ type: 'boolean'
638
+ }, {
639
+ type: 'array',
640
+ items: {
641
+ type: 'boolean'
642
+ }
643
+ }, {
644
+ type: 'object',
645
+ additionalProperties: {
646
+ type: 'boolean'
647
+ }
648
+ }]
578
649
  }
650
+ },
651
+ checkMemoizedVariableIsStatic: {
652
+ type: 'boolean'
579
653
  }
580
654
  }
581
- ]
655
+ }]
582
656
  },
583
657
  create(context) {
584
- const additionalHooks =
585
- context.options &&
586
- context.options[0] &&
587
- context.options[0].additionalHooks
588
- ? new RegExp(context.options[0].additionalHooks)
589
- : undefined;
590
- const enableDangerousAutofixThisMayCauseInfiniteLoops =
591
- (context.options &&
592
- context.options[0] &&
593
- context.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops) ||
594
- false;
595
- const staticHooks =
596
- (context.options &&
597
- context.options[0] &&
598
- context.options[0].staticHooks) ||
599
- {};
600
- const checkMemoizedVariableIsStatic =
601
- (context.options &&
602
- context.options[0] &&
603
- context.options[0].checkMemoizedVariableIsStatic) ||
604
- false;
658
+ const additionalHooks = context.options && context.options[0] && context.options[0].additionalHooks ? new RegExp(context.options[0].additionalHooks) : undefined;
659
+ const enableDangerousAutofixThisMayCauseInfiniteLoops = context.options && context.options[0] && context.options[0].enableDangerousAutofixThisMayCauseInfiniteLoops || false;
660
+ const staticHooks = context.options && context.options[0] && context.options[0].staticHooks || {};
661
+ const checkMemoizedVariableIsStatic = context.options && context.options[0] && context.options[0].checkMemoizedVariableIsStatic || false;
605
662
  const options = {
606
663
  additionalHooks,
607
664
  enableDangerousAutofixThisMayCauseInfiniteLoops,
@@ -609,11 +666,8 @@ var betterExhaustiveDeps = {
609
666
  checkMemoizedVariableIsStatic
610
667
  };
611
668
  function reportProblem(problem) {
612
- if (
613
- enableDangerousAutofixThisMayCauseInfiniteLoops &&
614
- Array.isArray(problem.suggest) &&
615
- problem.suggest.length > 0
616
- ) {
669
+ if (enableDangerousAutofixThisMayCauseInfiniteLoops &&
670
+ Array.isArray(problem.suggest) && problem.suggest.length > 0) {
617
671
  problem.fix = problem.suggest[0].fix;
618
672
  }
619
673
  context.report(problem);
@@ -633,28 +687,11 @@ var betterExhaustiveDeps = {
633
687
  return result;
634
688
  };
635
689
  }
636
- function visitFunctionWithDependencies(
637
- node,
638
- declaredDependenciesNode,
639
- reactiveHook,
640
- reactiveHookName,
641
- isEffect
642
- ) {
690
+ function visitFunctionWithDependencies(node, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect) {
643
691
  if (isEffect && node.async) {
644
692
  reportProblem({
645
693
  node: node,
646
- message:
647
- `Effect callbacks are synchronous to prevent race conditions. ` +
648
- `Put the async function inside:\n\n` +
649
- 'useEffect(() => {\n' +
650
- ' async function fetchData() {\n' +
651
- ' // You can await here\n' +
652
- ' const response = await MyAPI.getData(someId);\n' +
653
- ' // ...\n' +
654
- ' }\n' +
655
- ' fetchData();\n' +
656
- `}, [someId]); // Or [] if effect doesn't need props or state\n\n` +
657
- 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching'
694
+ message: "Effect callbacks are synchronous to prevent race conditions. " + "Put the async function inside:\n\n" + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching'
658
695
  });
659
696
  }
660
697
  const scope = scopeManager.acquire(node);
@@ -675,14 +712,8 @@ var betterExhaustiveDeps = {
675
712
  componentScope = currentScope;
676
713
  }
677
714
  const isArray = Array.isArray;
678
- const memoizedIsStableKnownHookValue = memoizeWithWeakMap(
679
- isStableKnownHookValue,
680
- stableKnownValueCache
681
- );
682
- const memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap(
683
- isFunctionWithoutCapturedValues,
684
- functionWithoutCapturedValueCache
685
- );
715
+ const memoizedIsStableKnownHookValue = memoizeWithWeakMap(isStableKnownHookValue, stableKnownValueCache);
716
+ const memoizedIsFunctionWithoutCapturedValues = memoizeWithWeakMap(isFunctionWithoutCapturedValues, functionWithoutCapturedValueCache);
686
717
  function isStableKnownHookValue(resolved) {
687
718
  if (!isArray(resolved.defs)) {
688
719
  return false;
@@ -709,40 +740,27 @@ var betterExhaustiveDeps = {
709
740
  return false;
710
741
  }
711
742
  }
712
- if (
713
- declaration.kind === 'const' &&
714
- init.type === 'Literal' &&
715
- (typeof init.value === 'string' ||
716
- typeof init.value === 'number' ||
717
- init.value == null)
718
- ) {
743
+ if (declaration.kind === 'const' && init.type === 'Literal' && (typeof init.value === 'string' || typeof init.value === 'number' || init.value == null)) {
719
744
  return true;
720
745
  }
721
746
  if (init.type !== 'CallExpression') {
722
747
  return false;
723
748
  }
724
749
  let callee = init.callee;
725
- if (
726
- callee.type === 'MemberExpression' &&
727
- callee.object.name === 'React' &&
728
- callee.property != null &&
729
- !callee.computed
730
- ) {
750
+ if (callee.type === 'MemberExpression' && callee.object.name === 'React' && callee.property != null && !callee.computed) {
731
751
  callee = callee.property;
732
752
  }
733
753
  if (callee.type !== 'Identifier') {
734
754
  return false;
735
755
  }
736
756
  const id = def.node.id;
737
- const { name } = callee;
757
+ const {
758
+ name
759
+ } = callee;
738
760
  if (name === 'useRef' && id.type === 'Identifier') {
739
761
  return true;
740
762
  } else if (name === 'useState' || name === 'useReducer') {
741
- if (
742
- id.type === 'ArrayPattern' &&
743
- id.elements.length === 2 &&
744
- isArray(resolved.identifiers)
745
- ) {
763
+ if (id.type === 'ArrayPattern' && id.elements.length === 2 && isArray(resolved.identifiers)) {
746
764
  if (id.elements[1] === resolved.identifiers[0]) {
747
765
  if (name === 'useState') {
748
766
  const references = resolved.references;
@@ -769,18 +787,11 @@ var betterExhaustiveDeps = {
769
787
  }
770
788
  }
771
789
  } else if (name === 'useTransition') {
772
- if (
773
- id.type === 'ArrayPattern' &&
774
- id.elements.length === 2 &&
775
- Array.isArray(resolved.identifiers) &&
776
- id.elements[1] === resolved.identifiers[0]
777
- ) {
790
+ if (id.type === 'ArrayPattern' && id.elements.length === 2 && Array.isArray(resolved.identifiers) &&
791
+ id.elements[1] === resolved.identifiers[0]) {
778
792
  return true;
779
793
  }
780
- } else if (
781
- options.checkMemoizedVariableIsStatic &&
782
- (name === 'useMemo' || name === 'useCallback')
783
- ) {
794
+ } else if (options.checkMemoizedVariableIsStatic && (name === 'useMemo' || name === 'useCallback')) {
784
795
  const hookArgs = callee.parent.arguments;
785
796
  if (hookArgs.length < 2) {
786
797
  return false;
@@ -790,13 +801,8 @@ var betterExhaustiveDeps = {
790
801
  return true;
791
802
  }
792
803
  for (const dependencyNode of dependencies) {
793
- const dependencyRefernece = resolved.scope.references.find(
794
- reference => reference.identifier === dependencyNode
795
- );
796
- if (
797
- dependencyRefernece !== undefined &&
798
- memoizedIsStableKnownHookValue(dependencyRefernece.resolved)
799
- ) {
804
+ const dependencyRefernece = resolved.scope.references.find(reference => reference.identifier === dependencyNode);
805
+ if (dependencyRefernece !== undefined && memoizedIsStableKnownHookValue(dependencyRefernece.resolved)) {
800
806
  continue;
801
807
  } else {
802
808
  return false;
@@ -805,11 +811,7 @@ var betterExhaustiveDeps = {
805
811
  return true;
806
812
  } else {
807
813
  Object.entries(options.staticHooks).forEach(([key, staticParts]) => {
808
- if (
809
- typeof staticParts === 'object' &&
810
- staticParts.regexp &&
811
- new RegExp(key).test(name)
812
- ) {
814
+ if (typeof staticParts === 'object' && staticParts.regexp && new RegExp(key).test(name)) {
813
815
  options.staticHooks[name] = staticParts.value;
814
816
  }
815
817
  });
@@ -818,23 +820,14 @@ var betterExhaustiveDeps = {
818
820
  if (staticParts === true) {
819
821
  return true;
820
822
  } else if (Array.isArray(staticParts)) {
821
- if (
822
- id.type === 'ArrayPattern' &&
823
- id.elements.length <= staticParts.length &&
824
- Array.isArray(resolved.identifiers)
825
- ) {
823
+ if (id.type === 'ArrayPattern' && id.elements.length <= staticParts.length && Array.isArray(resolved.identifiers)) {
826
824
  const idx = id.elements.indexOf(resolved.identifiers[0]);
827
825
  if (idx >= 0) {
828
826
  return staticParts[idx];
829
827
  }
830
828
  }
831
- } else if (
832
- typeof staticParts === 'object' &&
833
- id.type === 'ObjectPattern'
834
- ) {
835
- const property = id.properties.find(
836
- p => p.key === resolved.identifiers[0]
837
- );
829
+ } else if (typeof staticParts === 'object' && id.type === 'ObjectPattern') {
830
+ const property = id.properties.find(p => p.key === resolved.identifiers[0]);
838
831
  if (property) {
839
832
  return staticParts[property.key.name];
840
833
  }
@@ -862,11 +855,8 @@ var betterExhaustiveDeps = {
862
855
  const childScope = childScopes[i];
863
856
  const childScopeBlock = childScope.block;
864
857
  if (
865
- (fnNode.type === 'FunctionDeclaration' &&
866
- childScopeBlock === fnNode) ||
867
- (fnNode.type === 'VariableDeclarator' &&
868
- childScopeBlock.parent === fnNode)
869
- ) {
858
+ fnNode.type === 'FunctionDeclaration' && childScopeBlock === fnNode ||
859
+ fnNode.type === 'VariableDeclarator' && childScopeBlock.parent === fnNode) {
870
860
  fnScope = childScope;
871
861
  break;
872
862
  }
@@ -879,10 +869,8 @@ var betterExhaustiveDeps = {
879
869
  if (ref.resolved == null) {
880
870
  continue;
881
871
  }
882
- if (
883
- pureScopes.has(ref.resolved.scope) &&
884
- !memoizedIsStableKnownHookValue(ref.resolved)
885
- ) {
872
+ if (pureScopes.has(ref.resolved.scope) &&
873
+ !memoizedIsStableKnownHookValue(ref.resolved)) {
886
874
  return false;
887
875
  }
888
876
  }
@@ -894,9 +882,7 @@ var betterExhaustiveDeps = {
894
882
  let isInReturnedFunction = false;
895
883
  while (curScope.block !== node) {
896
884
  if (curScope.type === 'function') {
897
- isInReturnedFunction =
898
- curScope.block.parent != null &&
899
- curScope.block.parent.type === 'ReturnStatement';
885
+ isInReturnedFunction = curScope.block.parent != null && curScope.block.parent.type === 'ReturnStatement';
900
886
  }
901
887
  curScope = curScope.upper;
902
888
  }
@@ -913,34 +899,19 @@ var betterExhaustiveDeps = {
913
899
  if (!pureScopes.has(reference.resolved.scope)) {
914
900
  continue;
915
901
  }
916
- const referenceNode = fastFindReferenceWithParent(
917
- node,
918
- reference.identifier
919
- );
902
+ const referenceNode = fastFindReferenceWithParent(node, reference.identifier);
920
903
  const dependencyNode = getDependency(referenceNode);
921
- const dependency = analyzePropertyChain(
922
- dependencyNode,
923
- optionalChains
924
- );
904
+ const dependency = analyzePropertyChain(dependencyNode, optionalChains);
925
905
  if (
926
- isEffect &&
927
- dependencyNode.type === 'Identifier' &&
928
- (dependencyNode.parent.type === 'MemberExpression' ||
929
- dependencyNode.parent.type === 'OptionalMemberExpression') &&
930
- !dependencyNode.parent.computed &&
931
- dependencyNode.parent.property.type === 'Identifier' &&
932
- dependencyNode.parent.property.name === 'current' &&
933
- isInsideEffectCleanup(reference)
934
- ) {
906
+ isEffect &&
907
+ dependencyNode.type === 'Identifier' && (dependencyNode.parent.type === 'MemberExpression' || dependencyNode.parent.type === 'OptionalMemberExpression') && !dependencyNode.parent.computed && dependencyNode.parent.property.type === 'Identifier' && dependencyNode.parent.property.name === 'current' &&
908
+ isInsideEffectCleanup(reference)) {
935
909
  currentRefsInEffectCleanup.set(dependency, {
936
910
  reference,
937
911
  dependencyNode
938
912
  });
939
913
  }
940
- if (
941
- dependencyNode.parent.type === 'TSTypeQuery' ||
942
- dependencyNode.parent.type === 'TSTypeReference'
943
- ) {
914
+ if (dependencyNode.parent.type === 'TSTypeQuery' || dependencyNode.parent.type === 'TSTypeReference') {
944
915
  continue;
945
916
  }
946
917
  const def = reference.resolved.defs[0];
@@ -955,9 +926,7 @@ var betterExhaustiveDeps = {
955
926
  }
956
927
  if (!dependencies.has(dependency)) {
957
928
  const resolved = reference.resolved;
958
- const isStable =
959
- memoizedIsStableKnownHookValue(resolved) ||
960
- memoizedIsFunctionWithoutCapturedValues(resolved);
929
+ const isStable = memoizedIsStableKnownHookValue(resolved) || memoizedIsFunctionWithoutCapturedValues(resolved);
961
930
  dependencies.set(dependency, {
962
931
  isStable,
963
932
  references: [reference]
@@ -970,39 +939,33 @@ var betterExhaustiveDeps = {
970
939
  gatherDependenciesRecursively(childScope);
971
940
  }
972
941
  }
973
- currentRefsInEffectCleanup.forEach(
974
- ({ reference, dependencyNode }, dependency) => {
975
- const references = reference.resolved.references;
976
- let foundCurrentAssignment = false;
977
- for (const { identifier } of references) {
978
- const { parent } = identifier;
979
- if (
980
- parent != null &&
981
- parent.type === 'MemberExpression' &&
982
- !parent.computed &&
983
- parent.property.type === 'Identifier' &&
984
- parent.property.name === 'current' &&
985
- parent.parent.type === 'AssignmentExpression' &&
986
- parent.parent.left === parent
987
- ) {
988
- foundCurrentAssignment = true;
989
- break;
990
- }
991
- }
992
- if (foundCurrentAssignment) {
993
- return;
942
+ currentRefsInEffectCleanup.forEach(({
943
+ reference,
944
+ dependencyNode
945
+ }, dependency) => {
946
+ const references = reference.resolved.references;
947
+ let foundCurrentAssignment = false;
948
+ for (const {
949
+ identifier
950
+ } of references) {
951
+ const {
952
+ parent
953
+ } = identifier;
954
+ if (parent != null &&
955
+ parent.type === 'MemberExpression' && !parent.computed && parent.property.type === 'Identifier' && parent.property.name === 'current' &&
956
+ parent.parent.type === 'AssignmentExpression' && parent.parent.left === parent) {
957
+ foundCurrentAssignment = true;
958
+ break;
994
959
  }
995
- reportProblem({
996
- node: dependencyNode.parent.property,
997
- message:
998
- `The ref value '${dependency}.current' will likely have ` +
999
- `changed by the time this effect cleanup function runs. If ` +
1000
- `this ref points to a node rendered by React, copy ` +
1001
- `'${dependency}.current' to a variable inside the effect, and ` +
1002
- `use that variable in the cleanup function.`
1003
- });
1004
960
  }
1005
- );
961
+ if (foundCurrentAssignment) {
962
+ return;
963
+ }
964
+ reportProblem({
965
+ node: dependencyNode.parent.property,
966
+ message: "The ref value '".concat(dependency, ".current' will likely have ") + "changed by the time this effect cleanup function runs. If " + "this ref points to a node rendered by React, copy " + "'".concat(dependency, ".current' to a variable inside the effect, and ") + "use that variable in the cleanup function."
967
+ });
968
+ });
1006
969
  const staleAssignments = new Set();
1007
970
  function reportStaleAssignment(writeExpr, key) {
1008
971
  if (staleAssignments.has(key)) {
@@ -1011,17 +974,14 @@ var betterExhaustiveDeps = {
1011
974
  staleAssignments.add(key);
1012
975
  reportProblem({
1013
976
  node: writeExpr,
1014
- message:
1015
- `Assignments to the '${key}' variable from inside React Hook ` +
1016
- `${context.getSource(reactiveHook)} will be lost after each ` +
1017
- `render. To preserve the value over time, store it in a useRef ` +
1018
- `Hook and keep the mutable value in the '.current' property. ` +
1019
- `Otherwise, you can move this variable directly inside ` +
1020
- `${context.getSource(reactiveHook)}.`
977
+ message: "Assignments to the '".concat(key, "' variable from inside React Hook ") + "".concat(context.getSource(reactiveHook), " will be lost after each ") + "render. To preserve the value over time, store it in a useRef " + "Hook and keep the mutable value in the '.current' property. " + "Otherwise, you can move this variable directly inside " + "".concat(context.getSource(reactiveHook), ".")
1021
978
  });
1022
979
  }
1023
980
  const stableDependencies = new Set();
1024
- dependencies.forEach(({ isStable, references }, key) => {
981
+ dependencies.forEach(({
982
+ isStable,
983
+ references
984
+ }, key) => {
1025
985
  if (isStable) {
1026
986
  stableDependencies.add(key);
1027
987
  }
@@ -1036,7 +996,9 @@ var betterExhaustiveDeps = {
1036
996
  }
1037
997
  if (!declaredDependenciesNode) {
1038
998
  let setStateInsideEffectWithoutDeps = null;
1039
- dependencies.forEach(({ references }, key) => {
999
+ dependencies.forEach(({
1000
+ references
1001
+ }, key) => {
1040
1002
  if (setStateInsideEffectWithoutDeps) {
1041
1003
  return;
1042
1004
  }
@@ -1060,7 +1022,9 @@ var betterExhaustiveDeps = {
1060
1022
  });
1061
1023
  });
1062
1024
  if (setStateInsideEffectWithoutDeps) {
1063
- const { suggestedDependencies } = collectRecommendations({
1025
+ const {
1026
+ suggestedDependencies
1027
+ } = collectRecommendations({
1064
1028
  dependencies,
1065
1029
  declaredDependencies: [],
1066
1030
  stableDependencies,
@@ -1069,25 +1033,13 @@ var betterExhaustiveDeps = {
1069
1033
  });
1070
1034
  reportProblem({
1071
1035
  node: reactiveHook,
1072
- message:
1073
- `React Hook ${reactiveHookName} contains a call to '${setStateInsideEffectWithoutDeps}'. ` +
1074
- `Without a list of dependencies, this can lead to an infinite chain of updates. ` +
1075
- `To fix this, pass [` +
1076
- suggestedDependencies.join(', ') +
1077
- `] as a second argument to the ${reactiveHookName} Hook.`,
1078
- suggest: [
1079
- {
1080
- desc: `Add dependencies array: [${suggestedDependencies.join(
1081
- ', '
1082
- )}]`,
1083
- fix(fixer) {
1084
- return fixer.insertTextAfter(
1085
- node,
1086
- `, [${suggestedDependencies.join(', ')}]`
1087
- );
1088
- }
1036
+ message: "React Hook ".concat(reactiveHookName, " contains a call to '").concat(setStateInsideEffectWithoutDeps, "'. ") + "Without a list of dependencies, this can lead to an infinite chain of updates. " + "To fix this, pass [" + suggestedDependencies.join(', ') + "] as a second argument to the ".concat(reactiveHookName, " Hook."),
1037
+ suggest: [{
1038
+ desc: "Add dependencies array: [".concat(suggestedDependencies.join(', '), "]"),
1039
+ fix(fixer) {
1040
+ return fixer.insertTextAfter(node, ", [".concat(suggestedDependencies.join(', '), "]"));
1089
1041
  }
1090
- ]
1042
+ }]
1091
1043
  });
1092
1044
  }
1093
1045
  return;
@@ -1097,11 +1049,7 @@ var betterExhaustiveDeps = {
1097
1049
  if (declaredDependenciesNode.type !== 'ArrayExpression') {
1098
1050
  reportProblem({
1099
1051
  node: declaredDependenciesNode,
1100
- message:
1101
- `React Hook ${context.getSource(reactiveHook)} was passed a ` +
1102
- 'dependency list that is not an array literal. This means we ' +
1103
- "can't statically verify whether you've passed the correct " +
1104
- 'dependencies.'
1052
+ message: "React Hook ".concat(context.getSource(reactiveHook), " was passed a ") + 'dependency list that is not an array literal. This means we ' + "can't statically verify whether you've passed the correct " + 'dependencies.'
1105
1053
  });
1106
1054
  } else {
1107
1055
  declaredDependenciesNode.elements.forEach(declaredDependencyNode => {
@@ -1111,46 +1059,31 @@ var betterExhaustiveDeps = {
1111
1059
  if (declaredDependencyNode.type === 'SpreadElement') {
1112
1060
  reportProblem({
1113
1061
  node: declaredDependencyNode,
1114
- message:
1115
- `React Hook ${context.getSource(reactiveHook)} has a spread ` +
1116
- "element in its dependency array. This means we can't " +
1117
- "statically verify whether you've passed the " +
1118
- 'correct dependencies.'
1062
+ message: "React Hook ".concat(context.getSource(reactiveHook), " has a spread ") + "element in its dependency array. This means we can't " + "statically verify whether you've passed the " + 'correct dependencies.'
1119
1063
  });
1120
1064
  return;
1121
1065
  }
1122
1066
  let declaredDependency;
1123
1067
  try {
1124
- declaredDependency = analyzePropertyChain(
1125
- declaredDependencyNode,
1126
- null
1127
- );
1068
+ declaredDependency = analyzePropertyChain(declaredDependencyNode, null);
1128
1069
  } catch (err) {
1129
1070
  if (/Unsupported node type/.test(err.message)) {
1130
1071
  if (declaredDependencyNode.type === 'Literal') {
1131
1072
  if (dependencies.has(declaredDependencyNode.value)) {
1132
1073
  reportProblem({
1133
1074
  node: declaredDependencyNode,
1134
- message:
1135
- `The ${declaredDependencyNode.raw} literal is not a valid dependency ` +
1136
- `because it never changes. ` +
1137
- `Did you mean to include ${declaredDependencyNode.value} in the array instead?`
1075
+ message: "The ".concat(declaredDependencyNode.raw, " literal is not a valid dependency ") + "because it never changes. " + "Did you mean to include ".concat(declaredDependencyNode.value, " in the array instead?")
1138
1076
  });
1139
1077
  } else {
1140
1078
  reportProblem({
1141
1079
  node: declaredDependencyNode,
1142
- message:
1143
- `The ${declaredDependencyNode.raw} literal is not a valid dependency ` +
1144
- 'because it never changes. You can safely remove it.'
1080
+ message: "The ".concat(declaredDependencyNode.raw, " literal is not a valid dependency ") + 'because it never changes. You can safely remove it.'
1145
1081
  });
1146
1082
  }
1147
1083
  } else {
1148
1084
  reportProblem({
1149
1085
  node: declaredDependencyNode,
1150
- message:
1151
- `React Hook ${context.getSource(reactiveHook)} has a ` +
1152
- `complex expression in the dependency array. ` +
1153
- 'Extract it to a separate variable so it can be statically checked.'
1086
+ message: "React Hook ".concat(context.getSource(reactiveHook), " has a ") + "complex expression in the dependency array. " + 'Extract it to a separate variable so it can be statically checked.'
1154
1087
  });
1155
1088
  }
1156
1089
  return;
@@ -1158,16 +1091,10 @@ var betterExhaustiveDeps = {
1158
1091
  throw err;
1159
1092
  }
1160
1093
  let maybeID = declaredDependencyNode;
1161
- while (
1162
- maybeID.type === 'MemberExpression' ||
1163
- maybeID.type === 'OptionalMemberExpression' ||
1164
- maybeID.type === 'ChainExpression'
1165
- ) {
1094
+ while (maybeID.type === 'MemberExpression' || maybeID.type === 'OptionalMemberExpression' || maybeID.type === 'ChainExpression') {
1166
1095
  maybeID = maybeID.object || maybeID.expression.object;
1167
1096
  }
1168
- const isDeclaredInComponent = !componentScope.through.some(
1169
- ref => ref.identifier === maybeID
1170
- );
1097
+ const isDeclaredInComponent = !componentScope.through.some(ref => ref.identifier === maybeID);
1171
1098
  declaredDependencies.push({
1172
1099
  key: declaredDependency,
1173
1100
  node: declaredDependencyNode
@@ -1190,10 +1117,7 @@ var betterExhaustiveDeps = {
1190
1117
  isEffect
1191
1118
  });
1192
1119
  let suggestedDeps = suggestedDependencies;
1193
- const problemCount =
1194
- duplicateDependencies.size +
1195
- missingDependencies.size +
1196
- unnecessaryDependencies.size;
1120
+ const problemCount = duplicateDependencies.size + missingDependencies.size + unnecessaryDependencies.size;
1197
1121
  if (problemCount === 0) {
1198
1122
  const constructions = scanForConstructions({
1199
1123
  declaredDependencies,
@@ -1201,53 +1125,36 @@ var betterExhaustiveDeps = {
1201
1125
  componentScope,
1202
1126
  scope
1203
1127
  });
1204
- constructions.forEach(
1205
- ({ construction, isUsedOutsideOfHook, depType }) => {
1206
- const wrapperHook =
1207
- depType === 'function' ? 'useCallback' : 'useMemo';
1208
- const constructionType =
1209
- depType === 'function' ? 'definition' : 'initialization';
1210
- const defaultAdvice = `wrap the ${constructionType} of '${construction.name.name}' in its own ${wrapperHook}() Hook.`;
1211
- const advice = isUsedOutsideOfHook
1212
- ? `To fix this, ${defaultAdvice}`
1213
- : `Move it inside the ${reactiveHookName} callback. Alternatively, ${defaultAdvice}`;
1214
- const causation =
1215
- depType === 'conditional' || depType === 'logical expression'
1216
- ? 'could make'
1217
- : 'makes';
1218
- const message =
1219
- `The '${construction.name.name}' ${depType} ${causation} the dependencies of ` +
1220
- `${reactiveHookName} Hook (at line ${declaredDependenciesNode.loc.start.line}) ` +
1221
- `change on every render. ${advice}`;
1222
- let suggest;
1223
- if (
1224
- isUsedOutsideOfHook &&
1225
- construction.type === 'Variable' &&
1226
- depType === 'function'
1227
- ) {
1228
- suggest = [
1229
- {
1230
- desc: `Wrap the ${constructionType} of '${construction.name.name}' in its own ${wrapperHook}() Hook.`,
1231
- fix(fixer) {
1232
- const [before, after] =
1233
- wrapperHook === 'useMemo'
1234
- ? [`useMemo(() => { return `, '; })']
1235
- : ['useCallback(', ')'];
1236
- return [
1237
- fixer.insertTextBefore(construction.node.init, before),
1238
- fixer.insertTextAfter(construction.node.init, after)
1239
- ];
1240
- }
1241
- }
1242
- ];
1243
- }
1244
- reportProblem({
1245
- node: construction.node,
1246
- message,
1247
- suggest
1248
- });
1128
+ constructions.forEach(({
1129
+ construction,
1130
+ isUsedOutsideOfHook,
1131
+ depType
1132
+ }) => {
1133
+ const wrapperHook = depType === 'function' ? 'useCallback' : 'useMemo';
1134
+ const constructionType = depType === 'function' ? 'definition' : 'initialization';
1135
+ const defaultAdvice = "wrap the ".concat(constructionType, " of '").concat(construction.name.name, "' in its own ").concat(wrapperHook, "() Hook.");
1136
+ const advice = isUsedOutsideOfHook ? "To fix this, ".concat(defaultAdvice) : "Move it inside the ".concat(reactiveHookName, " callback. Alternatively, ").concat(defaultAdvice);
1137
+ const causation = depType === 'conditional' || depType === 'logical expression' ? 'could make' : 'makes';
1138
+ const message = "The '".concat(construction.name.name, "' ").concat(depType, " ").concat(causation, " the dependencies of ") + "".concat(reactiveHookName, " Hook (at line ").concat(declaredDependenciesNode.loc.start.line, ") ") + "change on every render. ".concat(advice);
1139
+ let suggest;
1140
+ if (isUsedOutsideOfHook && construction.type === 'Variable' &&
1141
+ depType === 'function') {
1142
+ suggest = [{
1143
+ desc: "Wrap the ".concat(constructionType, " of '").concat(construction.name.name, "' in its own ").concat(wrapperHook, "() Hook."),
1144
+ fix(fixer) {
1145
+ const [before, after] = wrapperHook === 'useMemo' ? ["useMemo(() => { return ", '; })'] : ['useCallback(', ')'];
1146
+ return [
1147
+ fixer.insertTextBefore(construction.node.init, before),
1148
+ fixer.insertTextAfter(construction.node.init, after)];
1149
+ }
1150
+ }];
1249
1151
  }
1250
- );
1152
+ reportProblem({
1153
+ node: construction.node,
1154
+ message,
1155
+ suggest
1156
+ });
1157
+ });
1251
1158
  return;
1252
1159
  }
1253
1160
  if (!isEffect && missingDependencies.size > 0) {
@@ -1287,19 +1194,7 @@ var betterExhaustiveDeps = {
1287
1194
  if (deps.size === 0) {
1288
1195
  return null;
1289
1196
  }
1290
- return (
1291
- (deps.size > 1 ? '' : singlePrefix + ' ') +
1292
- label +
1293
- ' ' +
1294
- (deps.size > 1 ? 'dependencies' : 'dependency') +
1295
- ': ' +
1296
- joinEnglish(
1297
- [...deps].sort().map(name => "'" + formatDependency(name) + "'")
1298
- ) +
1299
- `. Either ${fixVerb} ${
1300
- deps.size > 1 ? 'them' : 'it'
1301
- } or remove the dependency array.`
1302
- );
1197
+ return (deps.size > 1 ? '' : singlePrefix + ' ') + label + ' ' + (deps.size > 1 ? 'dependencies' : 'dependency') + ': ' + joinEnglish([...deps].sort().map(name => "'" + formatDependency(name) + "'")) + ". Either ".concat(fixVerb, " ").concat(deps.size > 1 ? 'them' : 'it', " or remove the dependency array.");
1303
1198
  }
1304
1199
  let extraWarning = '';
1305
1200
  if (unnecessaryDependencies.size > 0) {
@@ -1313,15 +1208,11 @@ var betterExhaustiveDeps = {
1313
1208
  }
1314
1209
  });
1315
1210
  if (badRef != null) {
1316
- extraWarning =
1317
- ` Mutable values like '${badRef}' aren't valid dependencies ` +
1318
- "because mutating them doesn't re-render the component.";
1211
+ extraWarning = " Mutable values like '".concat(badRef, "' aren't valid dependencies ") + "because mutating them doesn't re-render the component.";
1319
1212
  } else if (externalDependencies.size > 0) {
1320
1213
  const dep = [...externalDependencies][0];
1321
1214
  if (!scope.set.has(dep)) {
1322
- extraWarning =
1323
- ` Outer scope values like '${dep}' aren't valid dependencies ` +
1324
- `because mutating them doesn't re-render the component.`;
1215
+ extraWarning = " Outer scope values like '".concat(dep, "' aren't valid dependencies ") + "because mutating them doesn't re-render the component.";
1325
1216
  }
1326
1217
  }
1327
1218
  }
@@ -1336,10 +1227,7 @@ var betterExhaustiveDeps = {
1336
1227
  }
1337
1228
  let isPropsOnlyUsedInMembers = true;
1338
1229
  for (const ref of refs) {
1339
- const id = fastFindReferenceWithParent(
1340
- componentScope.block,
1341
- ref.identifier
1342
- );
1230
+ const id = fastFindReferenceWithParent(componentScope.block, ref.identifier);
1343
1231
  if (!id) {
1344
1232
  isPropsOnlyUsedInMembers = false;
1345
1233
  break;
@@ -1349,20 +1237,13 @@ var betterExhaustiveDeps = {
1349
1237
  isPropsOnlyUsedInMembers = false;
1350
1238
  break;
1351
1239
  }
1352
- if (
1353
- parent.type !== 'MemberExpression' &&
1354
- parent.type !== 'OptionalMemberExpression'
1355
- ) {
1240
+ if (parent.type !== 'MemberExpression' && parent.type !== 'OptionalMemberExpression') {
1356
1241
  isPropsOnlyUsedInMembers = false;
1357
1242
  break;
1358
1243
  }
1359
1244
  }
1360
1245
  if (isPropsOnlyUsedInMembers) {
1361
- extraWarning =
1362
- ` However, 'props' will change when *any* prop changes, so the ` +
1363
- `preferred fix is to destructure the 'props' object outside of ` +
1364
- `the ${reactiveHookName} call and refer to those specific props ` +
1365
- `inside ${context.getSource(reactiveHook)}.`;
1246
+ extraWarning = " However, 'props' will change when *any* prop changes, so the " + "preferred fix is to destructure the 'props' object outside of " + "the ".concat(reactiveHookName, " call and refer to those specific props ") + "inside ".concat(context.getSource(reactiveHook), ".");
1366
1247
  }
1367
1248
  }
1368
1249
  if (!extraWarning && missingDependencies.size > 0) {
@@ -1384,13 +1265,7 @@ var betterExhaustiveDeps = {
1384
1265
  let id;
1385
1266
  for (let i = 0; i < usedDep.references.length; i++) {
1386
1267
  id = usedDep.references[i].identifier;
1387
- if (
1388
- id != null &&
1389
- id.parent != null &&
1390
- (id.parent.type === 'CallExpression' ||
1391
- id.parent.type === 'OptionalCallExpression') &&
1392
- id.parent.callee === id
1393
- ) {
1268
+ if (id != null && id.parent != null && (id.parent.type === 'CallExpression' || id.parent.type === 'OptionalCallExpression') && id.parent.callee === id) {
1394
1269
  isFunctionCall = true;
1395
1270
  break;
1396
1271
  }
@@ -1401,10 +1276,7 @@ var betterExhaustiveDeps = {
1401
1276
  missingCallbackDep = missingDep;
1402
1277
  });
1403
1278
  if (missingCallbackDep != null) {
1404
- extraWarning =
1405
- ` If '${missingCallbackDep}' changes too often, ` +
1406
- `find the parent component that defines it ` +
1407
- `and wrap that definition in useCallback.`;
1279
+ extraWarning = " If '".concat(missingCallbackDep, "' changes too often, ") + "find the parent component that defines it " + "and wrap that definition in useCallback.";
1408
1280
  }
1409
1281
  }
1410
1282
  if (!extraWarning && missingDependencies.size > 0) {
@@ -1422,9 +1294,7 @@ var betterExhaustiveDeps = {
1422
1294
  maybeCall = id.parent;
1423
1295
  while (maybeCall != null && maybeCall !== componentScope.block) {
1424
1296
  if (maybeCall.type === 'CallExpression') {
1425
- const correspondingStateVariable = setStateCallSites.get(
1426
- maybeCall.callee
1427
- );
1297
+ const correspondingStateVariable = setStateCallSites.get(maybeCall.callee);
1428
1298
  if (correspondingStateVariable != null) {
1429
1299
  if (correspondingStateVariable.name === missingDep) {
1430
1300
  setStateRecommendation = {
@@ -1464,27 +1334,13 @@ var betterExhaustiveDeps = {
1464
1334
  if (setStateRecommendation != null) {
1465
1335
  switch (setStateRecommendation.form) {
1466
1336
  case 'reducer':
1467
- extraWarning =
1468
- ` You can also replace multiple useState variables with useReducer ` +
1469
- `if '${setStateRecommendation.setter}' needs the ` +
1470
- `current value of '${setStateRecommendation.missingDep}'.`;
1337
+ extraWarning = " You can also replace multiple useState variables with useReducer " + "if '".concat(setStateRecommendation.setter, "' needs the ") + "current value of '".concat(setStateRecommendation.missingDep, "'.");
1471
1338
  break;
1472
1339
  case 'inlineReducer':
1473
- extraWarning =
1474
- ` If '${setStateRecommendation.setter}' needs the ` +
1475
- `current value of '${setStateRecommendation.missingDep}', ` +
1476
- `you can also switch to useReducer instead of useState and ` +
1477
- `read '${setStateRecommendation.missingDep}' in the reducer.`;
1340
+ extraWarning = " If '".concat(setStateRecommendation.setter, "' needs the ") + "current value of '".concat(setStateRecommendation.missingDep, "', ") + "you can also switch to useReducer instead of useState and " + "read '".concat(setStateRecommendation.missingDep, "' in the reducer.");
1478
1341
  break;
1479
1342
  case 'updater':
1480
- extraWarning = ` You can also do a functional update '${
1481
- setStateRecommendation.setter
1482
- }(${setStateRecommendation.missingDep.slice(
1483
- 0,
1484
- 1
1485
- )} => ...)' if you only need '${
1486
- setStateRecommendation.missingDep
1487
- }' in the '${setStateRecommendation.setter}' call.`;
1343
+ extraWarning = " You can also do a functional update '".concat(setStateRecommendation.setter, "(").concat(setStateRecommendation.missingDep.slice(0, 1), " => ...)' if you only need '").concat(setStateRecommendation.missingDep, "' in the '").concat(setStateRecommendation.setter, "' call.");
1488
1344
  break;
1489
1345
  default:
1490
1346
  throw new Error('Unknown case.');
@@ -1493,35 +1349,14 @@ var betterExhaustiveDeps = {
1493
1349
  }
1494
1350
  reportProblem({
1495
1351
  node: declaredDependenciesNode,
1496
- message:
1497
- `React Hook ${context.getSource(reactiveHook)} has ` +
1498
- (getWarningMessage(missingDependencies, 'a', 'missing', 'include') ||
1499
- getWarningMessage(
1500
- unnecessaryDependencies,
1501
- 'an',
1502
- 'unnecessary',
1503
- 'exclude'
1504
- ) ||
1505
- getWarningMessage(
1506
- duplicateDependencies,
1507
- 'a',
1508
- 'duplicate',
1509
- 'omit'
1510
- )) +
1511
- extraWarning,
1512
- suggest: [
1513
- {
1514
- desc: `Update the dependencies array to be: [${suggestedDeps
1515
- .map(element => formatDependency(element))
1516
- .join(', ')}]`,
1517
- fix(fixer) {
1518
- return fixer.replaceText(
1519
- declaredDependenciesNode,
1520
- `[${suggestedDeps.map(element => formatDependency(element)).join(', ')}]`
1521
- );
1522
- }
1523
- }
1524
- ]
1352
+ message: "React Hook ".concat(context.getSource(reactiveHook), " has ") + (
1353
+ getWarningMessage(missingDependencies, 'a', 'missing', 'include') || getWarningMessage(unnecessaryDependencies, 'an', 'unnecessary', 'exclude') || getWarningMessage(duplicateDependencies, 'a', 'duplicate', 'omit')) + extraWarning,
1354
+ suggest: [{
1355
+ desc: "Update the dependencies array to be: [".concat(suggestedDeps.map(element => formatDependency(element)).join(', '), "]"),
1356
+ fix(fixer) {
1357
+ return fixer.replaceText(declaredDependenciesNode, "[".concat(suggestedDeps.map(element => formatDependency(element)).join(', '), "]"));
1358
+ }
1359
+ }]
1525
1360
  });
1526
1361
  }
1527
1362
  function visitCallExpression(node) {
@@ -1537,23 +1372,15 @@ var betterExhaustiveDeps = {
1537
1372
  if (!callback) {
1538
1373
  reportProblem({
1539
1374
  node: reactiveHook,
1540
- message:
1541
- `React Hook ${reactiveHookName} requires an effect callback. ` +
1542
- `Did you forget to pass a callback to the hook?`
1375
+ message: "React Hook ".concat(reactiveHookName, " requires an effect callback. ") + "Did you forget to pass a callback to the hook?"
1543
1376
  });
1544
1377
  return;
1545
1378
  }
1546
1379
  if (!declaredDependenciesNode && !isEffect) {
1547
- if (
1548
- reactiveHookName === 'useMemo' ||
1549
- reactiveHookName === 'useCallback'
1550
- ) {
1380
+ if (reactiveHookName === 'useMemo' || reactiveHookName === 'useCallback') {
1551
1381
  reportProblem({
1552
1382
  node: reactiveHook,
1553
- message:
1554
- `React Hook ${reactiveHookName} does nothing when called with ` +
1555
- `only one argument. Did you forget to pass an array of ` +
1556
- `dependencies?`
1383
+ message: "React Hook ".concat(reactiveHookName, " does nothing when called with ") + "only one argument. Did you forget to pass an array of " + "dependencies?"
1557
1384
  });
1558
1385
  }
1559
1386
  return;
@@ -1561,24 +1388,13 @@ var betterExhaustiveDeps = {
1561
1388
  switch (callback.type) {
1562
1389
  case 'FunctionExpression':
1563
1390
  case 'ArrowFunctionExpression':
1564
- visitFunctionWithDependencies(
1565
- callback,
1566
- declaredDependenciesNode,
1567
- reactiveHook,
1568
- reactiveHookName,
1569
- isEffect
1570
- );
1391
+ visitFunctionWithDependencies(callback, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect);
1571
1392
  return;
1572
1393
  case 'Identifier':
1573
1394
  if (!declaredDependenciesNode) {
1574
1395
  return;
1575
1396
  }
1576
- if (
1577
- declaredDependenciesNode.elements &&
1578
- declaredDependenciesNode.elements.some(
1579
- el => el && el.type === 'Identifier' && el.name === callback.name
1580
- )
1581
- ) {
1397
+ if (declaredDependenciesNode.elements && declaredDependenciesNode.elements.some(el => el && el.type === 'Identifier' && el.name === callback.name)) {
1582
1398
  return;
1583
1399
  }
1584
1400
  const variable = context.getScope().set.get(callback.name);
@@ -1594,13 +1410,7 @@ var betterExhaustiveDeps = {
1594
1410
  }
1595
1411
  switch (def.node.type) {
1596
1412
  case 'FunctionDeclaration':
1597
- visitFunctionWithDependencies(
1598
- def.node,
1599
- declaredDependenciesNode,
1600
- reactiveHook,
1601
- reactiveHookName,
1602
- isEffect
1603
- );
1413
+ visitFunctionWithDependencies(def.node, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect);
1604
1414
  return;
1605
1415
  case 'VariableDeclarator':
1606
1416
  const init = def.node.init;
@@ -1610,13 +1420,7 @@ var betterExhaustiveDeps = {
1610
1420
  switch (init.type) {
1611
1421
  case 'ArrowFunctionExpression':
1612
1422
  case 'FunctionExpression':
1613
- visitFunctionWithDependencies(
1614
- init,
1615
- declaredDependenciesNode,
1616
- reactiveHook,
1617
- reactiveHookName,
1618
- isEffect
1619
- );
1423
+ visitFunctionWithDependencies(init, declaredDependenciesNode, reactiveHook, reactiveHookName, isEffect);
1620
1424
  return;
1621
1425
  }
1622
1426
  break;
@@ -1625,28 +1429,19 @@ var betterExhaustiveDeps = {
1625
1429
  default:
1626
1430
  reportProblem({
1627
1431
  node: reactiveHook,
1628
- message:
1629
- `React Hook ${reactiveHookName} received a function whose dependencies ` +
1630
- `are unknown. Pass an inline function instead.`
1432
+ message: "React Hook ".concat(reactiveHookName, " received a function whose dependencies ") + "are unknown. Pass an inline function instead."
1631
1433
  });
1632
1434
  return;
1633
1435
  }
1634
1436
  reportProblem({
1635
1437
  node: reactiveHook,
1636
- message:
1637
- `React Hook ${reactiveHookName} has a missing dependency: '${callback.name}'. ` +
1638
- `Either include it or remove the dependency array.`,
1639
- suggest: [
1640
- {
1641
- desc: `Update the dependencies array to be: [${callback.name}]`,
1642
- fix(fixer) {
1643
- return fixer.replaceText(
1644
- declaredDependenciesNode,
1645
- `[${callback.name}]`
1646
- );
1647
- }
1438
+ message: "React Hook ".concat(reactiveHookName, " has a missing dependency: '").concat(callback.name, "'. ") + "Either include it or remove the dependency array.",
1439
+ suggest: [{
1440
+ desc: "Update the dependencies array to be: [".concat(callback.name, "]"),
1441
+ fix(fixer) {
1442
+ return fixer.replaceText(declaredDependenciesNode, "[".concat(callback.name, "]"));
1648
1443
  }
1649
- ]
1444
+ }]
1650
1445
  });
1651
1446
  }
1652
1447
  return {
@@ -1677,7 +1472,9 @@ function collectRecommendations({
1677
1472
  parent.isSubtreeUsed = true;
1678
1473
  });
1679
1474
  });
1680
- declaredDependencies.forEach(({ key }) => {
1475
+ declaredDependencies.forEach(({
1476
+ key
1477
+ }) => {
1681
1478
  const node = getOrCreateNodeByPath(depTree, key);
1682
1479
  node.isSatisfiedRecursively = true;
1683
1480
  });
@@ -1712,12 +1509,7 @@ function collectRecommendations({
1712
1509
  }
1713
1510
  const missingDependencies = new Set();
1714
1511
  const satisfyingDependencies = new Set();
1715
- scanTreeRecursively(
1716
- depTree,
1717
- missingDependencies,
1718
- satisfyingDependencies,
1719
- key => key
1720
- );
1512
+ scanTreeRecursively(depTree, missingDependencies, satisfyingDependencies, key => key);
1721
1513
  function scanTreeRecursively(node, missingPaths, satisfyingPaths, keyToPath) {
1722
1514
  node.children.forEach((child, key) => {
1723
1515
  const path = keyToPath(key);
@@ -1731,29 +1523,22 @@ function collectRecommendations({
1731
1523
  missingPaths.add(path);
1732
1524
  return;
1733
1525
  }
1734
- scanTreeRecursively(
1735
- child,
1736
- missingPaths,
1737
- satisfyingPaths,
1738
- childKey => path + '.' + childKey
1739
- );
1526
+ scanTreeRecursively(child, missingPaths, satisfyingPaths, childKey => path + '.' + childKey);
1740
1527
  });
1741
1528
  }
1742
1529
  const suggestedDependencies = [];
1743
1530
  const unnecessaryDependencies = new Set();
1744
1531
  const duplicateDependencies = new Set();
1745
- declaredDependencies.forEach(({ key }) => {
1532
+ declaredDependencies.forEach(({
1533
+ key
1534
+ }) => {
1746
1535
  if (satisfyingDependencies.has(key)) {
1747
1536
  if (!suggestedDependencies.includes(key)) {
1748
1537
  suggestedDependencies.push(key);
1749
1538
  } else {
1750
1539
  duplicateDependencies.add(key);
1751
1540
  }
1752
- } else if (
1753
- isEffect &&
1754
- !key.endsWith('.current') &&
1755
- !externalDependencies.has(key)
1756
- ) {
1541
+ } else if (isEffect && !key.endsWith('.current') && !externalDependencies.has(key)) {
1757
1542
  if (!suggestedDependencies.includes(key)) {
1758
1543
  suggestedDependencies.push(key);
1759
1544
  }
@@ -1783,18 +1568,12 @@ function getConstructionExpressionType(node) {
1783
1568
  case 'ClassExpression':
1784
1569
  return 'class';
1785
1570
  case 'ConditionalExpression':
1786
- if (
1787
- getConstructionExpressionType(node.consequent) != null ||
1788
- getConstructionExpressionType(node.alternate) != null
1789
- ) {
1571
+ if (getConstructionExpressionType(node.consequent) != null || getConstructionExpressionType(node.alternate) != null) {
1790
1572
  return 'conditional';
1791
1573
  }
1792
1574
  return null;
1793
1575
  case 'LogicalExpression':
1794
- if (
1795
- getConstructionExpressionType(node.left) != null ||
1796
- getConstructionExpressionType(node.right) != null
1797
- ) {
1576
+ if (getConstructionExpressionType(node.left) != null || getConstructionExpressionType(node.right) != null) {
1798
1577
  return 'logical expression';
1799
1578
  }
1800
1579
  return null;
@@ -1827,41 +1606,32 @@ function scanForConstructions({
1827
1606
  componentScope,
1828
1607
  scope
1829
1608
  }) {
1830
- const constructions = declaredDependencies
1831
- .map(({ key }) => {
1832
- const ref = componentScope.variables.find(v => v.name === key);
1833
- if (ref == null) {
1834
- return null;
1835
- }
1836
- const node = ref.defs[0];
1837
- if (node == null) {
1838
- return null;
1839
- }
1840
- if (
1841
- node.type === 'Variable' &&
1842
- node.node.type === 'VariableDeclarator' &&
1843
- node.node.id.type === 'Identifier' &&
1844
- node.node.init != null
1845
- ) {
1846
- const constantExpressionType = getConstructionExpressionType(
1847
- node.node.init
1848
- );
1849
- if (constantExpressionType != null) {
1850
- return [ref, constantExpressionType];
1851
- }
1852
- }
1853
- if (
1854
- node.type === 'FunctionName' &&
1855
- node.node.type === 'FunctionDeclaration'
1856
- ) {
1857
- return [ref, 'function'];
1858
- }
1859
- if (node.type === 'ClassName' && node.node.type === 'ClassDeclaration') {
1860
- return [ref, 'class'];
1861
- }
1609
+ const constructions = declaredDependencies.map(({
1610
+ key
1611
+ }) => {
1612
+ const ref = componentScope.variables.find(v => v.name === key);
1613
+ if (ref == null) {
1862
1614
  return null;
1863
- })
1864
- .filter(Boolean);
1615
+ }
1616
+ const node = ref.defs[0];
1617
+ if (node == null) {
1618
+ return null;
1619
+ }
1620
+ if (node.type === 'Variable' && node.node.type === 'VariableDeclarator' && node.node.id.type === 'Identifier' &&
1621
+ node.node.init != null) {
1622
+ const constantExpressionType = getConstructionExpressionType(node.node.init);
1623
+ if (constantExpressionType != null) {
1624
+ return [ref, constantExpressionType];
1625
+ }
1626
+ }
1627
+ if (node.type === 'FunctionName' && node.node.type === 'FunctionDeclaration') {
1628
+ return [ref, 'function'];
1629
+ }
1630
+ if (node.type === 'ClassName' && node.node.type === 'ClassDeclaration') {
1631
+ return [ref, 'class'];
1632
+ }
1633
+ return null;
1634
+ }).filter(Boolean);
1865
1635
  function isUsedOutsideOfHook(ref) {
1866
1636
  let foundWriteExpr = false;
1867
1637
  for (let i = 0; i < ref.references.length; i++) {
@@ -1877,10 +1647,8 @@ function scanForConstructions({
1877
1647
  while (currentScope !== scope && currentScope != null) {
1878
1648
  currentScope = currentScope.upper;
1879
1649
  }
1880
- if (
1881
- currentScope !== scope &&
1882
- !isAncestorNodeOf(declaredDependenciesNode, reference.identifier)
1883
- ) {
1650
+ if (currentScope !== scope &&
1651
+ !isAncestorNodeOf(declaredDependenciesNode, reference.identifier)) {
1884
1652
  return true;
1885
1653
  }
1886
1654
  }
@@ -1893,26 +1661,10 @@ function scanForConstructions({
1893
1661
  }));
1894
1662
  }
1895
1663
  function getDependency(node) {
1896
- if (
1897
- (node.parent.type === 'MemberExpression' ||
1898
- node.parent.type === 'OptionalMemberExpression') &&
1899
- node.parent.object === node &&
1900
- node.parent.property.name !== 'current' &&
1901
- !node.parent.computed &&
1902
- !(
1903
- node.parent.parent != null &&
1904
- (node.parent.parent.type === 'CallExpression' ||
1905
- node.parent.parent.type === 'OptionalCallExpression') &&
1906
- node.parent.parent.callee === node.parent
1907
- )
1908
- ) {
1664
+ if ((node.parent.type === 'MemberExpression' || node.parent.type === 'OptionalMemberExpression') && node.parent.object === node && node.parent.property.name !== 'current' && !node.parent.computed && !(node.parent.parent != null && (node.parent.parent.type === 'CallExpression' || node.parent.parent.type === 'OptionalCallExpression') && node.parent.parent.callee === node.parent)) {
1909
1665
  return getDependency(node.parent);
1910
1666
  } else if (
1911
- node.type === 'MemberExpression' &&
1912
- node.parent &&
1913
- node.parent.type === 'AssignmentExpression' &&
1914
- node.parent.left === node
1915
- ) {
1667
+ node.type === 'MemberExpression' && node.parent && node.parent.type === 'AssignmentExpression' && node.parent.left === node) {
1916
1668
  return node.object;
1917
1669
  }
1918
1670
  return node;
@@ -1938,36 +1690,30 @@ function analyzePropertyChain(node, optionalChains) {
1938
1690
  } else if (node.type === 'MemberExpression' && !node.computed) {
1939
1691
  const object = analyzePropertyChain(node.object, optionalChains);
1940
1692
  const property = analyzePropertyChain(node.property, null);
1941
- const result = `${object}.${property}`;
1693
+ const result = "".concat(object, ".").concat(property);
1942
1694
  markNode(node, optionalChains, result);
1943
1695
  return result;
1944
1696
  } else if (node.type === 'OptionalMemberExpression' && !node.computed) {
1945
1697
  const object = analyzePropertyChain(node.object, optionalChains);
1946
1698
  const property = analyzePropertyChain(node.property, null);
1947
- const result = `${object}.${property}`;
1699
+ const result = "".concat(object, ".").concat(property);
1948
1700
  markNode(node, optionalChains, result);
1949
1701
  return result;
1950
1702
  } else if (node.type === 'ChainExpression' && !node.computed) {
1951
1703
  const expression = node.expression;
1952
1704
  if (expression.type === 'CallExpression') {
1953
- throw new Error(`Unsupported node type: ${expression.type}`);
1705
+ throw new Error("Unsupported node type: ".concat(expression.type));
1954
1706
  }
1955
1707
  const object = analyzePropertyChain(expression.object, optionalChains);
1956
1708
  const property = analyzePropertyChain(expression.property, null);
1957
- const result = `${object}.${property}`;
1709
+ const result = "".concat(object, ".").concat(property);
1958
1710
  markNode(expression, optionalChains, result);
1959
1711
  return result;
1960
1712
  }
1961
- throw new Error(`Unsupported node type: ${node.type}`);
1713
+ throw new Error("Unsupported node type: ".concat(node.type));
1962
1714
  }
1963
1715
  function getNodeWithoutReactNamespace(node) {
1964
- if (
1965
- node.type === 'MemberExpression' &&
1966
- node.object.type === 'Identifier' &&
1967
- node.object.name === 'React' &&
1968
- node.property.type === 'Identifier' &&
1969
- !node.computed
1970
- ) {
1716
+ if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'React' && node.property.type === 'Identifier' && !node.computed) {
1971
1717
  return node.property;
1972
1718
  }
1973
1719
  return node;
@@ -2046,28 +1792,17 @@ function joinEnglish(arr) {
2046
1792
  return s;
2047
1793
  }
2048
1794
  function isNodeLike(val) {
2049
- return (
2050
- typeof val === 'object' &&
2051
- val != null &&
2052
- !Array.isArray(val) &&
2053
- typeof val.type === 'string'
2054
- );
1795
+ return typeof val === 'object' && val != null && !Array.isArray(val) && typeof val.type === 'string';
2055
1796
  }
2056
1797
  function isSameIdentifier(a, b) {
2057
- return (
2058
- (a.type === 'Identifier' || a.type === 'JSXIdentifier') &&
2059
- a.type === b.type &&
2060
- a.name === b.name &&
2061
- a.range[0] === b.range[0] &&
2062
- a.range[1] === b.range[1]
2063
- );
1798
+ return (a.type === 'Identifier' || a.type === 'JSXIdentifier') && a.type === b.type && a.name === b.name && a.range[0] === b.range[0] && a.range[1] === b.range[1];
2064
1799
  }
2065
1800
  function isAncestorNodeOf(a, b) {
2066
1801
  return a.range[0] <= b.range[0] && a.range[1] >= b.range[1];
2067
1802
  }
2068
1803
 
2069
1804
  const Components = require('eslint-plugin-react/lib/util/Components');
2070
- var hookUseRef = {
1805
+ var reactHookUseRef = {
2071
1806
  meta: {
2072
1807
  docs: {
2073
1808
  description: 'Ensure naming of useRef hook value.',
@@ -2075,12 +1810,14 @@ var hookUseRef = {
2075
1810
  },
2076
1811
  schema: [],
2077
1812
  type: 'suggestion',
2078
- hasSuggestions: true
1813
+ hasSuggestions: true,
1814
+ messages: {
1815
+ useRefName: 'useRef call is not end with "Ref"'
1816
+ }
2079
1817
  },
2080
1818
  create: Components.detect((context, component, util) => ({
2081
1819
  CallExpression(node) {
2082
- const isImmediateReturn =
2083
- node.parent && node.parent.type === 'ReturnStatement';
1820
+ const isImmediateReturn = node.parent && node.parent.type === 'ReturnStatement';
2084
1821
  if (isImmediateReturn || !util.isReactHookCall(node, ['useRef'])) {
2085
1822
  return;
2086
1823
  }
@@ -2091,7 +1828,7 @@ var hookUseRef = {
2091
1828
  if (!variable.endsWith('Ref')) {
2092
1829
  context.report({
2093
1830
  node: node,
2094
- message: 'useRef call is not end with "Ref"'
1831
+ messageId: 'useRefName'
2095
1832
  });
2096
1833
  }
2097
1834
  }
@@ -2100,54 +1837,39 @@ var hookUseRef = {
2100
1837
 
2101
1838
  function* updateImportStatement(context, fixer, key) {
2102
1839
  const sourceCode = context.sourceCode;
2103
- const importNode = sourceCode.ast.body.find(
2104
- node => node.type === 'ImportDeclaration' && node.source.value === 'react'
2105
- );
1840
+ const importNode = sourceCode.ast.body.find(node => node.type === 'ImportDeclaration' && node.source.value === 'react');
2106
1841
  if (!importNode) {
2107
- yield fixer.insertTextBefore(
2108
- sourceCode.ast.body[0],
2109
- `import { ${key} } from 'react';\n`
2110
- );
1842
+ yield fixer.insertTextBefore(sourceCode.ast.body[0], "import { ".concat(key, " } from 'react';\n"));
2111
1843
  return;
2112
1844
  }
2113
- if (
2114
- importNode.specifiers.length === 1 &&
2115
- importNode.specifiers[0].type === 'ImportDefaultSpecifier'
2116
- ) {
2117
- yield fixer.insertTextAfter(importNode.specifiers[0], `, { ${key} }`);
1845
+ if (importNode.specifiers.length === 1 && importNode.specifiers[0].type === 'ImportDefaultSpecifier') {
1846
+ yield fixer.insertTextAfter(importNode.specifiers[0], ", { ".concat(key, " }"));
2118
1847
  return;
2119
1848
  }
2120
- const alreadyImportedKeys = importNode.specifiers
2121
- .filter(specifier => specifier.type === 'ImportSpecifier')
2122
- .map(specifier => specifier.imported.name);
1849
+ const alreadyImportedKeys = importNode.specifiers.filter(specifier => specifier.type === 'ImportSpecifier').map(specifier => specifier.imported.name);
2123
1850
  if (alreadyImportedKeys.includes(key)) {
2124
1851
  return;
2125
1852
  }
2126
- yield fixer.insertTextAfter([...importNode.specifiers].pop(), `, ${key}`);
1853
+ yield fixer.insertTextAfter([...importNode.specifiers].pop(), ", ".concat(key));
2127
1854
  }
2128
- var preferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
1855
+ var reactPreferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
2129
1856
  defaultOptions: [],
2130
1857
  meta: {
2131
1858
  type: 'layout',
2132
1859
  fixable: 'code',
2133
1860
  docs: {
2134
- description:
2135
- 'Enforce importing each member of React namespace separately instead of accessing them through React namespace',
1861
+ description: 'Enforce importing each member of React namespace separately instead of accessing them through React namespace',
2136
1862
  recommended: 'recommended'
2137
1863
  },
2138
1864
  messages: {
2139
- illegalReactPropertyAccess:
2140
- 'Illegal React property access: {{name}}. Use named import instead.'
1865
+ illegalReactPropertyAccess: 'Illegal React property access: {{name}}. Use named import instead.'
2141
1866
  },
2142
1867
  schema: []
2143
1868
  },
2144
1869
  create(context) {
2145
1870
  return {
2146
1871
  TSQualifiedName(node) {
2147
- if (
2148
- ('name' in node.left && node.left.name !== 'React') ||
2149
- ('name' in node.right && node.right.name.endsWith('Event'))
2150
- ) {
1872
+ if ('name' in node.left && node.left.name !== 'React' || 'name' in node.right && node.right.name.endsWith('Event')) {
2151
1873
  return;
2152
1874
  }
2153
1875
  context.report({
@@ -2182,7 +1904,7 @@ var preferNamedPropertyAccess = utils.ESLintUtils.RuleCreator.withoutDocs({
2182
1904
  }
2183
1905
  });
2184
1906
 
2185
- var preferSxProp = {
1907
+ var reactPreferSxProp = {
2186
1908
  meta: {
2187
1909
  docs: {
2188
1910
  description: 'Prefer using sx prop instead of inline styles',
@@ -2190,36 +1912,29 @@ var preferSxProp = {
2190
1912
  recommended: true
2191
1913
  },
2192
1914
  messages: {
2193
- preferSxProp:
2194
- 'Avoid using inline styles, use sx prop or tss-react or styled-component instead'
1915
+ preferSxProp: 'Avoid using inline styles, use sx prop or tss-react or styled-component instead'
2195
1916
  },
2196
- schema: [
2197
- {
2198
- type: 'object',
2199
- properties: {
2200
- allowedFor: {
2201
- type: 'array',
2202
- uniqueItems: true,
2203
- items: { type: 'string' }
1917
+ schema: [{
1918
+ type: 'object',
1919
+ properties: {
1920
+ allowedFor: {
1921
+ type: 'array',
1922
+ uniqueItems: true,
1923
+ items: {
1924
+ type: 'string'
2204
1925
  }
2205
1926
  }
2206
1927
  }
2207
- ]
1928
+ }]
2208
1929
  },
2209
1930
  create(context) {
2210
1931
  const configuration = context.options[0] || {};
2211
1932
  const allowedFor = configuration.allowedFor || [];
2212
1933
  function checkComponent(node) {
2213
1934
  const parentName = node.parent.name;
2214
- const tag =
2215
- parentName.name ||
2216
- `${parentName.object.name}.${parentName.property.name}`;
1935
+ const tag = parentName.name || "".concat(parentName.object.name, ".").concat(parentName.property.name);
2217
1936
  const componentName = parentName.name || parentName.property.name;
2218
- if (
2219
- componentName &&
2220
- typeof componentName[0] === 'string' &&
2221
- componentName[0] !== componentName[0].toUpperCase()
2222
- ) {
1937
+ if (componentName && typeof componentName[0] === 'string' && componentName[0] !== componentName[0].toUpperCase()) {
2223
1938
  return;
2224
1939
  }
2225
1940
  if (allowedFor.includes(tag)) {
@@ -2235,9 +1950,7 @@ var preferSxProp = {
2235
1950
  }
2236
1951
  function checkDOMNodes(node) {
2237
1952
  const tag = node.parent.name.name;
2238
- if (
2239
- !(tag && typeof tag === 'string' && tag[0] !== tag[0].toUpperCase())
2240
- ) {
1953
+ if (!(tag && typeof tag === 'string' && tag[0] !== tag[0].toUpperCase())) {
2241
1954
  return;
2242
1955
  }
2243
1956
  if (allowedFor.includes(tag)) {
@@ -2277,25 +1990,24 @@ function getBasicIdentifier(node) {
2277
1990
  }
2278
1991
  function getBaseIdentifier(node) {
2279
1992
  switch (node.type) {
2280
- case 'Identifier': {
2281
- return node;
2282
- }
2283
- case 'CallExpression': {
2284
- return getBaseIdentifier(node.callee);
2285
- }
2286
- case 'MemberExpression': {
2287
- return getBaseIdentifier(node.object);
2288
- }
1993
+ case 'Identifier':
1994
+ {
1995
+ return node;
1996
+ }
1997
+ case 'CallExpression':
1998
+ {
1999
+ return getBaseIdentifier(node.callee);
2000
+ }
2001
+ case 'MemberExpression':
2002
+ {
2003
+ return getBaseIdentifier(node.object);
2004
+ }
2289
2005
  }
2290
2006
  return null;
2291
2007
  }
2292
2008
  function getStyesObj(node) {
2293
2009
  const isMakeStyles = node.callee.name === 'makeStyles';
2294
- const isModernApi =
2295
- node.callee.type === 'MemberExpression' &&
2296
- node.callee.property.name === 'create' &&
2297
- getBaseIdentifier(node.callee.object) &&
2298
- getBaseIdentifier(node.callee.object).name === 'tss';
2010
+ const isModernApi = node.callee.type === 'MemberExpression' && node.callee.property.name === 'create' && getBaseIdentifier(node.callee.object) && getBaseIdentifier(node.callee.object).name === 'tss';
2299
2011
  if (!isMakeStyles && !isModernApi) {
2300
2012
  return;
2301
2013
  }
@@ -2315,35 +2027,51 @@ function getStyesObj(node) {
2315
2027
  return styles;
2316
2028
  case 'ArrowFunctionExpression':
2317
2029
  {
2318
- const { body } = styles;
2030
+ const {
2031
+ body
2032
+ } = styles;
2319
2033
  switch (body.type) {
2320
2034
  case 'ObjectExpression':
2321
2035
  return body;
2322
- case 'BlockStatement': {
2323
- let stylesObj;
2324
- body.body.forEach(bodyNode => {
2325
- if (
2326
- bodyNode.type === 'ReturnStatement' &&
2327
- bodyNode.argument.type === 'ObjectExpression'
2328
- ) {
2329
- stylesObj = bodyNode.argument;
2330
- }
2331
- });
2332
- return stylesObj;
2333
- }
2036
+ case 'BlockStatement':
2037
+ {
2038
+ let stylesObj;
2039
+ body.body.forEach(bodyNode => {
2040
+ if (bodyNode.type === 'ReturnStatement' && bodyNode.argument.type === 'ObjectExpression') {
2041
+ stylesObj = bodyNode.argument;
2042
+ }
2043
+ });
2044
+ return stylesObj;
2045
+ }
2334
2046
  }
2335
2047
  }
2336
2048
  break;
2337
2049
  }
2338
2050
  }
2051
+ function loopStylesObj(node, callback) {
2052
+ if (node && node.type === 'ObjectExpression') {
2053
+ node.properties.forEach(property => {
2054
+ if (property.type === 'Property' && property.value) {
2055
+ if (property.value.type === 'ObjectExpression') {
2056
+ loopStylesObj(property.value, callback);
2057
+ } else {
2058
+ callback(property.value);
2059
+ }
2060
+ }
2061
+ });
2062
+ }
2063
+ }
2339
2064
 
2340
- var classNaming = {
2065
+ var tssClassNaming = {
2341
2066
  meta: {
2342
2067
  type: 'problem',
2343
2068
  docs: {
2344
2069
  description: 'Enforce camelCase class names in TSS',
2345
2070
  category: 'Best Practices',
2346
2071
  recommended: true
2072
+ },
2073
+ messages: {
2074
+ camelCase: 'Class `{{ className }}` must be camelCase in TSS.'
2347
2075
  }
2348
2076
  },
2349
2077
  create: function rule(context) {
@@ -2357,17 +2085,17 @@ var classNaming = {
2357
2085
  if (property.computed) {
2358
2086
  return;
2359
2087
  }
2360
- if (
2361
- property.type === 'ExperimentalSpreadProperty' ||
2362
- property.type === 'SpreadElement'
2363
- ) {
2088
+ if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {
2364
2089
  return;
2365
2090
  }
2366
2091
  const className = property.key.value || property.key.name;
2367
2092
  if (!eslintUtils.isCamelCase(className)) {
2368
2093
  context.report({
2369
2094
  node: property,
2370
- message: `Class \`${className}\` must be camelCase in TSS.`
2095
+ messageId: 'camelCase',
2096
+ data: {
2097
+ className
2098
+ }
2371
2099
  });
2372
2100
  }
2373
2101
  });
@@ -2376,20 +2104,201 @@ var classNaming = {
2376
2104
  }
2377
2105
  };
2378
2106
 
2379
- var noColorValue = {
2107
+ var colors = {
2108
+ aliceblue: [240, 248, 255],
2109
+ antiquewhite: [250, 235, 215],
2110
+ aqua: [0, 255, 255],
2111
+ aquamarine: [127, 255, 212],
2112
+ azure: [240, 255, 255],
2113
+ beige: [245, 245, 220],
2114
+ bisque: [255, 228, 196],
2115
+ black: [0, 0, 0],
2116
+ blanchedalmond: [255, 235, 205],
2117
+ blue: [0, 0, 255],
2118
+ blueviolet: [138, 43, 226],
2119
+ brown: [165, 42, 42],
2120
+ burlywood: [222, 184, 135],
2121
+ cadetblue: [95, 158, 160],
2122
+ chartreuse: [127, 255, 0],
2123
+ chocolate: [210, 105, 30],
2124
+ coral: [255, 127, 80],
2125
+ cornflowerblue: [100, 149, 237],
2126
+ cornsilk: [255, 248, 220],
2127
+ crimson: [220, 20, 60],
2128
+ cyan: [0, 255, 255],
2129
+ darkblue: [0, 0, 139],
2130
+ darkcyan: [0, 139, 139],
2131
+ darkgoldenrod: [184, 134, 11],
2132
+ darkgray: [169, 169, 169],
2133
+ darkgreen: [0, 100, 0],
2134
+ darkgrey: [169, 169, 169],
2135
+ darkkhaki: [189, 183, 107],
2136
+ darkmagenta: [139, 0, 139],
2137
+ darkolivegreen: [85, 107, 47],
2138
+ darkorange: [255, 140, 0],
2139
+ darkorchid: [153, 50, 204],
2140
+ darkred: [139, 0, 0],
2141
+ darksalmon: [233, 150, 122],
2142
+ darkseagreen: [143, 188, 143],
2143
+ darkslateblue: [72, 61, 139],
2144
+ darkslategray: [47, 79, 79],
2145
+ darkslategrey: [47, 79, 79],
2146
+ darkturquoise: [0, 206, 209],
2147
+ darkviolet: [148, 0, 211],
2148
+ deeppink: [255, 20, 147],
2149
+ deepskyblue: [0, 191, 255],
2150
+ dimgray: [105, 105, 105],
2151
+ dimgrey: [105, 105, 105],
2152
+ dodgerblue: [30, 144, 255],
2153
+ firebrick: [178, 34, 34],
2154
+ floralwhite: [255, 250, 240],
2155
+ forestgreen: [34, 139, 34],
2156
+ fuchsia: [255, 0, 255],
2157
+ gainsboro: [220, 220, 220],
2158
+ ghostwhite: [248, 248, 255],
2159
+ gold: [255, 215, 0],
2160
+ goldenrod: [218, 165, 32],
2161
+ gray: [128, 128, 128],
2162
+ green: [0, 128, 0],
2163
+ greenyellow: [173, 255, 47],
2164
+ grey: [128, 128, 128],
2165
+ honeydew: [240, 255, 240],
2166
+ hotpink: [255, 105, 180],
2167
+ indianred: [205, 92, 92],
2168
+ indigo: [75, 0, 130],
2169
+ ivory: [255, 255, 240],
2170
+ khaki: [240, 230, 140],
2171
+ lavender: [230, 230, 250],
2172
+ lavenderblush: [255, 240, 245],
2173
+ lawngreen: [124, 252, 0],
2174
+ lemonchiffon: [255, 250, 205],
2175
+ lightblue: [173, 216, 230],
2176
+ lightcoral: [240, 128, 128],
2177
+ lightcyan: [224, 255, 255],
2178
+ lightgoldenrodyellow: [250, 250, 210],
2179
+ lightgray: [211, 211, 211],
2180
+ lightgreen: [144, 238, 144],
2181
+ lightgrey: [211, 211, 211],
2182
+ lightpink: [255, 182, 193],
2183
+ lightsalmon: [255, 160, 122],
2184
+ lightseagreen: [32, 178, 170],
2185
+ lightskyblue: [135, 206, 250],
2186
+ lightslategray: [119, 136, 153],
2187
+ lightslategrey: [119, 136, 153],
2188
+ lightsteelblue: [176, 196, 222],
2189
+ lightyellow: [255, 255, 224],
2190
+ lime: [0, 255, 0],
2191
+ limegreen: [50, 205, 50],
2192
+ linen: [250, 240, 230],
2193
+ magenta: [255, 0, 255],
2194
+ maroon: [128, 0, 0],
2195
+ mediumaquamarine: [102, 205, 170],
2196
+ mediumblue: [0, 0, 205],
2197
+ mediumorchid: [186, 85, 211],
2198
+ mediumpurple: [147, 112, 219],
2199
+ mediumseagreen: [60, 179, 113],
2200
+ mediumslateblue: [123, 104, 238],
2201
+ mediumspringgreen: [0, 250, 154],
2202
+ mediumturquoise: [72, 209, 204],
2203
+ mediumvioletred: [199, 21, 133],
2204
+ midnightblue: [25, 25, 112],
2205
+ mintcream: [245, 255, 250],
2206
+ mistyrose: [255, 228, 225],
2207
+ moccasin: [255, 228, 181],
2208
+ navajowhite: [255, 222, 173],
2209
+ navy: [0, 0, 128],
2210
+ oldlace: [253, 245, 230],
2211
+ olive: [128, 128, 0],
2212
+ olivedrab: [107, 142, 35],
2213
+ orange: [255, 165, 0],
2214
+ orangered: [255, 69, 0],
2215
+ orchid: [218, 112, 214],
2216
+ palegoldenrod: [238, 232, 170],
2217
+ palegreen: [152, 251, 152],
2218
+ paleturquoise: [175, 238, 238],
2219
+ palevioletred: [219, 112, 147],
2220
+ papayawhip: [255, 239, 213],
2221
+ peachpuff: [255, 218, 185],
2222
+ peru: [205, 133, 63],
2223
+ pink: [255, 192, 203],
2224
+ plum: [221, 160, 221],
2225
+ powderblue: [176, 224, 230],
2226
+ purple: [128, 0, 128],
2227
+ rebeccapurple: [102, 51, 153],
2228
+ red: [255, 0, 0],
2229
+ rosybrown: [188, 143, 143],
2230
+ royalblue: [65, 105, 225],
2231
+ saddlebrown: [139, 69, 19],
2232
+ salmon: [250, 128, 114],
2233
+ sandybrown: [244, 164, 96],
2234
+ seagreen: [46, 139, 87],
2235
+ seashell: [255, 245, 238],
2236
+ sienna: [160, 82, 45],
2237
+ silver: [192, 192, 192],
2238
+ skyblue: [135, 206, 235],
2239
+ slateblue: [106, 90, 205],
2240
+ slategray: [112, 128, 144],
2241
+ slategrey: [112, 128, 144],
2242
+ snow: [255, 250, 250],
2243
+ springgreen: [0, 255, 127],
2244
+ steelblue: [70, 130, 180],
2245
+ tan: [210, 180, 140],
2246
+ teal: [0, 128, 128],
2247
+ thistle: [216, 191, 216],
2248
+ tomato: [255, 99, 71],
2249
+ turquoise: [64, 224, 208],
2250
+ violet: [238, 130, 238],
2251
+ wheat: [245, 222, 179],
2252
+ white: [255, 255, 255],
2253
+ whitesmoke: [245, 245, 245],
2254
+ yellow: [255, 255, 0],
2255
+ yellowgreen: [154, 205, 50]
2256
+ };
2257
+
2258
+ var tssNoColorName = {
2380
2259
  meta: {
2381
- type: 'problem',
2260
+ type: 'suggestion',
2382
2261
  docs: {
2383
- description:
2384
- 'Enforce the use of color variables instead of color codes within TSS',
2262
+ description: 'Enforce the use of color variables instead of color name within TSS',
2385
2263
  recommended: true
2264
+ },
2265
+ messages: {
2266
+ disallowColorName: 'Disallowed color name. Use color from `@mui/material/colors` or `theme.palette`.'
2386
2267
  }
2387
2268
  },
2388
2269
  create: function (context) {
2389
- const parserOptions = context.parserOptions;
2390
- if (!parserOptions || !parserOptions.project) {
2391
- return {};
2270
+ return {
2271
+ CallExpression(node) {
2272
+ const stylesObj = getStyesObj(node);
2273
+ if (!stylesObj) {
2274
+ return;
2275
+ }
2276
+ function checkColorLiteral(value) {
2277
+ if (value.type === 'Literal' && typeof value.value === 'string' && Object.keys(colors).includes(value.value.toLowerCase())) {
2278
+ context.report({
2279
+ node: value,
2280
+ messageId: 'disallowColorName'
2281
+ });
2282
+ }
2283
+ }
2284
+ loopStylesObj(stylesObj, checkColorLiteral);
2285
+ }
2286
+ };
2287
+ }
2288
+ };
2289
+
2290
+ var tssNoColorValue = {
2291
+ meta: {
2292
+ type: 'problem',
2293
+ docs: {
2294
+ description: 'Enforce the use of color variables instead of color codes within TSS',
2295
+ recommended: true
2296
+ },
2297
+ messages: {
2298
+ preferMuiColor: 'Prefer use color from `@mui/material/colors` or `theme.palette`.'
2392
2299
  }
2300
+ },
2301
+ create: function (context) {
2393
2302
  return {
2394
2303
  CallExpression(node) {
2395
2304
  const stylesObj = getStyesObj(node);
@@ -2398,43 +2307,31 @@ var noColorValue = {
2398
2307
  }
2399
2308
  function checkColorLiteral(value) {
2400
2309
  if (value.type === 'Literal' && typeof value.value === 'string') {
2401
- const colorCodePattern =
2402
- /#(?:[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;
2403
- const isColorCode = colorCodePattern.test(value.value);
2404
- if (isColorCode) {
2310
+ 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;
2311
+ if (colorCodePattern.test(value.value)) {
2405
2312
  context.report({
2406
2313
  node: value,
2407
- message: 'Use color variables instead of color codes in TSS.'
2314
+ messageId: 'preferMuiColor'
2408
2315
  });
2409
2316
  }
2410
2317
  }
2411
2318
  }
2412
- function loopStylesObj(obj) {
2413
- if (obj && obj.type === 'ObjectExpression') {
2414
- obj.properties.forEach(property => {
2415
- if (property.type === 'Property' && property.value) {
2416
- if (property.value.type === 'ObjectExpression') {
2417
- loopStylesObj(property.value);
2418
- } else {
2419
- checkColorLiteral(property.value);
2420
- }
2421
- }
2422
- });
2423
- }
2424
- }
2425
- loopStylesObj(stylesObj);
2319
+ loopStylesObj(stylesObj, checkColorLiteral);
2426
2320
  }
2427
2321
  };
2428
2322
  }
2429
2323
  };
2430
2324
 
2431
- var unusedClasses = {
2325
+ var tssUnusedClasses = {
2432
2326
  meta: {
2433
2327
  type: 'suggestion',
2434
2328
  docs: {
2435
2329
  description: 'Disallow unused classes in tss',
2436
2330
  category: 'Best Practices',
2437
2331
  recommended: true
2332
+ },
2333
+ messages: {
2334
+ unusedClass: 'Class `{{ className }}` is unused in JSX'
2438
2335
  }
2439
2336
  },
2440
2337
  create: function rule(context) {
@@ -2450,20 +2347,14 @@ var unusedClasses = {
2450
2347
  if (property.computed) {
2451
2348
  return;
2452
2349
  }
2453
- if (
2454
- property.type === 'ExperimentalSpreadProperty' ||
2455
- property.type === 'SpreadElement'
2456
- ) {
2350
+ if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {
2457
2351
  return;
2458
2352
  }
2459
2353
  definedClasses[property.key.value || property.key.name] = property;
2460
2354
  });
2461
2355
  },
2462
2356
  MemberExpression(node) {
2463
- if (
2464
- node.object.type === 'Identifier' &&
2465
- node.object.name === 'classes'
2466
- ) {
2357
+ if (node.object.type === 'Identifier' && node.object.name === 'classes') {
2467
2358
  const whichClass = getBasicIdentifier(node.property);
2468
2359
  if (whichClass) {
2469
2360
  usedClasses[whichClass] = true;
@@ -2477,14 +2368,15 @@ var unusedClasses = {
2477
2368
  if (classIdentifier !== 'classes') {
2478
2369
  return;
2479
2370
  }
2480
- const { parent } = node;
2371
+ const {
2372
+ parent
2373
+ } = node;
2481
2374
  if (parent.type !== 'MemberExpression') {
2482
2375
  return;
2483
2376
  }
2484
2377
  if (
2485
- node.object.object &&
2486
- node.object.object.type !== 'ThisExpression'
2487
- ) {
2378
+ node.object.object &&
2379
+ node.object.object.type !== 'ThisExpression') {
2488
2380
  return;
2489
2381
  }
2490
2382
  const propsIdentifier = getBasicIdentifier(parent.object);
@@ -2507,7 +2399,10 @@ var unusedClasses = {
2507
2399
  if (!usedClasses[definedClassKey]) {
2508
2400
  context.report({
2509
2401
  node: definedClasses[definedClassKey],
2510
- message: `Class \`${definedClassKey}\` is unused`
2402
+ messageId: 'unusedClass',
2403
+ data: {
2404
+ className: definedClassKey
2405
+ }
2511
2406
  });
2512
2407
  }
2513
2408
  });
@@ -2516,177 +2411,26 @@ var unusedClasses = {
2516
2411
  }
2517
2412
  };
2518
2413
 
2519
- var noAsyncArrayMethods = {
2520
- meta: {
2521
- docs: {
2522
- description:
2523
- 'No async callback for Array methods forEach, map, filter, reduce, some, every, etc.',
2524
- category: 'Array',
2525
- recommended: true
2526
- },
2527
- fixable: undefined,
2528
- schema: []
2529
- },
2530
- create: function (context) {
2531
- return {
2532
- ExpressionStatement: function (node) {
2533
- const notAllowedArrayMethods = [
2534
- 'forEach',
2535
- 'filter',
2536
- 'some',
2537
- 'every',
2538
- 'map',
2539
- 'reduce',
2540
- 'reduceRight',
2541
- 'flatMap',
2542
- 'find',
2543
- 'findIndex',
2544
- 'findLast',
2545
- 'findLastIndex'
2546
- ];
2547
- const { callee } = node.expression;
2548
- if (!callee || !callee.property || !callee.property.name) {
2549
- return;
2550
- }
2551
- if (notAllowedArrayMethods.includes(callee.property.name)) {
2552
- const functionArguments = node.expression.arguments.find(n => {
2553
- return ['ArrowFunctionExpression', 'FunctionExpression'].includes(
2554
- n.type
2555
- );
2556
- });
2557
- if (functionArguments && functionArguments.async) {
2558
- context.report({
2559
- node,
2560
- message: `No async function in method '${callee.property.name}'`
2561
- });
2562
- }
2563
- }
2564
- }
2565
- };
2566
- }
2567
- };
2568
-
2569
- var noThenCatchFinally = {
2570
- meta: {
2571
- type: 'suggestion',
2572
- docs: {
2573
- description:
2574
- 'Disallow the use of then()/catch()/finally() when invoking specific functions.'
2575
- },
2576
- schema: [
2577
- {
2578
- type: 'object',
2579
- properties: {
2580
- restrictedFunctions: {
2581
- type: 'array',
2582
- uniqueItems: true,
2583
- items: { type: 'string' }
2584
- }
2585
- }
2586
- }
2587
- ],
2588
- messages: {
2589
- forbiddenThenCatchFinally: `then()/catch()/finally() is forbidden when invoke {{ name }}().`
2590
- }
2591
- },
2592
- create(context) {
2593
- const configuration = context.options[0] || {};
2594
- const restrictedFunctions = configuration.restrictedFunctions || [];
2595
- function isTopLevelScoped() {
2596
- return context.getScope().block.type === 'Program';
2597
- }
2598
- function isThenCatchFinally(node) {
2599
- return (
2600
- node.property &&
2601
- (node.property.name === 'then' ||
2602
- node.property.name === 'catch' ||
2603
- node.property.name === 'finally')
2604
- );
2605
- }
2606
- return {
2607
- 'CallExpression > MemberExpression.callee'(node) {
2608
- if (isTopLevelScoped()) {
2609
- return;
2610
- }
2611
- if (!isThenCatchFinally(node)) {
2612
- return;
2613
- }
2614
- const callExpression = node.object;
2615
- if (
2616
- callExpression.type === 'CallExpression' &&
2617
- callExpression.callee.type === 'Identifier' &&
2618
- restrictedFunctions.includes(callExpression.callee.name)
2619
- ) {
2620
- context.report({
2621
- node: node.property,
2622
- messageId: 'forbiddenThenCatchFinally',
2623
- data: {
2624
- name: callExpression.callee.name
2625
- }
2626
- });
2627
- }
2628
- }
2629
- };
2630
- }
2631
- };
2632
-
2633
- var noUnnecessaryTemplateLiterals = {
2634
- meta: {
2635
- type: 'problem',
2636
- docs: {
2637
- description: 'Check if a template string contains only one ${}',
2638
- recommended: true
2639
- },
2640
- fixable: 'code',
2641
- schema: [],
2642
- messages: {
2643
- unnecessaryTemplateString:
2644
- 'Unnecessary template string with only one ${}.'
2645
- }
2646
- },
2647
- create(context) {
2648
- return {
2649
- TemplateLiteral(node) {
2650
- const code = context.sourceCode.getText(node);
2651
- if (
2652
- code.startsWith('`${') &&
2653
- code.endsWith('}`') &&
2654
- code.split('${').length === 2
2655
- ) {
2656
- context.report({
2657
- node,
2658
- messageId: 'unnecessaryTemplateString',
2659
- fix(fixer) {
2660
- return fixer.replaceText(
2661
- node,
2662
- code.substring(3, code.length - 2)
2663
- );
2664
- }
2665
- });
2666
- }
2667
- }
2668
- };
2669
- }
2670
- };
2671
-
2672
2414
  var ruleFiles = /*#__PURE__*/Object.freeze({
2673
2415
  __proto__: null,
2674
- rules_import_enforce_icon_alias: enforceIconAlias,
2675
- rules_import_monorepo: monorepo,
2676
- rules_intl_id_missing: idMissing,
2677
- rules_intl_id_prefix: idPrefix,
2678
- rules_intl_id_unused: idUnused,
2679
- rules_intl_no_default: noDefault,
2680
- rules_react_better_exhaustive_deps: betterExhaustiveDeps,
2681
- rules_react_hook_use_ref: hookUseRef,
2682
- rules_react_prefer_named_property_access: preferNamedPropertyAccess,
2683
- rules_react_prefer_sx_prop: preferSxProp,
2684
- rules_tss_class_naming: classNaming,
2685
- rules_tss_no_color_value: noColorValue,
2686
- rules_tss_unused_classes: unusedClasses,
2687
- rules_unprefixed_no_async_array_methods: noAsyncArrayMethods,
2688
- rules_unprefixed_no_then_catch_finally: noThenCatchFinally,
2689
- rules_unprefixed_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals
2416
+ rules_enforce_mui_icon_alias: enforceMuiIconAlias,
2417
+ rules_import_monorepo: importMonorepo,
2418
+ rules_intl_id_missing: intlIdMissing,
2419
+ rules_intl_id_prefix: intlIdPrefix,
2420
+ rules_intl_id_unused: intlIdUnused,
2421
+ rules_intl_no_default: intlNoDefault,
2422
+ rules_no_async_array_methods: noAsyncArrayMethods,
2423
+ rules_no_import_css: noImportCss,
2424
+ rules_no_then_catch_finally: noThenCatchFinally,
2425
+ rules_no_unnecessary_template_literals: noUnnecessaryTemplateLiterals,
2426
+ rules_react_better_exhaustive_deps: reactBetterExhaustiveDeps,
2427
+ rules_react_hook_use_ref: reactHookUseRef,
2428
+ rules_react_prefer_named_property_access: reactPreferNamedPropertyAccess,
2429
+ rules_react_prefer_sx_prop: reactPreferSxProp,
2430
+ rules_tss_class_naming: tssClassNaming,
2431
+ rules_tss_no_color_name: tssNoColorName,
2432
+ rules_tss_no_color_value: tssNoColorValue,
2433
+ rules_tss_unused_classes: tssUnusedClasses
2690
2434
  });
2691
2435
 
2692
2436
  const plugin = {
@@ -2704,13 +2448,12 @@ const plugin = {
2704
2448
  }
2705
2449
  };
2706
2450
  Object.keys(ruleFiles).forEach(key => {
2707
- const ruleKey = key.replace(/^rules_/, '').replace(/^unprefixed_/, '');
2451
+ const ruleKey = key.replace(/^rules_/, '');
2708
2452
  const finalKey = ruleKey.replace(/_/g, '-');
2709
2453
  const rule = ruleFiles[key];
2710
2454
  plugin.rules[finalKey] = rule;
2711
2455
  if (rule.meta && rule.meta.docs && rule.meta.docs.recommended) {
2712
- plugin.configs.recommended.rules[`@agilebot/${finalKey}`] =
2713
- rule.meta.type === 'suggestion' ? 'warn' : 'error';
2456
+ plugin.configs.recommended.rules["@agilebot/".concat(finalKey)] = rule.meta.type === 'suggestion' ? 'warn' : 'error';
2714
2457
  }
2715
2458
  });
2716
2459