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