@blumintinc/eslint-plugin-blumint 1.6.0 → 1.7.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.
@@ -91,6 +91,7 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
91
91
  }
92
92
  function isBuiltInType(typeName) {
93
93
  const builtInTypes = new Set([
94
+ // Primitive types
94
95
  'string',
95
96
  'number',
96
97
  'boolean',
@@ -101,6 +102,9 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
101
102
  'never',
102
103
  'unknown',
103
104
  'object',
105
+ 'symbol',
106
+ 'bigint',
107
+ // Built-in objects
104
108
  'Date',
105
109
  'RegExp',
106
110
  'Error',
@@ -113,6 +117,259 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
113
117
  'Set',
114
118
  'WeakMap',
115
119
  'WeakSet',
120
+ 'Proxy',
121
+ 'DataView',
122
+ 'ArrayBuffer',
123
+ 'SharedArrayBuffer',
124
+ 'Atomics',
125
+ 'Intl',
126
+ 'JSON',
127
+ 'Math',
128
+ 'Reflect',
129
+ 'WeakRef',
130
+ 'FinalizationRegistry',
131
+ // TypeScript utility types
132
+ 'Record',
133
+ 'Partial',
134
+ 'Required',
135
+ 'Readonly',
136
+ 'Pick',
137
+ 'Omit',
138
+ 'Exclude',
139
+ 'Extract',
140
+ 'NonNullable',
141
+ 'Parameters',
142
+ 'ConstructorParameters',
143
+ 'ReturnType',
144
+ 'InstanceType',
145
+ 'ThisParameterType',
146
+ 'OmitThisParameter',
147
+ 'ThisType',
148
+ 'Uppercase',
149
+ 'Lowercase',
150
+ 'Capitalize',
151
+ 'Uncapitalize',
152
+ 'Awaited',
153
+ 'PropertyKey',
154
+ 'Mutable',
155
+ 'DeepPartial',
156
+ 'DeepReadonly',
157
+ 'DeepRequired',
158
+ 'Merge',
159
+ 'MergeExclusive',
160
+ 'OptionalKeys',
161
+ 'RequiredKeys',
162
+ 'ReadonlyKeys',
163
+ 'WritableKeys',
164
+ 'UnionToIntersection',
165
+ 'UnionToTuple',
166
+ 'Promisable',
167
+ // React types
168
+ 'ReactElement',
169
+ 'ReactNode',
170
+ 'ReactChild',
171
+ 'ReactChildren',
172
+ 'ReactFragment',
173
+ 'ReactPortal',
174
+ 'ReactText',
175
+ 'JSX',
176
+ 'JSXElement',
177
+ 'JSXElementConstructor',
178
+ 'ComponentType',
179
+ 'ComponentProps',
180
+ 'ComponentRef',
181
+ 'ElementType',
182
+ 'ElementRef',
183
+ 'Ref',
184
+ 'RefObject',
185
+ 'RefCallback',
186
+ 'LegacyRef',
187
+ 'PropsWithRef',
188
+ 'PropsWithChildren',
189
+ 'PropsWithoutRef',
190
+ 'FC',
191
+ 'FunctionComponent',
192
+ 'VFC',
193
+ 'VoidFunctionComponent',
194
+ 'ForwardRefRenderFunction',
195
+ 'ForwardRefExoticComponent',
196
+ 'MutableRefObject',
197
+ 'ClassAttributes',
198
+ 'DOMAttributes',
199
+ 'CSSProperties',
200
+ 'StyleHTMLAttributes',
201
+ 'AriaAttributes',
202
+ 'DOMElement',
203
+ 'ReactHTML',
204
+ 'ReactSVG',
205
+ // Node.js types
206
+ 'Buffer',
207
+ 'ReadableStream',
208
+ 'WritableStream',
209
+ 'DuplexStream',
210
+ 'TransformStream',
211
+ 'ReadStream',
212
+ 'WriteStream',
213
+ 'EventEmitter',
214
+ 'Timeout',
215
+ 'Immediate',
216
+ 'NodeJS',
217
+ 'Process',
218
+ 'Global',
219
+ // DOM types
220
+ 'HTMLElement',
221
+ 'Element',
222
+ 'Node',
223
+ 'Document',
224
+ 'Window',
225
+ 'Event',
226
+ 'CustomEvent',
227
+ 'MouseEvent',
228
+ 'KeyboardEvent',
229
+ 'TouchEvent',
230
+ 'DragEvent',
231
+ 'ClipboardEvent',
232
+ 'FocusEvent',
233
+ 'FormEvent',
234
+ 'ChangeEvent',
235
+ 'AnimationEvent',
236
+ 'TransitionEvent',
237
+ 'SVGElement',
238
+ 'File',
239
+ 'FileList',
240
+ 'Blob',
241
+ 'URL',
242
+ 'URLSearchParams',
243
+ 'FormData',
244
+ 'Headers',
245
+ 'Request',
246
+ 'Response',
247
+ 'WebSocket',
248
+ 'Worker',
249
+ 'ServiceWorker',
250
+ 'MessagePort',
251
+ 'Storage',
252
+ 'CSSStyleDeclaration',
253
+ // Common library types
254
+ 'Observable',
255
+ 'Subscription',
256
+ 'Subject',
257
+ 'BehaviorSubject',
258
+ 'ReplaySubject',
259
+ 'AsyncSubject',
260
+ 'Observer',
261
+ 'Operator',
262
+ 'Scheduler',
263
+ 'Unsubscribable',
264
+ 'SubscriptionLike',
265
+ 'TeardownLogic',
266
+ 'MonoTypeOperatorFunction',
267
+ 'OperatorFunction',
268
+ 'UnaryFunction',
269
+ 'Action',
270
+ 'AnyAction',
271
+ 'Dispatch',
272
+ 'Reducer',
273
+ 'Store',
274
+ 'Middleware',
275
+ 'Selector',
276
+ 'ThunkAction',
277
+ 'ThunkDispatch',
278
+ 'Query',
279
+ 'Mutation',
280
+ 'QueryResult',
281
+ 'MutationResult',
282
+ 'UseQueryResult',
283
+ 'UseMutationResult',
284
+ 'UseInfiniteQueryResult',
285
+ 'Schema',
286
+ 'Model',
287
+ 'Document',
288
+ 'ObjectId',
289
+ 'Collection',
290
+ 'Db',
291
+ 'Client',
292
+ 'Session',
293
+ 'Transaction',
294
+ 'ValidationError',
295
+ 'ValidationResult',
296
+ 'Validator',
297
+ 'Logger',
298
+ 'LogLevel',
299
+ 'Options',
300
+ 'Settings',
301
+ 'Context',
302
+ 'Next',
303
+ 'Middleware',
304
+ 'Route',
305
+ 'Router',
306
+ 'Handler',
307
+ 'Controller',
308
+ 'Service',
309
+ 'Repository',
310
+ 'Entity',
311
+ 'DTO',
312
+ 'Enum',
313
+ 'Union',
314
+ 'Intersection',
315
+ 'Tuple',
316
+ 'Readonly',
317
+ 'ReadonlyArray',
318
+ 'ReadonlyMap',
319
+ 'ReadonlySet',
320
+ 'Iterable',
321
+ 'Iterator',
322
+ 'Generator',
323
+ 'AsyncIterator',
324
+ 'AsyncGenerator',
325
+ 'Thenable',
326
+ 'PromiseLike',
327
+ 'ArrayLike',
328
+ 'Indexable',
329
+ 'Nullable',
330
+ 'Optional',
331
+ 'NonOptional',
332
+ 'NonNullable',
333
+ 'NonUndefined',
334
+ 'NonVoid',
335
+ 'NonEmptyArray',
336
+ 'DeepReadonly',
337
+ 'DeepPartial',
338
+ 'DeepRequired',
339
+ 'DeepNonNullable',
340
+ 'DeepMutable',
341
+ 'Primitive',
342
+ 'Nullish',
343
+ 'Falsy',
344
+ 'Truthy',
345
+ 'Exact',
346
+ 'Strict',
347
+ 'Loose',
348
+ 'Writable',
349
+ 'Mutable',
350
+ 'Immutable',
351
+ 'Frozen',
352
+ 'Sealed',
353
+ 'Extensible',
354
+ 'Constructable',
355
+ 'Abstract',
356
+ 'Concrete',
357
+ 'Override',
358
+ 'Overwrite',
359
+ 'OmitByValue',
360
+ 'PickByValue',
361
+ 'RequiredBy',
362
+ 'OptionalBy',
363
+ 'ReadonlyBy',
364
+ 'MutableBy',
365
+ 'NullableBy',
366
+ 'NonNullableBy',
367
+ 'UndefinedBy',
368
+ 'NonUndefinedBy',
369
+ 'NeverBy',
370
+ 'UnknownBy',
371
+ 'AnyBy',
372
+ 'VoidBy',
116
373
  ]);
117
374
  return builtInTypes.has(typeName);
118
375
  }
@@ -135,7 +392,16 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
135
392
  }
136
393
  }
137
394
  }
395
+ function checkAndReportParameterType(param, messageId) {
396
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
397
+ checkAndReportType(param.typeAnnotation.typeAnnotation, param.typeAnnotation, messageId);
398
+ }
399
+ }
138
400
  function isTypeExported(typeName) {
401
+ // If it's a built-in type, consider it as "exported"
402
+ if (isBuiltInType(typeName)) {
403
+ return true;
404
+ }
139
405
  const sourceCode = context.getSourceCode();
140
406
  const program = sourceCode.ast;
141
407
  // Check for imported types first - if found, return true immediately
@@ -159,6 +425,11 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
159
425
  if (node.declaration?.type === utils_1.AST_NODE_TYPES.TSInterfaceDeclaration) {
160
426
  return node.declaration.id.name === typeName;
161
427
  }
428
+ // Check for export { Type } statements
429
+ if (node.specifiers) {
430
+ return node.specifiers.some((specifier) => specifier.type === utils_1.AST_NODE_TYPES.ExportSpecifier &&
431
+ specifier.local.name === typeName);
432
+ }
162
433
  }
163
434
  return false;
164
435
  });
@@ -186,15 +457,49 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
186
457
  }
187
458
  // Handle type aliases in variable declarations
188
459
  if (parent.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) {
460
+ // Check if the type alias itself is exported
189
461
  if (parent.parent?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) {
190
462
  return true;
191
463
  }
464
+ // If not exported, return false
465
+ return false;
192
466
  }
193
467
  // Handle type aliases in interface declarations
194
468
  if (parent.type === utils_1.AST_NODE_TYPES.TSInterfaceDeclaration) {
469
+ // Check if the interface itself is exported
195
470
  if (parent.parent?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) {
196
471
  return true;
197
472
  }
473
+ // If not exported, return false
474
+ return false;
475
+ }
476
+ // Handle type aliases in variable declarations
477
+ if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
478
+ if (parent.parent?.type === utils_1.AST_NODE_TYPES.VariableDeclaration) {
479
+ if (parent.parent.parent?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) {
480
+ return true;
481
+ }
482
+ }
483
+ }
484
+ // Handle type aliases in type declarations
485
+ if (parent.type === utils_1.AST_NODE_TYPES.Identifier) {
486
+ if (parent.parent?.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) {
487
+ // Check if the type alias itself is exported
488
+ if (parent.parent.parent?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) {
489
+ return true;
490
+ }
491
+ // If not exported, return false
492
+ return false;
493
+ }
494
+ }
495
+ // Handle type aliases in type declarations
496
+ if (def.node.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) {
497
+ // Check if the type alias itself is exported
498
+ if (def.node.parent?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration) {
499
+ return true;
500
+ }
501
+ // If not exported, return false
502
+ return false;
198
503
  }
199
504
  return false;
200
505
  }
@@ -211,10 +516,7 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
211
516
  }
212
517
  // Check parameter types
213
518
  node.params.forEach((param) => {
214
- if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
215
- param.typeAnnotation) {
216
- checkAndReportType(param.typeAnnotation.typeAnnotation, param.typeAnnotation, 'missingExportedType');
217
- }
519
+ checkAndReportParameterType(param, 'missingExportedType');
218
520
  });
219
521
  },
220
522
  'VariableDeclarator > ArrowFunctionExpression'(node) {
@@ -231,10 +533,7 @@ exports.enforceExportedFunctionTypes = (0, createRule_1.createRule)({
231
533
  }
232
534
  // Check parameter types
233
535
  node.params.forEach((param) => {
234
- if (param.type === utils_1.AST_NODE_TYPES.Identifier &&
235
- param.typeAnnotation) {
236
- checkAndReportType(param.typeAnnotation.typeAnnotation, param.typeAnnotation, 'missingExportedType');
237
- }
536
+ checkAndReportParameterType(param, 'missingExportedType');
238
537
  });
239
538
  },
240
539
  // Handle React components
@@ -0,0 +1,3 @@
1
+ type MessageIds = 'requireMemoizedTransformBefore' | 'requireMemoizedRender' | 'requireMemoizedRenderHits' | 'noDirectComponentInRender';
2
+ export declare const enforceRenderHitsMemoization: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<MessageIds, [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
3
+ export {};
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceRenderHitsMemoization = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ exports.enforceRenderHitsMemoization = (0, createRule_1.createRule)({
7
+ name: 'enforce-render-hits-memoization',
8
+ meta: {
9
+ type: 'problem',
10
+ docs: {
11
+ description: 'Enforce proper memoization and usage of useRenderHits and renderHits',
12
+ recommended: 'error',
13
+ },
14
+ schema: [],
15
+ messages: {
16
+ requireMemoizedTransformBefore: 'transformBefore prop must be memoized using useCallback',
17
+ requireMemoizedRender: 'render prop must be memoized using useCallback',
18
+ requireMemoizedRenderHits: 'renderHits must be used inside useMemo or useCallback',
19
+ noDirectComponentInRender: 'Do not pass React components directly to render prop, use a memoized arrow function instead',
20
+ },
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ const isMemoizedCall = (node) => {
25
+ if (node.type !== utils_1.AST_NODE_TYPES.CallExpression)
26
+ return false;
27
+ const callee = node.callee;
28
+ if (callee.type !== utils_1.AST_NODE_TYPES.Identifier)
29
+ return false;
30
+ return callee.name === 'useCallback' || callee.name === 'useMemo';
31
+ };
32
+ const isReactComponent = (node) => {
33
+ if (node.type !== utils_1.AST_NODE_TYPES.Identifier)
34
+ return false;
35
+ const name = node.name;
36
+ return /^[A-Z]/.test(name);
37
+ };
38
+ const isInsideMemoizedCall = (node) => {
39
+ let current = node;
40
+ while (current?.parent) {
41
+ if (isMemoizedCall(current.parent))
42
+ return true;
43
+ current = current.parent;
44
+ }
45
+ return false;
46
+ };
47
+ return {
48
+ CallExpression(node) {
49
+ if (node.callee.type === utils_1.AST_NODE_TYPES.Identifier && node.callee.name === 'useRenderHits') {
50
+ if (node.arguments.length === 0)
51
+ return;
52
+ const options = node.arguments[0];
53
+ if (options.type !== utils_1.AST_NODE_TYPES.ObjectExpression)
54
+ return;
55
+ for (const prop of options.properties) {
56
+ if (prop.type !== utils_1.AST_NODE_TYPES.Property)
57
+ continue;
58
+ if (prop.key.type !== utils_1.AST_NODE_TYPES.Identifier)
59
+ continue;
60
+ if (prop.key.name === 'transformBefore') {
61
+ if (!isInsideMemoizedCall(prop.value)) {
62
+ context.report({
63
+ node: prop.value,
64
+ messageId: 'requireMemoizedTransformBefore',
65
+ });
66
+ }
67
+ }
68
+ if (prop.key.name === 'render') {
69
+ if (isReactComponent(prop.value)) {
70
+ context.report({
71
+ node: prop.value,
72
+ messageId: 'noDirectComponentInRender',
73
+ });
74
+ }
75
+ else if (!isInsideMemoizedCall(prop.value)) {
76
+ context.report({
77
+ node: prop.value,
78
+ messageId: 'requireMemoizedRender',
79
+ });
80
+ }
81
+ }
82
+ }
83
+ }
84
+ if (node.callee.type === utils_1.AST_NODE_TYPES.Identifier && node.callee.name === 'renderHits') {
85
+ if (!isInsideMemoizedCall(node)) {
86
+ context.report({
87
+ node,
88
+ messageId: 'requireMemoizedRenderHits',
89
+ });
90
+ }
91
+ }
92
+ },
93
+ };
94
+ },
95
+ });
96
+ //# sourceMappingURL=enforce-render-hits-memoization.js.map
@@ -69,6 +69,7 @@ const VERBS_SET = new Set([
69
69
  'auto',
70
70
  'avoid',
71
71
  'back',
72
+ 'backfill',
72
73
  'backup',
73
74
  'bake',
74
75
  'balance',
@@ -40,6 +40,10 @@ function isImmutableValue(node) {
40
40
  function isMutableValue(node) {
41
41
  if (!node)
42
42
  return false;
43
+ // Check for JSX elements (always mutable due to props/context)
44
+ if (node.type === 'JSXElement' || node.type === 'JSXFragment') {
45
+ return true;
46
+ }
43
47
  // Check for object expressions (always mutable)
44
48
  if (node.type === 'ObjectExpression') {
45
49
  return true;
@@ -49,6 +49,12 @@ function getObjectUsagesInHook(hookBody, objectName) {
49
49
  const usages = new Set();
50
50
  const visited = new Set();
51
51
  let needsEntireObject = false;
52
+ // Built-in array methods that should not be considered as object properties
53
+ const ARRAY_METHODS = new Set([
54
+ 'map', 'filter', 'reduce', 'forEach', 'some', 'every', 'find', 'findIndex',
55
+ 'includes', 'indexOf', 'join', 'slice', 'splice', 'concat', 'push', 'pop',
56
+ 'shift', 'unshift', 'sort', 'reverse', 'flat', 'flatMap'
57
+ ]);
52
58
  function buildAccessPath(node) {
53
59
  const parts = [];
54
60
  let current = node;
@@ -62,6 +68,10 @@ function getObjectUsagesInHook(hookBody, objectName) {
62
68
  if (memberExpr.property.type !== utils_1.AST_NODE_TYPES.Identifier) {
63
69
  return null;
64
70
  }
71
+ // Skip array methods
72
+ if (memberExpr.property.name && ARRAY_METHODS.has(memberExpr.property.name)) {
73
+ return null;
74
+ }
65
75
  parts.unshift(memberExpr.property.name);
66
76
  if (memberExpr.optional) {
67
77
  hasOptionalChaining = true;
@@ -0,0 +1 @@
1
+ export declare const noFirestoreJestMock: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"noFirestoreJestMock", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noFirestoreJestMock = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ exports.noFirestoreJestMock = (0, createRule_1.createRule)({
7
+ name: 'no-firestore-jest-mock',
8
+ meta: {
9
+ type: 'problem',
10
+ docs: {
11
+ description: 'Prevent importing firestore-jest-mock in test files',
12
+ recommended: 'error',
13
+ },
14
+ fixable: 'code',
15
+ schema: [],
16
+ messages: {
17
+ noFirestoreJestMock: 'Do not import from firestore-jest-mock. Use mockFirestore from the centralized mock utility instead.',
18
+ },
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const filename = context.getFilename();
23
+ // Only apply rule to test files
24
+ if (!filename.endsWith('.test.ts')) {
25
+ return {};
26
+ }
27
+ return {
28
+ ImportDeclaration(node) {
29
+ if (node.source.value === 'firestore-jest-mock') {
30
+ context.report({
31
+ node,
32
+ messageId: 'noFirestoreJestMock',
33
+ fix(fixer) {
34
+ // Replace with mockFirestore import
35
+ return fixer.replaceText(node, "import { mockFirestore } from '../../../../../__mocks__/functions/src/config/mockFirestore';");
36
+ },
37
+ });
38
+ }
39
+ },
40
+ CallExpression(node) {
41
+ // Check for jest.mock('firestore-jest-mock')
42
+ if (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
43
+ node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
44
+ node.callee.object.name === 'jest' &&
45
+ node.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
46
+ node.callee.property.name === 'mock' &&
47
+ node.arguments.length > 0 &&
48
+ node.arguments[0].type === utils_1.AST_NODE_TYPES.Literal &&
49
+ node.arguments[0].value === 'firestore-jest-mock') {
50
+ context.report({
51
+ node,
52
+ messageId: 'noFirestoreJestMock',
53
+ });
54
+ }
55
+ },
56
+ };
57
+ },
58
+ });
59
+ //# sourceMappingURL=no-firestore-jest-mock.js.map
@@ -0,0 +1 @@
1
+ export declare const noMockFirebaseAdmin: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"noMockFirebaseAdmin", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noMockFirebaseAdmin = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const FIREBASE_ADMIN_PATHS = [
7
+ '../../config/firebaseAdmin',
8
+ '../config/firebaseAdmin',
9
+ './config/firebaseAdmin',
10
+ 'functions/src/config/firebaseAdmin',
11
+ ];
12
+ exports.noMockFirebaseAdmin = (0, createRule_1.createRule)({
13
+ name: 'no-mock-firebase-admin',
14
+ meta: {
15
+ type: 'problem',
16
+ docs: {
17
+ description: 'Prevent mocking of functions/src/config/firebaseAdmin',
18
+ recommended: 'error',
19
+ },
20
+ schema: [],
21
+ messages: {
22
+ noMockFirebaseAdmin: 'Do not mock firebaseAdmin directly. Use mockFirestore from __mocks__/functions/src/config/mockFirestore instead.',
23
+ },
24
+ },
25
+ defaultOptions: [],
26
+ create(context) {
27
+ return {
28
+ CallExpression(node) {
29
+ if (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
30
+ node.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
31
+ node.callee.object.name === 'jest' &&
32
+ node.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
33
+ node.callee.property.name === 'mock' &&
34
+ node.arguments.length > 0 &&
35
+ node.arguments[0].type === utils_1.AST_NODE_TYPES.Literal &&
36
+ typeof node.arguments[0].value === 'string') {
37
+ const mockPath = node.arguments[0].value;
38
+ const isFirebaseAdminMock = FIREBASE_ADMIN_PATHS.some(path => mockPath.endsWith(path) || mockPath.includes('firebaseAdmin'));
39
+ if (isFirebaseAdminMock) {
40
+ context.report({
41
+ node,
42
+ messageId: 'noMockFirebaseAdmin',
43
+ });
44
+ }
45
+ }
46
+ },
47
+ };
48
+ },
49
+ });
50
+ //# sourceMappingURL=no-mock-firebase-admin.js.map