@blumintinc/eslint-plugin-blumint 1.10.0 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +99 -84
  2. package/lib/index.js +10 -1
  3. package/lib/rules/class-methods-read-top-to-bottom.js +10 -0
  4. package/lib/rules/consistent-callback-naming.js +20 -16
  5. package/lib/rules/enforce-assert-throws.js +10 -5
  6. package/lib/rules/enforce-boolean-naming-prefixes.d.ts +7 -0
  7. package/lib/rules/enforce-boolean-naming-prefixes.js +462 -0
  8. package/lib/rules/enforce-callable-types.d.ts +1 -1
  9. package/lib/rules/enforce-callable-types.js +13 -13
  10. package/lib/rules/enforce-callback-memo.js +6 -3
  11. package/lib/rules/enforce-centralized-mock-firestore.js +8 -6
  12. package/lib/rules/enforce-css-media-queries.js +3 -3
  13. package/lib/rules/enforce-dynamic-file-naming.js +9 -7
  14. package/lib/rules/enforce-dynamic-imports.js +1 -1
  15. package/lib/rules/enforce-firestore-doc-ref-generic.js +16 -12
  16. package/lib/rules/enforce-firestore-facade.js +7 -3
  17. package/lib/rules/enforce-firestore-path-utils.js +5 -2
  18. package/lib/rules/enforce-global-constants.d.ts +1 -0
  19. package/lib/rules/enforce-global-constants.js +77 -0
  20. package/lib/rules/enforce-id-capitalization.js +23 -5
  21. package/lib/rules/enforce-identifiable-firestore-type.js +17 -10
  22. package/lib/rules/enforce-memoize-async.js +2 -2
  23. package/lib/rules/enforce-positive-naming.js +71 -27
  24. package/lib/rules/enforce-props-argument-name.js +31 -9
  25. package/lib/rules/enforce-realtimedb-path-utils.js +2 -1
  26. package/lib/rules/enforce-singular-type-names.js +4 -1
  27. package/lib/rules/enforce-timestamp-now.js +3 -4
  28. package/lib/rules/enforce-verb-noun-naming.js +18 -8
  29. package/lib/rules/ensure-pointer-events-none.js +20 -11
  30. package/lib/rules/extract-global-constants.js +25 -10
  31. package/lib/rules/fast-deep-equal-over-microdiff.d.ts +3 -0
  32. package/lib/rules/fast-deep-equal-over-microdiff.js +182 -0
  33. package/lib/rules/key-only-outermost-element.js +13 -7
  34. package/lib/rules/no-always-true-false-conditions.js +52 -18
  35. package/lib/rules/no-async-array-filter.js +1 -1
  36. package/lib/rules/no-circular-references.js +121 -59
  37. package/lib/rules/no-entire-object-hook-deps.js +113 -29
  38. package/lib/rules/no-explicit-return-type.js +3 -2
  39. package/lib/rules/no-firestore-jest-mock.js +1 -1
  40. package/lib/rules/no-firestore-object-arrays.js +2 -1
  41. package/lib/rules/no-hungarian.js +3 -3
  42. package/lib/rules/no-jsx-in-hooks.js +4 -3
  43. package/lib/rules/no-margin-properties.js +25 -18
  44. package/lib/rules/no-mixed-firestore-transactions.js +8 -4
  45. package/lib/rules/no-mock-firebase-admin.js +6 -1
  46. package/lib/rules/no-object-values-on-strings.js +28 -10
  47. package/lib/rules/no-type-assertion-returns.js +13 -1
  48. package/lib/rules/no-unnecessary-destructuring.js +1 -1
  49. package/lib/rules/no-unnecessary-verb-suffix.js +0 -31
  50. package/lib/rules/no-unused-props.js +10 -7
  51. package/lib/rules/no-unused-usestate.js +19 -6
  52. package/lib/rules/omit-index-html.js +1 -1
  53. package/lib/rules/prefer-batch-operations.js +19 -6
  54. package/lib/rules/prefer-clone-deep.js +16 -11
  55. package/lib/rules/prefer-destructuring-no-class.js +19 -0
  56. package/lib/rules/prefer-fragment-component.js +19 -16
  57. package/lib/rules/prefer-global-router-state-key.js +6 -4
  58. package/lib/rules/prefer-settings-object.js +1 -1
  59. package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +12 -4
  60. package/lib/rules/react-usememo-should-be-component.js +64 -18
  61. package/lib/rules/require-hooks-default-params.js +25 -15
  62. package/lib/rules/require-usememo-object-literals.js +3 -2
  63. package/lib/rules/semantic-function-prefixes.js +15 -3
  64. package/lib/rules/sync-onwrite-name-func.js +5 -3
  65. package/lib/utils/ASTHelpers.js +6 -2
  66. package/lib/utils/graph/ClassGraphBuilder.js +4 -1
  67. package/lib/utils/graph/ClassGraphSorterReadability.js +3 -1
  68. package/package.json +3 -3
  69. package/lib/rules/require-image-overlayed.d.ts +0 -7
  70. package/lib/rules/require-image-overlayed.js +0 -82
@@ -5,20 +5,22 @@ const utils_1 = require("@typescript-eslint/utils");
5
5
  const createRule_1 = require("../utils/createRule");
6
6
  // Common negative prefixes for boolean variables
7
7
  const BOOLEAN_NEGATIVE_PREFIXES = ['not', 'no', 'non', 'un', 'in', 'dis'];
8
+ // Words that contain negative prefixes but should be treated as valid
9
+ const EXCEPTION_WORDS = ['interaction', 'interactions'];
8
10
  // Map of negative boolean terms to suggested positive alternatives
9
11
  const BOOLEAN_POSITIVE_ALTERNATIVES = {
10
12
  // Boolean prefixes
11
- 'isNot': ['is'],
12
- 'isUn': ['is'],
13
- 'isDis': ['is'],
14
- 'isIn': ['is'],
15
- 'isNon': ['is'],
16
- 'hasNo': ['has'],
17
- 'hasNot': ['has'],
18
- 'canNot': ['can'],
19
- 'shouldNot': ['should'],
20
- 'willNot': ['will'],
21
- 'doesNot': ['does'],
13
+ isNot: ['is'],
14
+ isUn: ['is'],
15
+ isDis: ['is'],
16
+ isIn: ['is'],
17
+ isNon: ['is'],
18
+ hasNo: ['has'],
19
+ hasNot: ['has'],
20
+ canNot: ['can'],
21
+ shouldNot: ['should'],
22
+ willNot: ['will'],
23
+ doesNot: ['does'],
22
24
  };
23
25
  exports.enforcePositiveNaming = (0, createRule_1.createRule)({
24
26
  name: 'enforce-positive-naming',
@@ -56,20 +58,52 @@ exports.enforcePositiveNaming = (0, createRule_1.createRule)({
56
58
  function hasBooleanNegativeNaming(name) {
57
59
  // Check for exact matches in our alternatives map first
58
60
  if (BOOLEAN_POSITIVE_ALTERNATIVES[name]) {
59
- return { isNegative: true, alternatives: BOOLEAN_POSITIVE_ALTERNATIVES[name] };
61
+ return {
62
+ isNegative: true,
63
+ alternatives: BOOLEAN_POSITIVE_ALTERNATIVES[name],
64
+ };
60
65
  }
61
66
  // Check for negative prefixes in boolean-like variables
62
- if (name.startsWith('is') || name.startsWith('has') || name.startsWith('can') ||
63
- name.startsWith('should') || name.startsWith('will') || name.startsWith('does')) {
67
+ if (name.startsWith('is') ||
68
+ name.startsWith('has') ||
69
+ name.startsWith('can') ||
70
+ name.startsWith('should') ||
71
+ name.startsWith('will') ||
72
+ name.startsWith('does')) {
73
+ // Check if the name contains any exception words
74
+ for (const exceptionWord of EXCEPTION_WORDS) {
75
+ const lowerCaseName = name.toLowerCase();
76
+ if (lowerCaseName.includes(exceptionWord.toLowerCase())) {
77
+ return { isNegative: false, alternatives: [] };
78
+ }
79
+ }
64
80
  for (const prefix of BOOLEAN_NEGATIVE_PREFIXES) {
65
81
  // Check for patterns like isNot, hasNo, canNot, etc.
66
82
  const prefixPatterns = [
67
- { pattern: new RegExp(`^is${prefix}`, 'i'), key: `is${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
68
- { pattern: new RegExp(`^has${prefix}`, 'i'), key: `has${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
69
- { pattern: new RegExp(`^can${prefix}`, 'i'), key: `can${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
70
- { pattern: new RegExp(`^should${prefix}`, 'i'), key: `should${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
71
- { pattern: new RegExp(`^will${prefix}`, 'i'), key: `will${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
72
- { pattern: new RegExp(`^does${prefix}`, 'i'), key: `does${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
83
+ {
84
+ pattern: new RegExp(`^is${prefix}`, 'i'),
85
+ key: `is${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
86
+ },
87
+ {
88
+ pattern: new RegExp(`^has${prefix}`, 'i'),
89
+ key: `has${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
90
+ },
91
+ {
92
+ pattern: new RegExp(`^can${prefix}`, 'i'),
93
+ key: `can${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
94
+ },
95
+ {
96
+ pattern: new RegExp(`^should${prefix}`, 'i'),
97
+ key: `should${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
98
+ },
99
+ {
100
+ pattern: new RegExp(`^will${prefix}`, 'i'),
101
+ key: `will${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
102
+ },
103
+ {
104
+ pattern: new RegExp(`^does${prefix}`, 'i'),
105
+ key: `does${prefix.charAt(0).toUpperCase() + prefix.slice(1)}`,
106
+ },
73
107
  ];
74
108
  for (const { pattern, key } of prefixPatterns) {
75
109
  if (pattern.test(name)) {
@@ -82,10 +116,16 @@ exports.enforcePositiveNaming = (0, createRule_1.createRule)({
82
116
  if (alternatives.length > 0) {
83
117
  // Suggest the positive version with the rest of the name
84
118
  const restOfName = name.replace(pattern, '');
85
- const suggestedAlternatives = alternatives.map(alt => `${alt}${restOfName.charAt(0).toUpperCase() + restOfName.slice(1)}`);
86
- return { isNegative: true, alternatives: suggestedAlternatives };
119
+ const suggestedAlternatives = alternatives.map((alt) => `${alt}${restOfName.charAt(0).toUpperCase() + restOfName.slice(1)}`);
120
+ return {
121
+ isNegative: true,
122
+ alternatives: suggestedAlternatives,
123
+ };
87
124
  }
88
- return { isNegative: true, alternatives: ['a positive alternative'] };
125
+ return {
126
+ isNegative: true,
127
+ alternatives: ['a positive alternative'],
128
+ };
89
129
  }
90
130
  }
91
131
  }
@@ -118,9 +158,12 @@ exports.enforcePositiveNaming = (0, createRule_1.createRule)({
118
158
  }
119
159
  // Check if the node has a name that suggests it's a boolean
120
160
  if (node.type === utils_1.AST_NODE_TYPES.Identifier &&
121
- (node.name.startsWith('is') || node.name.startsWith('has') ||
122
- node.name.startsWith('can') || node.name.startsWith('should') ||
123
- node.name.startsWith('will') || node.name.startsWith('does'))) {
161
+ (node.name.startsWith('is') ||
162
+ node.name.startsWith('has') ||
163
+ node.name.startsWith('can') ||
164
+ node.name.startsWith('should') ||
165
+ node.name.startsWith('will') ||
166
+ node.name.startsWith('does'))) {
124
167
  return true;
125
168
  }
126
169
  return false;
@@ -238,7 +281,8 @@ exports.enforcePositiveNaming = (0, createRule_1.createRule)({
238
281
  return;
239
282
  // Only check boolean properties
240
283
  if (!isBooleanLike(node.key) &&
241
- !(node.typeAnnotation?.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSBooleanKeyword))
284
+ !(node.typeAnnotation?.typeAnnotation.type ===
285
+ utils_1.AST_NODE_TYPES.TSBooleanKeyword))
242
286
  return;
243
287
  const propertyName = node.key.name;
244
288
  const { isNegative, alternatives } = hasBooleanNegativeNaming(propertyName);
@@ -72,7 +72,15 @@ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
72
72
  if (typeName.endsWith('Props')) {
73
73
  return null;
74
74
  }
75
- const suffixes = ['Config', 'Settings', 'Options', 'Params', 'Parameters', 'Args', 'Arguments'];
75
+ const suffixes = [
76
+ 'Config',
77
+ 'Settings',
78
+ 'Options',
79
+ 'Params',
80
+ 'Parameters',
81
+ 'Args',
82
+ 'Arguments',
83
+ ];
76
84
  for (const suffix of suffixes) {
77
85
  if (typeName.endsWith(suffix)) {
78
86
  return suffix;
@@ -96,13 +104,20 @@ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
96
104
  }
97
105
  const param = node.params[0];
98
106
  // Skip primitive parameters
99
- if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && (param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSStringKeyword ||
100
- param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSNumberKeyword ||
101
- param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSBooleanKeyword)) {
107
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
108
+ param.typeAnnotation &&
109
+ (param.typeAnnotation.typeAnnotation.type ===
110
+ utils_1.AST_NODE_TYPES.TSStringKeyword ||
111
+ param.typeAnnotation.typeAnnotation.type ===
112
+ utils_1.AST_NODE_TYPES.TSNumberKeyword ||
113
+ param.typeAnnotation.typeAnnotation.type ===
114
+ utils_1.AST_NODE_TYPES.TSBooleanKeyword)) {
102
115
  return;
103
116
  }
104
117
  // Check if the parameter has a type annotation
105
- if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && param.typeAnnotation.typeAnnotation) {
118
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
119
+ param.typeAnnotation &&
120
+ param.typeAnnotation.typeAnnotation) {
106
121
  const typeName = getTypeName(param.typeAnnotation.typeAnnotation);
107
122
  if (typeName) {
108
123
  const nonPropsSuffix = hasNonPropsSuffix(typeName);
@@ -128,13 +143,20 @@ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
128
143
  }
129
144
  const param = constructor.params[0];
130
145
  // Skip primitive parameters
131
- if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && (param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSStringKeyword ||
132
- param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSNumberKeyword ||
133
- param.typeAnnotation.typeAnnotation.type === utils_1.AST_NODE_TYPES.TSBooleanKeyword)) {
146
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
147
+ param.typeAnnotation &&
148
+ (param.typeAnnotation.typeAnnotation.type ===
149
+ utils_1.AST_NODE_TYPES.TSStringKeyword ||
150
+ param.typeAnnotation.typeAnnotation.type ===
151
+ utils_1.AST_NODE_TYPES.TSNumberKeyword ||
152
+ param.typeAnnotation.typeAnnotation.type ===
153
+ utils_1.AST_NODE_TYPES.TSBooleanKeyword)) {
134
154
  return;
135
155
  }
136
156
  // Check if the parameter has a type annotation
137
- if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && param.typeAnnotation.typeAnnotation) {
157
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
158
+ param.typeAnnotation &&
159
+ param.typeAnnotation.typeAnnotation) {
138
160
  const typeName = getTypeName(param.typeAnnotation.typeAnnotation);
139
161
  if (typeName) {
140
162
  const nonPropsSuffix = hasNonPropsSuffix(typeName);
@@ -55,7 +55,8 @@ exports.enforceRealtimedbPathUtils = (0, createRule_1.createRule)({
55
55
  return false;
56
56
  }
57
57
  function isStringLiteralOrTemplate(node) {
58
- return ((node.type === utils_1.AST_NODE_TYPES.Literal && typeof node.value === 'string') ||
58
+ return ((node.type === utils_1.AST_NODE_TYPES.Literal &&
59
+ typeof node.value === 'string') ||
59
60
  node.type === utils_1.AST_NODE_TYPES.TemplateLiteral);
60
61
  }
61
62
  function isUtilityFunction(node) {
@@ -38,7 +38,10 @@ exports.enforceSingularTypeNames = (0, createRule_1.createRule)({
38
38
  if (name.length < 3)
39
39
  return false;
40
40
  // Skip checking if name ends with 'Props' or 'Params'
41
- if (name.endsWith('Props') || name.endsWith('Params') || name.endsWith('Options') || name.endsWith('Settings'))
41
+ if (name.endsWith('Props') ||
42
+ name.endsWith('Params') ||
43
+ name.endsWith('Options') ||
44
+ name.endsWith('Settings'))
42
45
  return false;
43
46
  // Skip checking if name is already singular according to pluralize
44
47
  if (pluralize.isSingular(name))
@@ -51,8 +51,7 @@ exports.enforceTimestampNow = (0, createRule_1.createRule)({
51
51
  return true;
52
52
  }
53
53
  // Check if the argument is a variable reference to a Date object
54
- if (arg &&
55
- arg.type === utils_1.AST_NODE_TYPES.Identifier) {
54
+ if (arg && arg.type === utils_1.AST_NODE_TYPES.Identifier) {
56
55
  // If it's a variable, we need to check if it's a Date that's being modified
57
56
  // If it's modified, we shouldn't flag it
58
57
  return false;
@@ -95,11 +94,11 @@ exports.enforceTimestampNow = (0, createRule_1.createRule)({
95
94
  function isDateBeingModified(dateVar) {
96
95
  // Look through the scope to find if this variable is modified
97
96
  const scope = context.getScope();
98
- const variable = scope.variables.find(v => v.name === dateVar);
97
+ const variable = scope.variables.find((v) => v.name === dateVar);
99
98
  if (!variable)
100
99
  return false;
101
100
  // Check if any references to this variable are followed by property access and modification
102
- return variable.references.some(ref => {
101
+ return variable.references.some((ref) => {
103
102
  const id = ref.identifier;
104
103
  const parent = id.parent;
105
104
  // Check for patterns like dateVar.setDate(), dateVar.setHours(), etc.
@@ -4608,7 +4608,9 @@ exports.enforceVerbNounNaming = (0, createRule_1.createRule)({
4608
4608
  return true;
4609
4609
  }
4610
4610
  // Check for JSX assigned to variables then returned
4611
- if (text.includes('const ') && text.includes('<') && text.includes('return')) {
4611
+ if (text.includes('const ') &&
4612
+ text.includes('<') &&
4613
+ text.includes('return')) {
4612
4614
  return true;
4613
4615
  }
4614
4616
  return false;
@@ -4624,9 +4626,11 @@ exports.enforceVerbNounNaming = (0, createRule_1.createRule)({
4624
4626
  if (node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration && node.id) {
4625
4627
  functionName = node.id.name;
4626
4628
  }
4627
- else if (node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression || node.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
4629
+ else if (node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
4630
+ node.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
4628
4631
  const parent = node.parent;
4629
- if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator && parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
4632
+ if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
4633
+ parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
4630
4634
  functionName = parent.id.name;
4631
4635
  }
4632
4636
  }
@@ -4644,20 +4648,26 @@ exports.enforceVerbNounNaming = (0, createRule_1.createRule)({
4644
4648
  const parent = node.parent;
4645
4649
  if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
4646
4650
  const id = parent.id;
4647
- if (id.type === utils_1.AST_NODE_TYPES.Identifier && id.typeAnnotation?.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation) {
4648
- const typeText = context.getSourceCode().getText(id.typeAnnotation.typeAnnotation);
4649
- return typeText.includes('React.') || typeText.includes('FC') || typeText.includes('FunctionComponent');
4651
+ if (id.type === utils_1.AST_NODE_TYPES.Identifier &&
4652
+ id.typeAnnotation?.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation) {
4653
+ const typeText = context
4654
+ .getSourceCode()
4655
+ .getText(id.typeAnnotation.typeAnnotation);
4656
+ return (typeText.includes('React.') ||
4657
+ typeText.includes('FC') ||
4658
+ typeText.includes('FunctionComponent'));
4650
4659
  }
4651
4660
  }
4652
4661
  }
4653
4662
  return false;
4654
4663
  })(),
4655
4664
  // 5. Component name ends with "Unmemoized" (common React pattern)
4656
- functionName && functionName.endsWith('Unmemoized')
4665
+ functionName && functionName.endsWith('Unmemoized'),
4657
4666
  ];
4658
4667
  // Consider it a React component if it matches at least 2 indicators
4659
4668
  // OR if it has the Unmemoized suffix (strong indicator of a React component)
4660
- return indicators.filter(Boolean).length >= 2 || (!!functionName && functionName.endsWith('Unmemoized'));
4669
+ return (indicators.filter(Boolean).length >= 2 ||
4670
+ (!!functionName && functionName.endsWith('Unmemoized')));
4661
4671
  }
4662
4672
  return {
4663
4673
  FunctionDeclaration(node) {
@@ -59,7 +59,8 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
59
59
  if (property.key.type === utils_1.AST_NODE_TYPES.Identifier) {
60
60
  propertyName = property.key.name;
61
61
  }
62
- else if (property.key.type === utils_1.AST_NODE_TYPES.Literal && typeof property.key.value === 'string') {
62
+ else if (property.key.type === utils_1.AST_NODE_TYPES.Literal &&
63
+ typeof property.key.value === 'string') {
63
64
  propertyName = property.key.value;
64
65
  }
65
66
  // Get property value if it's a string literal
@@ -97,7 +98,9 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
97
98
  const isAbsolutePositioned = absolutePositionedStyles.get(node) || false;
98
99
  const pointerEventsValue = stylesWithPointerEvents.get(node);
99
100
  // If this is a pseudo-element with absolute positioning but no pointer-events
100
- if (isPseudoElement && isAbsolutePositioned && pointerEventsValue === undefined) {
101
+ if (isPseudoElement &&
102
+ isAbsolutePositioned &&
103
+ pointerEventsValue === undefined) {
101
104
  context.report({
102
105
  node,
103
106
  messageId: 'missingPointerEventsNone',
@@ -113,11 +116,13 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
113
116
  return fixer.insertTextAfter(lastPropertyToken, `, pointerEvents: 'none'`);
114
117
  }
115
118
  return null;
116
- }
119
+ },
117
120
  });
118
121
  }
119
122
  // If this is a pseudo-element with absolute positioning and pointer-events: auto
120
- if (isPseudoElement && isAbsolutePositioned && pointerEventsValue === 'auto') {
123
+ if (isPseudoElement &&
124
+ isAbsolutePositioned &&
125
+ pointerEventsValue === 'auto') {
121
126
  // Don't report an error if pointer-events is explicitly set to 'auto'
122
127
  // This is an intentional choice by the developer
123
128
  }
@@ -139,15 +144,17 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
139
144
  }
140
145
  if (isStyledComponent) {
141
146
  // For styled-components, we need to check the template content
142
- const template = node.quasi.quasis.map(q => q.value.raw).join('');
147
+ const template = node.quasi.quasis.map((q) => q.value.raw).join('');
143
148
  // Check if it contains a pseudo-element with position: absolute/fixed
144
149
  if (hasPseudoElementSelector(template) &&
145
- (template.includes('position: absolute') || template.includes('position: fixed'))) {
150
+ (template.includes('position: absolute') ||
151
+ template.includes('position: fixed'))) {
146
152
  // Check if it's missing pointer-events: none
147
- if (!template.includes('pointer-events: none') && !template.includes('pointer-events:none')) {
153
+ if (!template.includes('pointer-events: none') &&
154
+ !template.includes('pointer-events:none')) {
148
155
  context.report({
149
156
  node,
150
- messageId: 'missingPointerEventsNone'
157
+ messageId: 'missingPointerEventsNone',
151
158
  });
152
159
  }
153
160
  }
@@ -155,7 +162,8 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
155
162
  },
156
163
  // Process style objects in JSX
157
164
  JSXAttribute(node) {
158
- if (node.name.type !== utils_1.AST_NODE_TYPES.JSXIdentifier || node.name.name !== 'style')
165
+ if (node.name.type !== utils_1.AST_NODE_TYPES.JSXIdentifier ||
166
+ node.name.name !== 'style')
159
167
  return;
160
168
  if (node.value?.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer &&
161
169
  node.value.expression.type === utils_1.AST_NODE_TYPES.ObjectExpression) {
@@ -185,7 +193,8 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
185
193
  else if (parent.type === utils_1.AST_NODE_TYPES.CallExpression) {
186
194
  // Check for CSS-in-JS libraries like emotion's css() function
187
195
  const callee = parent.callee;
188
- if (callee.type === utils_1.AST_NODE_TYPES.Identifier && callee.name === 'css') {
196
+ if (callee.type === utils_1.AST_NODE_TYPES.Identifier &&
197
+ callee.name === 'css') {
189
198
  isStyleObject = true;
190
199
  }
191
200
  }
@@ -204,7 +213,7 @@ exports.ensurePointerEventsNone = (0, createRule_1.createRule)({
204
213
  processStyleObject(node.value);
205
214
  checkStyleObject(node.value, node.key.value);
206
215
  }
207
- }
216
+ },
208
217
  };
209
218
  },
210
219
  });
@@ -54,10 +54,10 @@ function isMutableValue(node) {
54
54
  if (node.elements.length === 0)
55
55
  return true;
56
56
  // Arrays with spread elements are mutable
57
- if (node.elements.some(element => !element || element.type === 'SpreadElement'))
57
+ if (node.elements.some((element) => !element || element.type === 'SpreadElement'))
58
58
  return true;
59
59
  // Arrays with non-immutable values are mutable
60
- return node.elements.some(element => !isImmutableValue(element));
60
+ return node.elements.some((element) => !isImmutableValue(element));
61
61
  }
62
62
  // Check for new expressions (e.g., new Map(), new Set())
63
63
  if (node.type === 'NewExpression') {
@@ -83,7 +83,7 @@ function isMutableValue(node) {
83
83
  'splice',
84
84
  'reverse',
85
85
  'sort',
86
- 'fill'
86
+ 'fill',
87
87
  ];
88
88
  return mutatingMethods.includes(methodName);
89
89
  }
@@ -93,7 +93,8 @@ function isMutableValue(node) {
93
93
  function isNumericLiteral(node) {
94
94
  if (!node)
95
95
  return false;
96
- return node.type === 'Literal' && typeof node.value === 'number';
96
+ return (node.type === 'Literal' &&
97
+ typeof node.value === 'number');
97
98
  }
98
99
  function isZeroOrOne(node) {
99
100
  if (!isNumericLiteral(node))
@@ -168,7 +169,10 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
168
169
  // Check initialization
169
170
  if (node.init && node.init.type === 'VariableDeclaration') {
170
171
  for (const decl of node.init.declarations) {
171
- if (decl.init && isNumericLiteral(decl.init) && !isZeroOrOne(decl.init) && !isAsConstExpression(decl.init)) {
172
+ if (decl.init &&
173
+ isNumericLiteral(decl.init) &&
174
+ !isZeroOrOne(decl.init) &&
175
+ !isAsConstExpression(decl.init)) {
172
176
  context.report({
173
177
  node: decl.init,
174
178
  messageId: 'requireAsConst',
@@ -181,7 +185,9 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
181
185
  }
182
186
  // Check test condition
183
187
  if (node.test && node.test.type === 'BinaryExpression') {
184
- if (isNumericLiteral(node.test.right) && !isZeroOrOne(node.test.right) && !isAsConstExpression(node.test.right)) {
188
+ if (isNumericLiteral(node.test.right) &&
189
+ !isZeroOrOne(node.test.right) &&
190
+ !isAsConstExpression(node.test.right)) {
185
191
  context.report({
186
192
  node: node.test.right,
187
193
  messageId: 'requireAsConst',
@@ -194,7 +200,10 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
194
200
  // Check update expression
195
201
  if (node.update) {
196
202
  if (node.update.type === 'AssignmentExpression') {
197
- if (node.update.right && isNumericLiteral(node.update.right) && !isZeroOrOne(node.update.right) && !isAsConstExpression(node.update.right)) {
203
+ if (node.update.right &&
204
+ isNumericLiteral(node.update.right) &&
205
+ !isZeroOrOne(node.update.right) &&
206
+ !isAsConstExpression(node.update.right)) {
198
207
  context.report({
199
208
  node: node.update.right,
200
209
  messageId: 'requireAsConst',
@@ -205,7 +214,9 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
205
214
  }
206
215
  }
207
216
  else if (node.update.type === 'BinaryExpression') {
208
- if (isNumericLiteral(node.update.right) && !isZeroOrOne(node.update.right) && !isAsConstExpression(node.update.right)) {
217
+ if (isNumericLiteral(node.update.right) &&
218
+ !isZeroOrOne(node.update.right) &&
219
+ !isAsConstExpression(node.update.right)) {
209
220
  context.report({
210
221
  node: node.update.right,
211
222
  messageId: 'requireAsConst',
@@ -220,7 +231,9 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
220
231
  WhileStatement(node) {
221
232
  // Check test condition
222
233
  if (node.test.type === 'BinaryExpression') {
223
- if (isNumericLiteral(node.test.right) && !isZeroOrOne(node.test.right) && !isAsConstExpression(node.test.right)) {
234
+ if (isNumericLiteral(node.test.right) &&
235
+ !isZeroOrOne(node.test.right) &&
236
+ !isAsConstExpression(node.test.right)) {
224
237
  context.report({
225
238
  node: node.test.right,
226
239
  messageId: 'requireAsConst',
@@ -234,7 +247,9 @@ exports.extractGlobalConstants = (0, createRule_1.createRule)({
234
247
  DoWhileStatement(node) {
235
248
  // Check test condition
236
249
  if (node.test.type === 'BinaryExpression') {
237
- if (isNumericLiteral(node.test.right) && !isZeroOrOne(node.test.right) && !isAsConstExpression(node.test.right)) {
250
+ if (isNumericLiteral(node.test.right) &&
251
+ !isZeroOrOne(node.test.right) &&
252
+ !isAsConstExpression(node.test.right)) {
238
253
  context.report({
239
254
  node: node.test.right,
240
255
  messageId: 'requireAsConst',
@@ -0,0 +1,3 @@
1
+ type MessageIds = 'useFastDeepEqual' | 'addFastDeepEqualImport';
2
+ export declare const fastDeepEqualOverMicrodiff: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<MessageIds, [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
3
+ export {};