@tanstack/eslint-plugin-query 5.72.1 → 5.73.3

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 (62) hide show
  1. package/{dist/index.js → build/legacy/chunk-4ISZM335.js} +20 -51
  2. package/build/legacy/chunk-4ISZM335.js.map +1 -0
  3. package/build/legacy/index.cjs +1013 -0
  4. package/build/legacy/index.cjs.map +1 -0
  5. package/{dist → build/legacy}/index.d.cts +4 -11
  6. package/{dist → build/legacy}/index.d.ts +4 -11
  7. package/build/legacy/index.js +47 -0
  8. package/build/legacy/index.js.map +1 -0
  9. package/build/legacy/rules.cjs +973 -0
  10. package/build/legacy/rules.cjs.map +1 -0
  11. package/build/legacy/rules.d.cts +6 -0
  12. package/build/legacy/rules.d.ts +6 -0
  13. package/build/legacy/rules.js +7 -0
  14. package/build/legacy/rules.js.map +1 -0
  15. package/build/legacy/types.cjs +19 -0
  16. package/build/legacy/types.cjs.map +1 -0
  17. package/build/legacy/types.d.cts +5 -0
  18. package/build/legacy/types.d.ts +5 -0
  19. package/build/legacy/types.js +1 -0
  20. package/build/legacy/types.js.map +1 -0
  21. package/{dist/rules.js → build/modern/chunk-6ZHBB3IQ.js} +2 -1
  22. package/build/modern/chunk-6ZHBB3IQ.js.map +1 -0
  23. package/{dist → build/modern}/index.cjs +10 -5
  24. package/build/modern/index.cjs.map +1 -0
  25. package/build/modern/index.d.cts +17 -0
  26. package/build/modern/index.d.ts +17 -0
  27. package/build/modern/index.js +47 -0
  28. package/build/modern/index.js.map +1 -0
  29. package/build/modern/rules.cjs.map +1 -0
  30. package/build/modern/rules.d.cts +6 -0
  31. package/build/modern/rules.d.ts +6 -0
  32. package/build/modern/rules.js +7 -0
  33. package/build/modern/rules.js.map +1 -0
  34. package/build/modern/types.cjs +20 -0
  35. package/build/modern/types.cjs.map +1 -0
  36. package/build/modern/types.d.cts +5 -0
  37. package/build/modern/types.d.ts +5 -0
  38. package/build/modern/types.js +1 -0
  39. package/build/modern/types.js.map +1 -0
  40. package/package.json +12 -10
  41. package/src/index.ts +54 -0
  42. package/src/rules/exhaustive-deps/exhaustive-deps.rule.ts +184 -0
  43. package/src/rules/exhaustive-deps/exhaustive-deps.utils.ts +41 -0
  44. package/src/rules/infinite-query-property-order/constants.ts +17 -0
  45. package/src/rules/infinite-query-property-order/infinite-query-property-order.rule.ts +107 -0
  46. package/src/rules/infinite-query-property-order/infinite-query-property-order.utils.ts +67 -0
  47. package/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts +115 -0
  48. package/src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts +11 -0
  49. package/src/rules/no-unstable-deps/no-unstable-deps.rule.ts +129 -0
  50. package/src/rules/no-void-query-fn/no-void-query-fn.rule.ts +84 -0
  51. package/src/rules/stable-query-client/stable-query-client.rule.ts +88 -0
  52. package/src/rules.ts +25 -0
  53. package/src/types.ts +3 -0
  54. package/src/utils/ast-utils.ts +391 -0
  55. package/src/utils/detect-react-query-imports.ts +97 -0
  56. package/src/utils/get-docs-url.ts +2 -0
  57. package/src/utils/unique-by.ts +3 -0
  58. package/dist/index.cjs.map +0 -1
  59. package/dist/index.js.map +0 -1
  60. package/dist/rules.cjs.map +0 -1
  61. package/dist/rules.js.map +0 -1
  62. /package/{dist → build/modern}/rules.cjs +0 -0
@@ -0,0 +1,17 @@
1
+ import { rules } from './rules.cjs';
2
+ import { ESLint, Linter } from 'eslint';
3
+ import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
4
+ import '@typescript-eslint/utils';
5
+ import './types.cjs';
6
+
7
+ type RuleKey = keyof typeof rules;
8
+ interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
9
+ rules: Record<RuleKey, RuleModule<any, any, any>>;
10
+ configs: {
11
+ recommended: ESLint.ConfigData;
12
+ 'flat/recommended': Array<Linter.Config>;
13
+ };
14
+ }
15
+ declare const plugin: Plugin;
16
+
17
+ export { type Plugin, plugin as default, plugin };
@@ -0,0 +1,17 @@
1
+ import { rules } from './rules.js';
2
+ import { ESLint, Linter } from 'eslint';
3
+ import { RuleModule } from '@typescript-eslint/utils/ts-eslint';
4
+ import '@typescript-eslint/utils';
5
+ import './types.js';
6
+
7
+ type RuleKey = keyof typeof rules;
8
+ interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
9
+ rules: Record<RuleKey, RuleModule<any, any, any>>;
10
+ configs: {
11
+ recommended: ESLint.ConfigData;
12
+ 'flat/recommended': Array<Linter.Config>;
13
+ };
14
+ }
15
+ declare const plugin: Plugin;
16
+
17
+ export { type Plugin, plugin as default, plugin };
@@ -0,0 +1,47 @@
1
+ import {
2
+ rules
3
+ } from "./chunk-6ZHBB3IQ.js";
4
+
5
+ // src/index.ts
6
+ var plugin = {
7
+ meta: {
8
+ name: "@tanstack/eslint-plugin-query"
9
+ },
10
+ configs: {},
11
+ rules
12
+ };
13
+ Object.assign(plugin.configs, {
14
+ recommended: {
15
+ plugins: ["@tanstack/query"],
16
+ rules: {
17
+ "@tanstack/query/exhaustive-deps": "error",
18
+ "@tanstack/query/no-rest-destructuring": "warn",
19
+ "@tanstack/query/stable-query-client": "error",
20
+ "@tanstack/query/no-unstable-deps": "error",
21
+ "@tanstack/query/infinite-query-property-order": "error",
22
+ "@tanstack/query/no-void-query-fn": "error"
23
+ }
24
+ },
25
+ "flat/recommended": [
26
+ {
27
+ name: "tanstack/query/flat/recommended",
28
+ plugins: {
29
+ "@tanstack/query": plugin
30
+ },
31
+ rules: {
32
+ "@tanstack/query/exhaustive-deps": "error",
33
+ "@tanstack/query/no-rest-destructuring": "warn",
34
+ "@tanstack/query/stable-query-client": "error",
35
+ "@tanstack/query/no-unstable-deps": "error",
36
+ "@tanstack/query/infinite-query-property-order": "error",
37
+ "@tanstack/query/no-void-query-fn": "error"
38
+ }
39
+ }
40
+ ]
41
+ });
42
+ var index_default = plugin;
43
+ export {
44
+ index_default as default,
45
+ plugin
46
+ };
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import { rules } from './rules'\nimport type { ESLint, Linter } from 'eslint'\nimport type { RuleModule } from '@typescript-eslint/utils/ts-eslint'\n\ntype RuleKey = keyof typeof rules\n\nexport interface Plugin extends Omit<ESLint.Plugin, 'rules'> {\n rules: Record<RuleKey, RuleModule<any, any, any>>\n configs: {\n recommended: ESLint.ConfigData\n 'flat/recommended': Array<Linter.Config>\n }\n}\n\nexport const plugin: Plugin = {\n meta: {\n name: '@tanstack/eslint-plugin-query',\n },\n configs: {} as Plugin['configs'],\n rules,\n}\n\n// Assign configs here so we can reference `plugin`\nObject.assign(plugin.configs, {\n recommended: {\n plugins: ['@tanstack/query'],\n rules: {\n '@tanstack/query/exhaustive-deps': 'error',\n '@tanstack/query/no-rest-destructuring': 'warn',\n '@tanstack/query/stable-query-client': 'error',\n '@tanstack/query/no-unstable-deps': 'error',\n '@tanstack/query/infinite-query-property-order': 'error',\n '@tanstack/query/no-void-query-fn': 'error',\n },\n },\n 'flat/recommended': [\n {\n name: 'tanstack/query/flat/recommended',\n plugins: {\n '@tanstack/query': plugin,\n },\n rules: {\n '@tanstack/query/exhaustive-deps': 'error',\n '@tanstack/query/no-rest-destructuring': 'warn',\n '@tanstack/query/stable-query-client': 'error',\n '@tanstack/query/no-unstable-deps': 'error',\n '@tanstack/query/infinite-query-property-order': 'error',\n '@tanstack/query/no-void-query-fn': 'error',\n },\n },\n ],\n})\n\nexport default plugin\n"],"mappings":";;;;;AAcO,IAAM,SAAiB;AAAA,EAC5B,MAAM;AAAA,IACJ,MAAM;AAAA,EACR;AAAA,EACA,SAAS,CAAC;AAAA,EACV;AACF;AAGA,OAAO,OAAO,OAAO,SAAS;AAAA,EAC5B,aAAa;AAAA,IACX,SAAS,CAAC,iBAAiB;AAAA,IAC3B,OAAO;AAAA,MACL,mCAAmC;AAAA,MACnC,yCAAyC;AAAA,MACzC,uCAAuC;AAAA,MACvC,oCAAoC;AAAA,MACpC,iDAAiD;AAAA,MACjD,oCAAoC;AAAA,IACtC;AAAA,EACF;AAAA,EACA,oBAAoB;AAAA,IAClB;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,QACP,mBAAmB;AAAA,MACrB;AAAA,MACA,OAAO;AAAA,QACL,mCAAmC;AAAA,QACnC,yCAAyC;AAAA,QACzC,uCAAuC;AAAA,QACvC,oCAAoC;AAAA,QACpC,iDAAiD;AAAA,QACjD,oCAAoC;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACF,CAAC;AAED,IAAO,gBAAQ;","names":[]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/rules.ts","../../src/rules/exhaustive-deps/exhaustive-deps.rule.ts","../../src/utils/ast-utils.ts","../../src/utils/unique-by.ts","../../src/utils/get-docs-url.ts","../../src/utils/detect-react-query-imports.ts","../../src/rules/exhaustive-deps/exhaustive-deps.utils.ts","../../src/rules/stable-query-client/stable-query-client.rule.ts","../../src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts","../../src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts","../../src/rules/no-unstable-deps/no-unstable-deps.rule.ts","../../src/rules/infinite-query-property-order/infinite-query-property-order.rule.ts","../../src/rules/infinite-query-property-order/infinite-query-property-order.utils.ts","../../src/rules/infinite-query-property-order/constants.ts","../../src/rules/no-void-query-fn/no-void-query-fn.rule.ts"],"sourcesContent":["import * as exhaustiveDeps from './rules/exhaustive-deps/exhaustive-deps.rule'\nimport * as stableQueryClient from './rules/stable-query-client/stable-query-client.rule'\nimport * as noRestDestructuring from './rules/no-rest-destructuring/no-rest-destructuring.rule'\nimport * as noUnstableDeps from './rules/no-unstable-deps/no-unstable-deps.rule'\nimport * as infiniteQueryPropertyOrder from './rules/infinite-query-property-order/infinite-query-property-order.rule'\nimport * as noVoidQueryFn from './rules/no-void-query-fn/no-void-query-fn.rule'\nimport type { ESLintUtils } from '@typescript-eslint/utils'\nimport type { ExtraRuleDocs } from './types'\n\nexport const rules: Record<\n string,\n ESLintUtils.RuleModule<\n string,\n ReadonlyArray<unknown>,\n ExtraRuleDocs,\n ESLintUtils.RuleListener\n >\n> = {\n [exhaustiveDeps.name]: exhaustiveDeps.rule,\n [stableQueryClient.name]: stableQueryClient.rule,\n [noRestDestructuring.name]: noRestDestructuring.rule,\n [noUnstableDeps.name]: noUnstableDeps.rule,\n [infiniteQueryPropertyOrder.name]: infiniteQueryPropertyOrder.rule,\n [noVoidQueryFn.name]: noVoidQueryFn.rule,\n}\n","import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\nimport { ASTUtils } from '../../utils/ast-utils'\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { uniqueBy } from '../../utils/unique-by'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport { ExhaustiveDepsUtils } from './exhaustive-deps.utils'\nimport type { TSESLint, TSESTree } from '@typescript-eslint/utils'\nimport type { ExtraRuleDocs } from '../../types'\n\nconst QUERY_KEY = 'queryKey'\nconst QUERY_FN = 'queryFn'\n\nexport const name = 'exhaustive-deps'\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description: 'Exhaustive deps rule for useQuery',\n recommended: 'error',\n },\n messages: {\n missingDeps: `The following dependencies are missing in your queryKey: {{deps}}`,\n fixTo: 'Fix to {{result}}',\n },\n hasSuggestions: true,\n fixable: 'code',\n schema: [],\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context) => {\n return {\n Property: (node) => {\n if (\n !ASTUtils.isObjectExpression(node.parent) ||\n !ASTUtils.isIdentifierWithName(node.key, QUERY_KEY)\n ) {\n return\n }\n\n const scopeManager = context.sourceCode.scopeManager\n const queryKey = ASTUtils.findPropertyWithIdentifierKey(\n node.parent.properties,\n QUERY_KEY,\n )\n const queryFn = ASTUtils.findPropertyWithIdentifierKey(\n node.parent.properties,\n QUERY_FN,\n )\n\n if (\n scopeManager === null ||\n queryKey === undefined ||\n queryFn === undefined ||\n !ASTUtils.isNodeOfOneOf(queryFn.value, [\n AST_NODE_TYPES.ArrowFunctionExpression,\n AST_NODE_TYPES.FunctionExpression,\n AST_NODE_TYPES.ConditionalExpression,\n ])\n ) {\n return\n }\n\n let queryKeyNode = queryKey.value\n\n if (\n queryKeyNode.type === AST_NODE_TYPES.TSAsExpression &&\n queryKeyNode.expression.type === AST_NODE_TYPES.ArrayExpression\n ) {\n queryKeyNode = queryKeyNode.expression\n }\n\n if (queryKeyNode.type === AST_NODE_TYPES.Identifier) {\n const expression = ASTUtils.getReferencedExpressionByIdentifier({\n context,\n node: queryKeyNode,\n })\n\n if (expression?.type === AST_NODE_TYPES.ArrayExpression) {\n queryKeyNode = expression\n }\n }\n\n const externalRefs = ASTUtils.getExternalRefs({\n scopeManager,\n sourceCode: context.sourceCode,\n node: getQueryFnRelevantNode(queryFn),\n })\n\n const relevantRefs = externalRefs.filter((reference) =>\n ExhaustiveDepsUtils.isRelevantReference({\n sourceCode: context.sourceCode,\n reference,\n scopeManager,\n node: getQueryFnRelevantNode(queryFn),\n }),\n )\n\n const existingKeys = ASTUtils.getNestedIdentifiers(queryKeyNode).map(\n (identifier) =>\n ASTUtils.mapKeyNodeToBaseText(identifier, context.sourceCode),\n )\n\n const missingRefs = relevantRefs\n .map((ref) => ({\n ref: ref,\n text: ASTUtils.mapKeyNodeToBaseText(\n ref.identifier,\n context.sourceCode,\n ),\n }))\n .filter(({ ref, text }) => {\n return (\n !ref.isTypeReference &&\n !ASTUtils.isAncestorIsCallee(ref.identifier) &&\n !existingKeys.some((existingKey) => existingKey === text) &&\n !existingKeys.includes(text.split(/[?.]/)[0] ?? '')\n )\n })\n .map(({ ref, text }) => ({\n identifier: ref.identifier,\n text: text,\n }))\n\n const uniqueMissingRefs = uniqueBy(missingRefs, (x) => x.text)\n\n if (uniqueMissingRefs.length > 0) {\n const missingAsText = uniqueMissingRefs\n .map((ref) =>\n ASTUtils.mapKeyNodeToText(ref.identifier, context.sourceCode),\n )\n .join(', ')\n\n const queryKeyValue = context.sourceCode.getText(queryKeyNode)\n\n const existingWithMissing =\n queryKeyValue === '[]'\n ? `[${missingAsText}]`\n : queryKeyValue.replace(/\\]$/, `, ${missingAsText}]`)\n\n const suggestions: TSESLint.ReportSuggestionArray<string> = []\n\n if (queryKeyNode.type === AST_NODE_TYPES.ArrayExpression) {\n suggestions.push({\n messageId: 'fixTo',\n data: { result: existingWithMissing },\n fix(fixer) {\n return fixer.replaceText(queryKeyNode, existingWithMissing)\n },\n })\n }\n\n context.report({\n node: node,\n messageId: 'missingDeps',\n data: {\n deps: uniqueMissingRefs.map((ref) => ref.text).join(', '),\n },\n suggest: suggestions,\n })\n }\n },\n }\n }),\n})\n\nfunction getQueryFnRelevantNode(queryFn: TSESTree.Property) {\n if (queryFn.value.type !== AST_NODE_TYPES.ConditionalExpression) {\n return queryFn.value\n }\n\n if (\n queryFn.value.consequent.type === AST_NODE_TYPES.Identifier &&\n queryFn.value.consequent.name === 'skipToken'\n ) {\n return queryFn.value.alternate\n }\n\n return queryFn.value.consequent\n}\n","import { AST_NODE_TYPES } from '@typescript-eslint/utils'\nimport { uniqueBy } from './unique-by'\nimport type { TSESLint, TSESTree } from '@typescript-eslint/utils'\n\nexport const ASTUtils = {\n isNodeOfOneOf<T extends AST_NODE_TYPES>(\n node: TSESTree.Node,\n types: ReadonlyArray<T>,\n ): node is TSESTree.Node & { type: T } {\n return types.includes(node.type as T)\n },\n isIdentifier(node: TSESTree.Node): node is TSESTree.Identifier {\n return node.type === AST_NODE_TYPES.Identifier\n },\n isIdentifierWithName(\n node: TSESTree.Node,\n name: string,\n ): node is TSESTree.Identifier {\n return ASTUtils.isIdentifier(node) && node.name === name\n },\n isIdentifierWithOneOfNames<T extends Array<string>>(\n node: TSESTree.Node,\n name: T,\n ): node is TSESTree.Identifier & { name: T[number] } {\n return ASTUtils.isIdentifier(node) && name.includes(node.name)\n },\n isProperty(node: TSESTree.Node): node is TSESTree.Property {\n return node.type === AST_NODE_TYPES.Property\n },\n isObjectExpression(node: TSESTree.Node): node is TSESTree.ObjectExpression {\n return node.type === AST_NODE_TYPES.ObjectExpression\n },\n isPropertyWithIdentifierKey(\n node: TSESTree.Node,\n key: string,\n ): node is TSESTree.Property {\n return (\n ASTUtils.isProperty(node) && ASTUtils.isIdentifierWithName(node.key, key)\n )\n },\n findPropertyWithIdentifierKey(\n properties: Array<TSESTree.ObjectLiteralElement>,\n key: string,\n ): TSESTree.Property | undefined {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n return properties.find((x) =>\n ASTUtils.isPropertyWithIdentifierKey(x, key),\n ) as TSESTree.Property | undefined\n },\n getNestedIdentifiers(node: TSESTree.Node): Array<TSESTree.Identifier> {\n const identifiers: Array<TSESTree.Identifier> = []\n\n if (ASTUtils.isIdentifier(node)) {\n identifiers.push(node)\n }\n\n if ('arguments' in node) {\n node.arguments.forEach((x) => {\n identifiers.push(...ASTUtils.getNestedIdentifiers(x))\n })\n }\n\n if ('elements' in node) {\n node.elements.forEach((x) => {\n if (x !== null) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(x))\n }\n })\n }\n\n if ('properties' in node) {\n node.properties.forEach((x) => {\n identifiers.push(...ASTUtils.getNestedIdentifiers(x))\n })\n }\n\n if ('expressions' in node) {\n node.expressions.forEach((x) => {\n identifiers.push(...ASTUtils.getNestedIdentifiers(x))\n })\n }\n\n if ('left' in node) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.left))\n }\n\n if ('right' in node) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.right))\n }\n\n if (node.type === AST_NODE_TYPES.Property) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.value))\n }\n\n if (node.type === AST_NODE_TYPES.SpreadElement) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument))\n }\n\n if (node.type === AST_NODE_TYPES.MemberExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.object))\n }\n\n if (node.type === AST_NODE_TYPES.UnaryExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument))\n }\n\n if (node.type === AST_NODE_TYPES.ChainExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.expression))\n }\n\n if (node.type === AST_NODE_TYPES.TSNonNullExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.expression))\n }\n\n if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.body))\n }\n\n if (node.type === AST_NODE_TYPES.FunctionExpression) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.body))\n }\n\n if (node.type === AST_NODE_TYPES.BlockStatement) {\n identifiers.push(\n ...node.body.map((body) => ASTUtils.getNestedIdentifiers(body)).flat(),\n )\n }\n\n if (node.type === AST_NODE_TYPES.ReturnStatement && node.argument) {\n identifiers.push(...ASTUtils.getNestedIdentifiers(node.argument))\n }\n\n return identifiers\n },\n isAncestorIsCallee(identifier: TSESTree.Node) {\n let previousNode = identifier\n let currentNode = identifier.parent\n\n while (currentNode !== undefined) {\n if (\n currentNode.type === AST_NODE_TYPES.CallExpression &&\n currentNode.callee === previousNode\n ) {\n return true\n }\n\n if (currentNode.type !== AST_NODE_TYPES.MemberExpression) {\n return false\n }\n\n previousNode = currentNode\n currentNode = currentNode.parent\n }\n\n return false\n },\n traverseUpOnly(\n identifier: TSESTree.Node,\n allowedNodeTypes: Array<AST_NODE_TYPES>,\n ): TSESTree.Node {\n const parent = identifier.parent\n\n if (parent !== undefined && allowedNodeTypes.includes(parent.type)) {\n return ASTUtils.traverseUpOnly(parent, allowedNodeTypes)\n }\n\n return identifier\n },\n isDeclaredInNode(params: {\n functionNode: TSESTree.Node\n reference: TSESLint.Scope.Reference\n scopeManager: TSESLint.Scope.ScopeManager\n }) {\n const { functionNode, reference, scopeManager } = params\n const scope = scopeManager.acquire(functionNode)\n\n if (scope === null) {\n return false\n }\n\n return scope.set.has(reference.identifier.name)\n },\n getExternalRefs(params: {\n scopeManager: TSESLint.Scope.ScopeManager\n sourceCode: Readonly<TSESLint.SourceCode>\n node: TSESTree.Node\n }): Array<TSESLint.Scope.Reference> {\n const { scopeManager, sourceCode, node } = params\n const scope = scopeManager.acquire(node)\n\n if (scope === null) {\n return []\n }\n\n const references = scope.references\n .filter((x) => x.isRead() && !scope.set.has(x.identifier.name))\n .map((x) => {\n const referenceNode = ASTUtils.traverseUpOnly(x.identifier, [\n AST_NODE_TYPES.MemberExpression,\n AST_NODE_TYPES.Identifier,\n ])\n\n return {\n variable: x,\n node: referenceNode,\n text: sourceCode.getText(referenceNode),\n }\n })\n\n const localRefIds = new Set(\n [...scope.set.values()].map((x) => sourceCode.getText(x.identifiers[0])),\n )\n\n const externalRefs = references.filter(\n (x) => x.variable.resolved === null || !localRefIds.has(x.text),\n )\n\n return uniqueBy(externalRefs, (x) => x.text).map((x) => x.variable)\n },\n mapKeyNodeToText(\n node: TSESTree.Node,\n sourceCode: Readonly<TSESLint.SourceCode>,\n ) {\n return sourceCode.getText(\n ASTUtils.traverseUpOnly(node, [\n AST_NODE_TYPES.MemberExpression,\n AST_NODE_TYPES.TSNonNullExpression,\n AST_NODE_TYPES.Identifier,\n ]),\n )\n },\n mapKeyNodeToBaseText(\n node: TSESTree.Node,\n sourceCode: Readonly<TSESLint.SourceCode>,\n ) {\n return ASTUtils.mapKeyNodeToText(node, sourceCode).replace(\n /(?:\\?(\\.)|!)/g,\n '$1',\n )\n },\n isValidReactComponentOrHookName(\n identifier: TSESTree.Identifier | null | undefined,\n ) {\n return (\n identifier !== null &&\n identifier !== undefined &&\n /^(use|[A-Z])/.test(identifier.name)\n )\n },\n getFunctionAncestor(\n sourceCode: Readonly<TSESLint.SourceCode>,\n node: TSESTree.Node,\n ) {\n for (const ancestor of sourceCode.getAncestors(node)) {\n if (\n ASTUtils.isNodeOfOneOf(ancestor, [\n AST_NODE_TYPES.FunctionDeclaration,\n AST_NODE_TYPES.FunctionExpression,\n AST_NODE_TYPES.ArrowFunctionExpression,\n ])\n ) {\n return ancestor\n }\n\n if (\n ancestor.parent?.type === AST_NODE_TYPES.VariableDeclarator &&\n ancestor.parent.id.type === AST_NODE_TYPES.Identifier &&\n ASTUtils.isNodeOfOneOf(ancestor, [\n AST_NODE_TYPES.FunctionDeclaration,\n AST_NODE_TYPES.FunctionExpression,\n AST_NODE_TYPES.ArrowFunctionExpression,\n ])\n ) {\n return ancestor\n }\n }\n\n return undefined\n },\n getReferencedExpressionByIdentifier(params: {\n node: TSESTree.Node\n context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>\n }) {\n const { node, context } = params\n\n // we need the fallbacks for backwards compat with eslint < 8.37.0\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const sourceCode = context.sourceCode ?? context.getSourceCode()\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const scope = context.sourceCode.getScope(node)\n ? sourceCode.getScope(node)\n : context.getScope()\n\n const resolvedNode = scope.references.find((ref) => ref.identifier === node)\n ?.resolved?.defs[0]?.node\n\n if (resolvedNode?.type !== AST_NODE_TYPES.VariableDeclarator) {\n return null\n }\n\n return resolvedNode.init\n },\n getClosestVariableDeclarator(node: TSESTree.Node) {\n let currentNode: TSESTree.Node | undefined = node\n\n while (currentNode.type !== AST_NODE_TYPES.Program) {\n if (currentNode.type === AST_NODE_TYPES.VariableDeclarator) {\n return currentNode\n }\n\n currentNode = currentNode.parent\n }\n\n return undefined\n },\n getNestedReturnStatements(\n node: TSESTree.Node,\n ): Array<TSESTree.ReturnStatement> {\n const returnStatements: Array<TSESTree.ReturnStatement> = []\n\n if (node.type === AST_NODE_TYPES.ReturnStatement) {\n returnStatements.push(node)\n }\n\n if ('body' in node && node.body !== undefined && node.body !== null) {\n Array.isArray(node.body)\n ? node.body.forEach((x) => {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(x))\n })\n : returnStatements.push(\n ...ASTUtils.getNestedReturnStatements(node.body),\n )\n }\n\n if ('consequent' in node) {\n Array.isArray(node.consequent)\n ? node.consequent.forEach((x) => {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(x))\n })\n : returnStatements.push(\n ...ASTUtils.getNestedReturnStatements(node.consequent),\n )\n }\n\n if ('alternate' in node && node.alternate !== null) {\n Array.isArray(node.alternate)\n ? node.alternate.forEach((x) => {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(x))\n })\n : returnStatements.push(\n ...ASTUtils.getNestedReturnStatements(node.alternate),\n )\n }\n\n if ('cases' in node) {\n node.cases.forEach((x) => {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(x))\n })\n }\n\n if ('block' in node) {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(node.block))\n }\n\n if ('handler' in node && node.handler !== null) {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(node.handler))\n }\n\n if ('finalizer' in node && node.finalizer !== null) {\n returnStatements.push(\n ...ASTUtils.getNestedReturnStatements(node.finalizer),\n )\n }\n\n if (\n 'expression' in node &&\n node.expression !== true &&\n node.expression !== false\n ) {\n returnStatements.push(\n ...ASTUtils.getNestedReturnStatements(node.expression),\n )\n }\n\n if ('test' in node && node.test !== null) {\n returnStatements.push(...ASTUtils.getNestedReturnStatements(node.test))\n }\n\n return returnStatements\n },\n}\n","export function uniqueBy<T>(arr: Array<T>, fn: (x: T) => unknown): Array<T> {\n return arr.filter((x, i, a) => a.findIndex((y) => fn(x) === fn(y)) === i)\n}\n","export const getDocsUrl = (ruleName: string): string =>\n `https://tanstack.com/query/latest/docs/eslint/${ruleName}`\n","import { TSESTree } from '@typescript-eslint/utils'\nimport type { ESLintUtils, TSESLint } from '@typescript-eslint/utils'\n\ntype Create = Parameters<\n ReturnType<typeof ESLintUtils.RuleCreator>\n>[0]['create']\n\ntype Context = Parameters<Create>[0]\ntype Options = Parameters<Create>[1]\ntype Helpers = {\n isSpecificTanstackQueryImport: (\n node: TSESTree.Identifier,\n source: string,\n ) => boolean\n isTanstackQueryImport: (node: TSESTree.Identifier) => boolean\n}\n\ntype EnhancedCreate = (\n context: Context,\n options: Options,\n helpers: Helpers,\n) => ReturnType<Create>\n\nexport function detectTanstackQueryImports(create: EnhancedCreate): Create {\n return (context, optionsWithDefault) => {\n const tanstackQueryImportSpecifiers: Array<TSESTree.ImportClause> = []\n\n const helpers: Helpers = {\n isSpecificTanstackQueryImport(node, source) {\n return !!tanstackQueryImportSpecifiers.find((specifier) => {\n if (\n specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier &&\n specifier.parent.type ===\n TSESTree.AST_NODE_TYPES.ImportDeclaration &&\n specifier.parent.source.value === source\n ) {\n return node.name === specifier.local.name\n }\n\n return false\n })\n },\n isTanstackQueryImport(node) {\n return !!tanstackQueryImportSpecifiers.find((specifier) => {\n if (specifier.type === TSESTree.AST_NODE_TYPES.ImportSpecifier) {\n return node.name === specifier.local.name\n }\n\n return false\n })\n },\n }\n\n const detectionInstructions: TSESLint.RuleListener = {\n ImportDeclaration(node) {\n if (\n node.specifiers.length > 0 &&\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n (node.importKind === 'value' || node.importKind === undefined) &&\n node.source.value.startsWith('@tanstack/') &&\n node.source.value.endsWith('-query')\n ) {\n tanstackQueryImportSpecifiers.push(...node.specifiers)\n }\n },\n }\n\n // Call original rule definition\n const ruleInstructions = create(context, optionsWithDefault, helpers)\n const enhancedRuleInstructions: TSESLint.RuleListener = {}\n\n const allKeys = new Set(\n Object.keys(detectionInstructions).concat(Object.keys(ruleInstructions)),\n )\n\n // Iterate over ALL instructions keys so we can override original rule instructions\n // to prevent their execution if conditions to report errors are not met.\n allKeys.forEach((instruction) => {\n enhancedRuleInstructions[instruction] = (node) => {\n if (instruction in detectionInstructions) {\n detectionInstructions[instruction]?.(node)\n }\n\n const ruleInstruction = ruleInstructions[instruction]\n\n // TODO: canReportErrors()\n if (ruleInstruction) {\n return ruleInstruction(node)\n }\n\n return undefined\n }\n })\n\n return enhancedRuleInstructions\n }\n}\n","import { AST_NODE_TYPES } from '@typescript-eslint/utils'\nimport { ASTUtils } from '../../utils/ast-utils'\nimport type { TSESLint, TSESTree } from '@typescript-eslint/utils'\n\nexport const ExhaustiveDepsUtils = {\n isRelevantReference(params: {\n sourceCode: Readonly<TSESLint.SourceCode>\n reference: TSESLint.Scope.Reference\n scopeManager: TSESLint.Scope.ScopeManager\n node: TSESTree.Node\n }) {\n const { sourceCode, reference, scopeManager, node } = params\n const component = ASTUtils.getFunctionAncestor(sourceCode, node)\n\n if (component === undefined) {\n return false\n }\n\n if (\n !ASTUtils.isDeclaredInNode({\n scopeManager,\n reference,\n functionNode: component,\n })\n ) {\n return false\n }\n\n return (\n reference.identifier.name !== 'undefined' &&\n reference.identifier.parent.type !== AST_NODE_TYPES.NewExpression &&\n !ExhaustiveDepsUtils.isInstanceOfKind(reference.identifier.parent)\n )\n },\n isInstanceOfKind(node: TSESTree.Node) {\n return (\n node.type === AST_NODE_TYPES.BinaryExpression &&\n node.operator === 'instanceof'\n )\n },\n}\n","import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\nimport { ASTUtils } from '../../utils/ast-utils'\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport type { TSESLint } from '@typescript-eslint/utils'\nimport type { ExtraRuleDocs } from '../../types'\n\nexport const name = 'stable-query-client'\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description: 'Makes sure that QueryClient is stable',\n recommended: 'error',\n },\n messages: {\n unstable: [\n 'QueryClient is not stable. It should be either extracted from the component or wrapped in React.useState.',\n 'See https://tkdodo.eu/blog/react-query-fa-qs#2-the-queryclient-is-not-stable',\n ].join('\\n'),\n fixTo: 'Fix to {{result}}',\n },\n hasSuggestions: true,\n fixable: 'code',\n schema: [],\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context, _, helpers) => {\n return {\n NewExpression: (node) => {\n if (\n node.callee.type !== AST_NODE_TYPES.Identifier ||\n node.callee.name !== 'QueryClient' ||\n node.parent.type !== AST_NODE_TYPES.VariableDeclarator ||\n !helpers.isSpecificTanstackQueryImport(\n node.callee,\n '@tanstack/react-query',\n )\n ) {\n return\n }\n\n const fnAncestor = ASTUtils.getFunctionAncestor(\n context.sourceCode,\n node,\n )\n const isReactServerComponent = fnAncestor?.async === true\n\n if (\n !ASTUtils.isValidReactComponentOrHookName(fnAncestor?.id) ||\n isReactServerComponent\n ) {\n return\n }\n\n context.report({\n node: node.parent,\n messageId: 'unstable',\n fix: (() => {\n const { parent } = node\n\n if (parent.id.type !== AST_NODE_TYPES.Identifier) {\n return\n }\n\n // we need the fallbacks for backwards compat with eslint < 8.37.0\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const sourceCode = context.sourceCode ?? context.getSourceCode()\n const nodeText = sourceCode.getText(node)\n const variableName = parent.id.name\n\n return (fixer: TSESLint.RuleFixer) => {\n return fixer.replaceTextRange(\n [parent.range[0], parent.range[1]],\n `[${variableName}] = React.useState(() => ${nodeText})`,\n )\n }\n })(),\n })\n },\n }\n }),\n})\n","import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { ASTUtils } from '../../utils/ast-utils'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport { NoRestDestructuringUtils } from './no-rest-destructuring.utils'\nimport type { ExtraRuleDocs } from '../../types'\n\nexport const name = 'no-rest-destructuring'\n\nconst queryHooks = [\n 'useQuery',\n 'useQueries',\n 'useInfiniteQuery',\n 'useSuspenseQuery',\n 'useSuspenseQueries',\n 'useSuspenseInfiniteQuery',\n]\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallows rest destructuring in queries',\n recommended: 'warn',\n },\n messages: {\n objectRestDestructure: `Object rest destructuring on a query will observe all changes to the query, leading to excessive re-renders.`,\n },\n schema: [],\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context, _, helpers) => {\n const queryResultVariables = new Set<string>()\n\n return {\n CallExpression: (node) => {\n if (\n !ASTUtils.isIdentifierWithOneOfNames(node.callee, queryHooks) ||\n node.parent.type !== AST_NODE_TYPES.VariableDeclarator ||\n !helpers.isTanstackQueryImport(node.callee)\n ) {\n return\n }\n\n const returnValue = node.parent.id\n\n if (\n node.callee.name !== 'useQueries' &&\n node.callee.name !== 'useSuspenseQueries'\n ) {\n if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) {\n return context.report({\n node: node.parent,\n messageId: 'objectRestDestructure',\n })\n }\n\n if (returnValue.type === AST_NODE_TYPES.Identifier) {\n queryResultVariables.add(returnValue.name)\n }\n\n return\n }\n\n if (returnValue.type !== AST_NODE_TYPES.ArrayPattern) {\n if (returnValue.type === AST_NODE_TYPES.Identifier) {\n queryResultVariables.add(returnValue.name)\n }\n return\n }\n\n returnValue.elements.forEach((queryResult) => {\n if (queryResult === null) {\n return\n }\n if (NoRestDestructuringUtils.isObjectRestDestructuring(queryResult)) {\n context.report({\n node: queryResult,\n messageId: 'objectRestDestructure',\n })\n }\n })\n },\n\n VariableDeclarator: (node) => {\n if (\n node.init?.type === AST_NODE_TYPES.Identifier &&\n queryResultVariables.has(node.init.name) &&\n NoRestDestructuringUtils.isObjectRestDestructuring(node.id)\n ) {\n context.report({\n node,\n messageId: 'objectRestDestructure',\n })\n }\n },\n\n SpreadElement: (node) => {\n if (\n node.argument.type === AST_NODE_TYPES.Identifier &&\n queryResultVariables.has(node.argument.name)\n ) {\n context.report({\n node,\n messageId: 'objectRestDestructure',\n })\n }\n },\n }\n }),\n})\n","import { AST_NODE_TYPES } from '@typescript-eslint/utils'\nimport type { TSESTree } from '@typescript-eslint/utils'\n\nexport const NoRestDestructuringUtils = {\n isObjectRestDestructuring(node: TSESTree.Node): boolean {\n if (node.type !== AST_NODE_TYPES.ObjectPattern) {\n return false\n }\n return node.properties.some((p) => p.type === AST_NODE_TYPES.RestElement)\n },\n}\n","import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport type { TSESTree } from '@typescript-eslint/utils'\nimport type { ExtraRuleDocs } from '../../types'\n\nexport const name = 'no-unstable-deps'\n\nexport const reactHookNames = ['useEffect', 'useCallback', 'useMemo']\nexport const useQueryHookNames = [\n 'useQuery',\n 'useSuspenseQuery',\n 'useQueries',\n 'useSuspenseQueries',\n 'useInfiniteQuery',\n 'useSuspenseInfiniteQuery',\n]\nconst allHookNames = ['useMutation', ...useQueryHookNames]\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow putting the result of query hooks directly in a React hook dependency array',\n recommended: 'error',\n },\n messages: {\n 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}}.`,\n },\n schema: [],\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context) => {\n const trackedVariables: Record<string, string> = {}\n const hookAliasMap: Record<string, string> = {}\n\n function getReactHook(node: TSESTree.CallExpression): string | undefined {\n if (node.callee.type === 'Identifier') {\n const calleeName = node.callee.name\n // Check if the identifier is a known React hook or an alias\n if (reactHookNames.includes(calleeName) || calleeName in hookAliasMap) {\n return calleeName\n }\n } else if (\n node.callee.type === 'MemberExpression' &&\n node.callee.object.type === 'Identifier' &&\n node.callee.object.name === 'React' &&\n node.callee.property.type === 'Identifier' &&\n reactHookNames.includes(node.callee.property.name)\n ) {\n // Member expression case: `React.useCallback`\n return node.callee.property.name\n }\n return undefined\n }\n\n function collectVariableNames(\n pattern: TSESTree.BindingName,\n queryHook: string,\n ) {\n if (pattern.type === AST_NODE_TYPES.Identifier) {\n trackedVariables[pattern.name] = queryHook\n }\n }\n\n return {\n ImportDeclaration(node: TSESTree.ImportDeclaration) {\n if (\n node.specifiers.length > 0 &&\n node.importKind === 'value' &&\n node.source.value === 'React'\n ) {\n node.specifiers.forEach((specifier) => {\n if (\n specifier.type === AST_NODE_TYPES.ImportSpecifier &&\n specifier.imported.type === AST_NODE_TYPES.Identifier &&\n reactHookNames.includes(specifier.imported.name)\n ) {\n // Track alias or direct import\n hookAliasMap[specifier.local.name] = specifier.imported.name\n }\n })\n }\n },\n\n VariableDeclarator(node) {\n if (\n node.init !== null &&\n node.init.type === AST_NODE_TYPES.CallExpression &&\n node.init.callee.type === AST_NODE_TYPES.Identifier &&\n allHookNames.includes(node.init.callee.name)\n ) {\n collectVariableNames(node.id, node.init.callee.name)\n }\n },\n CallExpression: (node) => {\n const reactHook = getReactHook(node)\n if (\n reactHook !== undefined &&\n node.arguments.length > 1 &&\n node.arguments[1]?.type === AST_NODE_TYPES.ArrayExpression\n ) {\n const depsArray = node.arguments[1].elements\n depsArray.forEach((dep) => {\n if (\n dep !== null &&\n dep.type === AST_NODE_TYPES.Identifier &&\n trackedVariables[dep.name] !== undefined\n ) {\n const queryHook = trackedVariables[dep.name]\n context.report({\n node: dep,\n messageId: 'noUnstableDeps',\n data: {\n queryHook,\n reactHook,\n },\n })\n }\n })\n }\n },\n }\n }),\n})\n","import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'\n\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport { sortDataByOrder } from './infinite-query-property-order.utils'\nimport { infiniteQueryFunctions, sortRules } from './constants'\nimport type { InfiniteQueryFunctions } from './constants'\nimport type { ExtraRuleDocs } from '../../types'\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nconst infiniteQueryFunctionsSet = new Set(infiniteQueryFunctions)\nfunction isInfiniteQueryFunction(node: any): node is InfiniteQueryFunctions {\n return infiniteQueryFunctionsSet.has(node)\n}\n\nexport const name = 'infinite-query-property-order'\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Ensure correct order of inference sensitive properties for infinite queries',\n recommended: 'error',\n },\n messages: {\n invalidOrder: 'Invalid order of properties for `{{function}}`.',\n },\n schema: [],\n hasSuggestions: true,\n fixable: 'code',\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context) => {\n return {\n CallExpression(node) {\n if (node.callee.type !== AST_NODE_TYPES.Identifier) {\n return\n }\n const infiniteQueryFunction = node.callee.name\n if (!isInfiniteQueryFunction(infiniteQueryFunction)) {\n return\n }\n const argument = node.arguments[0]\n if (argument === undefined || argument.type !== 'ObjectExpression') {\n return\n }\n\n const allProperties = argument.properties\n\n // no need to sort if there is at max 1 property\n if (allProperties.length < 2) {\n return\n }\n\n const properties = allProperties.flatMap((p, index) => {\n if (\n p.type === AST_NODE_TYPES.Property &&\n p.key.type === AST_NODE_TYPES.Identifier\n ) {\n return { name: p.key.name, property: p }\n } else return { name: `_property_${index}`, property: p }\n })\n\n const sortedProperties = sortDataByOrder(properties, sortRules, 'name')\n if (sortedProperties === null) {\n return\n }\n context.report({\n node: argument,\n data: { function: node.callee.name },\n messageId: 'invalidOrder',\n fix(fixer) {\n const sourceCode = context.sourceCode\n\n const reorderedText = sortedProperties.reduce(\n (sourceText, specifier, index) => {\n let textBetweenProperties = ''\n if (index < allProperties.length - 1) {\n textBetweenProperties = sourceCode\n .getText()\n .slice(\n allProperties[index]!.range[1],\n allProperties[index + 1]!.range[0],\n )\n }\n return (\n sourceText +\n sourceCode.getText(specifier.property) +\n textBetweenProperties\n )\n },\n '',\n )\n return fixer.replaceTextRange(\n [allProperties[0]!.range[0], allProperties.at(-1)!.range[1]],\n reorderedText,\n )\n },\n })\n },\n }\n }),\n})\n","export function sortDataByOrder<T, TKey extends keyof T>(\n data: Array<T> | ReadonlyArray<T>,\n orderRules: ReadonlyArray<\n Readonly<[ReadonlyArray<T[TKey]>, ReadonlyArray<T[TKey]>]>\n >,\n key: TKey,\n): Array<T> | null {\n const getSubsetIndex = (\n item: T[TKey],\n subsets: ReadonlyArray<ReadonlyArray<T[TKey]> | Array<T[TKey]>>,\n ): number | null => {\n for (let i = 0; i < subsets.length; i++) {\n if (subsets[i]?.includes(item)) {\n return i\n }\n }\n return null\n }\n\n const orderSets = orderRules.reduce(\n (sets, [A, B]) => [...sets, A, B],\n [] as Array<ReadonlyArray<T[TKey]> | Array<T[TKey]>>,\n )\n\n const inOrderArray = data.filter(\n (item) => getSubsetIndex(item[key], orderSets) !== null,\n )\n\n let wasResorted = false as boolean\n\n // Sort by the relative order defined by the rules\n const sortedArray = inOrderArray.sort((a, b) => {\n const aKey = a[key],\n bKey = b[key]\n const aSubsetIndex = getSubsetIndex(aKey, orderSets)\n const bSubsetIndex = getSubsetIndex(bKey, orderSets)\n\n // If both items belong to different subsets, sort by their subset order\n if (\n aSubsetIndex !== null &&\n bSubsetIndex !== null &&\n aSubsetIndex !== bSubsetIndex\n ) {\n return aSubsetIndex - bSubsetIndex\n }\n\n // If both items belong to the same subset or neither is in the subset, keep their relative order\n return 0\n })\n\n const inOrderIterator = sortedArray.values()\n const result = data.map((item) => {\n if (getSubsetIndex(item[key], orderSets) !== null) {\n const sortedItem = inOrderIterator.next().value!\n if (sortedItem[key] !== item[key]) {\n wasResorted = true\n }\n return sortedItem\n }\n return item\n })\n\n if (!wasResorted) {\n return null\n }\n return result\n}\n","export const infiniteQueryFunctions = [\n 'infiniteQueryOptions',\n 'useInfiniteQuery',\n 'useSuspenseInfiniteQuery',\n] as const\n\nexport type InfiniteQueryFunctions = (typeof infiniteQueryFunctions)[number]\n\nexport const checkedProperties = [\n 'queryFn',\n 'getPreviousPageParam',\n 'getNextPageParam',\n] as const\n\nexport const sortRules = [\n [['queryFn'], ['getPreviousPageParam', 'getNextPageParam']],\n] as const\n","import { ESLintUtils } from '@typescript-eslint/utils'\nimport ts from 'typescript'\nimport { ASTUtils } from '../../utils/ast-utils'\nimport { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'\nimport { getDocsUrl } from '../../utils/get-docs-url'\nimport type { ExtraRuleDocs } from '../../types'\n\nexport const name = 'no-void-query-fn'\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description: 'Ensures queryFn returns a non-undefined value',\n recommended: 'error',\n },\n messages: {\n noVoidReturn: 'queryFn must return a non-undefined value',\n },\n schema: [],\n },\n defaultOptions: [],\n\n create: detectTanstackQueryImports((context) => {\n return {\n Property(node) {\n if (\n !ASTUtils.isObjectExpression(node.parent) ||\n !ASTUtils.isIdentifierWithName(node.key, 'queryFn')\n ) {\n return\n }\n\n const parserServices = context.sourceCode.parserServices\n\n if (\n !parserServices ||\n !parserServices.esTreeNodeToTSNodeMap ||\n !parserServices.program\n ) {\n return\n }\n\n const checker = parserServices.program.getTypeChecker()\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node.value)\n const type = checker.getTypeAtLocation(tsNode)\n\n // Get the return type of the function\n if (type.getCallSignatures().length > 0) {\n const returnType = type.getCallSignatures()[0]?.getReturnType()\n\n if (!returnType) {\n return\n }\n\n // Check if return type is void or undefined\n if (isIllegalReturn(checker, returnType)) {\n context.report({\n node: node.value,\n messageId: 'noVoidReturn',\n })\n }\n }\n },\n }\n }),\n})\n\nfunction isIllegalReturn(checker: ts.TypeChecker, type: ts.Type): boolean {\n const awaited = checker.getAwaitedType(type)\n\n if (!awaited) return false\n\n if (awaited.isUnion()) {\n return awaited.types.some((t) => isIllegalReturn(checker, t))\n }\n\n return awaited.flags & (ts.TypeFlags.Void | ts.TypeFlags.Undefined)\n ? true\n : false\n}\n"],"mappings":"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","names":["import_utils","name","import_utils","import_utils","import_utils","name","createRule","rule","import_utils","import_utils","name","createRule","rule","import_utils","name","createRule","rule","import_utils","createRule","name","rule","import_utils","name","createRule","rule","ts","name","rule"]}
@@ -0,0 +1,6 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { ExtraRuleDocs } from './types.cjs';
3
+
4
+ declare const rules: Record<string, ESLintUtils.RuleModule<string, ReadonlyArray<unknown>, ExtraRuleDocs, ESLintUtils.RuleListener>>;
5
+
6
+ export { rules };
@@ -0,0 +1,6 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { ExtraRuleDocs } from './types.js';
3
+
4
+ declare const rules: Record<string, ESLintUtils.RuleModule<string, ReadonlyArray<unknown>, ExtraRuleDocs, ESLintUtils.RuleListener>>;
5
+
6
+ export { rules };
@@ -0,0 +1,7 @@
1
+ import {
2
+ rules
3
+ } from "./chunk-6ZHBB3IQ.js";
4
+ export {
5
+ rules
6
+ };
7
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
19
+ module.exports = module.exports.default
20
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts"],"sourcesContent":["export type ExtraRuleDocs = {\n recommended: 'strict' | 'error' | 'warn'\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,5 @@
1
+ type ExtraRuleDocs = {
2
+ recommended: 'strict' | 'error' | 'warn';
3
+ };
4
+
5
+ export type { ExtraRuleDocs };
@@ -0,0 +1,5 @@
1
+ type ExtraRuleDocs = {
2
+ recommended: 'strict' | 'error' | 'warn';
3
+ };
4
+
5
+ export type { ExtraRuleDocs };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/eslint-plugin-query",
3
- "version": "5.72.1",
3
+ "version": "5.73.3",
4
4
  "description": "ESLint plugin for TanStack Query",
5
5
  "author": "Eliya Cohen",
6
6
  "license": "MIT",
@@ -15,26 +15,28 @@
15
15
  "url": "https://github.com/sponsors/tannerlinsley"
16
16
  },
17
17
  "type": "module",
18
- "types": "dist/index.d.ts",
19
- "main": "dist/index.cjs",
20
- "module": "dist/index.js",
18
+ "types": "build/legacy/index.d.ts",
19
+ "main": "build/legacy/index.cjs",
20
+ "module": "build/legacy/index.js",
21
+ "react-native": "src/index.ts",
21
22
  "exports": {
22
23
  ".": {
23
24
  "import": {
24
- "@tanstack/custom-condition": "./src/index.ts",
25
- "types": "./dist/index.d.ts",
26
- "default": "./dist/index.js"
25
+ "types": "./build/modern/index.d.ts",
26
+ "default": "./build/modern/index.js"
27
27
  },
28
28
  "require": {
29
- "types": "./dist/index.d.cts",
30
- "default": "./dist/index.cjs"
29
+ "types": "./build/modern/index.d.cts",
30
+ "default": "./build/modern/index.cjs"
31
31
  }
32
32
  },
33
33
  "./package.json": "./package.json"
34
34
  },
35
35
  "sideEffects": false,
36
36
  "files": [
37
- "dist"
37
+ "build",
38
+ "src",
39
+ "!src/__tests__"
38
40
  ],
39
41
  "dependencies": {
40
42
  "@typescript-eslint/utils": "^8.18.1"
package/src/index.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { rules } from './rules'
2
+ import type { ESLint, Linter } from 'eslint'
3
+ import type { RuleModule } from '@typescript-eslint/utils/ts-eslint'
4
+
5
+ type RuleKey = keyof typeof rules
6
+
7
+ export interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
8
+ rules: Record<RuleKey, RuleModule<any, any, any>>
9
+ configs: {
10
+ recommended: ESLint.ConfigData
11
+ 'flat/recommended': Array<Linter.Config>
12
+ }
13
+ }
14
+
15
+ export const plugin: Plugin = {
16
+ meta: {
17
+ name: '@tanstack/eslint-plugin-query',
18
+ },
19
+ configs: {} as Plugin['configs'],
20
+ rules,
21
+ }
22
+
23
+ // Assign configs here so we can reference `plugin`
24
+ Object.assign(plugin.configs, {
25
+ recommended: {
26
+ plugins: ['@tanstack/query'],
27
+ rules: {
28
+ '@tanstack/query/exhaustive-deps': 'error',
29
+ '@tanstack/query/no-rest-destructuring': 'warn',
30
+ '@tanstack/query/stable-query-client': 'error',
31
+ '@tanstack/query/no-unstable-deps': 'error',
32
+ '@tanstack/query/infinite-query-property-order': 'error',
33
+ '@tanstack/query/no-void-query-fn': 'error',
34
+ },
35
+ },
36
+ 'flat/recommended': [
37
+ {
38
+ name: 'tanstack/query/flat/recommended',
39
+ plugins: {
40
+ '@tanstack/query': plugin,
41
+ },
42
+ rules: {
43
+ '@tanstack/query/exhaustive-deps': 'error',
44
+ '@tanstack/query/no-rest-destructuring': 'warn',
45
+ '@tanstack/query/stable-query-client': 'error',
46
+ '@tanstack/query/no-unstable-deps': 'error',
47
+ '@tanstack/query/infinite-query-property-order': 'error',
48
+ '@tanstack/query/no-void-query-fn': 'error',
49
+ },
50
+ },
51
+ ],
52
+ })
53
+
54
+ export default plugin
@@ -0,0 +1,184 @@
1
+ import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'
2
+ import { ASTUtils } from '../../utils/ast-utils'
3
+ import { getDocsUrl } from '../../utils/get-docs-url'
4
+ import { uniqueBy } from '../../utils/unique-by'
5
+ import { detectTanstackQueryImports } from '../../utils/detect-react-query-imports'
6
+ import { ExhaustiveDepsUtils } from './exhaustive-deps.utils'
7
+ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
8
+ import type { ExtraRuleDocs } from '../../types'
9
+
10
+ const QUERY_KEY = 'queryKey'
11
+ const QUERY_FN = 'queryFn'
12
+
13
+ export const name = 'exhaustive-deps'
14
+
15
+ const createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl)
16
+
17
+ export const rule = createRule({
18
+ name,
19
+ meta: {
20
+ type: 'problem',
21
+ docs: {
22
+ description: 'Exhaustive deps rule for useQuery',
23
+ recommended: 'error',
24
+ },
25
+ messages: {
26
+ missingDeps: `The following dependencies are missing in your queryKey: {{deps}}`,
27
+ fixTo: 'Fix to {{result}}',
28
+ },
29
+ hasSuggestions: true,
30
+ fixable: 'code',
31
+ schema: [],
32
+ },
33
+ defaultOptions: [],
34
+
35
+ create: detectTanstackQueryImports((context) => {
36
+ return {
37
+ Property: (node) => {
38
+ if (
39
+ !ASTUtils.isObjectExpression(node.parent) ||
40
+ !ASTUtils.isIdentifierWithName(node.key, QUERY_KEY)
41
+ ) {
42
+ return
43
+ }
44
+
45
+ const scopeManager = context.sourceCode.scopeManager
46
+ const queryKey = ASTUtils.findPropertyWithIdentifierKey(
47
+ node.parent.properties,
48
+ QUERY_KEY,
49
+ )
50
+ const queryFn = ASTUtils.findPropertyWithIdentifierKey(
51
+ node.parent.properties,
52
+ QUERY_FN,
53
+ )
54
+
55
+ if (
56
+ scopeManager === null ||
57
+ queryKey === undefined ||
58
+ queryFn === undefined ||
59
+ !ASTUtils.isNodeOfOneOf(queryFn.value, [
60
+ AST_NODE_TYPES.ArrowFunctionExpression,
61
+ AST_NODE_TYPES.FunctionExpression,
62
+ AST_NODE_TYPES.ConditionalExpression,
63
+ ])
64
+ ) {
65
+ return
66
+ }
67
+
68
+ let queryKeyNode = queryKey.value
69
+
70
+ if (
71
+ queryKeyNode.type === AST_NODE_TYPES.TSAsExpression &&
72
+ queryKeyNode.expression.type === AST_NODE_TYPES.ArrayExpression
73
+ ) {
74
+ queryKeyNode = queryKeyNode.expression
75
+ }
76
+
77
+ if (queryKeyNode.type === AST_NODE_TYPES.Identifier) {
78
+ const expression = ASTUtils.getReferencedExpressionByIdentifier({
79
+ context,
80
+ node: queryKeyNode,
81
+ })
82
+
83
+ if (expression?.type === AST_NODE_TYPES.ArrayExpression) {
84
+ queryKeyNode = expression
85
+ }
86
+ }
87
+
88
+ const externalRefs = ASTUtils.getExternalRefs({
89
+ scopeManager,
90
+ sourceCode: context.sourceCode,
91
+ node: getQueryFnRelevantNode(queryFn),
92
+ })
93
+
94
+ const relevantRefs = externalRefs.filter((reference) =>
95
+ ExhaustiveDepsUtils.isRelevantReference({
96
+ sourceCode: context.sourceCode,
97
+ reference,
98
+ scopeManager,
99
+ node: getQueryFnRelevantNode(queryFn),
100
+ }),
101
+ )
102
+
103
+ const existingKeys = ASTUtils.getNestedIdentifiers(queryKeyNode).map(
104
+ (identifier) =>
105
+ ASTUtils.mapKeyNodeToBaseText(identifier, context.sourceCode),
106
+ )
107
+
108
+ const missingRefs = relevantRefs
109
+ .map((ref) => ({
110
+ ref: ref,
111
+ text: ASTUtils.mapKeyNodeToBaseText(
112
+ ref.identifier,
113
+ context.sourceCode,
114
+ ),
115
+ }))
116
+ .filter(({ ref, text }) => {
117
+ return (
118
+ !ref.isTypeReference &&
119
+ !ASTUtils.isAncestorIsCallee(ref.identifier) &&
120
+ !existingKeys.some((existingKey) => existingKey === text) &&
121
+ !existingKeys.includes(text.split(/[?.]/)[0] ?? '')
122
+ )
123
+ })
124
+ .map(({ ref, text }) => ({
125
+ identifier: ref.identifier,
126
+ text: text,
127
+ }))
128
+
129
+ const uniqueMissingRefs = uniqueBy(missingRefs, (x) => x.text)
130
+
131
+ if (uniqueMissingRefs.length > 0) {
132
+ const missingAsText = uniqueMissingRefs
133
+ .map((ref) =>
134
+ ASTUtils.mapKeyNodeToText(ref.identifier, context.sourceCode),
135
+ )
136
+ .join(', ')
137
+
138
+ const queryKeyValue = context.sourceCode.getText(queryKeyNode)
139
+
140
+ const existingWithMissing =
141
+ queryKeyValue === '[]'
142
+ ? `[${missingAsText}]`
143
+ : queryKeyValue.replace(/\]$/, `, ${missingAsText}]`)
144
+
145
+ const suggestions: TSESLint.ReportSuggestionArray<string> = []
146
+
147
+ if (queryKeyNode.type === AST_NODE_TYPES.ArrayExpression) {
148
+ suggestions.push({
149
+ messageId: 'fixTo',
150
+ data: { result: existingWithMissing },
151
+ fix(fixer) {
152
+ return fixer.replaceText(queryKeyNode, existingWithMissing)
153
+ },
154
+ })
155
+ }
156
+
157
+ context.report({
158
+ node: node,
159
+ messageId: 'missingDeps',
160
+ data: {
161
+ deps: uniqueMissingRefs.map((ref) => ref.text).join(', '),
162
+ },
163
+ suggest: suggestions,
164
+ })
165
+ }
166
+ },
167
+ }
168
+ }),
169
+ })
170
+
171
+ function getQueryFnRelevantNode(queryFn: TSESTree.Property) {
172
+ if (queryFn.value.type !== AST_NODE_TYPES.ConditionalExpression) {
173
+ return queryFn.value
174
+ }
175
+
176
+ if (
177
+ queryFn.value.consequent.type === AST_NODE_TYPES.Identifier &&
178
+ queryFn.value.consequent.name === 'skipToken'
179
+ ) {
180
+ return queryFn.value.alternate
181
+ }
182
+
183
+ return queryFn.value.consequent
184
+ }
@@ -0,0 +1,41 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2
+ import { ASTUtils } from '../../utils/ast-utils'
3
+ import type { TSESLint, TSESTree } from '@typescript-eslint/utils'
4
+
5
+ export const ExhaustiveDepsUtils = {
6
+ isRelevantReference(params: {
7
+ sourceCode: Readonly<TSESLint.SourceCode>
8
+ reference: TSESLint.Scope.Reference
9
+ scopeManager: TSESLint.Scope.ScopeManager
10
+ node: TSESTree.Node
11
+ }) {
12
+ const { sourceCode, reference, scopeManager, node } = params
13
+ const component = ASTUtils.getFunctionAncestor(sourceCode, node)
14
+
15
+ if (component === undefined) {
16
+ return false
17
+ }
18
+
19
+ if (
20
+ !ASTUtils.isDeclaredInNode({
21
+ scopeManager,
22
+ reference,
23
+ functionNode: component,
24
+ })
25
+ ) {
26
+ return false
27
+ }
28
+
29
+ return (
30
+ reference.identifier.name !== 'undefined' &&
31
+ reference.identifier.parent.type !== AST_NODE_TYPES.NewExpression &&
32
+ !ExhaustiveDepsUtils.isInstanceOfKind(reference.identifier.parent)
33
+ )
34
+ },
35
+ isInstanceOfKind(node: TSESTree.Node) {
36
+ return (
37
+ node.type === AST_NODE_TYPES.BinaryExpression &&
38
+ node.operator === 'instanceof'
39
+ )
40
+ },
41
+ }