@tanstack/eslint-plugin-query 5.94.4 → 5.95.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 (48) hide show
  1. package/build/legacy/_tsup-dts-rollup.d.cts +329 -0
  2. package/build/legacy/_tsup-dts-rollup.d.ts +329 -0
  3. package/build/legacy/chunk-T44AUBX4.js +1344 -0
  4. package/build/legacy/chunk-T44AUBX4.js.map +1 -0
  5. package/build/legacy/index.cjs +1413 -0
  6. package/build/legacy/index.cjs.map +1 -0
  7. package/build/legacy/index.d.cts +3 -0
  8. package/build/legacy/index.d.ts +3 -0
  9. package/build/legacy/index.js +50 -0
  10. package/build/legacy/index.js.map +1 -0
  11. package/build/legacy/rules.cjs +1370 -0
  12. package/build/legacy/rules.cjs.map +1 -0
  13. package/build/legacy/rules.d.cts +1 -0
  14. package/build/legacy/rules.d.ts +1 -0
  15. package/build/legacy/rules.js +7 -0
  16. package/build/legacy/rules.js.map +1 -0
  17. package/build/legacy/types.cjs +19 -0
  18. package/build/legacy/types.cjs.map +1 -0
  19. package/build/legacy/types.d.cts +1 -0
  20. package/build/legacy/types.d.ts +1 -0
  21. package/build/legacy/types.js +1 -0
  22. package/build/legacy/types.js.map +1 -0
  23. package/build/modern/_tsup-dts-rollup.d.cts +329 -0
  24. package/build/modern/_tsup-dts-rollup.d.ts +329 -0
  25. package/build/modern/chunk-XH4ABCYA.js +1335 -0
  26. package/build/modern/chunk-XH4ABCYA.js.map +1 -0
  27. package/build/modern/index.cjs +1405 -0
  28. package/build/modern/index.cjs.map +1 -0
  29. package/build/modern/index.d.cts +3 -0
  30. package/build/modern/index.d.ts +3 -0
  31. package/build/modern/index.js +50 -0
  32. package/build/modern/index.js.map +1 -0
  33. package/build/modern/rules.cjs +1362 -0
  34. package/build/modern/rules.cjs.map +1 -0
  35. package/build/modern/rules.d.cts +1 -0
  36. package/build/modern/rules.d.ts +1 -0
  37. package/build/modern/rules.js +7 -0
  38. package/build/modern/rules.js.map +1 -0
  39. package/build/modern/types.cjs +20 -0
  40. package/build/modern/types.cjs.map +1 -0
  41. package/build/modern/types.d.cts +1 -0
  42. package/build/modern/types.d.ts +1 -0
  43. package/build/modern/types.js +1 -0
  44. package/build/modern/types.js.map +1 -0
  45. package/package.json +1 -1
  46. package/src/rules/exhaustive-deps/exhaustive-deps.rule.ts +136 -90
  47. package/src/rules/exhaustive-deps/exhaustive-deps.utils.ts +248 -22
  48. package/src/utils/ast-utils.ts +2 -25
@@ -0,0 +1,1344 @@
1
+ // src/rules/exhaustive-deps/exhaustive-deps.rule.ts
2
+ import { AST_NODE_TYPES as AST_NODE_TYPES3, ESLintUtils } from "@typescript-eslint/utils";
3
+
4
+ // src/utils/ast-utils.ts
5
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
6
+
7
+ // src/utils/unique-by.ts
8
+ function uniqueBy(arr, fn) {
9
+ return arr.filter((x, i, a) => a.findIndex((y) => fn(x) === fn(y)) === i);
10
+ }
11
+
12
+ // src/utils/ast-utils.ts
13
+ var ASTUtils = {
14
+ isNodeOfOneOf(node, types) {
15
+ return types.includes(node.type);
16
+ },
17
+ isIdentifier(node) {
18
+ return node.type === AST_NODE_TYPES.Identifier;
19
+ },
20
+ isIdentifierWithName(node, name8) {
21
+ return ASTUtils.isIdentifier(node) && node.name === name8;
22
+ },
23
+ isIdentifierWithOneOfNames(node, name8) {
24
+ return ASTUtils.isIdentifier(node) && name8.includes(node.name);
25
+ },
26
+ isProperty(node) {
27
+ return node.type === AST_NODE_TYPES.Property;
28
+ },
29
+ isObjectExpression(node) {
30
+ return node.type === AST_NODE_TYPES.ObjectExpression;
31
+ },
32
+ isPropertyWithIdentifierKey(node, key) {
33
+ return ASTUtils.isProperty(node) && ASTUtils.isIdentifierWithName(node.key, key);
34
+ },
35
+ findPropertyWithIdentifierKey(properties, key) {
36
+ return properties.find(
37
+ (x) => ASTUtils.isPropertyWithIdentifierKey(x, key)
38
+ );
39
+ },
40
+ getNestedIdentifiers(node) {
41
+ const identifiers = [];
42
+ if (ASTUtils.isIdentifier(node)) {
43
+ identifiers.push(node);
44
+ }
45
+ if ("arguments" in node) {
46
+ node.arguments.forEach((x) => {
47
+ identifiers.push(...ASTUtils.getNestedIdentifiers(x));
48
+ });
49
+ }
50
+ if ("elements" in node) {
51
+ node.elements.forEach((x) => {
52
+ if (x !== null) {
53
+ identifiers.push(...ASTUtils.getNestedIdentifiers(x));
54
+ }
55
+ });
56
+ }
57
+ if ("properties" in node) {
58
+ node.properties.forEach((x) => {
59
+ identifiers.push(...ASTUtils.getNestedIdentifiers(x));
60
+ });
61
+ }
62
+ if ("expressions" in node) {
63
+ node.expressions.forEach((x) => {
64
+ identifiers.push(...ASTUtils.getNestedIdentifiers(x));
65
+ });
66
+ }
67
+ if ("left" in node) {
68
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.left));
69
+ }
70
+ if ("right" in node) {
71
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.right));
72
+ }
73
+ if (node.type === AST_NODE_TYPES.Property) {
74
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.value));
75
+ }
76
+ if (node.type === AST_NODE_TYPES.SpreadElement) {
77
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument));
78
+ }
79
+ if (node.type === AST_NODE_TYPES.MemberExpression) {
80
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.object));
81
+ }
82
+ if (node.type === AST_NODE_TYPES.UnaryExpression) {
83
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument));
84
+ }
85
+ if (node.type === AST_NODE_TYPES.ChainExpression) {
86
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.expression));
87
+ }
88
+ if (node.type === AST_NODE_TYPES.TSNonNullExpression) {
89
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.expression));
90
+ }
91
+ if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
92
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.body));
93
+ }
94
+ if (node.type === AST_NODE_TYPES.FunctionExpression) {
95
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.body));
96
+ }
97
+ if (node.type === AST_NODE_TYPES.BlockStatement) {
98
+ identifiers.push(
99
+ ...node.body.map((body) => ASTUtils.getNestedIdentifiers(body)).flat()
100
+ );
101
+ }
102
+ if (node.type === AST_NODE_TYPES.ReturnStatement && node.argument) {
103
+ identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument));
104
+ }
105
+ return identifiers;
106
+ },
107
+ traverseUpOnly(identifier, allowedNodeTypes) {
108
+ const parent = identifier.parent;
109
+ if (parent !== void 0 && allowedNodeTypes.includes(parent.type)) {
110
+ return ASTUtils.traverseUpOnly(parent, allowedNodeTypes);
111
+ }
112
+ return identifier;
113
+ },
114
+ isDeclaredInNode(params) {
115
+ const { functionNode, reference, scopeManager } = params;
116
+ const scope = scopeManager.acquire(functionNode);
117
+ if (scope === null) {
118
+ return false;
119
+ }
120
+ return scope.set.has(reference.identifier.name);
121
+ },
122
+ getExternalRefs(params) {
123
+ const { scopeManager, sourceCode, node } = params;
124
+ const scope = scopeManager.acquire(node);
125
+ if (scope === null) {
126
+ return [];
127
+ }
128
+ const collectReferences = (currentScope) => {
129
+ const references2 = [...currentScope.references];
130
+ for (const childScope of currentScope.childScopes) {
131
+ references2.push(...collectReferences(childScope));
132
+ }
133
+ return references2;
134
+ };
135
+ const references = collectReferences(scope).filter((x) => x.isRead() && !scope.set.has(x.identifier.name)).map((x) => {
136
+ const referenceNode = ASTUtils.traverseUpOnly(x.identifier, [
137
+ AST_NODE_TYPES.MemberExpression,
138
+ AST_NODE_TYPES.Identifier
139
+ ]);
140
+ return {
141
+ variable: x,
142
+ node: referenceNode,
143
+ text: sourceCode.getText(referenceNode)
144
+ };
145
+ });
146
+ const localRefIds = new Set(
147
+ [...scope.set.values()].map((x) => sourceCode.getText(x.identifiers[0]))
148
+ );
149
+ const externalRefs = references.filter(
150
+ (x) => x.variable.resolved === null || !localRefIds.has(x.text)
151
+ );
152
+ return uniqueBy(externalRefs, (x) => x.text).map((x) => x.variable);
153
+ },
154
+ mapKeyNodeToText(node, sourceCode) {
155
+ return sourceCode.getText(
156
+ ASTUtils.traverseUpOnly(node, [
157
+ AST_NODE_TYPES.MemberExpression,
158
+ AST_NODE_TYPES.TSNonNullExpression,
159
+ AST_NODE_TYPES.Identifier
160
+ ])
161
+ );
162
+ },
163
+ mapKeyNodeToBaseText(node, sourceCode) {
164
+ return ASTUtils.mapKeyNodeToText(node, sourceCode).replace(
165
+ /(?:\?(\.)|!)/g,
166
+ "$1"
167
+ );
168
+ },
169
+ isValidReactComponentOrHookName(identifier) {
170
+ return identifier !== null && identifier !== void 0 && /^(use|[A-Z])/.test(identifier.name);
171
+ },
172
+ getFunctionAncestor(sourceCode, node) {
173
+ var _a;
174
+ for (const ancestor of sourceCode.getAncestors(node)) {
175
+ if (ASTUtils.isNodeOfOneOf(ancestor, [
176
+ AST_NODE_TYPES.FunctionDeclaration,
177
+ AST_NODE_TYPES.FunctionExpression,
178
+ AST_NODE_TYPES.ArrowFunctionExpression
179
+ ])) {
180
+ return ancestor;
181
+ }
182
+ if (((_a = ancestor.parent) == null ? void 0 : _a.type) === AST_NODE_TYPES.VariableDeclarator && ancestor.parent.id.type === AST_NODE_TYPES.Identifier && ASTUtils.isNodeOfOneOf(ancestor, [
183
+ AST_NODE_TYPES.FunctionDeclaration,
184
+ AST_NODE_TYPES.FunctionExpression,
185
+ AST_NODE_TYPES.ArrowFunctionExpression
186
+ ])) {
187
+ return ancestor;
188
+ }
189
+ }
190
+ return void 0;
191
+ },
192
+ getReferencedExpressionByIdentifier(params) {
193
+ var _a, _b, _c;
194
+ const { node, context } = params;
195
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
196
+ const scope = context.sourceCode.getScope(node) ? sourceCode.getScope(node) : context.getScope();
197
+ const resolvedNode = (_c = (_b = (_a = scope.references.find((ref) => ref.identifier === node)) == null ? void 0 : _a.resolved) == null ? void 0 : _b.defs[0]) == null ? void 0 : _c.node;
198
+ if ((resolvedNode == null ? void 0 : resolvedNode.type) !== AST_NODE_TYPES.VariableDeclarator) {
199
+ return null;
200
+ }
201
+ return resolvedNode.init;
202
+ },
203
+ getClosestVariableDeclarator(node) {
204
+ let currentNode = node;
205
+ while (currentNode.type !== AST_NODE_TYPES.Program) {
206
+ if (currentNode.type === AST_NODE_TYPES.VariableDeclarator) {
207
+ return currentNode;
208
+ }
209
+ currentNode = currentNode.parent;
210
+ }
211
+ return void 0;
212
+ },
213
+ getNestedReturnStatements(node) {
214
+ const returnStatements = [];
215
+ if (node.type === AST_NODE_TYPES.ReturnStatement) {
216
+ returnStatements.push(node);
217
+ }
218
+ if ("body" in node && node.body !== void 0 && node.body !== null) {
219
+ Array.isArray(node.body) ? node.body.forEach((x) => {
220
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(x));
221
+ }) : returnStatements.push(
222
+ ...ASTUtils.getNestedReturnStatements(node.body)
223
+ );
224
+ }
225
+ if ("consequent" in node) {
226
+ Array.isArray(node.consequent) ? node.consequent.forEach((x) => {
227
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(x));
228
+ }) : returnStatements.push(
229
+ ...ASTUtils.getNestedReturnStatements(node.consequent)
230
+ );
231
+ }
232
+ if ("alternate" in node && node.alternate !== null) {
233
+ Array.isArray(node.alternate) ? node.alternate.forEach((x) => {
234
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(x));
235
+ }) : returnStatements.push(
236
+ ...ASTUtils.getNestedReturnStatements(node.alternate)
237
+ );
238
+ }
239
+ if ("cases" in node) {
240
+ node.cases.forEach((x) => {
241
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(x));
242
+ });
243
+ }
244
+ if ("block" in node) {
245
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(node.block));
246
+ }
247
+ if ("handler" in node && node.handler !== null) {
248
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(node.handler));
249
+ }
250
+ if ("finalizer" in node && node.finalizer !== null) {
251
+ returnStatements.push(
252
+ ...ASTUtils.getNestedReturnStatements(node.finalizer)
253
+ );
254
+ }
255
+ if ("expression" in node && node.expression !== true && node.expression !== false) {
256
+ returnStatements.push(
257
+ ...ASTUtils.getNestedReturnStatements(node.expression)
258
+ );
259
+ }
260
+ if ("test" in node && node.test !== null) {
261
+ returnStatements.push(...ASTUtils.getNestedReturnStatements(node.test));
262
+ }
263
+ return returnStatements;
264
+ }
265
+ };
266
+
267
+ // src/utils/get-docs-url.ts
268
+ var getDocsUrl = (ruleName) => `https://tanstack.com/query/latest/docs/eslint/${ruleName}`;
269
+
270
+ // src/utils/detect-react-query-imports.ts
271
+ import { TSESTree } from "@typescript-eslint/utils";
272
+ function detectTanstackQueryImports(create) {
273
+ return (context, optionsWithDefault) => {
274
+ const tanstackQueryImportSpecifiers = [];
275
+ const helpers = {
276
+ isSpecificTanstackQueryImport(node, source) {
277
+ return !!tanstackQueryImportSpecifiers.find((specifier) => {
278
+ if (specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier && specifier.parent.type === TSESTree.AST_NODE_TYPES.ImportDeclaration && specifier.parent.source.value === source) {
279
+ return node.name === specifier.local.name;
280
+ }
281
+ return false;
282
+ });
283
+ },
284
+ isTanstackQueryImport(node) {
285
+ return !!tanstackQueryImportSpecifiers.find((specifier) => {
286
+ if (specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier) {
287
+ return node.name === specifier.local.name;
288
+ }
289
+ return false;
290
+ });
291
+ }
292
+ };
293
+ const detectionInstructions = {
294
+ ImportDeclaration(node) {
295
+ if (node.specifiers.length > 0 && // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
296
+ (node.importKind === "value" || node.importKind === void 0) && node.source.value.startsWith("@tanstack/") && node.source.value.endsWith("-query")) {
297
+ tanstackQueryImportSpecifiers.push(...node.specifiers);
298
+ }
299
+ }
300
+ };
301
+ const ruleInstructions = create(context, optionsWithDefault, helpers);
302
+ const enhancedRuleInstructions = {};
303
+ const allKeys = new Set(
304
+ Object.keys(detectionInstructions).concat(Object.keys(ruleInstructions))
305
+ );
306
+ allKeys.forEach((instruction) => {
307
+ enhancedRuleInstructions[instruction] = (node) => {
308
+ var _a;
309
+ if (instruction in detectionInstructions) {
310
+ (_a = detectionInstructions[instruction]) == null ? void 0 : _a.call(detectionInstructions, node);
311
+ }
312
+ const ruleInstruction = ruleInstructions[instruction];
313
+ if (ruleInstruction) {
314
+ return ruleInstruction(node);
315
+ }
316
+ return void 0;
317
+ };
318
+ });
319
+ return enhancedRuleInstructions;
320
+ };
321
+ }
322
+
323
+ // src/rules/exhaustive-deps/exhaustive-deps.utils.ts
324
+ import { AST_NODE_TYPES as AST_NODE_TYPES2 } from "@typescript-eslint/utils";
325
+ var ExhaustiveDepsUtils = {
326
+ isRelevantReference(params) {
327
+ var _a, _b;
328
+ const { sourceCode, reference, scopeManager, node, filename } = params;
329
+ const component = ASTUtils.getFunctionAncestor(sourceCode, node);
330
+ const queryFnScope = scopeManager.acquire(node);
331
+ if (queryFnScope === null || reference.isValueReference === false) {
332
+ return false;
333
+ }
334
+ let currentScope = ((_a = reference.resolved) == null ? void 0 : _a.scope) ?? null;
335
+ while (currentScope !== null) {
336
+ if (currentScope === queryFnScope) {
337
+ return false;
338
+ }
339
+ currentScope = currentScope.upper;
340
+ }
341
+ if (component !== void 0) {
342
+ if (!ASTUtils.isDeclaredInNode({
343
+ scopeManager,
344
+ reference,
345
+ functionNode: component
346
+ })) {
347
+ return false;
348
+ }
349
+ } else {
350
+ const isVueFile = filename.endsWith(".vue");
351
+ if (!isVueFile) {
352
+ return false;
353
+ }
354
+ const definition = (_b = reference.resolved) == null ? void 0 : _b.defs[0];
355
+ const isGlobalVariable = definition === void 0;
356
+ const isImport = (definition == null ? void 0 : definition.type) === "ImportBinding";
357
+ if (isGlobalVariable || isImport) {
358
+ return false;
359
+ }
360
+ }
361
+ return reference.identifier.name !== "undefined" && reference.identifier.parent.type !== AST_NODE_TYPES2.NewExpression && !ExhaustiveDepsUtils.isInstanceOfKind(reference.identifier.parent);
362
+ },
363
+ /**
364
+ * Given required refs and existing queryKey entries, compute missing dependency paths
365
+ * respecting allowlisted variables and types.
366
+ */
367
+ computeFilteredMissingPaths(params) {
368
+ const {
369
+ requiredRefs,
370
+ allowlistedVariables,
371
+ existingRootIdentifiers,
372
+ existingFullPaths
373
+ } = params;
374
+ const missingPaths = /* @__PURE__ */ new Set();
375
+ for (const { root, path, allowlistedByType } of requiredRefs) {
376
+ if (existingRootIdentifiers.has(root)) continue;
377
+ if (allowlistedVariables.has(root)) continue;
378
+ if (existingFullPaths.has(path)) continue;
379
+ if (allowlistedByType) continue;
380
+ missingPaths.add(path);
381
+ }
382
+ for (const path of missingPaths) {
383
+ const root = path.split(".")[0];
384
+ if (root !== path && root !== void 0 && missingPaths.has(root)) {
385
+ missingPaths.delete(path);
386
+ }
387
+ }
388
+ return Array.from(missingPaths);
389
+ },
390
+ /**
391
+ * Extract existing queryKey deps as root identifiers and full member paths.
392
+ */
393
+ collectQueryKeyDeps(params) {
394
+ const { sourceCode, scopeManager, queryKeyNode } = params;
395
+ const roots = /* @__PURE__ */ new Set();
396
+ const paths = /* @__PURE__ */ new Set();
397
+ const visitorKeys = sourceCode.visitorKeys;
398
+ function addRoot(name8) {
399
+ const cleaned = ExhaustiveDepsUtils.normalizeChain(name8);
400
+ roots.add(cleaned);
401
+ paths.add(cleaned);
402
+ }
403
+ function addFull(text) {
404
+ const cleaned = ExhaustiveDepsUtils.normalizeChain(text);
405
+ paths.add(cleaned);
406
+ }
407
+ function addRefPath(refPath) {
408
+ if (!refPath) return;
409
+ if (refPath.coversRootMembers) {
410
+ addRoot(refPath.root);
411
+ return;
412
+ }
413
+ addFull(refPath.path);
414
+ }
415
+ function visitChildren(node) {
416
+ const keys = visitorKeys[node.type] ?? [];
417
+ for (const key of keys) {
418
+ const value = node[key];
419
+ if (Array.isArray(value)) {
420
+ for (const item of value) {
421
+ if (ExhaustiveDepsUtils.isNode(item)) {
422
+ visit(item);
423
+ }
424
+ }
425
+ continue;
426
+ }
427
+ if (ExhaustiveDepsUtils.isNode(value)) {
428
+ visit(value);
429
+ }
430
+ }
431
+ }
432
+ function visit(node) {
433
+ if (!node) return;
434
+ switch (node.type) {
435
+ case AST_NODE_TYPES2.Identifier: {
436
+ addRefPath(
437
+ ExhaustiveDepsUtils.computeRefPath({
438
+ identifier: node,
439
+ sourceCode
440
+ })
441
+ );
442
+ return;
443
+ }
444
+ case AST_NODE_TYPES2.ArrowFunctionExpression:
445
+ case AST_NODE_TYPES2.FunctionExpression:
446
+ for (const reference of ExhaustiveDepsUtils.collectExternalRefsInFunction(
447
+ {
448
+ functionNode: node,
449
+ scopeManager
450
+ }
451
+ )) {
452
+ if (reference.identifier.type !== AST_NODE_TYPES2.Identifier) {
453
+ continue;
454
+ }
455
+ addRefPath(
456
+ ExhaustiveDepsUtils.computeRefPath({
457
+ identifier: reference.identifier,
458
+ sourceCode
459
+ })
460
+ );
461
+ }
462
+ return;
463
+ case AST_NODE_TYPES2.Property:
464
+ visit(node.value);
465
+ return;
466
+ case AST_NODE_TYPES2.MemberExpression:
467
+ if (node.parent.type === AST_NODE_TYPES2.CallExpression && node.parent.callee === node && node.object.type === AST_NODE_TYPES2.Identifier) {
468
+ addRoot(node.object.name);
469
+ } else {
470
+ visit(node.object);
471
+ }
472
+ return;
473
+ case AST_NODE_TYPES2.CallExpression:
474
+ node.arguments.forEach((argument) => visit(argument));
475
+ switch (node.callee.type) {
476
+ case AST_NODE_TYPES2.Identifier:
477
+ case AST_NODE_TYPES2.MemberExpression:
478
+ case AST_NODE_TYPES2.ChainExpression:
479
+ case AST_NODE_TYPES2.TSNonNullExpression:
480
+ visit(node.callee);
481
+ break;
482
+ }
483
+ return;
484
+ }
485
+ visitChildren(node);
486
+ }
487
+ visit(queryKeyNode);
488
+ return { roots, paths };
489
+ },
490
+ isNode(value) {
491
+ return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
492
+ },
493
+ /**
494
+ * Checks whether the resolved variable is allowlisted by its type annotation
495
+ */
496
+ variableIsAllowlistedByType(params) {
497
+ const { allowlistedTypes, variable } = params;
498
+ if (allowlistedTypes.size === 0) return false;
499
+ if (!variable) return false;
500
+ for (const id of variable.identifiers) {
501
+ if (id.typeAnnotation) {
502
+ const typeIdentifiers = /* @__PURE__ */ new Set();
503
+ ExhaustiveDepsUtils.collectTypeIdentifiers(
504
+ id.typeAnnotation.typeAnnotation,
505
+ typeIdentifiers
506
+ );
507
+ for (const typeIdentifier of typeIdentifiers) {
508
+ if (allowlistedTypes.has(typeIdentifier)) return true;
509
+ }
510
+ }
511
+ }
512
+ return false;
513
+ },
514
+ isInstanceOfKind(node) {
515
+ return node.type === AST_NODE_TYPES2.BinaryExpression && node.operator === "instanceof";
516
+ },
517
+ /**
518
+ * Normalizes a chain by removing optional chaining operators
519
+ *
520
+ * Example: `a?.b.c!` -> `a.b.c`
521
+ */
522
+ normalizeChain(text) {
523
+ return text.replace(/(?:\?(\.)|!)/g, "$1");
524
+ },
525
+ /**
526
+ * Computes the reference path for an identifier
527
+ *
528
+ * Example: `a.b.c!` -> `{ path: 'a.b.c', root: 'a' }`
529
+ */
530
+ computeRefPath(params) {
531
+ const { identifier, sourceCode } = params;
532
+ const fullChainNode = ASTUtils.traverseUpOnly(identifier, [
533
+ AST_NODE_TYPES2.MemberExpression,
534
+ AST_NODE_TYPES2.TSNonNullExpression,
535
+ AST_NODE_TYPES2.Identifier
536
+ ]);
537
+ const fullText = ExhaustiveDepsUtils.normalizeChain(
538
+ sourceCode.getText(fullChainNode)
539
+ );
540
+ const parent = fullChainNode.parent;
541
+ let dependencyPath = fullText;
542
+ let coversRootMembers = fullText === identifier.name;
543
+ if (parent && parent.type === AST_NODE_TYPES2.CallExpression && parent.callee === fullChainNode) {
544
+ const segments = fullText.split(".");
545
+ if (segments.length > 1) {
546
+ dependencyPath = segments.slice(0, -1).join(".");
547
+ }
548
+ coversRootMembers = false;
549
+ }
550
+ dependencyPath = dependencyPath.split(".")[0] === "" ? identifier.name : dependencyPath;
551
+ const root = dependencyPath.split(".")[0];
552
+ return {
553
+ path: dependencyPath,
554
+ root: root ?? identifier.name,
555
+ coversRootMembers: coversRootMembers && dependencyPath === root
556
+ };
557
+ },
558
+ collectExternalRefsInFunction(params) {
559
+ const { functionNode, scopeManager } = params;
560
+ const functionScope = scopeManager.acquire(functionNode);
561
+ if (functionScope === null) {
562
+ return [];
563
+ }
564
+ const externalRefs = [];
565
+ function collect(scope) {
566
+ for (const reference of scope.references) {
567
+ if (!reference.isRead() || reference.resolved === null) {
568
+ continue;
569
+ }
570
+ let currentScope = reference.resolved.scope;
571
+ let declaredInsideFunction = false;
572
+ while (currentScope !== null) {
573
+ if (currentScope === functionScope) {
574
+ declaredInsideFunction = true;
575
+ break;
576
+ }
577
+ currentScope = currentScope.upper;
578
+ }
579
+ if (!declaredInsideFunction) {
580
+ externalRefs.push(reference);
581
+ }
582
+ }
583
+ for (const childScope of scope.childScopes) {
584
+ collect(childScope);
585
+ }
586
+ }
587
+ collect(functionScope);
588
+ return externalRefs;
589
+ },
590
+ /**
591
+ * Recursively collects type identifiers from a type annotation
592
+ */
593
+ collectTypeIdentifiers(typeNode, out) {
594
+ switch (typeNode.type) {
595
+ case AST_NODE_TYPES2.TSTypeReference: {
596
+ if (typeNode.typeName.type === AST_NODE_TYPES2.Identifier) {
597
+ out.add(typeNode.typeName.name);
598
+ }
599
+ break;
600
+ }
601
+ case AST_NODE_TYPES2.TSUnionType:
602
+ case AST_NODE_TYPES2.TSIntersectionType: {
603
+ typeNode.types.forEach(
604
+ (t) => ExhaustiveDepsUtils.collectTypeIdentifiers(t, out)
605
+ );
606
+ break;
607
+ }
608
+ case AST_NODE_TYPES2.TSArrayType: {
609
+ ExhaustiveDepsUtils.collectTypeIdentifiers(typeNode.elementType, out);
610
+ break;
611
+ }
612
+ case AST_NODE_TYPES2.TSTupleType: {
613
+ typeNode.elementTypes.forEach(
614
+ (et) => ExhaustiveDepsUtils.collectTypeIdentifiers(et, out)
615
+ );
616
+ break;
617
+ }
618
+ }
619
+ },
620
+ /**
621
+ * Gets the function expression nodes from a queryFn property, handling conditional expressions.
622
+ * When neither branch is skipToken, returns both branches so all deps are scanned.
623
+ */
624
+ getQueryFnNodes(queryFn) {
625
+ if (queryFn.value.type !== AST_NODE_TYPES2.ConditionalExpression) {
626
+ return [queryFn.value];
627
+ }
628
+ if (queryFn.value.consequent.type === AST_NODE_TYPES2.Identifier && queryFn.value.consequent.name === "skipToken") {
629
+ return [queryFn.value.alternate];
630
+ }
631
+ if (queryFn.value.alternate.type === AST_NODE_TYPES2.Identifier && queryFn.value.alternate.name === "skipToken") {
632
+ return [queryFn.value.consequent];
633
+ }
634
+ return [queryFn.value.consequent, queryFn.value.alternate];
635
+ }
636
+ };
637
+
638
+ // src/rules/exhaustive-deps/exhaustive-deps.rule.ts
639
+ var QUERY_KEY = "queryKey";
640
+ var QUERY_FN = "queryFn";
641
+ var name = "exhaustive-deps";
642
+ var createRule = ESLintUtils.RuleCreator(getDocsUrl);
643
+ var rule = createRule({
644
+ name,
645
+ meta: {
646
+ type: "problem",
647
+ docs: {
648
+ description: "Exhaustive deps rule for useQuery",
649
+ recommended: "error"
650
+ },
651
+ messages: {
652
+ missingDeps: `The following dependencies are missing in your queryKey: {{deps}}`,
653
+ fixTo: "Fix to {{result}}"
654
+ },
655
+ hasSuggestions: true,
656
+ fixable: "code",
657
+ schema: [
658
+ {
659
+ type: "object",
660
+ properties: {
661
+ allowlist: {
662
+ type: "object",
663
+ properties: {
664
+ variables: { type: "array", items: { type: "string" } },
665
+ types: { type: "array", items: { type: "string" } }
666
+ },
667
+ additionalProperties: false
668
+ }
669
+ },
670
+ additionalProperties: false
671
+ }
672
+ ]
673
+ },
674
+ defaultOptions: [],
675
+ create: detectTanstackQueryImports((context) => {
676
+ return {
677
+ ObjectExpression: (node) => {
678
+ var _a, _b;
679
+ const scopeManager = context.sourceCode.scopeManager;
680
+ const queryKey = ASTUtils.findPropertyWithIdentifierKey(
681
+ node.properties,
682
+ QUERY_KEY
683
+ );
684
+ const queryFn = ASTUtils.findPropertyWithIdentifierKey(
685
+ node.properties,
686
+ QUERY_FN
687
+ );
688
+ if (scopeManager === null || queryKey === void 0 || queryFn === void 0 || !ASTUtils.isNodeOfOneOf(queryFn.value, [
689
+ AST_NODE_TYPES3.ArrowFunctionExpression,
690
+ AST_NODE_TYPES3.FunctionExpression,
691
+ AST_NODE_TYPES3.ConditionalExpression
692
+ ])) {
693
+ return;
694
+ }
695
+ const queryKeyNode = dereferenceVariablesAndTypeAssertions(
696
+ queryKey.value,
697
+ context
698
+ );
699
+ const queryFnNodes = ExhaustiveDepsUtils.getQueryFnNodes(queryFn);
700
+ const externalRefs = queryFnNodes.flatMap(
701
+ (fnNode) => ASTUtils.getExternalRefs({
702
+ scopeManager,
703
+ sourceCode: context.sourceCode,
704
+ node: fnNode
705
+ })
706
+ );
707
+ const relevantRefs = externalRefs.filter(
708
+ (reference) => queryFnNodes.some(
709
+ (fnNode) => ExhaustiveDepsUtils.isRelevantReference({
710
+ sourceCode: context.sourceCode,
711
+ reference,
712
+ scopeManager,
713
+ node: fnNode,
714
+ filename: context.filename
715
+ })
716
+ )
717
+ );
718
+ const ruleOptions = context.options.at(0);
719
+ const allowlistedVariables = new Set(
720
+ ((_a = ruleOptions == null ? void 0 : ruleOptions.allowlist) == null ? void 0 : _a.variables) ?? []
721
+ );
722
+ const allowlistedTypes = new Set(((_b = ruleOptions == null ? void 0 : ruleOptions.allowlist) == null ? void 0 : _b.types) ?? []);
723
+ const requiredRefs = relevantRefs.flatMap((ref) => {
724
+ if (ref.identifier.type !== AST_NODE_TYPES3.Identifier) return [];
725
+ const refPath = ExhaustiveDepsUtils.computeRefPath({
726
+ identifier: ref.identifier,
727
+ sourceCode: context.sourceCode
728
+ });
729
+ if (refPath === null) return [];
730
+ return [
731
+ {
732
+ ...refPath,
733
+ allowlistedByType: ExhaustiveDepsUtils.variableIsAllowlistedByType({
734
+ allowlistedTypes,
735
+ variable: ref.resolved ?? null
736
+ })
737
+ }
738
+ ];
739
+ });
740
+ if (requiredRefs.length === 0) return;
741
+ const queryKeyDeps = ExhaustiveDepsUtils.collectQueryKeyDeps({
742
+ sourceCode: context.sourceCode,
743
+ scopeManager,
744
+ queryKeyNode
745
+ });
746
+ const missingPaths = ExhaustiveDepsUtils.computeFilteredMissingPaths({
747
+ requiredRefs,
748
+ allowlistedVariables,
749
+ existingRootIdentifiers: queryKeyDeps.roots,
750
+ existingFullPaths: queryKeyDeps.paths
751
+ });
752
+ if (missingPaths.length === 0) return;
753
+ const missingAsText = missingPaths.join(", ");
754
+ const suggestions = buildSuggestions({
755
+ queryKeyNode,
756
+ missingPaths,
757
+ missingAsText,
758
+ sourceCode: context.sourceCode
759
+ });
760
+ context.report({
761
+ node,
762
+ messageId: "missingDeps",
763
+ data: { deps: missingAsText },
764
+ suggest: suggestions
765
+ });
766
+ }
767
+ };
768
+ })
769
+ });
770
+ function buildSuggestions(params) {
771
+ const { queryKeyNode, missingPaths, missingAsText, sourceCode } = params;
772
+ if (queryKeyNode.type !== AST_NODE_TYPES3.ArrayExpression) {
773
+ return [];
774
+ }
775
+ const closingBracket = sourceCode.getLastToken(queryKeyNode);
776
+ if (!closingBracket) return [];
777
+ const existingElements = queryKeyNode.elements.filter((el) => el !== null).map((el) => sourceCode.getText(el));
778
+ const resultText = `[${[...existingElements, ...missingPaths].join(", ")}]`;
779
+ if (queryKeyNode.elements.length === 0) {
780
+ return [
781
+ {
782
+ messageId: "fixTo",
783
+ data: { result: resultText },
784
+ fix: (fixer) => fixer.replaceText(queryKeyNode, resultText)
785
+ }
786
+ ];
787
+ }
788
+ const tokenBefore = sourceCode.getTokenBefore(closingBracket);
789
+ const separator = (tokenBefore == null ? void 0 : tokenBefore.value) === "," ? " " : ", ";
790
+ return [
791
+ {
792
+ messageId: "fixTo",
793
+ data: { result: resultText },
794
+ fix: (fixer) => fixer.insertTextBefore(closingBracket, `${separator}${missingAsText}`)
795
+ }
796
+ ];
797
+ }
798
+ function dereferenceVariablesAndTypeAssertions(queryKeyNode, context) {
799
+ const visitedNodes = /* @__PURE__ */ new Set();
800
+ for (let i = 0; i < 1 << 8; ++i) {
801
+ if (visitedNodes.has(queryKeyNode)) {
802
+ return queryKeyNode;
803
+ }
804
+ visitedNodes.add(queryKeyNode);
805
+ switch (queryKeyNode.type) {
806
+ case AST_NODE_TYPES3.TSAsExpression:
807
+ queryKeyNode = queryKeyNode.expression;
808
+ break;
809
+ case AST_NODE_TYPES3.Identifier: {
810
+ const expression = ASTUtils.getReferencedExpressionByIdentifier({
811
+ context,
812
+ node: queryKeyNode
813
+ });
814
+ if (expression == null) {
815
+ return queryKeyNode;
816
+ }
817
+ queryKeyNode = expression;
818
+ break;
819
+ }
820
+ default:
821
+ return queryKeyNode;
822
+ }
823
+ }
824
+ return queryKeyNode;
825
+ }
826
+
827
+ // src/rules/stable-query-client/stable-query-client.rule.ts
828
+ import { AST_NODE_TYPES as AST_NODE_TYPES4, ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
829
+ var name2 = "stable-query-client";
830
+ var createRule2 = ESLintUtils2.RuleCreator(getDocsUrl);
831
+ var rule2 = createRule2({
832
+ name: name2,
833
+ meta: {
834
+ type: "problem",
835
+ docs: {
836
+ description: "Makes sure that QueryClient is stable",
837
+ recommended: "error"
838
+ },
839
+ messages: {
840
+ unstable: [
841
+ "QueryClient is not stable. It should be either extracted from the component or wrapped in React.useState.",
842
+ "See https://tkdodo.eu/blog/react-query-fa-qs#2-the-queryclient-is-not-stable"
843
+ ].join("\n"),
844
+ fixTo: "Fix to {{result}}"
845
+ },
846
+ hasSuggestions: true,
847
+ fixable: "code",
848
+ schema: []
849
+ },
850
+ defaultOptions: [],
851
+ create: detectTanstackQueryImports((context, _, helpers) => {
852
+ return {
853
+ NewExpression: (node) => {
854
+ if (node.callee.type !== AST_NODE_TYPES4.Identifier || node.callee.name !== "QueryClient" || node.parent.type !== AST_NODE_TYPES4.VariableDeclarator || !helpers.isSpecificTanstackQueryImport(
855
+ node.callee,
856
+ "@tanstack/react-query"
857
+ )) {
858
+ return;
859
+ }
860
+ const fnAncestor = ASTUtils.getFunctionAncestor(
861
+ context.sourceCode,
862
+ node
863
+ );
864
+ const isReactServerComponent = (fnAncestor == null ? void 0 : fnAncestor.async) === true;
865
+ if (!ASTUtils.isValidReactComponentOrHookName(fnAncestor == null ? void 0 : fnAncestor.id) || isReactServerComponent) {
866
+ return;
867
+ }
868
+ context.report({
869
+ node: node.parent,
870
+ messageId: "unstable",
871
+ fix: (() => {
872
+ const { parent } = node;
873
+ if (parent.id.type !== AST_NODE_TYPES4.Identifier) {
874
+ return;
875
+ }
876
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
877
+ const nodeText = sourceCode.getText(node);
878
+ const variableName = parent.id.name;
879
+ return (fixer) => {
880
+ return fixer.replaceTextRange(
881
+ [parent.range[0], parent.range[1]],
882
+ `[${variableName}] = React.useState(() => ${nodeText})`
883
+ );
884
+ };
885
+ })()
886
+ });
887
+ }
888
+ };
889
+ })
890
+ });
891
+
892
+ // src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts
893
+ import { AST_NODE_TYPES as AST_NODE_TYPES6, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
894
+
895
+ // src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts
896
+ import { AST_NODE_TYPES as AST_NODE_TYPES5 } from "@typescript-eslint/utils";
897
+ var NoRestDestructuringUtils = {
898
+ isObjectRestDestructuring(node) {
899
+ if (node.type !== AST_NODE_TYPES5.ObjectPattern) {
900
+ return false;
901
+ }
902
+ return node.properties.some((p) => p.type === AST_NODE_TYPES5.RestElement);
903
+ }
904
+ };
905
+
906
+ // src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts
907
+ var name3 = "no-rest-destructuring";
908
+ var queryHooks = [
909
+ "useQuery",
910
+ "useQueries",
911
+ "useInfiniteQuery",
912
+ "useSuspenseQuery",
913
+ "useSuspenseQueries",
914
+ "useSuspenseInfiniteQuery"
915
+ ];
916
+ var createRule3 = ESLintUtils3.RuleCreator(getDocsUrl);
917
+ var rule3 = createRule3({
918
+ name: name3,
919
+ meta: {
920
+ type: "problem",
921
+ docs: {
922
+ description: "Disallows rest destructuring in queries",
923
+ recommended: "warn"
924
+ },
925
+ messages: {
926
+ objectRestDestructure: `Object rest destructuring on a query will observe all changes to the query, leading to excessive re-renders.`
927
+ },
928
+ schema: []
929
+ },
930
+ defaultOptions: [],
931
+ create: detectTanstackQueryImports((context, _, helpers) => {
932
+ const queryResultVariables = /* @__PURE__ */ new Set();
933
+ return {
934
+ CallExpression: (node) => {
935
+ if (!ASTUtils.isIdentifierWithOneOfNames(node.callee, queryHooks) || node.parent.type !== AST_NODE_TYPES6.VariableDeclarator || !helpers.isTanstackQueryImport(node.callee)) {
936
+ return;
937
+ }
938
+ const returnValue = node.parent.id;
939
+ if (node.callee.name !== "useQueries" && node.callee.name !== "useSuspenseQueries") {
940
+ if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) {
941
+ return context.report({
942
+ node: node.parent,
943
+ messageId: "objectRestDestructure"
944
+ });
945
+ }
946
+ if (returnValue.type === AST_NODE_TYPES6.Identifier) {
947
+ queryResultVariables.add(returnValue.name);
948
+ }
949
+ return;
950
+ }
951
+ if (returnValue.type !== AST_NODE_TYPES6.ArrayPattern) {
952
+ if (returnValue.type === AST_NODE_TYPES6.Identifier) {
953
+ queryResultVariables.add(returnValue.name);
954
+ }
955
+ return;
956
+ }
957
+ returnValue.elements.forEach((queryResult) => {
958
+ if (queryResult === null) {
959
+ return;
960
+ }
961
+ if (NoRestDestructuringUtils.isObjectRestDestructuring(queryResult)) {
962
+ context.report({
963
+ node: queryResult,
964
+ messageId: "objectRestDestructure"
965
+ });
966
+ }
967
+ });
968
+ },
969
+ VariableDeclarator: (node) => {
970
+ var _a;
971
+ if (((_a = node.init) == null ? void 0 : _a.type) === AST_NODE_TYPES6.Identifier && queryResultVariables.has(node.init.name) && NoRestDestructuringUtils.isObjectRestDestructuring(node.id)) {
972
+ context.report({
973
+ node,
974
+ messageId: "objectRestDestructure"
975
+ });
976
+ }
977
+ },
978
+ SpreadElement: (node) => {
979
+ if (node.argument.type === AST_NODE_TYPES6.Identifier && queryResultVariables.has(node.argument.name)) {
980
+ context.report({
981
+ node,
982
+ messageId: "objectRestDestructure"
983
+ });
984
+ }
985
+ }
986
+ };
987
+ })
988
+ });
989
+
990
+ // src/rules/no-unstable-deps/no-unstable-deps.rule.ts
991
+ import { AST_NODE_TYPES as AST_NODE_TYPES7, ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
992
+ var name4 = "no-unstable-deps";
993
+ var reactHookNames = ["useEffect", "useCallback", "useMemo"];
994
+ var useQueryHookNames = [
995
+ "useQuery",
996
+ "useSuspenseQuery",
997
+ "useQueries",
998
+ "useSuspenseQueries",
999
+ "useInfiniteQuery",
1000
+ "useSuspenseInfiniteQuery"
1001
+ ];
1002
+ var allHookNames = ["useMutation", ...useQueryHookNames];
1003
+ var createRule4 = ESLintUtils4.RuleCreator(getDocsUrl);
1004
+ var rule4 = createRule4({
1005
+ name: name4,
1006
+ meta: {
1007
+ type: "problem",
1008
+ docs: {
1009
+ description: "Disallow putting the result of query hooks directly in a React hook dependency array",
1010
+ recommended: "error"
1011
+ },
1012
+ messages: {
1013
+ noUnstableDeps: `The result of {{queryHook}} is not referentially stable, so don't pass it directly into the dependencies array of {{reactHook}}. Instead, destructure the return value of {{queryHook}} and pass the destructured values into the dependency array of {{reactHook}}.`
1014
+ },
1015
+ schema: []
1016
+ },
1017
+ defaultOptions: [],
1018
+ create: detectTanstackQueryImports((context, _options, helpers) => {
1019
+ const trackedVariables = {};
1020
+ const hookAliasMap = {};
1021
+ function getReactHook(node) {
1022
+ if (node.callee.type === "Identifier") {
1023
+ const calleeName = node.callee.name;
1024
+ if (reactHookNames.includes(calleeName) || calleeName in hookAliasMap) {
1025
+ return calleeName;
1026
+ }
1027
+ } else if (node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "React" && node.callee.property.type === "Identifier" && reactHookNames.includes(node.callee.property.name)) {
1028
+ return node.callee.property.name;
1029
+ }
1030
+ return void 0;
1031
+ }
1032
+ function collectVariableNames(pattern, queryHook) {
1033
+ if (pattern.type === AST_NODE_TYPES7.Identifier) {
1034
+ trackedVariables[pattern.name] = queryHook;
1035
+ }
1036
+ }
1037
+ function hasCombineProperty(callExpression) {
1038
+ if (callExpression.arguments.length === 0) return false;
1039
+ const firstArg = callExpression.arguments[0];
1040
+ if (!firstArg || firstArg.type !== AST_NODE_TYPES7.ObjectExpression)
1041
+ return false;
1042
+ return firstArg.properties.some(
1043
+ (prop) => prop.type === AST_NODE_TYPES7.Property && prop.key.type === AST_NODE_TYPES7.Identifier && prop.key.name === "combine"
1044
+ );
1045
+ }
1046
+ return {
1047
+ ImportDeclaration(node) {
1048
+ if (node.specifiers.length > 0 && node.importKind === "value" && node.source.value === "React") {
1049
+ node.specifiers.forEach((specifier) => {
1050
+ if (specifier.type === AST_NODE_TYPES7.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES7.Identifier && reactHookNames.includes(specifier.imported.name)) {
1051
+ hookAliasMap[specifier.local.name] = specifier.imported.name;
1052
+ }
1053
+ });
1054
+ }
1055
+ },
1056
+ VariableDeclarator(node) {
1057
+ if (node.init !== null && node.init.type === AST_NODE_TYPES7.CallExpression && node.init.callee.type === AST_NODE_TYPES7.Identifier && allHookNames.includes(node.init.callee.name) && helpers.isTanstackQueryImport(node.init.callee)) {
1058
+ if (node.init.callee.name === "useQueries" && hasCombineProperty(node.init)) {
1059
+ return;
1060
+ }
1061
+ collectVariableNames(node.id, node.init.callee.name);
1062
+ }
1063
+ },
1064
+ CallExpression: (node) => {
1065
+ var _a;
1066
+ const reactHook = getReactHook(node);
1067
+ if (reactHook !== void 0 && node.arguments.length > 1 && ((_a = node.arguments[1]) == null ? void 0 : _a.type) === AST_NODE_TYPES7.ArrayExpression) {
1068
+ const depsArray = node.arguments[1].elements;
1069
+ depsArray.forEach((dep) => {
1070
+ if (dep !== null && dep.type === AST_NODE_TYPES7.Identifier && trackedVariables[dep.name] !== void 0) {
1071
+ const queryHook = trackedVariables[dep.name];
1072
+ context.report({
1073
+ node: dep,
1074
+ messageId: "noUnstableDeps",
1075
+ data: {
1076
+ queryHook,
1077
+ reactHook
1078
+ }
1079
+ });
1080
+ }
1081
+ });
1082
+ }
1083
+ }
1084
+ };
1085
+ })
1086
+ });
1087
+
1088
+ // src/utils/create-property-order-rule.ts
1089
+ import { AST_NODE_TYPES as AST_NODE_TYPES8, ESLintUtils as ESLintUtils5 } from "@typescript-eslint/utils";
1090
+
1091
+ // src/utils/sort-data-by-order.ts
1092
+ function sortDataByOrder(data, orderRules, key) {
1093
+ const getSubsetIndex = (item, subsets) => {
1094
+ var _a;
1095
+ for (let i = 0; i < subsets.length; i++) {
1096
+ if ((_a = subsets[i]) == null ? void 0 : _a.includes(item)) {
1097
+ return i;
1098
+ }
1099
+ }
1100
+ return null;
1101
+ };
1102
+ const orderSets = orderRules.reduce(
1103
+ (sets, [A, B]) => [...sets, A, B],
1104
+ []
1105
+ );
1106
+ const inOrderArray = data.filter(
1107
+ (item) => getSubsetIndex(item[key], orderSets) !== null
1108
+ );
1109
+ let wasResorted = false;
1110
+ const sortedArray = inOrderArray.sort((a, b) => {
1111
+ const aKey = a[key], bKey = b[key];
1112
+ const aSubsetIndex = getSubsetIndex(aKey, orderSets);
1113
+ const bSubsetIndex = getSubsetIndex(bKey, orderSets);
1114
+ if (aSubsetIndex !== null && bSubsetIndex !== null && aSubsetIndex !== bSubsetIndex) {
1115
+ return aSubsetIndex - bSubsetIndex;
1116
+ }
1117
+ return 0;
1118
+ });
1119
+ const inOrderIterator = sortedArray.values();
1120
+ const result = data.map((item) => {
1121
+ if (getSubsetIndex(item[key], orderSets) !== null) {
1122
+ const sortedItem = inOrderIterator.next().value;
1123
+ if (sortedItem[key] !== item[key]) {
1124
+ wasResorted = true;
1125
+ }
1126
+ return sortedItem;
1127
+ }
1128
+ return item;
1129
+ });
1130
+ if (!wasResorted) {
1131
+ return null;
1132
+ }
1133
+ return result;
1134
+ }
1135
+
1136
+ // src/utils/create-property-order-rule.ts
1137
+ var createRule5 = ESLintUtils5.RuleCreator(getDocsUrl);
1138
+ function createPropertyOrderRule(options, targetFunctions, orderRules) {
1139
+ const targetFunctionSet = new Set(targetFunctions);
1140
+ function isTargetFunction(node) {
1141
+ return targetFunctionSet.has(node);
1142
+ }
1143
+ return createRule5({
1144
+ ...options,
1145
+ create: detectTanstackQueryImports((context) => {
1146
+ return {
1147
+ CallExpression(node) {
1148
+ if (node.callee.type !== AST_NODE_TYPES8.Identifier) {
1149
+ return;
1150
+ }
1151
+ const functions = node.callee.name;
1152
+ if (!isTargetFunction(functions)) {
1153
+ return;
1154
+ }
1155
+ const argument = node.arguments[0];
1156
+ if (argument === void 0 || argument.type !== "ObjectExpression") {
1157
+ return;
1158
+ }
1159
+ const allProperties = argument.properties;
1160
+ if (allProperties.length < 2) {
1161
+ return;
1162
+ }
1163
+ const properties = allProperties.flatMap((p, index) => {
1164
+ if (p.type === AST_NODE_TYPES8.Property && p.key.type === AST_NODE_TYPES8.Identifier) {
1165
+ return { name: p.key.name, property: p };
1166
+ } else return { name: `_property_${index}`, property: p };
1167
+ });
1168
+ const sortedProperties = sortDataByOrder(
1169
+ properties,
1170
+ orderRules,
1171
+ "name"
1172
+ );
1173
+ if (sortedProperties === null) {
1174
+ return;
1175
+ }
1176
+ context.report({
1177
+ node: argument,
1178
+ data: { function: node.callee.name },
1179
+ messageId: "invalidOrder",
1180
+ fix(fixer) {
1181
+ const sourceCode = context.sourceCode;
1182
+ const reorderedText = sortedProperties.reduce(
1183
+ (sourceText, specifier, index) => {
1184
+ let textBetweenProperties = "";
1185
+ if (index < allProperties.length - 1) {
1186
+ textBetweenProperties = sourceCode.getText().slice(
1187
+ allProperties[index].range[1],
1188
+ allProperties[index + 1].range[0]
1189
+ );
1190
+ }
1191
+ return sourceText + sourceCode.getText(specifier.property) + textBetweenProperties;
1192
+ },
1193
+ ""
1194
+ );
1195
+ return fixer.replaceTextRange(
1196
+ [allProperties[0].range[0], allProperties.at(-1).range[1]],
1197
+ reorderedText
1198
+ );
1199
+ }
1200
+ });
1201
+ }
1202
+ };
1203
+ })
1204
+ });
1205
+ }
1206
+
1207
+ // src/rules/infinite-query-property-order/constants.ts
1208
+ var infiniteQueryFunctions = [
1209
+ "infiniteQueryOptions",
1210
+ "useInfiniteQuery",
1211
+ "useSuspenseInfiniteQuery"
1212
+ ];
1213
+ var sortRules = [
1214
+ [["queryFn"], ["getPreviousPageParam", "getNextPageParam"]]
1215
+ ];
1216
+
1217
+ // src/rules/infinite-query-property-order/infinite-query-property-order.rule.ts
1218
+ var name5 = "infinite-query-property-order";
1219
+ var rule5 = createPropertyOrderRule(
1220
+ {
1221
+ name: name5,
1222
+ meta: {
1223
+ type: "problem",
1224
+ docs: {
1225
+ description: "Ensure correct order of inference sensitive properties for infinite queries",
1226
+ recommended: "error"
1227
+ },
1228
+ messages: {
1229
+ invalidOrder: "Invalid order of properties for `{{function}}`."
1230
+ },
1231
+ schema: [],
1232
+ hasSuggestions: true,
1233
+ fixable: "code"
1234
+ },
1235
+ defaultOptions: []
1236
+ },
1237
+ infiniteQueryFunctions,
1238
+ sortRules
1239
+ );
1240
+
1241
+ // src/rules/no-void-query-fn/no-void-query-fn.rule.ts
1242
+ import { ESLintUtils as ESLintUtils6 } from "@typescript-eslint/utils";
1243
+ var TypeFlags = {
1244
+ Void: 16384,
1245
+ Undefined: 32768
1246
+ };
1247
+ var name6 = "no-void-query-fn";
1248
+ var createRule6 = ESLintUtils6.RuleCreator(getDocsUrl);
1249
+ var rule6 = createRule6({
1250
+ name: name6,
1251
+ meta: {
1252
+ type: "problem",
1253
+ docs: {
1254
+ description: "Ensures queryFn returns a non-undefined value",
1255
+ recommended: "error"
1256
+ },
1257
+ messages: {
1258
+ noVoidReturn: "queryFn must return a non-undefined value"
1259
+ },
1260
+ schema: []
1261
+ },
1262
+ defaultOptions: [],
1263
+ create: detectTanstackQueryImports((context) => {
1264
+ return {
1265
+ Property(node) {
1266
+ var _a;
1267
+ if (!ASTUtils.isObjectExpression(node.parent) || !ASTUtils.isIdentifierWithName(node.key, "queryFn")) {
1268
+ return;
1269
+ }
1270
+ const parserServices = context.sourceCode.parserServices;
1271
+ if (!parserServices || !parserServices.esTreeNodeToTSNodeMap || !parserServices.program) {
1272
+ return;
1273
+ }
1274
+ const checker = parserServices.program.getTypeChecker();
1275
+ const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node.value);
1276
+ const type = checker.getTypeAtLocation(tsNode);
1277
+ if (type.getCallSignatures().length > 0) {
1278
+ const returnType = (_a = type.getCallSignatures()[0]) == null ? void 0 : _a.getReturnType();
1279
+ if (!returnType) {
1280
+ return;
1281
+ }
1282
+ if (isIllegalReturn(checker, returnType)) {
1283
+ context.report({
1284
+ node: node.value,
1285
+ messageId: "noVoidReturn"
1286
+ });
1287
+ }
1288
+ }
1289
+ }
1290
+ };
1291
+ })
1292
+ });
1293
+ function isIllegalReturn(checker, type) {
1294
+ const awaited = checker.getAwaitedType(type);
1295
+ if (!awaited) return false;
1296
+ if (awaited.isUnion()) {
1297
+ return awaited.types.some((t) => isIllegalReturn(checker, t));
1298
+ }
1299
+ return awaited.flags & (TypeFlags.Void | TypeFlags.Undefined) ? true : false;
1300
+ }
1301
+
1302
+ // src/rules/mutation-property-order/constants.ts
1303
+ var mutationFunctions = ["useMutation"];
1304
+ var sortRules2 = [[["onMutate"], ["onError", "onSettled"]]];
1305
+
1306
+ // src/rules/mutation-property-order/mutation-property-order.rule.ts
1307
+ var name7 = "mutation-property-order";
1308
+ var rule7 = createPropertyOrderRule(
1309
+ {
1310
+ name: name7,
1311
+ meta: {
1312
+ type: "problem",
1313
+ docs: {
1314
+ description: "Ensure correct order of inference-sensitive properties in useMutation()",
1315
+ recommended: "error"
1316
+ },
1317
+ messages: {
1318
+ invalidOrder: "Invalid order of properties for `{{function}}`."
1319
+ },
1320
+ schema: [],
1321
+ hasSuggestions: true,
1322
+ fixable: "code"
1323
+ },
1324
+ defaultOptions: []
1325
+ },
1326
+ mutationFunctions,
1327
+ sortRules2
1328
+ );
1329
+
1330
+ // src/rules.ts
1331
+ var rules = {
1332
+ [name]: rule,
1333
+ [name2]: rule2,
1334
+ [name3]: rule3,
1335
+ [name4]: rule4,
1336
+ [name5]: rule5,
1337
+ [name6]: rule6,
1338
+ [name7]: rule7
1339
+ };
1340
+
1341
+ export {
1342
+ rules
1343
+ };
1344
+ //# sourceMappingURL=chunk-T44AUBX4.js.map