@blumintinc/eslint-plugin-blumint 1.13.0 → 1.14.0

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 (186) hide show
  1. package/README.md +170 -139
  2. package/lib/index.js +190 -1
  3. package/lib/rules/array-methods-this-context.js +1 -1
  4. package/lib/rules/class-methods-read-top-to-bottom.js +24 -5
  5. package/lib/rules/consistent-callback-naming.js +1 -1
  6. package/lib/rules/dynamic-https-errors.js +3 -4
  7. package/lib/rules/enforce-assert-safe-object-key.js +11 -11
  8. package/lib/rules/enforce-boolean-naming-prefixes.js +11 -23
  9. package/lib/rules/enforce-callback-memo.js +1 -1
  10. package/lib/rules/enforce-centralized-mock-firestore.js +1 -1
  11. package/lib/rules/enforce-console-error.js +35 -7
  12. package/lib/rules/enforce-dynamic-file-naming.d.ts +2 -0
  13. package/lib/rules/enforce-dynamic-file-naming.js +53 -28
  14. package/lib/rules/enforce-early-destructuring.d.ts +2 -0
  15. package/lib/rules/enforce-early-destructuring.js +980 -0
  16. package/lib/rules/enforce-empty-object-check.d.ts +11 -0
  17. package/lib/rules/enforce-empty-object-check.js +502 -0
  18. package/lib/rules/enforce-exported-function-types.js +1 -1
  19. package/lib/rules/enforce-fieldpath-syntax-in-docsetter.js +100 -50
  20. package/lib/rules/enforce-firestore-doc-ref-generic.js +15 -3
  21. package/lib/rules/enforce-firestore-facade.js +4 -2
  22. package/lib/rules/enforce-firestore-set-merge.js +3 -4
  23. package/lib/rules/enforce-global-constants.js +1 -1
  24. package/lib/rules/enforce-identifiable-firestore-type.js +108 -58
  25. package/lib/rules/enforce-memoize-async.js +2 -6
  26. package/lib/rules/enforce-memoize-getters.js +39 -15
  27. package/lib/rules/enforce-microdiff.js +1 -1
  28. package/lib/rules/enforce-object-literal-as-const.js +4 -4
  29. package/lib/rules/enforce-positive-naming.js +4 -0
  30. package/lib/rules/enforce-props-argument-name.js +2 -2
  31. package/lib/rules/enforce-safe-stringify.js +1 -1
  32. package/lib/rules/enforce-serializable-params.js +3 -3
  33. package/lib/rules/enforce-singular-type-names.js +1 -1
  34. package/lib/rules/enforce-stable-hash-spread-props.d.ts +13 -0
  35. package/lib/rules/enforce-stable-hash-spread-props.js +342 -0
  36. package/lib/rules/enforce-storage-context.d.ts +9 -0
  37. package/lib/rules/enforce-storage-context.js +646 -0
  38. package/lib/rules/enforce-timestamp-now.js +23 -7
  39. package/lib/rules/enforce-transform-memoization.d.ts +4 -0
  40. package/lib/rules/enforce-transform-memoization.js +416 -0
  41. package/lib/rules/enforce-typescript-markdown-code-blocks.js +7 -3
  42. package/lib/rules/enforce-unique-cursor-headers.d.ts +16 -0
  43. package/lib/rules/enforce-unique-cursor-headers.js +365 -0
  44. package/lib/rules/enforce-verb-noun-naming.js +5 -4
  45. package/lib/rules/ensure-pointer-events-none.js +28 -2
  46. package/lib/rules/export-if-in-doubt.js +27 -4
  47. package/lib/rules/extract-global-constants.js +40 -13
  48. package/lib/rules/fast-deep-equal-over-microdiff.js +29 -39
  49. package/lib/rules/firestore-transaction-reads-before-writes.js +50 -4
  50. package/lib/rules/flatten-push-calls.d.ts +2 -0
  51. package/lib/rules/flatten-push-calls.js +428 -0
  52. package/lib/rules/global-const-style.js +50 -19
  53. package/lib/rules/jsdoc-above-field.d.ts +11 -0
  54. package/lib/rules/jsdoc-above-field.js +208 -0
  55. package/lib/rules/key-only-outermost-element.js +21 -3
  56. package/lib/rules/logical-top-to-bottom-grouping.d.ts +5 -0
  57. package/lib/rules/logical-top-to-bottom-grouping.js +1258 -0
  58. package/lib/rules/memo-compare-deeply-complex-props.d.ts +3 -0
  59. package/lib/rules/memo-compare-deeply-complex-props.js +788 -0
  60. package/lib/rules/memo-nested-react-components.d.ts +8 -0
  61. package/lib/rules/memo-nested-react-components.js +410 -0
  62. package/lib/rules/no-always-true-false-conditions.d.ts +2 -1
  63. package/lib/rules/no-always-true-false-conditions.js +68 -8
  64. package/lib/rules/no-array-length-in-deps.js +9 -3
  65. package/lib/rules/no-async-foreach.js +210 -12
  66. package/lib/rules/no-circular-references.js +18 -17
  67. package/lib/rules/no-class-instance-destructuring.js +55 -12
  68. package/lib/rules/no-complex-cloud-params.js +7 -3
  69. package/lib/rules/no-compositing-layer-props.js +2 -2
  70. package/lib/rules/no-conditional-literals-in-jsx.js +37 -12
  71. package/lib/rules/no-console-error.d.ts +9 -0
  72. package/lib/rules/no-console-error.js +525 -0
  73. package/lib/rules/no-curly-brackets-around-commented-properties.d.ts +2 -0
  74. package/lib/rules/no-curly-brackets-around-commented-properties.js +258 -0
  75. package/lib/rules/no-empty-dependency-use-callbacks.d.ts +11 -0
  76. package/lib/rules/no-empty-dependency-use-callbacks.js +576 -0
  77. package/lib/rules/no-entire-object-hook-deps.js +4 -6
  78. package/lib/rules/no-excessive-parent-chain.js +1 -1
  79. package/lib/rules/no-explicit-return-type.d.ts +2 -1
  80. package/lib/rules/no-explicit-return-type.js +215 -26
  81. package/lib/rules/no-filter-without-return.js +5 -1
  82. package/lib/rules/no-firestore-jest-mock.d.ts +2 -1
  83. package/lib/rules/no-firestore-jest-mock.js +126 -8
  84. package/lib/rules/no-firestore-object-arrays.js +67 -12
  85. package/lib/rules/no-handler-suffix.d.ts +12 -0
  86. package/lib/rules/no-handler-suffix.js +305 -0
  87. package/lib/rules/no-hungarian.js +1 -1
  88. package/lib/rules/no-inline-component-prop.d.ts +10 -0
  89. package/lib/rules/no-inline-component-prop.js +456 -0
  90. package/lib/rules/no-jsx-in-hooks.js +6 -1
  91. package/lib/rules/no-jsx-whitespace-literal.js +8 -2
  92. package/lib/rules/no-margin-properties.js +6 -6
  93. package/lib/rules/no-memoize-on-static.js +9 -1
  94. package/lib/rules/no-misleading-boolean-prefixes.js +7 -3
  95. package/lib/rules/no-misused-switch-case.js +22 -1
  96. package/lib/rules/no-mixed-firestore-transactions.d.ts +3 -1
  97. package/lib/rules/no-mixed-firestore-transactions.js +296 -34
  98. package/lib/rules/no-mock-firebase-admin.js +5 -2
  99. package/lib/rules/no-object-values-on-strings.js +10 -2
  100. package/lib/rules/no-overridable-method-calls-in-constructor.js +29 -17
  101. package/lib/rules/no-passthrough-getters.js +38 -2
  102. package/lib/rules/no-redundant-annotation-assertion.d.ts +2 -0
  103. package/lib/rules/no-redundant-annotation-assertion.js +402 -0
  104. package/lib/rules/no-redundant-param-types.js +16 -6
  105. package/lib/rules/no-redundant-this-params.d.ts +3 -0
  106. package/lib/rules/no-redundant-this-params.js +459 -0
  107. package/lib/rules/no-redundant-usecallback-wrapper.js +16 -3
  108. package/lib/rules/no-res-error-status-in-onrequest.d.ts +4 -0
  109. package/lib/rules/no-res-error-status-in-onrequest.js +521 -0
  110. package/lib/rules/no-restricted-properties-fix.js +11 -10
  111. package/lib/rules/no-separate-loading-state.js +7 -16
  112. package/lib/rules/no-stale-state-across-await.js +1 -1
  113. package/lib/rules/no-type-assertion-returns.js +43 -49
  114. package/lib/rules/no-undefined-null-passthrough.js +61 -31
  115. package/lib/rules/no-unmemoized-memo-without-props.d.ts +8 -0
  116. package/lib/rules/no-unmemoized-memo-without-props.js +426 -0
  117. package/lib/rules/no-unnecessary-destructuring-rename.d.ts +2 -0
  118. package/lib/rules/no-unnecessary-destructuring-rename.js +347 -0
  119. package/lib/rules/no-unnecessary-destructuring.js +14 -4
  120. package/lib/rules/no-unnecessary-verb-suffix.js +2 -1
  121. package/lib/rules/no-unpinned-dependencies.js +36 -5
  122. package/lib/rules/no-unused-props.d.ts +2 -2
  123. package/lib/rules/no-unused-props.js +295 -91
  124. package/lib/rules/no-unused-usestate.js +6 -2
  125. package/lib/rules/no-useless-fragment.js +28 -2
  126. package/lib/rules/no-useless-usememo-primitives.d.ts +9 -0
  127. package/lib/rules/no-useless-usememo-primitives.js +393 -0
  128. package/lib/rules/no-usememo-for-pass-by-value.d.ts +13 -0
  129. package/lib/rules/no-usememo-for-pass-by-value.js +757 -0
  130. package/lib/rules/no-uuidv4-base62-as-key.js +18 -13
  131. package/lib/rules/omit-index-html.d.ts +2 -1
  132. package/lib/rules/omit-index-html.js +62 -7
  133. package/lib/rules/optimize-object-boolean-conditions.js +6 -4
  134. package/lib/rules/parallelize-async-operations.js +24 -5
  135. package/lib/rules/prefer-batch-operations.d.ts +1 -3
  136. package/lib/rules/prefer-batch-operations.js +32 -5
  137. package/lib/rules/prefer-block-comments-for-declarations.js +9 -4
  138. package/lib/rules/prefer-clone-deep.js +3 -3
  139. package/lib/rules/prefer-destructuring-no-class.d.ts +2 -1
  140. package/lib/rules/prefer-destructuring-no-class.js +244 -59
  141. package/lib/rules/prefer-docsetter-setall.d.ts +2 -0
  142. package/lib/rules/prefer-docsetter-setall.js +243 -0
  143. package/lib/rules/prefer-field-paths-in-transforms.js +4 -3
  144. package/lib/rules/prefer-fragment-component.js +1 -1
  145. package/lib/rules/prefer-fragment-shorthand.js +2 -1
  146. package/lib/rules/prefer-getter-over-parameterless-method.d.ts +13 -0
  147. package/lib/rules/prefer-getter-over-parameterless-method.js +648 -0
  148. package/lib/rules/prefer-global-router-state-key.js +88 -13
  149. package/lib/rules/prefer-memoized-props.d.ts +3 -0
  150. package/lib/rules/prefer-memoized-props.js +445 -0
  151. package/lib/rules/prefer-next-dynamic.js +60 -69
  152. package/lib/rules/prefer-nullish-coalescing-boolean-props.js +9 -4
  153. package/lib/rules/prefer-nullish-coalescing-override.d.ts +2 -1
  154. package/lib/rules/prefer-nullish-coalescing-override.js +11 -5
  155. package/lib/rules/prefer-params-over-parent-id.js +220 -171
  156. package/lib/rules/prefer-settings-object.js +2 -2
  157. package/lib/rules/prefer-type-over-interface.js +7 -2
  158. package/lib/rules/prefer-url-tostring-over-tojson.js +6 -3
  159. package/lib/rules/prefer-use-deep-compare-memo.js +8 -5
  160. package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +1 -1
  161. package/lib/rules/prefer-utility-function-over-private-static.js +34 -2
  162. package/lib/rules/prevent-children-clobber.d.ts +2 -0
  163. package/lib/rules/prevent-children-clobber.js +536 -0
  164. package/lib/rules/react-memoize-literals.d.ts +4 -0
  165. package/lib/rules/react-memoize-literals.js +495 -0
  166. package/lib/rules/react-usememo-should-be-component.js +2 -2
  167. package/lib/rules/require-hooks-default-params.js +17 -16
  168. package/lib/rules/require-https-error-cause.d.ts +4 -0
  169. package/lib/rules/require-https-error-cause.js +136 -0
  170. package/lib/rules/require-https-error.js +43 -21
  171. package/lib/rules/require-image-optimized.js +1 -1
  172. package/lib/rules/require-memo.js +1 -1
  173. package/lib/rules/require-memoize-jsx-returners.d.ts +3 -0
  174. package/lib/rules/require-memoize-jsx-returners.js +485 -0
  175. package/lib/rules/require-usememo-object-literals.js +2 -3
  176. package/lib/rules/test-file-location-enforcement.js +1 -1
  177. package/lib/rules/use-latest-callback.js +6 -5
  178. package/lib/rules/vertically-group-related-functions.d.ts +16 -0
  179. package/lib/rules/vertically-group-related-functions.js +480 -0
  180. package/lib/utils/ASTHelpers.d.ts +13 -1
  181. package/lib/utils/ASTHelpers.js +24 -0
  182. package/lib/utils/getMethodName.d.ts +27 -0
  183. package/lib/utils/getMethodName.js +35 -0
  184. package/lib/utils/tsTypeClassifier.d.ts +30 -0
  185. package/lib/utils/tsTypeClassifier.js +149 -0
  186. package/package.json +3 -1
@@ -0,0 +1,459 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noRedundantThisParams = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ exports.noRedundantThisParams = (0, createRule_1.createRule)({
7
+ name: 'no-redundant-this-params',
8
+ meta: {
9
+ type: 'suggestion',
10
+ docs: {
11
+ description: 'Disallow passing class instance members (this.foo) into class instance methods; access the member from this inside the method instead.',
12
+ recommended: 'error',
13
+ },
14
+ fixable: undefined,
15
+ schema: [],
16
+ messages: {
17
+ redundantInstanceArg: 'Method "{{methodName}}" receives "{{memberText}}"{{parameterNote}}. Instance state already lives on "this"; threading it through parameters duplicates class state and bloats the signature. Read "{{memberText}}" inside "{{methodName}}" instead of accepting it as an argument.',
18
+ redundantInstanceValueInObject: 'Method "{{methodName}}" receives an argument that contains "{{memberText}}"{{parameterNote}}. Routing instance state through parameters hides the shared `this` contract and complicates refactors. Remove that property from the call and read "{{memberText}}" directly inside "{{methodName}}".',
19
+ },
20
+ },
21
+ defaultOptions: [],
22
+ create(context) {
23
+ const classInfoMap = new WeakMap();
24
+ function isFunctionLike(node) {
25
+ return (node?.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
26
+ node?.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
27
+ node?.type === utils_1.AST_NODE_TYPES.FunctionDeclaration);
28
+ }
29
+ function getNameFromPropertyName(key) {
30
+ if (key.type === utils_1.AST_NODE_TYPES.Identifier) {
31
+ return key.name;
32
+ }
33
+ if (key.type === utils_1.AST_NODE_TYPES.Literal) {
34
+ return typeof key.value === 'string' ? key.value : String(key.value);
35
+ }
36
+ if (key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) {
37
+ return `#${key.name}`;
38
+ }
39
+ return null;
40
+ }
41
+ function getMethodNameFromCallee(callee) {
42
+ const maybeChain = callee;
43
+ const unwrapped = maybeChain.type === utils_1.AST_NODE_TYPES.ChainExpression
44
+ ? maybeChain.expression
45
+ : callee;
46
+ if (unwrapped.type === utils_1.AST_NODE_TYPES.MemberExpression &&
47
+ !unwrapped.computed &&
48
+ unwrapped.object.type === utils_1.AST_NODE_TYPES.ThisExpression &&
49
+ (unwrapped.property.type === utils_1.AST_NODE_TYPES.Identifier ||
50
+ unwrapped.property.type === utils_1.AST_NODE_TYPES.PrivateIdentifier)) {
51
+ return getNameFromPropertyName(unwrapped.property);
52
+ }
53
+ return null;
54
+ }
55
+ function getMethodParams(member) {
56
+ const value = member.value;
57
+ if (value &&
58
+ (value.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
59
+ value.type === utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression)) {
60
+ return value.params;
61
+ }
62
+ return [];
63
+ }
64
+ function getPropertyMethodParams(member) {
65
+ if (member.value &&
66
+ (member.value.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
67
+ member.value.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression)) {
68
+ return member.value.params;
69
+ }
70
+ const annotation = member.typeAnnotation?.typeAnnotation;
71
+ if (!member.value &&
72
+ member.optional &&
73
+ annotation &&
74
+ annotation.type === utils_1.AST_NODE_TYPES.TSFunctionType) {
75
+ return annotation.params;
76
+ }
77
+ return [];
78
+ }
79
+ function collectClassInfo(node) {
80
+ const methods = new Map();
81
+ function setMethod(methodName, meta) {
82
+ /**
83
+ * Prefer instance methods over static methods when names collide.
84
+ * Calls like `this.method()` always resolve to the instance member, so the rule tracks the
85
+ * instance signature even if a static overload exists in the AST.
86
+ */
87
+ const existing = methods.get(methodName);
88
+ if (!existing) {
89
+ methods.set(methodName, meta);
90
+ return;
91
+ }
92
+ if (existing.isStatic && !meta.isStatic) {
93
+ methods.set(methodName, meta);
94
+ return;
95
+ }
96
+ if (!existing.isStatic && meta.isStatic) {
97
+ return;
98
+ }
99
+ methods.set(methodName, meta);
100
+ }
101
+ for (const member of node.body.body) {
102
+ if (member.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
103
+ member.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) {
104
+ if (member.kind === 'constructor') {
105
+ continue;
106
+ }
107
+ const methodName = getNameFromPropertyName(member.key);
108
+ if (!methodName) {
109
+ continue;
110
+ }
111
+ setMethod(methodName, {
112
+ params: getMethodParams(member),
113
+ isStatic: Boolean(member.static),
114
+ isAbstract: member.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition,
115
+ });
116
+ }
117
+ else if (member.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
118
+ const methodName = member.key
119
+ ? getNameFromPropertyName(member.key)
120
+ : null;
121
+ if (!methodName || member.static) {
122
+ continue;
123
+ }
124
+ const params = getPropertyMethodParams(member);
125
+ if (params.length === 0) {
126
+ continue;
127
+ }
128
+ setMethod(methodName, {
129
+ params,
130
+ isStatic: false,
131
+ isAbstract: false,
132
+ });
133
+ }
134
+ }
135
+ classInfoMap.set(node, { methods });
136
+ }
137
+ function findEnclosingClass(node) {
138
+ let current = node.parent;
139
+ while (current) {
140
+ if (current.type === utils_1.AST_NODE_TYPES.ClassDeclaration ||
141
+ current.type === utils_1.AST_NODE_TYPES.ClassExpression) {
142
+ return current;
143
+ }
144
+ current = current.parent;
145
+ }
146
+ return null;
147
+ }
148
+ function findEnclosingMember(node) {
149
+ let current = node.parent;
150
+ while (current) {
151
+ if (current.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
152
+ current.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
153
+ return current;
154
+ }
155
+ current = current.parent;
156
+ }
157
+ return null;
158
+ }
159
+ function getMemberFunction(member) {
160
+ if (!member) {
161
+ return null;
162
+ }
163
+ if (member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
164
+ member.value &&
165
+ member.value.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
166
+ return member.value;
167
+ }
168
+ if (member.type === utils_1.AST_NODE_TYPES.PropertyDefinition &&
169
+ member.value &&
170
+ (member.value.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
171
+ member.value.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression)) {
172
+ return member.value;
173
+ }
174
+ return null;
175
+ }
176
+ function hasNestedFunctionBetween(leaf, boundary) {
177
+ let current = leaf.parent;
178
+ while (current && current !== boundary) {
179
+ if (isFunctionLike(current)) {
180
+ return true;
181
+ }
182
+ current = current.parent;
183
+ }
184
+ return false;
185
+ }
186
+ function isTransparentExpressionWrapper(node) {
187
+ // Babel emits ParenthesizedExpression nodes that are not modeled in TSESTree; treating them
188
+ // as transparent prevents parentheses from changing nested/transformed classification.
189
+ return (node.type === utils_1.AST_NODE_TYPES.TSAsExpression ||
190
+ node.type === utils_1.AST_NODE_TYPES.TSTypeAssertion ||
191
+ node.type === utils_1.AST_NODE_TYPES.TSNonNullExpression ||
192
+ node.type === utils_1.AST_NODE_TYPES.TSSatisfiesExpression ||
193
+ node.type === utils_1.AST_NODE_TYPES.TSInstantiationExpression ||
194
+ node.type === 'ParenthesizedExpression');
195
+ }
196
+ function unwrapTransparentExpression(node) {
197
+ let current = node;
198
+ while (isTransparentExpressionWrapper(current)) {
199
+ current = current.expression;
200
+ }
201
+ return current;
202
+ }
203
+ function isExpressionMemberChainObject(node) {
204
+ let current = node;
205
+ let parent = current.parent;
206
+ while (parent &&
207
+ isTransparentExpressionWrapper(parent) &&
208
+ parent.expression === current) {
209
+ current = parent;
210
+ parent = current.parent;
211
+ }
212
+ return (parent?.type === utils_1.AST_NODE_TYPES.MemberExpression &&
213
+ parent.object === current);
214
+ }
215
+ function getMemberText(propertyName) {
216
+ return `this.${propertyName}`;
217
+ }
218
+ function isTransformingNode(node) {
219
+ switch (node.type) {
220
+ case utils_1.AST_NODE_TYPES.CallExpression:
221
+ case utils_1.AST_NODE_TYPES.NewExpression:
222
+ case utils_1.AST_NODE_TYPES.TaggedTemplateExpression:
223
+ case utils_1.AST_NODE_TYPES.TemplateLiteral:
224
+ case utils_1.AST_NODE_TYPES.BinaryExpression:
225
+ case utils_1.AST_NODE_TYPES.LogicalExpression:
226
+ case utils_1.AST_NODE_TYPES.ConditionalExpression:
227
+ case utils_1.AST_NODE_TYPES.SequenceExpression:
228
+ case utils_1.AST_NODE_TYPES.UnaryExpression:
229
+ case utils_1.AST_NODE_TYPES.UpdateExpression:
230
+ case utils_1.AST_NODE_TYPES.AwaitExpression:
231
+ case utils_1.AST_NODE_TYPES.YieldExpression:
232
+ case utils_1.AST_NODE_TYPES.AssignmentExpression:
233
+ return true;
234
+ default:
235
+ return false;
236
+ }
237
+ }
238
+ function collectThisAccesses(expression) {
239
+ const normalized = unwrapTransparentExpression(expression);
240
+ const results = [];
241
+ function visit(node, nested, transformed) {
242
+ const isParenthesized = node.type === 'ParenthesizedExpression';
243
+ const isMemberChainObject = isExpressionMemberChainObject(node);
244
+ if (isParenthesized) {
245
+ visit(node.expression, nested || (node !== normalized && !isMemberChainObject), transformed);
246
+ return;
247
+ }
248
+ const nextNested = nested || (node !== normalized && !isMemberChainObject);
249
+ const nextTransformed = transformed || isTransformingNode(node);
250
+ switch (node.type) {
251
+ case utils_1.AST_NODE_TYPES.MemberExpression: {
252
+ if (!node.computed &&
253
+ node.object.type === utils_1.AST_NODE_TYPES.ThisExpression &&
254
+ (node.property.type === utils_1.AST_NODE_TYPES.Identifier ||
255
+ node.property.type === utils_1.AST_NODE_TYPES.PrivateIdentifier)) {
256
+ const propertyName = getNameFromPropertyName(node.property);
257
+ if (propertyName && !nextTransformed) {
258
+ results.push({
259
+ node,
260
+ propertyName,
261
+ nested: nextNested,
262
+ transformed: nextTransformed,
263
+ });
264
+ return;
265
+ }
266
+ }
267
+ visit(node.object, nextNested, nextTransformed);
268
+ if (node.computed) {
269
+ visit(node.property, true, nextTransformed);
270
+ }
271
+ return;
272
+ }
273
+ case utils_1.AST_NODE_TYPES.ChainExpression:
274
+ visit(node.expression, nextNested, nextTransformed);
275
+ return;
276
+ case utils_1.AST_NODE_TYPES.ObjectExpression:
277
+ for (const prop of node.properties) {
278
+ if (prop.type === utils_1.AST_NODE_TYPES.Property) {
279
+ if (prop.computed) {
280
+ visit(prop.key, true, nextTransformed);
281
+ }
282
+ visit(prop.value, true, nextTransformed);
283
+ }
284
+ else if (prop.type === utils_1.AST_NODE_TYPES.SpreadElement) {
285
+ visit(prop.argument, true, nextTransformed);
286
+ }
287
+ }
288
+ return;
289
+ case utils_1.AST_NODE_TYPES.ArrayExpression:
290
+ for (const element of node.elements) {
291
+ if (!element) {
292
+ continue;
293
+ }
294
+ if (element.type === utils_1.AST_NODE_TYPES.SpreadElement) {
295
+ visit(element.argument, true, nextTransformed);
296
+ continue;
297
+ }
298
+ visit(element, true, nextTransformed);
299
+ }
300
+ return;
301
+ case utils_1.AST_NODE_TYPES.CallExpression:
302
+ case utils_1.AST_NODE_TYPES.NewExpression:
303
+ for (const arg of node.arguments) {
304
+ if (arg) {
305
+ visit(arg, true, true);
306
+ }
307
+ }
308
+ return;
309
+ case utils_1.AST_NODE_TYPES.SpreadElement:
310
+ visit(node.argument, true, nextTransformed);
311
+ return;
312
+ case utils_1.AST_NODE_TYPES.BinaryExpression:
313
+ case utils_1.AST_NODE_TYPES.LogicalExpression:
314
+ visit(node.left, true, true);
315
+ visit(node.right, true, true);
316
+ return;
317
+ case utils_1.AST_NODE_TYPES.ConditionalExpression:
318
+ visit(node.test, true, true);
319
+ visit(node.consequent, true, true);
320
+ visit(node.alternate, true, true);
321
+ return;
322
+ case utils_1.AST_NODE_TYPES.TemplateLiteral:
323
+ node.expressions.forEach((expr) => visit(expr, true, true));
324
+ return;
325
+ case utils_1.AST_NODE_TYPES.TaggedTemplateExpression:
326
+ visit(node.tag, true, true);
327
+ visit(node.quasi, true, true);
328
+ return;
329
+ case utils_1.AST_NODE_TYPES.SequenceExpression:
330
+ node.expressions.forEach((expr) => visit(expr, true, true));
331
+ return;
332
+ case utils_1.AST_NODE_TYPES.UnaryExpression:
333
+ case utils_1.AST_NODE_TYPES.UpdateExpression:
334
+ case utils_1.AST_NODE_TYPES.AwaitExpression:
335
+ case utils_1.AST_NODE_TYPES.YieldExpression:
336
+ if (node.argument) {
337
+ visit(node.argument, true, true);
338
+ }
339
+ return;
340
+ case utils_1.AST_NODE_TYPES.AssignmentExpression:
341
+ visit(node.left, true, true);
342
+ visit(node.right, true, true);
343
+ return;
344
+ case utils_1.AST_NODE_TYPES.TSAsExpression:
345
+ case utils_1.AST_NODE_TYPES.TSTypeAssertion:
346
+ case utils_1.AST_NODE_TYPES.TSNonNullExpression:
347
+ case utils_1.AST_NODE_TYPES.TSSatisfiesExpression:
348
+ case utils_1.AST_NODE_TYPES.TSInstantiationExpression:
349
+ visit(node.expression, nextNested, nextTransformed);
350
+ return;
351
+ default:
352
+ if (isFunctionLike(node)) {
353
+ return;
354
+ }
355
+ }
356
+ }
357
+ visit(normalized, false, false);
358
+ return results;
359
+ }
360
+ function getParameterName(param) {
361
+ if (!param) {
362
+ return null;
363
+ }
364
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier) {
365
+ return param.name;
366
+ }
367
+ if (param.type === utils_1.AST_NODE_TYPES.AssignmentPattern) {
368
+ if (param.left.type === utils_1.AST_NODE_TYPES.Identifier) {
369
+ return param.left.name;
370
+ }
371
+ if (param.left.type === utils_1.AST_NODE_TYPES.ObjectPattern) {
372
+ return null;
373
+ }
374
+ }
375
+ if (param.type === utils_1.AST_NODE_TYPES.RestElement) {
376
+ return param.argument.type === utils_1.AST_NODE_TYPES.Identifier
377
+ ? param.argument.name
378
+ : null;
379
+ }
380
+ if (param.type === utils_1.AST_NODE_TYPES.TSParameterProperty) {
381
+ const { parameter } = param;
382
+ if (parameter.type === utils_1.AST_NODE_TYPES.Identifier) {
383
+ return parameter.name;
384
+ }
385
+ if (parameter.type === utils_1.AST_NODE_TYPES.AssignmentPattern &&
386
+ parameter.left.type === utils_1.AST_NODE_TYPES.Identifier) {
387
+ return parameter.left.name;
388
+ }
389
+ }
390
+ return null;
391
+ }
392
+ function buildParameterNote(paramName) {
393
+ return paramName ? ` (parameter "${paramName}")` : '';
394
+ }
395
+ function reportAccess(methodName, methodMeta, argIndex, access) {
396
+ const paramName = getParameterName(methodMeta.params[argIndex]);
397
+ const parameterNote = buildParameterNote(paramName);
398
+ const memberText = getMemberText(access.propertyName);
399
+ const messageId = access.nested
400
+ ? 'redundantInstanceValueInObject'
401
+ : 'redundantInstanceArg';
402
+ context.report({
403
+ node: access.node,
404
+ messageId,
405
+ data: {
406
+ methodName,
407
+ memberText,
408
+ parameterNote,
409
+ },
410
+ });
411
+ }
412
+ return {
413
+ 'ClassDeclaration, ClassExpression'(node) {
414
+ collectClassInfo(node);
415
+ },
416
+ CallExpression(node) {
417
+ const methodName = getMethodNameFromCallee(node.callee);
418
+ if (!methodName || methodName === 'constructor') {
419
+ return;
420
+ }
421
+ const classNode = findEnclosingClass(node);
422
+ if (!classNode) {
423
+ return;
424
+ }
425
+ const classInfo = classInfoMap.get(classNode);
426
+ const methodMeta = classInfo?.methods.get(methodName);
427
+ if (!methodMeta || methodMeta.isStatic) {
428
+ return;
429
+ }
430
+ const member = findEnclosingMember(node);
431
+ const memberFunction = getMemberFunction(member);
432
+ if (memberFunction) {
433
+ if (hasNestedFunctionBetween(node, memberFunction)) {
434
+ return;
435
+ }
436
+ }
437
+ else {
438
+ if (!member || member.type !== utils_1.AST_NODE_TYPES.PropertyDefinition) {
439
+ return;
440
+ }
441
+ if (hasNestedFunctionBetween(node, member)) {
442
+ return;
443
+ }
444
+ }
445
+ node.arguments.forEach((arg, index) => {
446
+ if (!arg) {
447
+ return;
448
+ }
449
+ const targetNode = arg.type === utils_1.AST_NODE_TYPES.SpreadElement ? arg.argument : arg;
450
+ const accesses = collectThisAccesses(targetNode);
451
+ for (const access of accesses) {
452
+ reportAccess(methodName, methodMeta, index, access);
453
+ }
454
+ });
455
+ },
456
+ };
457
+ },
458
+ });
459
+ //# sourceMappingURL=no-redundant-this-params.js.map
@@ -131,7 +131,7 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
131
131
  },
132
132
  ],
133
133
  messages: {
134
- redundantWrapper: 'Redundant useCallback wrapper around an already memoized callback. Pass the memoized function directly.',
134
+ redundantWrapper: 'useCallback is wrapping memoized callback "{{callbackName}}", adding a redundant dependency array without improving stability. Pass the hook/context callback directly so React keeps the original stable reference and avoids wrapper allocations and dependency drift.',
135
135
  },
136
136
  },
137
137
  defaultOptions: [{}],
@@ -139,6 +139,7 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
139
139
  const option = context.options?.[0] ?? {};
140
140
  const knownHooks = new Set(option.memoizedHookNames ?? []);
141
141
  const assumeAllUseAreMemoized = option.assumeAllUseAreMemoized === true;
142
+ const sourceCode = context.sourceCode;
142
143
  // Track identifiers coming from hook-like calls
143
144
  const hookReturnObjects = new Set(); // variables assigned to a hook call result (object or function)
144
145
  const hookReturnProps = new Set(); // properties destructured from a hook call result
@@ -203,12 +204,17 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
203
204
  context.report({
204
205
  node,
205
206
  messageId: 'redundantWrapper',
207
+ data: { callbackName: sourceCode.getText(unwrappedArg) },
206
208
  fix: (fixer) => fixer.replaceText(node, replaceText),
207
209
  });
208
210
  }
209
211
  else {
210
212
  // Member function — report only, no fix to avoid breaking `this`.
211
- context.report({ node, messageId: 'redundantWrapper' });
213
+ context.report({
214
+ node,
215
+ messageId: 'redundantWrapper',
216
+ data: { callbackName: sourceCode.getText(unwrappedArg) },
217
+ });
212
218
  }
213
219
  }
214
220
  return;
@@ -240,12 +246,17 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
240
246
  context.report({
241
247
  node,
242
248
  messageId: 'redundantWrapper',
249
+ data: { callbackName: sourceCode.getText(callee) },
243
250
  fix: (fixer) => fixer.replaceText(node, replaceText),
244
251
  });
245
252
  }
246
253
  else {
247
254
  // Member function — report only, no fix to avoid breaking `this`.
248
- context.report({ node, messageId: 'redundantWrapper' });
255
+ context.report({
256
+ node,
257
+ messageId: 'redundantWrapper',
258
+ data: { callbackName: sourceCode.getText(callee) },
259
+ });
249
260
  }
250
261
  }
251
262
  }
@@ -289,6 +300,7 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
289
300
  context.report({
290
301
  node,
291
302
  messageId: 'redundantWrapper',
303
+ data: { callbackName: sourceCode.getText(callee) },
292
304
  fix: (fixer) => fixer.replaceText(node, replaceText),
293
305
  });
294
306
  }
@@ -297,6 +309,7 @@ exports.noRedundantUseCallbackWrapper = (0, createRule_1.createRule)({
297
309
  context.report({
298
310
  node,
299
311
  messageId: 'redundantWrapper',
312
+ data: { callbackName: sourceCode.getText(callee) },
300
313
  });
301
314
  }
302
315
  }
@@ -0,0 +1,4 @@
1
+ import { TSESLint } from '@typescript-eslint/utils';
2
+ type MessageIds = 'useHttpsErrorForStatus' | 'useHttpsErrorForComputedStatus' | 'useHttpsErrorForWrapper';
3
+ export declare const requireHttpsErrorInOnRequestHandlers: TSESLint.RuleModule<MessageIds, never[]>;
4
+ export {};