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