@blumintinc/eslint-plugin-blumint 1.7.2 → 1.8.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 (41) hide show
  1. package/README.md +39 -62
  2. package/lib/index.js +37 -1
  3. package/lib/rules/enforce-assert-throws.js +48 -3
  4. package/lib/rules/enforce-assertSafe-object-key.d.ts +2 -0
  5. package/lib/rules/enforce-assertSafe-object-key.js +284 -0
  6. package/lib/rules/enforce-centralized-mock-firestore.js +193 -15
  7. package/lib/rules/enforce-firestore-facade.js +8 -0
  8. package/lib/rules/enforce-microdiff.d.ts +3 -0
  9. package/lib/rules/enforce-microdiff.js +379 -0
  10. package/lib/rules/enforce-mock-firestore.js +2 -2
  11. package/lib/rules/enforce-object-literal-as-const.d.ts +4 -0
  12. package/lib/rules/enforce-object-literal-as-const.js +88 -0
  13. package/lib/rules/enforce-positive-naming.d.ts +1 -0
  14. package/lib/rules/enforce-positive-naming.js +363 -0
  15. package/lib/rules/enforce-props-argument-name.d.ts +8 -0
  16. package/lib/rules/enforce-props-argument-name.js +182 -0
  17. package/lib/rules/enforce-render-hits-memoization.js +166 -17
  18. package/lib/rules/enforce-timestamp-now.d.ts +1 -0
  19. package/lib/rules/enforce-timestamp-now.js +223 -0
  20. package/lib/rules/enforce-verb-noun-naming.js +1 -0
  21. package/lib/rules/extract-global-constants.d.ts +1 -1
  22. package/lib/rules/extract-global-constants.js +109 -1
  23. package/lib/rules/global-const-style.js +3 -2
  24. package/lib/rules/no-always-true-false-conditions.d.ts +3 -0
  25. package/lib/rules/no-always-true-false-conditions.js +1202 -0
  26. package/lib/rules/no-firestore-jest-mock.js +27 -4
  27. package/lib/rules/no-mock-firebase-admin.js +21 -8
  28. package/lib/rules/no-type-assertion-returns.d.ts +9 -0
  29. package/lib/rules/no-type-assertion-returns.js +289 -0
  30. package/lib/rules/no-unnecessary-verb-suffix.d.ts +1 -0
  31. package/lib/rules/no-unnecessary-verb-suffix.js +203 -0
  32. package/lib/rules/no-unused-props.js +47 -1
  33. package/lib/rules/prefer-clone-deep.js +294 -22
  34. package/lib/rules/prefer-fragment-component.js +265 -34
  35. package/lib/rules/prefer-global-router-state-key.d.ts +5 -0
  36. package/lib/rules/prefer-global-router-state-key.js +89 -0
  37. package/lib/rules/prefer-utility-function-over-private-static.d.ts +1 -0
  38. package/lib/rules/prefer-utility-function-over-private-static.js +77 -0
  39. package/lib/rules/react-usememo-should-be-component.d.ts +1 -0
  40. package/lib/rules/react-usememo-should-be-component.js +256 -0
  41. package/package.json +5 -5
@@ -0,0 +1,363 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforcePositiveNaming = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ // Common negative prefixes and words to detect
7
+ const NEGATIVE_PREFIXES = ['not', 'no', 'non', 'un', 'in', 'dis'];
8
+ const NEGATIVE_WORDS = [
9
+ 'invalid',
10
+ 'disabled',
11
+ 'incomplete',
12
+ 'unpaid',
13
+ 'inactive',
14
+ 'disallowed',
15
+ 'unauthorized',
16
+ 'unverified',
17
+ 'prevent',
18
+ 'avoid',
19
+ 'block',
20
+ 'deny',
21
+ 'reject',
22
+ 'exclude',
23
+ 'fail',
24
+ 'missing',
25
+ 'forbidden',
26
+ 'impossible',
27
+ 'error',
28
+ 'broken',
29
+ 'banned',
30
+ 'restricted',
31
+ 'limitation',
32
+ 'limitation',
33
+ 'blocked',
34
+ 'prohibited',
35
+ ];
36
+ // Whitelist of acceptable negative terms (technical terms, common patterns)
37
+ const ALLOWED_NEGATIVE_TERMS = new Set([
38
+ 'isNaN',
39
+ 'isNull',
40
+ 'isUndefined',
41
+ 'isEmpty',
42
+ 'isOffline',
43
+ 'isMissing',
44
+ 'isOutOfStock',
45
+ 'isOutOfBounds',
46
+ 'isOffPeak',
47
+ 'isNoticeable',
48
+ 'hasNotification',
49
+ 'isNoteworthy',
50
+ 'isNone',
51
+ 'isNegative',
52
+ 'isNeutral',
53
+ 'isNotification',
54
+ 'isNote',
55
+ 'hasNote',
56
+ ]);
57
+ // Map of negative terms to suggested positive alternatives
58
+ const POSITIVE_ALTERNATIVES = {
59
+ // Prefixes
60
+ 'isNot': ['is'],
61
+ 'isUn': ['is'],
62
+ 'isDis': ['is'],
63
+ 'isIn': ['is'],
64
+ 'isNon': ['is'],
65
+ 'hasNo': ['has'],
66
+ 'hasNot': ['has'],
67
+ 'canNot': ['can'],
68
+ 'shouldNot': ['should'],
69
+ 'willNot': ['will'],
70
+ 'doesNot': ['does'],
71
+ // Words
72
+ 'isInvalid': ['isValid'],
73
+ 'isDisabled': ['isEnabled'],
74
+ 'isIncomplete': ['isComplete'],
75
+ 'isUnpaid': ['isPaid', 'hasPaid'],
76
+ 'isInactive': ['isActive'],
77
+ 'isDisallowed': ['isAllowed'],
78
+ 'isUnauthorized': ['isAuthorized'],
79
+ 'isUnverified': ['isVerified'],
80
+ 'isImpossible': ['isPossible'],
81
+ 'isError': ['isSuccess', 'isValid'],
82
+ 'isBroken': ['isWorking', 'isFunctional'],
83
+ 'isBanned': ['isAllowed', 'isPermitted'],
84
+ 'isRestricted': ['isAllowed', 'isAccessible'],
85
+ 'isBlocked': ['isAllowed', 'isAccessible'],
86
+ 'isProhibited': ['isAllowed', 'isPermitted'],
87
+ 'prevent': ['allow', 'enable'],
88
+ 'avoid': ['use', 'prefer'],
89
+ 'block': ['allow', 'permit'],
90
+ 'deny': ['allow', 'grant'],
91
+ 'reject': ['accept', 'approve'],
92
+ 'exclude': ['include'],
93
+ 'fail': ['succeed', 'pass'],
94
+ 'missing': ['present', 'available'],
95
+ 'forbidden': ['allowed', 'permitted'],
96
+ 'disabled': ['enabled'],
97
+ 'incomplete': ['complete'],
98
+ 'invalid': ['valid'],
99
+ 'disallowed': ['allowed'],
100
+ 'unauthorized': ['authorized'],
101
+ 'unverified': ['verified'],
102
+ 'inactive': ['active'],
103
+ 'disabledFeatures': ['enabledFeatures'],
104
+ 'inactiveUsers': ['activeUsers'],
105
+ 'disableFeature': ['enableFeature'],
106
+ 'disableAccount': ['enableAccount'],
107
+ 'blockUser': ['allowUser'],
108
+ 'preventAccess': ['allowAccess', 'enableAccess'],
109
+ 'restrictAccess': ['allowAccess', 'grantAccess'],
110
+ 'limitations': ['capabilities', 'features'],
111
+ 'limitation': ['capability', 'feature'],
112
+ };
113
+ exports.enforcePositiveNaming = (0, createRule_1.createRule)({
114
+ name: 'enforce-positive-naming',
115
+ meta: {
116
+ type: 'suggestion',
117
+ docs: {
118
+ description: 'Enforce positive variable naming patterns and avoid negative naming',
119
+ recommended: 'error',
120
+ },
121
+ schema: [],
122
+ messages: {
123
+ avoidNegativeNaming: 'Avoid negative naming "{{name}}". Consider using a positive alternative like: {{alternatives}}',
124
+ },
125
+ },
126
+ defaultOptions: [],
127
+ create(context) {
128
+ /**
129
+ * Check if a name has negative connotations
130
+ */
131
+ function hasNegativeNaming(name) {
132
+ // Skip checking if the name is in the whitelist
133
+ if (ALLOWED_NEGATIVE_TERMS.has(name)) {
134
+ return { isNegative: false, alternatives: [] };
135
+ }
136
+ // Check for exact matches in our alternatives map first
137
+ if (POSITIVE_ALTERNATIVES[name]) {
138
+ return { isNegative: true, alternatives: POSITIVE_ALTERNATIVES[name] };
139
+ }
140
+ // Check for negative prefixes
141
+ for (const prefix of NEGATIVE_PREFIXES) {
142
+ // Check for patterns like isNot, hasNo, canNot, etc.
143
+ const prefixPatterns = [
144
+ { pattern: new RegExp(`^is${prefix}`, 'i'), key: `is${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
145
+ { pattern: new RegExp(`^has${prefix}`, 'i'), key: `has${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
146
+ { pattern: new RegExp(`^can${prefix}`, 'i'), key: `can${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
147
+ { pattern: new RegExp(`^should${prefix}`, 'i'), key: `should${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
148
+ { pattern: new RegExp(`^will${prefix}`, 'i'), key: `will${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
149
+ { pattern: new RegExp(`^does${prefix}`, 'i'), key: `does${prefix.charAt(0).toUpperCase() + prefix.slice(1)}` },
150
+ ];
151
+ for (const { pattern, key } of prefixPatterns) {
152
+ if (pattern.test(name)) {
153
+ // If we have a direct match for this pattern (like isNotVerified -> isVerified)
154
+ const directMatch = POSITIVE_ALTERNATIVES[name];
155
+ if (directMatch) {
156
+ return { isNegative: true, alternatives: directMatch };
157
+ }
158
+ const alternatives = POSITIVE_ALTERNATIVES[key] || [];
159
+ if (alternatives.length > 0) {
160
+ // Suggest the positive version with the rest of the name
161
+ const restOfName = name.replace(pattern, '');
162
+ const suggestedAlternatives = alternatives.map(alt => `${alt}${restOfName.charAt(0).toUpperCase() + restOfName.slice(1)}`);
163
+ return { isNegative: true, alternatives: suggestedAlternatives };
164
+ }
165
+ return { isNegative: true, alternatives: ['a positive alternative'] };
166
+ }
167
+ }
168
+ }
169
+ // Check for exact negative words
170
+ for (const word of NEGATIVE_WORDS) {
171
+ if (name.toLowerCase() === word.toLowerCase()) {
172
+ const alternatives = POSITIVE_ALTERNATIVES[word] || [];
173
+ return {
174
+ isNegative: true,
175
+ alternatives: alternatives.length ? alternatives : ['a positive alternative']
176
+ };
177
+ }
178
+ }
179
+ // Check for negative words in camelCase/PascalCase
180
+ for (const word of NEGATIVE_WORDS) {
181
+ // Match the word at the beginning or after a capital letter
182
+ const pattern = new RegExp(`(^|[A-Z])${word}($|[A-Z])`, 'i');
183
+ if (pattern.test(name)) {
184
+ // For compound names like isInvalid, check if we have a specific suggestion
185
+ const exactMatch = `is${word.charAt(0).toUpperCase() + word.slice(1)}`;
186
+ if (POSITIVE_ALTERNATIVES[exactMatch]) {
187
+ return { isNegative: true, alternatives: POSITIVE_ALTERNATIVES[exactMatch] };
188
+ }
189
+ // Otherwise suggest general alternatives for the negative word
190
+ const alternatives = POSITIVE_ALTERNATIVES[word] || [];
191
+ return {
192
+ isNegative: true,
193
+ alternatives: alternatives.length ? alternatives : ['a positive alternative']
194
+ };
195
+ }
196
+ }
197
+ return { isNegative: false, alternatives: [] };
198
+ }
199
+ /**
200
+ * Check variable declarations for negative naming
201
+ */
202
+ function checkVariableDeclaration(node) {
203
+ if (node.id.type !== utils_1.AST_NODE_TYPES.Identifier)
204
+ return;
205
+ const variableName = node.id.name;
206
+ const { isNegative, alternatives } = hasNegativeNaming(variableName);
207
+ if (isNegative) {
208
+ context.report({
209
+ node: node.id,
210
+ messageId: 'avoidNegativeNaming',
211
+ data: {
212
+ name: variableName,
213
+ alternatives: alternatives.join(', '),
214
+ },
215
+ });
216
+ }
217
+ }
218
+ /**
219
+ * Check function declarations for negative naming
220
+ */
221
+ function checkFunctionDeclaration(node) {
222
+ // Skip anonymous functions
223
+ if (!node.id && node.parent?.type !== utils_1.AST_NODE_TYPES.VariableDeclarator) {
224
+ return;
225
+ }
226
+ // Get function name from either the function declaration or variable declarator
227
+ let functionName = '';
228
+ if (node.id) {
229
+ functionName = node.id.name;
230
+ }
231
+ else if (node.parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator &&
232
+ node.parent.id.type === utils_1.AST_NODE_TYPES.Identifier) {
233
+ functionName = node.parent.id.name;
234
+ }
235
+ else if (node.parent?.type === utils_1.AST_NODE_TYPES.Property &&
236
+ node.parent.key.type === utils_1.AST_NODE_TYPES.Identifier) {
237
+ // Handle object method shorthand
238
+ functionName = node.parent.key.name;
239
+ }
240
+ if (!functionName)
241
+ return;
242
+ const { isNegative, alternatives } = hasNegativeNaming(functionName);
243
+ if (isNegative) {
244
+ context.report({
245
+ node: node.id || node,
246
+ messageId: 'avoidNegativeNaming',
247
+ data: {
248
+ name: functionName,
249
+ alternatives: alternatives.join(', '),
250
+ },
251
+ });
252
+ }
253
+ }
254
+ /**
255
+ * Check method definitions for negative naming
256
+ */
257
+ function checkMethodDefinition(node) {
258
+ if (node.key.type !== utils_1.AST_NODE_TYPES.Identifier)
259
+ return;
260
+ const methodName = node.key.name;
261
+ const { isNegative, alternatives } = hasNegativeNaming(methodName);
262
+ if (isNegative) {
263
+ context.report({
264
+ node: node.key,
265
+ messageId: 'avoidNegativeNaming',
266
+ data: {
267
+ name: methodName,
268
+ alternatives: alternatives.join(', '),
269
+ },
270
+ });
271
+ }
272
+ }
273
+ /**
274
+ * Check property definitions for negative naming
275
+ */
276
+ function checkProperty(node) {
277
+ if (node.key.type !== utils_1.AST_NODE_TYPES.Identifier)
278
+ return;
279
+ const propertyName = node.key.name;
280
+ const { isNegative, alternatives } = hasNegativeNaming(propertyName);
281
+ if (isNegative) {
282
+ context.report({
283
+ node: node.key,
284
+ messageId: 'avoidNegativeNaming',
285
+ data: {
286
+ name: propertyName,
287
+ alternatives: alternatives.join(', '),
288
+ },
289
+ });
290
+ }
291
+ }
292
+ /**
293
+ * Check TSPropertySignature for negative naming (in interfaces)
294
+ */
295
+ function checkPropertySignature(node) {
296
+ if (node.key.type !== utils_1.AST_NODE_TYPES.Identifier)
297
+ return;
298
+ const propertyName = node.key.name;
299
+ const { isNegative, alternatives } = hasNegativeNaming(propertyName);
300
+ if (isNegative) {
301
+ context.report({
302
+ node: node.key,
303
+ messageId: 'avoidNegativeNaming',
304
+ data: {
305
+ name: propertyName,
306
+ alternatives: alternatives.join(', '),
307
+ },
308
+ });
309
+ }
310
+ }
311
+ /**
312
+ * Check parameter names for negative naming
313
+ */
314
+ function checkParameter(node) {
315
+ if (node.type !== utils_1.AST_NODE_TYPES.Identifier)
316
+ return;
317
+ const paramName = node.name;
318
+ const { isNegative, alternatives } = hasNegativeNaming(paramName);
319
+ if (isNegative) {
320
+ context.report({
321
+ node,
322
+ messageId: 'avoidNegativeNaming',
323
+ data: {
324
+ name: paramName,
325
+ alternatives: alternatives.join(', '),
326
+ },
327
+ });
328
+ }
329
+ }
330
+ return {
331
+ VariableDeclarator: checkVariableDeclaration,
332
+ FunctionDeclaration: checkFunctionDeclaration,
333
+ // Only check function expressions when they're not part of a variable declaration
334
+ // to avoid duplicate errors
335
+ FunctionExpression(node) {
336
+ if (node.parent?.type !== utils_1.AST_NODE_TYPES.VariableDeclarator) {
337
+ checkFunctionDeclaration(node);
338
+ }
339
+ },
340
+ // Only check arrow function expressions when they're not part of a variable declaration
341
+ // to avoid duplicate errors
342
+ ArrowFunctionExpression(node) {
343
+ if (node.parent?.type !== utils_1.AST_NODE_TYPES.VariableDeclarator) {
344
+ checkFunctionDeclaration(node);
345
+ }
346
+ },
347
+ MethodDefinition: checkMethodDefinition,
348
+ Property: checkProperty,
349
+ TSPropertySignature: checkPropertySignature,
350
+ Identifier(node) {
351
+ // Check parameter names in function declarations
352
+ if (node.parent &&
353
+ (node.parent.type === utils_1.AST_NODE_TYPES.FunctionDeclaration ||
354
+ node.parent.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
355
+ node.parent.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression) &&
356
+ node.parent.params.includes(node)) {
357
+ checkParameter(node);
358
+ }
359
+ },
360
+ };
361
+ },
362
+ });
363
+ //# sourceMappingURL=enforce-positive-naming.js.map
@@ -0,0 +1,8 @@
1
+ type Options = [
2
+ {
3
+ enforceDestructuring?: boolean;
4
+ ignoreExternalInterfaces?: boolean;
5
+ }
6
+ ];
7
+ export declare const enforcePropsArgumentName: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"usePropsForType", Options, import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
8
+ export {};
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforcePropsArgumentName = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const defaultOptions = {
7
+ enforceDestructuring: false,
8
+ ignoreExternalInterfaces: true,
9
+ };
10
+ exports.enforcePropsArgumentName = (0, createRule_1.createRule)({
11
+ name: 'enforce-props-argument-name',
12
+ meta: {
13
+ type: 'suggestion',
14
+ docs: {
15
+ description: 'Enforce using "Props" suffix in type names for parameter objects',
16
+ recommended: 'error',
17
+ },
18
+ fixable: 'code',
19
+ schema: [
20
+ {
21
+ type: 'object',
22
+ properties: {
23
+ enforceDestructuring: {
24
+ type: 'boolean',
25
+ },
26
+ ignoreExternalInterfaces: {
27
+ type: 'boolean',
28
+ },
29
+ },
30
+ additionalProperties: false,
31
+ },
32
+ ],
33
+ messages: {
34
+ usePropsForType: 'Use "Props" suffix in type name instead of "{{ typeSuffix }}"',
35
+ },
36
+ },
37
+ defaultOptions: [defaultOptions],
38
+ create(context, [options]) {
39
+ const finalOptions = { ...defaultOptions, ...options };
40
+ // Check if a node is from an external library
41
+ function isFromExternalLibrary(node) {
42
+ if (!finalOptions.ignoreExternalInterfaces) {
43
+ return false;
44
+ }
45
+ let current = node;
46
+ while (current.parent) {
47
+ if (current.type === utils_1.AST_NODE_TYPES.TSInterfaceDeclaration) {
48
+ // Check if the interface extends something from an external library
49
+ const interfaceDecl = current;
50
+ if (interfaceDecl.extends && interfaceDecl.extends.length > 0) {
51
+ // Check if any of the extended interfaces are from external libraries
52
+ // This is a simplified check - a more robust implementation would trace imports
53
+ return true;
54
+ }
55
+ }
56
+ current = current.parent;
57
+ }
58
+ return false;
59
+ }
60
+ // Extract type name from a type annotation
61
+ function getTypeName(typeAnnotation) {
62
+ if (typeAnnotation.type === utils_1.AST_NODE_TYPES.TSTypeReference) {
63
+ const typeName = typeAnnotation.typeName;
64
+ if (typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
65
+ return typeName.name;
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ // Check if a type name has a non-"Props" suffix
71
+ function hasNonPropsSuffix(typeName) {
72
+ if (typeName.endsWith('Props')) {
73
+ return null;
74
+ }
75
+ const suffixes = ['Config', 'Settings', 'Options', 'Params', 'Parameters', 'Args', 'Arguments'];
76
+ for (const suffix of suffixes) {
77
+ if (typeName.endsWith(suffix)) {
78
+ return suffix;
79
+ }
80
+ }
81
+ return null;
82
+ }
83
+ // Fix type name
84
+ function fixTypeName(fixer, node, oldName, suffix) {
85
+ if (node.type === utils_1.AST_NODE_TYPES.TSTypeReference &&
86
+ node.typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
87
+ const baseName = oldName.slice(0, -suffix.length);
88
+ return fixer.replaceText(node.typeName, `${baseName}Props`);
89
+ }
90
+ return null;
91
+ }
92
+ // Check function parameters
93
+ function checkFunctionParams(node) {
94
+ if (node.params.length !== 1) {
95
+ return; // Only check functions with a single parameter
96
+ }
97
+ const param = node.params[0];
98
+ // 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)) {
102
+ return;
103
+ }
104
+ // Check if the parameter has a type annotation
105
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && param.typeAnnotation.typeAnnotation) {
106
+ const typeName = getTypeName(param.typeAnnotation.typeAnnotation);
107
+ if (typeName) {
108
+ const nonPropsSuffix = hasNonPropsSuffix(typeName);
109
+ if (nonPropsSuffix) {
110
+ context.report({
111
+ node: param.typeAnnotation.typeAnnotation,
112
+ messageId: 'usePropsForType',
113
+ data: { typeSuffix: nonPropsSuffix },
114
+ fix: (fixer) => fixTypeName(fixer, param.typeAnnotation.typeAnnotation, typeName, nonPropsSuffix),
115
+ });
116
+ }
117
+ }
118
+ }
119
+ }
120
+ // Check class constructor parameters
121
+ function checkClassConstructor(node) {
122
+ if (node.kind !== 'constructor') {
123
+ return;
124
+ }
125
+ const constructor = node.value;
126
+ if (constructor.params.length !== 1) {
127
+ return; // Only check constructors with a single parameter
128
+ }
129
+ const param = constructor.params[0];
130
+ // 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)) {
134
+ return;
135
+ }
136
+ // Check if the parameter has a type annotation
137
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation && param.typeAnnotation.typeAnnotation) {
138
+ const typeName = getTypeName(param.typeAnnotation.typeAnnotation);
139
+ if (typeName) {
140
+ const nonPropsSuffix = hasNonPropsSuffix(typeName);
141
+ if (nonPropsSuffix) {
142
+ context.report({
143
+ node: param.typeAnnotation.typeAnnotation,
144
+ messageId: 'usePropsForType',
145
+ data: { typeSuffix: nonPropsSuffix },
146
+ fix: (fixer) => fixTypeName(fixer, param.typeAnnotation.typeAnnotation, typeName, nonPropsSuffix),
147
+ });
148
+ }
149
+ }
150
+ }
151
+ }
152
+ // Check type definitions
153
+ function checkTypeDefinition(node) {
154
+ if (!node.id || !node.id.name) {
155
+ return;
156
+ }
157
+ const typeName = node.id.name;
158
+ const nonPropsSuffix = hasNonPropsSuffix(typeName);
159
+ if (nonPropsSuffix && !isFromExternalLibrary(node)) {
160
+ const baseName = typeName.slice(0, -nonPropsSuffix.length);
161
+ const newTypeName = `${baseName}Props`;
162
+ context.report({
163
+ node: node.id,
164
+ messageId: 'usePropsForType',
165
+ data: { typeSuffix: nonPropsSuffix },
166
+ fix: (fixer) => {
167
+ return fixer.replaceText(node.id, newTypeName);
168
+ },
169
+ });
170
+ }
171
+ }
172
+ return {
173
+ FunctionDeclaration: checkFunctionParams,
174
+ FunctionExpression: checkFunctionParams,
175
+ ArrowFunctionExpression: checkFunctionParams,
176
+ TSMethodSignature: checkFunctionParams,
177
+ MethodDefinition: checkClassConstructor,
178
+ TSTypeAliasDeclaration: checkTypeDefinition,
179
+ };
180
+ },
181
+ });
182
+ //# sourceMappingURL=enforce-props-argument-name.js.map