From ac7232f46a7dc08ed5ae0dd3728fe52c26417875 Mon Sep 17 00:00:00 2001 From: minjee Date: Sun, 31 Dec 2023 13:51:46 +0000 Subject: [PATCH 1/4] feat(eslint-plugin): add `no-callbacks` rule --- .../src/configs/index.test.ts | 1 + .../eslint-plugin-query/src/rules/index.ts | 2 + .../rules/no-callbacks/no-callbacks.rule.ts | 160 +++++++++++ .../rules/no-callbacks/no-callbacks.test.ts | 254 ++++++++++++++++++ 4 files changed, 417 insertions(+) create mode 100644 packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts create mode 100644 packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts diff --git a/packages/eslint-plugin-query/src/configs/index.test.ts b/packages/eslint-plugin-query/src/configs/index.test.ts index 6bab6df741..0d2413d60d 100644 --- a/packages/eslint-plugin-query/src/configs/index.test.ts +++ b/packages/eslint-plugin-query/src/configs/index.test.ts @@ -10,6 +10,7 @@ describe('configs', () => { ], "rules": { "@tanstack/query/exhaustive-deps": "error", + "@tanstack/query/no-callbacks": "error", "@tanstack/query/prefer-query-object-syntax": "error", "@tanstack/query/stable-query-client": "error", }, diff --git a/packages/eslint-plugin-query/src/rules/index.ts b/packages/eslint-plugin-query/src/rules/index.ts index 392479bf6b..d17d512873 100644 --- a/packages/eslint-plugin-query/src/rules/index.ts +++ b/packages/eslint-plugin-query/src/rules/index.ts @@ -1,9 +1,11 @@ import * as exhaustiveDeps from './exhaustive-deps/exhaustive-deps.rule' +import * as noCallbacks from './no-callbacks/no-callbacks.rule' import * as preferObjectSyntax from './prefer-query-object-syntax/prefer-query-object-syntax' import * as stableQueryClient from './stable-query-client/stable-query-client.rule' export const rules = { [exhaustiveDeps.name]: exhaustiveDeps.rule, + [noCallbacks.name]: noCallbacks.rule, [preferObjectSyntax.name]: preferObjectSyntax.rule, [stableQueryClient.name]: stableQueryClient.rule, } diff --git a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts b/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts new file mode 100644 index 0000000000..ef1f0580ab --- /dev/null +++ b/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts @@ -0,0 +1,160 @@ +import { AST_NODE_TYPES } from '@typescript-eslint/utils' +import { createRule } from '../../utils/create-rule' +import { ASTUtils } from '../../utils/ast-utils' +import type { TSESLint, TSESTree } from '@typescript-eslint/utils' + +const ON_SUCCESS = 'onSuccess' +const ON_ERROR = 'onError' +const ON_SETTLED = 'onSettled' + +const CALLBACKS = [ON_SUCCESS, ON_ERROR, ON_SETTLED] + +const QUERY_CALLS = ['useQuery'] + +const messages = { + noCallbacks: `The following callbacks will be removed in the next major version: {{callbacks}}`, +} + +type MessageKey = keyof typeof messages + +export const name = 'no-callbacks' + +export const rule: TSESLint.RuleModule = + createRule({ + name, + meta: { + type: 'problem', + docs: { + description: 'Makes sure that deprecated callbacks are not used', + recommended: 'error', + }, + messages: messages, + schema: [], + }, + defaultOptions: [], + + create(context, _, helpers) { + return { + CallExpression(node) { + if ( + !ASTUtils.isIdentifierWithOneOfNames(node.callee, QUERY_CALLS) || + !helpers.isTanstackQueryImport(node.callee) + ) { + return + } + + const firstArgument = node.arguments[0] + + if (!firstArgument) { + return + } + + if ( + node.arguments.length === 1 && + firstArgument.type === AST_NODE_TYPES.CallExpression + ) { + const referencedCallExpression = + ASTUtils.getReferencedExpressionByIdentifier({ + context, + node: firstArgument.callee, + }) + + if ( + referencedCallExpression === null || + !ASTUtils.isNodeOfOneOf(referencedCallExpression, [ + AST_NODE_TYPES.ArrowFunctionExpression, + AST_NODE_TYPES.FunctionDeclaration, + AST_NODE_TYPES.FunctionExpression, + ]) + ) { + return + } + + if ( + referencedCallExpression.type === + AST_NODE_TYPES.ArrowFunctionExpression && + referencedCallExpression.expression + ) { + return runCheckOnNode({ + context: context, + callNode: node, + expression: referencedCallExpression.body, + messageId: 'noCallbacks', + }) + } + + const returnStmts = ASTUtils.getNestedReturnStatements( + referencedCallExpression, + ) + + for (const stmt of returnStmts) { + if (stmt.argument === null) { + return + } + + runCheckOnNode({ + context: context, + callNode: node, + expression: stmt.argument, + messageId: 'noCallbacks', + }) + } + + return + } + + if (firstArgument.type === AST_NODE_TYPES.Identifier) { + const referencedNode = ASTUtils.getReferencedExpressionByIdentifier( + { + context, + node: firstArgument, + }, + ) + + if (referencedNode?.type === AST_NODE_TYPES.ObjectExpression) { + return runCheckOnNode({ + context: context, + callNode: node, + expression: referencedNode, + messageId: 'noCallbacks', + }) + } + } + + runCheckOnNode({ + context: context, + callNode: node, + expression: firstArgument, + messageId: 'noCallbacks', + }) + }, + } + }, + }) + +function runCheckOnNode(params: { + context: Readonly> + callNode: TSESTree.CallExpression + expression: TSESTree.Node + messageId: MessageKey +}) { + const { context, expression, messageId, callNode } = params + + const callbacks = CALLBACKS.filter((callback) => + [expression, ...callNode.arguments].some( + (node) => + node.type === AST_NODE_TYPES.ObjectExpression && + ASTUtils.findPropertyWithIdentifierKey(node.properties, callback), + ), + ) + + if (callbacks.length > 0) { + context.report({ + node: callNode, + messageId, + data: { + callbacks: callbacks.join(', '), + }, + }) + } +} diff --git a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts b/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts new file mode 100644 index 0000000000..fd12789c49 --- /dev/null +++ b/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts @@ -0,0 +1,254 @@ +import { ESLintUtils } from '@typescript-eslint/utils' +import { normalizeIndent } from '../../utils/test-utils' +import { name, rule } from './no-callbacks.rule' + +const ruleTester = new ESLintUtils.RuleTester({ + parser: '@typescript-eslint/parser', + settings: {}, +}) + +ruleTester.run(name, rule, { + valid: [ + { + code: normalizeIndent` + useQuery() + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery(); + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery({ queryKey, queryFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const result = useQuery({ queryKey, queryFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { createQuery } from "@tanstack/solid-query"; + const result = createQuery({ queryKey, queryFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { useQuery } from "somewhere-else"; + useQuery(queryKey, queryFn, { enabled }); + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getPosts = async () => Promise.resolve([]); + const postsQuery = { queryKey: ["posts"], queryFn: () => getPosts() }; + const usePosts = () => useQuery(postsQuery); + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = () => ({ queryKey: ['foo'], queryFn: () => Promise.resolve(5) }) + useQuery(getQuery()) + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = () => { + return { queryKey: ['foo'], queryFn: () => Promise.resolve(5) }; + } + useQuery(getQuery()) + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = () => { + const queryKey = () => ['foo']; + const queryFn = () => { + return Promise.resolve(5); + } + return { queryKey, queryFn }; + } + useQuery(getQuery()) + `, + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = () => { + try { + return { queryKey: ['foo'], queryFn: () => Promise.resolve(5) }; + } finally { + return { queryKey: ['foo'], queryFn: () => Promise.resolve(5) }; + } + } + useQuery(getQuery()) + `, + }, + { + code: normalizeIndent` + useMutation() + `, + }, + { + code: normalizeIndent` + import { useMutation } from "@tanstack/react-query"; + useMutation(); + `, + }, + { + code: normalizeIndent` + import { useMutation } from "@tanstack/react-query"; + useMutation({ mutationKey, mutationFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { useMutation } from "@tanstack/react-query"; + const result = useMutation({ mutationKey, mutationFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { createMutation } from "@tanstack/solid-query"; + const result = createMutation({ mutationKey, mutationFn, enabled }); + `, + }, + { + code: normalizeIndent` + import { useMutation } from "somewhere-else"; + useMutation(mutationKey, mutationFn, { enabled }); + `, + }, + { + code: normalizeIndent` + import { useMutation } from "@tanstack/react-query"; + const getPosts = async () => Promise.resolve([]); + const postsQuery = { mutationKey: ["posts"], mutationFn: () => getPosts() }; + const usePosts = () => useMutation(postsQuery); + `, + }, + ], + + invalid: [ + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery({ queryKey, queryFn, enabled, onSuccess: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery({ queryKey, queryFn, enabled, onError: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery({ queryKey, queryFn, enabled, onSettled: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery(queryKey, queryFn, { enabled, onSuccess: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = () => ({ queryKey: ['foo'], onSuccess: () => {} }) + useQuery(getQuery()) + `, + errors: [{ messageId: 'noCallbacks' }], + }, + + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery(['data'], () => fetchData(), { enabled: false, onSuccess: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery(queryKey, { queryFn, enabled, onSuccess: () => {} }); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = (x) => { + try { + return { queryKey: "foo", queryFn: () => Promise.resolve(1), onSuccess: () => {} }; + } catch (e) { + if (x > 1) { + return { queryKey: "bar", queryFn: () => Promise.resolve(2) }; + } else { + return null; + } + } + }; + useQuery(getQuery(x)); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = (x) => { + switch (x) { + case 1: + return { queryKey: "foo", queryFn: () => Promise.resolve(1), onSuccess: () => {} }; + default: + return null; + } + }; + useQuery(getQuery(x)); + `, + errors: [{ messageId: 'noCallbacks' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + const getQuery = (x, y) => { + if (x) { + return { queryKey: "foo", queryFn: () => Promise.resolve(1), onSuccess: () => {}, onError: () => {} }; + } else { + if (y) { + return { queryKey: "bar", queryFn: () => Promise.resolve(2) }; + } else { + return () => Promise.resolve(3); + } + } + }; + useQuery(getQuery(x)); + `, + errors: [ + { + messageId: 'noCallbacks', + data: { + callbacks: 'onSuccess, onError', + }, + }, + ], + }, + ], +}) From d7217d1ce1d88dab658ffe1c48ca0ad333e3fb48 Mon Sep 17 00:00:00 2001 From: minjee Date: Fri, 5 Jan 2024 19:03:15 +0000 Subject: [PATCH 2/4] rename rule and add docs --- docs/config.json | 4 ++ docs/react/eslint/eslint-plugin-query.md | 1 + docs/react/eslint/no-deprecated-options.md | 65 +++++++++++++++++++ .../src/configs/index.test.ts | 2 +- .../eslint-plugin-query/src/rules/index.ts | 2 +- .../no-deprecated-options.rule.ts} | 2 +- .../no-deprecated-options.test.ts} | 2 +- 7 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 docs/react/eslint/no-deprecated-options.md rename packages/eslint-plugin-query/src/rules/{no-callbacks/no-callbacks.rule.ts => no-deprecated-options/no-deprecated-options.rule.ts} (99%) rename packages/eslint-plugin-query/src/rules/{no-callbacks/no-callbacks.test.ts => no-deprecated-options/no-deprecated-options.test.ts} (99%) diff --git a/docs/config.json b/docs/config.json index bde7e2d5df..b87d7987ef 100644 --- a/docs/config.json +++ b/docs/config.json @@ -303,6 +303,10 @@ "label": "Exhaustive Deps", "to": "react/eslint/exhaustive-deps" }, + { + "label": "No deprecated options", + "to": "react/eslint/no-deprecated-options" + }, { "label": "Prefer object syntax", "to": "react/eslint/prefer-query-object-syntax" diff --git a/docs/react/eslint/eslint-plugin-query.md b/docs/react/eslint/eslint-plugin-query.md index e470a59f19..e7132497b1 100644 --- a/docs/react/eslint/eslint-plugin-query.md +++ b/docs/react/eslint/eslint-plugin-query.md @@ -33,6 +33,7 @@ Then configure the rules you want to use under the rules section: { "rules": { "@tanstack/query/exhaustive-deps": "error", + "@tanstack/query/no-deprecated-options": "error", "@tanstack/query/prefer-query-object-syntax": "error", "@tanstack/query/stable-query-client": "error" } diff --git a/docs/react/eslint/no-deprecated-options.md b/docs/react/eslint/no-deprecated-options.md new file mode 100644 index 0000000000..eb5501ccb4 --- /dev/null +++ b/docs/react/eslint/no-deprecated-options.md @@ -0,0 +1,65 @@ +--- +id: no-deprecated-options +title: Disallowing deprecated options +--- + +This rule warns about deprecated [`useQuery`](https://tanstack.com/query/v4/docs/reference/useQuery) options which will be removed in [TanStack Query v5](https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5). + +## Rule Details + +Examples of **incorrect** code for this rule: + +```tsx +/* eslint "@tanstack/query/no-deprecated-options": "error" */ + +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), + onSuccess: () => {}, +}) + +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), + onError: () => {}, +}) + +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), + onSettled: () => {}, +}) + +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), + isDataEqual: (oldData, newData) => customCheck(oldData, newData), +}) +``` + +Examples of **correct** code for this rule: + +```tsx +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), +}) + +useQuery({ + queryKey: ['todo', todoId], + queryFn: () => api.getTodo(todoId), + structuralSharing: (oldData, newData) => + customCheck(oldData, newData) + ? oldData + : replaceEqualDeep(oldData, newData), +}) +``` + +## When Not To Use It + +If you don't plan to upgrade to TanStack Query v5, then you will not need this rule. + +## Attributes + +- [x] ✅ Recommended +- [ ] 🔧 Fixable diff --git a/packages/eslint-plugin-query/src/configs/index.test.ts b/packages/eslint-plugin-query/src/configs/index.test.ts index 0d2413d60d..4cd8c5312b 100644 --- a/packages/eslint-plugin-query/src/configs/index.test.ts +++ b/packages/eslint-plugin-query/src/configs/index.test.ts @@ -10,7 +10,7 @@ describe('configs', () => { ], "rules": { "@tanstack/query/exhaustive-deps": "error", - "@tanstack/query/no-callbacks": "error", + "@tanstack/query/no-deprecated-options": "error", "@tanstack/query/prefer-query-object-syntax": "error", "@tanstack/query/stable-query-client": "error", }, diff --git a/packages/eslint-plugin-query/src/rules/index.ts b/packages/eslint-plugin-query/src/rules/index.ts index d17d512873..618d5d406b 100644 --- a/packages/eslint-plugin-query/src/rules/index.ts +++ b/packages/eslint-plugin-query/src/rules/index.ts @@ -1,5 +1,5 @@ import * as exhaustiveDeps from './exhaustive-deps/exhaustive-deps.rule' -import * as noCallbacks from './no-callbacks/no-callbacks.rule' +import * as noCallbacks from './no-deprecated-options/no-deprecated-options.rule' import * as preferObjectSyntax from './prefer-query-object-syntax/prefer-query-object-syntax' import * as stableQueryClient from './stable-query-client/stable-query-client.rule' diff --git a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts similarity index 99% rename from packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts rename to packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts index ef1f0580ab..b4cdb4170f 100644 --- a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.rule.ts +++ b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts @@ -17,7 +17,7 @@ const messages = { type MessageKey = keyof typeof messages -export const name = 'no-callbacks' +export const name = 'no-deprecated-options' export const rule: TSESLint.RuleModule = createRule({ diff --git a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts similarity index 99% rename from packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts rename to packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts index fd12789c49..42c872da58 100644 --- a/packages/eslint-plugin-query/src/rules/no-callbacks/no-callbacks.test.ts +++ b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts @@ -1,6 +1,6 @@ import { ESLintUtils } from '@typescript-eslint/utils' import { normalizeIndent } from '../../utils/test-utils' -import { name, rule } from './no-callbacks.rule' +import { name, rule } from './no-deprecated-options.rule' const ruleTester = new ESLintUtils.RuleTester({ parser: '@typescript-eslint/parser', From c6039539b2028898e6f6c86d72783a8bcdef53cd Mon Sep 17 00:00:00 2001 From: minjee Date: Fri, 5 Jan 2024 19:44:49 +0000 Subject: [PATCH 3/4] handle isDataEqual and improve rule --- .../no-deprecated-options.rule.ts | 54 ++++++++++--------- .../no-deprecated-options.test.ts | 35 +++++++----- 2 files changed, 52 insertions(+), 37 deletions(-) diff --git a/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts index b4cdb4170f..97ec1e0731 100644 --- a/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts +++ b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.rule.ts @@ -6,13 +6,19 @@ import type { TSESLint, TSESTree } from '@typescript-eslint/utils' const ON_SUCCESS = 'onSuccess' const ON_ERROR = 'onError' const ON_SETTLED = 'onSettled' +const IS_DATA_EQUAL = 'isDataEqual' -const CALLBACKS = [ON_SUCCESS, ON_ERROR, ON_SETTLED] +const DEPRECATED_OPTIONS = [ + ON_SUCCESS, + ON_ERROR, + ON_SETTLED, + IS_DATA_EQUAL, +] as const -const QUERY_CALLS = ['useQuery'] +const QUERY_CALLS = ['useQuery' as const] const messages = { - noCallbacks: `The following callbacks will be removed in the next major version: {{callbacks}}`, + noDeprecatedOptions: `Option \`{{option}}\` will be removed in the next major version`, } type MessageKey = keyof typeof messages @@ -25,7 +31,7 @@ export const rule: TSESLint.RuleModule = meta: { type: 'problem', docs: { - description: 'Makes sure that deprecated callbacks are not used', + description: 'Disallows deprecated options', recommended: 'error', }, messages: messages, @@ -79,7 +85,7 @@ export const rule: TSESLint.RuleModule = context: context, callNode: node, expression: referencedCallExpression.body, - messageId: 'noCallbacks', + messageId: 'noDeprecatedOptions', }) } @@ -96,7 +102,7 @@ export const rule: TSESLint.RuleModule = context: context, callNode: node, expression: stmt.argument, - messageId: 'noCallbacks', + messageId: 'noDeprecatedOptions', }) } @@ -116,7 +122,7 @@ export const rule: TSESLint.RuleModule = context: context, callNode: node, expression: referencedNode, - messageId: 'noCallbacks', + messageId: 'noDeprecatedOptions', }) } } @@ -125,7 +131,7 @@ export const rule: TSESLint.RuleModule = context: context, callNode: node, expression: firstArgument, - messageId: 'noCallbacks', + messageId: 'noDeprecatedOptions', }) }, } @@ -140,21 +146,21 @@ function runCheckOnNode(params: { }) { const { context, expression, messageId, callNode } = params - const callbacks = CALLBACKS.filter((callback) => - [expression, ...callNode.arguments].some( - (node) => - node.type === AST_NODE_TYPES.ObjectExpression && - ASTUtils.findPropertyWithIdentifierKey(node.properties, callback), - ), - ) - - if (callbacks.length > 0) { - context.report({ - node: callNode, - messageId, - data: { - callbacks: callbacks.join(', '), - }, - }) + const nodes = new Set([expression, ...callNode.arguments]) + + for (const node of nodes) { + for (const option of DEPRECATED_OPTIONS) { + if (node.type !== AST_NODE_TYPES.ObjectExpression) { + continue + } + + const property = ASTUtils.findPropertyWithIdentifierKey( + node.properties, + option, + ) + if (property) { + context.report({ node: property, messageId, data: { option } }) + } + } } } diff --git a/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts index 42c872da58..249a3ad449 100644 --- a/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts +++ b/packages/eslint-plugin-query/src/rules/no-deprecated-options/no-deprecated-options.test.ts @@ -145,28 +145,35 @@ ruleTester.run(name, rule, { import { useQuery } from "@tanstack/react-query"; useQuery({ queryKey, queryFn, enabled, onSuccess: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` import { useQuery } from "@tanstack/react-query"; useQuery({ queryKey, queryFn, enabled, onError: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` import { useQuery } from "@tanstack/react-query"; useQuery({ queryKey, queryFn, enabled, onSettled: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], + }, + { + code: normalizeIndent` + import { useQuery } from "@tanstack/react-query"; + useQuery({ queryKey, queryFn, enabled, isDataEqual: () => {} }); + `, + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` import { useQuery } from "@tanstack/react-query"; useQuery(queryKey, queryFn, { enabled, onSuccess: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` @@ -174,7 +181,7 @@ ruleTester.run(name, rule, { const getQuery = () => ({ queryKey: ['foo'], onSuccess: () => {} }) useQuery(getQuery()) `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { @@ -182,14 +189,14 @@ ruleTester.run(name, rule, { import { useQuery } from "@tanstack/react-query"; useQuery(['data'], () => fetchData(), { enabled: false, onSuccess: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` import { useQuery } from "@tanstack/react-query"; useQuery(queryKey, { queryFn, enabled, onSuccess: () => {} }); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { @@ -208,7 +215,7 @@ ruleTester.run(name, rule, { }; useQuery(getQuery(x)); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` @@ -223,7 +230,7 @@ ruleTester.run(name, rule, { }; useQuery(getQuery(x)); `, - errors: [{ messageId: 'noCallbacks' }], + errors: [{ messageId: 'noDeprecatedOptions' }], }, { code: normalizeIndent` @@ -243,10 +250,12 @@ ruleTester.run(name, rule, { `, errors: [ { - messageId: 'noCallbacks', - data: { - callbacks: 'onSuccess, onError', - }, + messageId: 'noDeprecatedOptions', + data: { option: 'onSuccess' }, + }, + { + messageId: 'noDeprecatedOptions', + data: { option: 'onError' }, }, ], }, From 69a0c87e624e651607083b2b35e78e4d9e8e9613 Mon Sep 17 00:00:00 2001 From: minjee Date: Fri, 5 Jan 2024 19:54:35 +0000 Subject: [PATCH 4/4] rename a reference --- packages/eslint-plugin-query/src/rules/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin-query/src/rules/index.ts b/packages/eslint-plugin-query/src/rules/index.ts index 618d5d406b..ae01c20916 100644 --- a/packages/eslint-plugin-query/src/rules/index.ts +++ b/packages/eslint-plugin-query/src/rules/index.ts @@ -1,11 +1,11 @@ import * as exhaustiveDeps from './exhaustive-deps/exhaustive-deps.rule' -import * as noCallbacks from './no-deprecated-options/no-deprecated-options.rule' +import * as noDeprecatedOptions from './no-deprecated-options/no-deprecated-options.rule' import * as preferObjectSyntax from './prefer-query-object-syntax/prefer-query-object-syntax' import * as stableQueryClient from './stable-query-client/stable-query-client.rule' export const rules = { [exhaustiveDeps.name]: exhaustiveDeps.rule, - [noCallbacks.name]: noCallbacks.rule, + [noDeprecatedOptions.name]: noDeprecatedOptions.rule, [preferObjectSyntax.name]: preferObjectSyntax.rule, [stableQueryClient.name]: stableQueryClient.rule, }