snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
25
packages/query-codemods/eslint.config.js
Normal file
25
packages/query-codemods/eslint.config.js
Normal file
@@ -0,0 +1,25 @@
|
||||
// @ts-check
|
||||
|
||||
import rootConfig from './root.eslint.config.js'
|
||||
|
||||
export default [
|
||||
...rootConfig,
|
||||
{
|
||||
rules: {
|
||||
'cspell/spellchecker': 'off',
|
||||
'@typescript-eslint/no-unnecessary-condition': 'off',
|
||||
'import/no-duplicates': 'off',
|
||||
'import/no-unresolved': 'off',
|
||||
'import/order': 'off',
|
||||
'no-shadow': 'off',
|
||||
'sort-imports': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['src/**/__testfixtures__/**'],
|
||||
rules: {
|
||||
// Codemod fixtures intentionally preserve historical QueryClient syntax.
|
||||
'no-restricted-syntax': 'off',
|
||||
},
|
||||
},
|
||||
]
|
||||
38
packages/query-codemods/package.json
Normal file
38
packages/query-codemods/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@tanstack/query-codemods",
|
||||
"private": true,
|
||||
"description": "Collection of codemods to make the migration easier.",
|
||||
"author": "Balázs Máté Petró",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/TanStack/query.git",
|
||||
"directory": "packages/query-codemods"
|
||||
},
|
||||
"homepage": "https://tanstack.com/query",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "premove ./coverage ./dist-ts",
|
||||
"test:eslint": "eslint --concurrency=auto ./src",
|
||||
"test:lib": "vitest",
|
||||
"test:lib:dev": "pnpm run test:lib --watch"
|
||||
},
|
||||
"type": "module",
|
||||
"exports": {
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"src",
|
||||
"!src/jest.config.js",
|
||||
"!src/**/__testfixtures__",
|
||||
"!src/**/__tests__"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/jscodeshift": "17.3.0",
|
||||
"jscodeshift": "17.3.0"
|
||||
}
|
||||
}
|
||||
1
packages/query-codemods/root.eslint.config.js
Symbolic link
1
packages/query-codemods/root.eslint.config.js
Symbolic link
@@ -0,0 +1 @@
|
||||
../../eslint.config.js
|
||||
208
packages/query-codemods/src/utils/index.cjs
Normal file
208
packages/query-codemods/src/utils/index.cjs
Normal file
@@ -0,0 +1,208 @@
|
||||
module.exports = ({ root, jscodeshift }) => {
|
||||
const findImportIdentifierOf = (importSpecifiers, identifier) => {
|
||||
const specifier = importSpecifiers
|
||||
.filter((node) => node.value.imported.name === identifier)
|
||||
.paths()
|
||||
|
||||
if (specifier.length > 0) {
|
||||
return specifier[0].value.local
|
||||
}
|
||||
|
||||
return jscodeshift.identifier(identifier)
|
||||
}
|
||||
|
||||
const findImportSpecifiers = (packageName) =>
|
||||
root
|
||||
.find(jscodeshift.ImportDeclaration, {
|
||||
source: {
|
||||
value: packageName,
|
||||
},
|
||||
})
|
||||
.find(jscodeshift.ImportSpecifier, {})
|
||||
|
||||
const locateImports = (
|
||||
identifiers,
|
||||
packageName = '@tanstack/react-query',
|
||||
) => {
|
||||
const findNamespaceImportIdentifier = () => {
|
||||
const specifier = root
|
||||
.find(jscodeshift.ImportDeclaration, {
|
||||
source: {
|
||||
value: packageName,
|
||||
},
|
||||
})
|
||||
.find(jscodeshift.ImportNamespaceSpecifier)
|
||||
.paths()
|
||||
|
||||
return specifier.length > 0 ? specifier[0].value.local : null
|
||||
}
|
||||
|
||||
/**
|
||||
* First, we search for the namespace import identifier because if we have any, we assume the consumer uses
|
||||
* namespace imports. In this case, we won't search for named imports at all.
|
||||
*/
|
||||
const namespaceImportIdentifier = findNamespaceImportIdentifier()
|
||||
|
||||
if (namespaceImportIdentifier) {
|
||||
const identifierMap = {}
|
||||
|
||||
for (const identifier of identifiers) {
|
||||
identifierMap[identifier] = jscodeshift.identifier(identifier)
|
||||
}
|
||||
|
||||
return {
|
||||
namespace: namespaceImportIdentifier,
|
||||
...identifierMap,
|
||||
}
|
||||
}
|
||||
|
||||
const importSpecifiers = findImportSpecifiers(packageName)
|
||||
const identifierMap = {}
|
||||
|
||||
for (const identifier of identifiers) {
|
||||
identifierMap[identifier] = findImportIdentifierOf(
|
||||
importSpecifiers,
|
||||
identifier,
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
namespace: null,
|
||||
...identifierMap,
|
||||
}
|
||||
}
|
||||
|
||||
const findAllMethodCalls = () =>
|
||||
root
|
||||
// First, we need to find all method calls.
|
||||
.find(jscodeshift.CallExpression, {
|
||||
callee: {
|
||||
type: jscodeshift.MemberExpression.name,
|
||||
property: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const findQueryClientIdentifiers = (importIdentifiers) =>
|
||||
root
|
||||
.find(jscodeshift.VariableDeclarator, {})
|
||||
.filter((node) => {
|
||||
if (node.value.init) {
|
||||
const initializer = node.value.init
|
||||
|
||||
return (
|
||||
isClassInstantiationOf(
|
||||
initializer,
|
||||
getSelectorByImports(importIdentifiers, 'QueryClient'),
|
||||
) ||
|
||||
isFunctionCallOf(
|
||||
initializer,
|
||||
getSelectorByImports(importIdentifiers, 'useQueryClient'),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
.paths()
|
||||
.map((node) => node.value.id.name)
|
||||
|
||||
const isCallExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.CallExpression.name })
|
||||
|
||||
const isIdentifier = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.Identifier.name })
|
||||
|
||||
const isMemberExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.MemberExpression.name })
|
||||
|
||||
const isNewExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.NewExpression.name })
|
||||
|
||||
const isArrayExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.ArrayExpression.name })
|
||||
|
||||
const isObjectExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.ObjectExpression.name })
|
||||
|
||||
const isObjectProperty = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.ObjectProperty.name })
|
||||
|
||||
const isSpreadElement = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.SpreadElement.name })
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isFunctionDefinition = (node) => {
|
||||
const isArrowFunctionExpression = jscodeshift.match(node, {
|
||||
type: jscodeshift.ArrowFunctionExpression.name,
|
||||
})
|
||||
const isFunctionExpression = jscodeshift.match(node, {
|
||||
type: jscodeshift.FunctionExpression.name,
|
||||
})
|
||||
|
||||
return isArrowFunctionExpression || isFunctionExpression
|
||||
}
|
||||
|
||||
const warn = (message) => {
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
console.warn(message)
|
||||
}
|
||||
}
|
||||
|
||||
const isClassInstantiationOf = (node, selector) => {
|
||||
if (!isNewExpression(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const parts = selector.split('.')
|
||||
|
||||
return parts.length === 1
|
||||
? isIdentifier(node.callee) && node.callee.name === parts[0]
|
||||
: isMemberExpression(node.callee) &&
|
||||
node.callee.object.name === parts[0] &&
|
||||
node.callee.property.name === parts[1]
|
||||
}
|
||||
|
||||
const isFunctionCallOf = (node, selector) => {
|
||||
if (!isCallExpression(node)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const parts = selector.split('.')
|
||||
|
||||
return parts.length === 1
|
||||
? isIdentifier(node.callee) && node.callee.name === parts[0]
|
||||
: isMemberExpression(node.callee) &&
|
||||
node.callee.object.name === parts[0] &&
|
||||
node.callee.property.name === parts[1]
|
||||
}
|
||||
|
||||
const getSelectorByImports = (imports, path) =>
|
||||
imports.namespace
|
||||
? `${imports.namespace.name}.${imports[path].name}`
|
||||
: imports[path].name
|
||||
|
||||
return {
|
||||
findAllMethodCalls,
|
||||
getSelectorByImports,
|
||||
isCallExpression,
|
||||
isClassInstantiationOf,
|
||||
isFunctionCallOf,
|
||||
isIdentifier,
|
||||
isMemberExpression,
|
||||
isArrayExpression,
|
||||
isObjectExpression,
|
||||
isObjectProperty,
|
||||
isSpreadElement,
|
||||
isFunctionDefinition,
|
||||
locateImports,
|
||||
warn,
|
||||
queryClient: {
|
||||
findQueryClientIdentifiers,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
module.exports = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName = '@tanstack/react-query',
|
||||
}) => {
|
||||
const isGetQueryCacheMethodCall = (
|
||||
initializer,
|
||||
importIdentifiers,
|
||||
knownQueryClientIds,
|
||||
) => {
|
||||
const isKnownQueryClient = (node) =>
|
||||
utils.isIdentifier(node) && knownQueryClientIds.includes(node.name)
|
||||
|
||||
const isGetQueryCacheIdentifier = (node) =>
|
||||
utils.isIdentifier(node) && node.name === 'getQueryCache'
|
||||
|
||||
const isValidInitializer = (node) =>
|
||||
utils.isCallExpression(node) && utils.isMemberExpression(node.callee)
|
||||
|
||||
if (isValidInitializer(initializer)) {
|
||||
const instance = initializer.callee.object
|
||||
|
||||
return (
|
||||
isGetQueryCacheIdentifier(initializer.callee.property) &&
|
||||
(isKnownQueryClient(instance) ||
|
||||
utils.isFunctionCallOf(
|
||||
instance,
|
||||
utils.getSelectorByImports(importIdentifiers, 'useQueryClient'),
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const findQueryCacheInstantiations = (
|
||||
importIdentifiers,
|
||||
knownQueryClientIds,
|
||||
) =>
|
||||
root.find(jscodeshift.VariableDeclarator, {}).filter((node) => {
|
||||
if (node.value.init) {
|
||||
const initializer = node.value.init
|
||||
|
||||
return (
|
||||
utils.isClassInstantiationOf(
|
||||
initializer,
|
||||
utils.getSelectorByImports(importIdentifiers, 'QueryCache'),
|
||||
) ||
|
||||
isGetQueryCacheMethodCall(
|
||||
initializer,
|
||||
importIdentifiers,
|
||||
knownQueryClientIds,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
const filterQueryCacheMethodCalls = (node) =>
|
||||
utils.isIdentifier(node) && ['find', 'findAll'].includes(node.name)
|
||||
|
||||
const findQueryCacheMethodCalls = (importIdentifiers) => {
|
||||
/**
|
||||
* Here we collect all query client instantiations. We have to make aware of them because the query cache can be
|
||||
* accessed by the query client as well.
|
||||
*/
|
||||
const queryClientIdentifiers =
|
||||
utils.queryClient.findQueryClientIdentifiers(importIdentifiers)
|
||||
/**
|
||||
* Here we collect all query cache instantiations. The reason is simple: the methods can be called on query cache
|
||||
* instances, to locate the possible usages we need to be aware of the identifier names.
|
||||
*/
|
||||
const queryCacheIdentifiers = findQueryCacheInstantiations(
|
||||
importIdentifiers,
|
||||
queryClientIdentifiers,
|
||||
)
|
||||
.paths()
|
||||
.map((node) => node.value.id.name)
|
||||
|
||||
return (
|
||||
utils
|
||||
// First, we need to find all method calls.
|
||||
.findAllMethodCalls()
|
||||
// Then we narrow the collection to all `fetch` and `fetchAll` methods.
|
||||
.filter((node) =>
|
||||
filterQueryCacheMethodCalls(node.value.callee.property),
|
||||
)
|
||||
.filter((node) => {
|
||||
const object = node.value.callee.object
|
||||
|
||||
// If the method is called on a `QueryCache` instance, we keep it in the collection.
|
||||
if (utils.isIdentifier(object)) {
|
||||
return queryCacheIdentifiers.includes(object.name)
|
||||
}
|
||||
|
||||
// If the method is called on a `QueryClient` instance, we keep it in the collection.
|
||||
if (utils.isCallExpression(object)) {
|
||||
return isGetQueryCacheMethodCall(
|
||||
object,
|
||||
importIdentifiers,
|
||||
queryClientIdentifiers,
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const execute = (replacer) => {
|
||||
findQueryCacheMethodCalls(
|
||||
utils.locateImports(
|
||||
['QueryCache', 'QueryClient', 'useQueryClient'],
|
||||
packageName,
|
||||
),
|
||||
).replaceWith(replacer)
|
||||
}
|
||||
|
||||
return {
|
||||
execute,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
module.exports = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName = '@tanstack/react-query',
|
||||
}) => {
|
||||
const filterQueryClientMethodCalls = (node, methods) =>
|
||||
utils.isIdentifier(node) && methods.includes(node.name)
|
||||
|
||||
const findQueryClientMethodCalls = (importIdentifiers, methods) => {
|
||||
/**
|
||||
* Here we collect all query client instantiations. We have to make aware of them because some method calls might
|
||||
* be invoked on these instances.
|
||||
*/
|
||||
const queryClientIdentifiers =
|
||||
utils.queryClient.findQueryClientIdentifiers(importIdentifiers)
|
||||
|
||||
return (
|
||||
utils
|
||||
// First, we need to find all method calls.
|
||||
.findAllMethodCalls()
|
||||
// Then we narrow the collection to `QueryClient` methods.
|
||||
.filter((node) =>
|
||||
filterQueryClientMethodCalls(node.value.callee.property, methods),
|
||||
)
|
||||
.filter((node) => {
|
||||
const object = node.value.callee.object
|
||||
|
||||
// If the method is called on a `QueryClient` instance, we keep it in the collection.
|
||||
if (utils.isIdentifier(object)) {
|
||||
return queryClientIdentifiers.includes(object.name)
|
||||
}
|
||||
|
||||
// If the method is called on the return value of `useQueryClient` hook, we keep it in the collection.
|
||||
return utils.isFunctionCallOf(
|
||||
object,
|
||||
utils.getSelectorByImports(importIdentifiers, 'useQueryClient'),
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const execute = (methods, replacer) => {
|
||||
findQueryClientMethodCalls(
|
||||
utils.locateImports(['QueryClient', 'useQueryClient'], packageName),
|
||||
methods,
|
||||
).replaceWith(replacer)
|
||||
}
|
||||
|
||||
return {
|
||||
execute,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
module.exports = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName = '@tanstack/react-query',
|
||||
}) => {
|
||||
const filterUseQueryLikeHookCalls = (node, importIdentifiers, hooks) => {
|
||||
for (const hook of hooks) {
|
||||
const selector = utils.getSelectorByImports(importIdentifiers, hook)
|
||||
|
||||
if (utils.isFunctionCallOf(node, selector)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
const findUseQueryLikeHookCalls = (importIdentifiers, hooks) =>
|
||||
root
|
||||
// First, we need to find all call expressions.
|
||||
.find(jscodeshift.CallExpression, {})
|
||||
// Then we narrow the collection to the `useQuery` like hook calls.
|
||||
.filter((node) =>
|
||||
filterUseQueryLikeHookCalls(node.value, importIdentifiers, hooks),
|
||||
)
|
||||
|
||||
const execute = (hooks, replacer) => {
|
||||
findUseQueryLikeHookCalls(
|
||||
utils.locateImports(hooks, packageName),
|
||||
hooks,
|
||||
).replaceWith(replacer)
|
||||
}
|
||||
|
||||
return {
|
||||
execute,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
QueryCache,
|
||||
QueryClient,
|
||||
useInfiniteQuery,
|
||||
useIsFetching,
|
||||
useIsMutating,
|
||||
useMutation,
|
||||
useQueries,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
useQuery('todos')
|
||||
useInfiniteQuery('todos')
|
||||
useMutation('todos')
|
||||
useIsFetching('todos')
|
||||
useIsMutating('todos')
|
||||
useQueries([query1, query2])
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.getMutationDefaults('todos')
|
||||
queryClient.getQueriesData('todos')
|
||||
queryClient.getQueryData('todos')
|
||||
queryClient.getQueryDefaults('todos')
|
||||
queryClient.getQueryState('todos')
|
||||
queryClient.isFetching('todos')
|
||||
queryClient.setMutationDefaults('todos', { mutationFn: async () => null })
|
||||
queryClient.setQueriesData('todos', () => null)
|
||||
queryClient.setQueryData('todos', () => null)
|
||||
queryClient.setQueryDefaults('todos', { queryFn: async () => null })
|
||||
queryClient.cancelQueries('todos')
|
||||
queryClient.fetchInfiniteQuery('todos')
|
||||
queryClient.fetchQuery('todos')
|
||||
queryClient.invalidateQueries('todos')
|
||||
queryClient.prefetchInfiniteQuery('todos')
|
||||
queryClient.prefetchQuery('todos')
|
||||
queryClient.refetchQueries('todos')
|
||||
queryClient.removeQueries('todos')
|
||||
queryClient.resetQueries('todos')
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getMutationDefaults('todos')
|
||||
useQueryClient().getQueriesData('todos')
|
||||
useQueryClient().getQueryData('todos')
|
||||
useQueryClient().getQueryDefaults('todos')
|
||||
useQueryClient().getQueryState('todos')
|
||||
useQueryClient().isFetching('todos')
|
||||
useQueryClient().setMutationDefaults('todos', {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
useQueryClient().setQueriesData('todos', () => null)
|
||||
useQueryClient().setQueryData('todos', () => null)
|
||||
useQueryClient().setQueryDefaults('todos', { queryFn: async () => null })
|
||||
useQueryClient().cancelQueries('todos')
|
||||
useQueryClient().fetchInfiniteQuery('todos')
|
||||
useQueryClient().fetchQuery('todos')
|
||||
useQueryClient().invalidateQueries('todos')
|
||||
useQueryClient().prefetchInfiniteQuery('todos')
|
||||
useQueryClient().prefetchQuery('todos')
|
||||
useQueryClient().refetchQueries('todos')
|
||||
useQueryClient().removeQueries('todos')
|
||||
useQueryClient().resetQueries('todos')
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new QueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find('todos')
|
||||
queryCache1.findAll('todos')
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = useQueryClient()
|
||||
queryClient1.getQueryCache().find('todos')
|
||||
queryClient1.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryClient2 = new QueryClient({})
|
||||
queryClient2.getQueryCache().find('todos')
|
||||
queryClient2.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find('todos')
|
||||
queryCache2.findAll('todos')
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getQueryCache().find('todos')
|
||||
useQueryClient().getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache3 = useQueryClient().getQueryCache()
|
||||
queryCache3.find('todos')
|
||||
queryCache3.findAll('todos')
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
QueryCache,
|
||||
QueryClient,
|
||||
useInfiniteQuery,
|
||||
useIsFetching,
|
||||
useIsMutating,
|
||||
useMutation,
|
||||
useQueries,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
useQuery(['todos'])
|
||||
useInfiniteQuery(['todos'])
|
||||
useMutation(['todos'])
|
||||
useIsFetching(['todos'])
|
||||
useIsMutating(['todos'])
|
||||
useQueries({
|
||||
queries: [query1, query2]
|
||||
})
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.getMutationDefaults(['todos'])
|
||||
queryClient.getQueriesData(['todos'])
|
||||
queryClient.getQueryData(['todos'])
|
||||
queryClient.getQueryDefaults(['todos'])
|
||||
queryClient.getQueryState(['todos'])
|
||||
queryClient.isFetching(['todos'])
|
||||
queryClient.setMutationDefaults(['todos'], { mutationFn: async () => null })
|
||||
queryClient.setQueriesData(['todos'], () => null)
|
||||
queryClient.setQueryData(['todos'], () => null)
|
||||
queryClient.setQueryDefaults(['todos'], { queryFn: async () => null })
|
||||
queryClient.cancelQueries(['todos'])
|
||||
queryClient.fetchInfiniteQuery(['todos'])
|
||||
queryClient.fetchQuery(['todos'])
|
||||
queryClient.invalidateQueries(['todos'])
|
||||
queryClient.prefetchInfiniteQuery(['todos'])
|
||||
queryClient.prefetchQuery(['todos'])
|
||||
queryClient.refetchQueries(['todos'])
|
||||
queryClient.removeQueries(['todos'])
|
||||
queryClient.resetQueries(['todos'])
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getMutationDefaults(['todos'])
|
||||
useQueryClient().getQueriesData(['todos'])
|
||||
useQueryClient().getQueryData(['todos'])
|
||||
useQueryClient().getQueryDefaults(['todos'])
|
||||
useQueryClient().getQueryState(['todos'])
|
||||
useQueryClient().isFetching(['todos'])
|
||||
useQueryClient().setMutationDefaults(['todos'], {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
useQueryClient().setQueriesData(['todos'], () => null)
|
||||
useQueryClient().setQueryData(['todos'], () => null)
|
||||
useQueryClient().setQueryDefaults(['todos'], { queryFn: async () => null })
|
||||
useQueryClient().cancelQueries(['todos'])
|
||||
useQueryClient().fetchInfiniteQuery(['todos'])
|
||||
useQueryClient().fetchQuery(['todos'])
|
||||
useQueryClient().invalidateQueries(['todos'])
|
||||
useQueryClient().prefetchInfiniteQuery(['todos'])
|
||||
useQueryClient().prefetchQuery(['todos'])
|
||||
useQueryClient().refetchQueries(['todos'])
|
||||
useQueryClient().removeQueries(['todos'])
|
||||
useQueryClient().resetQueries(['todos'])
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new QueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find(['todos'])
|
||||
queryCache1.findAll(['todos'])
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = useQueryClient()
|
||||
queryClient1.getQueryCache().find(['todos'])
|
||||
queryClient1.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryClient2 = new QueryClient({})
|
||||
queryClient2.getQueryCache().find(['todos'])
|
||||
queryClient2.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find(['todos'])
|
||||
queryCache2.findAll(['todos'])
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getQueryCache().find(['todos'])
|
||||
useQueryClient().getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache3 = useQueryClient().getQueryCache()
|
||||
queryCache3.find(['todos'])
|
||||
queryCache3.findAll(['todos'])
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
QueryCache as RenamedQueryCache,
|
||||
QueryClient as RenamedQueryClient,
|
||||
useInfiniteQuery as useRenamedInfiniteQuery,
|
||||
useIsFetching as useRenamedIsFetching,
|
||||
useIsMutating as useRenamedIsMutating,
|
||||
useMutation as useRenamedMutation,
|
||||
useQueries as useRenamedQueries,
|
||||
useQuery as useRenamedQuery,
|
||||
useQueryClient as useRenamedQueryClient,
|
||||
} from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
useRenamedQuery('todos')
|
||||
useRenamedInfiniteQuery('todos')
|
||||
useRenamedMutation('todos')
|
||||
useRenamedIsFetching('todos')
|
||||
useRenamedIsMutating('todos')
|
||||
useRenamedQueries([query1, query2])
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useRenamedQueryClient()
|
||||
queryClient.getMutationDefaults('todos')
|
||||
queryClient.getQueriesData('todos')
|
||||
queryClient.getQueryData('todos')
|
||||
queryClient.getQueryDefaults('todos')
|
||||
queryClient.getQueryState('todos')
|
||||
queryClient.isFetching('todos')
|
||||
queryClient.setMutationDefaults('todos', { mutationFn: async () => null })
|
||||
queryClient.setQueriesData('todos', () => null)
|
||||
queryClient.setQueryData('todos', () => null)
|
||||
queryClient.setQueryDefaults('todos', { queryFn: async () => null })
|
||||
queryClient.cancelQueries('todos')
|
||||
queryClient.fetchInfiniteQuery('todos')
|
||||
queryClient.fetchQuery('todos')
|
||||
queryClient.invalidateQueries('todos')
|
||||
queryClient.prefetchInfiniteQuery('todos')
|
||||
queryClient.prefetchQuery('todos')
|
||||
queryClient.refetchQueries('todos')
|
||||
queryClient.removeQueries('todos')
|
||||
queryClient.resetQueries('todos')
|
||||
// --- Direct hook call.
|
||||
useRenamedQueryClient().getMutationDefaults('todos')
|
||||
useRenamedQueryClient().getQueriesData('todos')
|
||||
useRenamedQueryClient().getQueryData('todos')
|
||||
useRenamedQueryClient().getQueryDefaults('todos')
|
||||
useRenamedQueryClient().getQueryState('todos')
|
||||
useRenamedQueryClient().isFetching('todos')
|
||||
useRenamedQueryClient().setMutationDefaults('todos', {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
useRenamedQueryClient().setQueriesData('todos', () => null)
|
||||
useRenamedQueryClient().setQueryData('todos', () => null)
|
||||
useRenamedQueryClient().setQueryDefaults('todos', {
|
||||
queryFn: async () => null,
|
||||
})
|
||||
useRenamedQueryClient().cancelQueries('todos')
|
||||
useRenamedQueryClient().fetchInfiniteQuery('todos')
|
||||
useRenamedQueryClient().fetchQuery('todos')
|
||||
useRenamedQueryClient().invalidateQueries('todos')
|
||||
useRenamedQueryClient().prefetchInfiniteQuery('todos')
|
||||
useRenamedQueryClient().prefetchQuery('todos')
|
||||
useRenamedQueryClient().refetchQueries('todos')
|
||||
useRenamedQueryClient().removeQueries('todos')
|
||||
useRenamedQueryClient().resetQueries('todos')
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new RenamedQueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find('todos')
|
||||
queryCache1.findAll('todos')
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = useRenamedQueryClient()
|
||||
queryClient1.getQueryCache().find('todos')
|
||||
queryClient1.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryClient2 = new RenamedQueryClient({})
|
||||
queryClient2.getQueryCache().find('todos')
|
||||
queryClient2.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find('todos')
|
||||
queryCache2.findAll('todos')
|
||||
// --- Direct hook call.
|
||||
useRenamedQueryClient().getQueryCache().find('todos')
|
||||
useRenamedQueryClient().getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache3 = useRenamedQueryClient().getQueryCache()
|
||||
queryCache3.find('todos')
|
||||
queryCache3.findAll('todos')
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
QueryCache as RenamedQueryCache,
|
||||
QueryClient as RenamedQueryClient,
|
||||
useInfiniteQuery as useRenamedInfiniteQuery,
|
||||
useIsFetching as useRenamedIsFetching,
|
||||
useIsMutating as useRenamedIsMutating,
|
||||
useMutation as useRenamedMutation,
|
||||
useQueries as useRenamedQueries,
|
||||
useQuery as useRenamedQuery,
|
||||
useQueryClient as useRenamedQueryClient,
|
||||
} from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
useRenamedQuery(['todos'])
|
||||
useRenamedInfiniteQuery(['todos'])
|
||||
useRenamedMutation(['todos'])
|
||||
useRenamedIsFetching(['todos'])
|
||||
useRenamedIsMutating(['todos'])
|
||||
useRenamedQueries({
|
||||
queries: [query1, query2]
|
||||
})
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useRenamedQueryClient()
|
||||
queryClient.getMutationDefaults(['todos'])
|
||||
queryClient.getQueriesData(['todos'])
|
||||
queryClient.getQueryData(['todos'])
|
||||
queryClient.getQueryDefaults(['todos'])
|
||||
queryClient.getQueryState(['todos'])
|
||||
queryClient.isFetching(['todos'])
|
||||
queryClient.setMutationDefaults(['todos'], { mutationFn: async () => null })
|
||||
queryClient.setQueriesData(['todos'], () => null)
|
||||
queryClient.setQueryData(['todos'], () => null)
|
||||
queryClient.setQueryDefaults(['todos'], { queryFn: async () => null })
|
||||
queryClient.cancelQueries(['todos'])
|
||||
queryClient.fetchInfiniteQuery(['todos'])
|
||||
queryClient.fetchQuery(['todos'])
|
||||
queryClient.invalidateQueries(['todos'])
|
||||
queryClient.prefetchInfiniteQuery(['todos'])
|
||||
queryClient.prefetchQuery(['todos'])
|
||||
queryClient.refetchQueries(['todos'])
|
||||
queryClient.removeQueries(['todos'])
|
||||
queryClient.resetQueries(['todos'])
|
||||
// --- Direct hook call.
|
||||
useRenamedQueryClient().getMutationDefaults(['todos'])
|
||||
useRenamedQueryClient().getQueriesData(['todos'])
|
||||
useRenamedQueryClient().getQueryData(['todos'])
|
||||
useRenamedQueryClient().getQueryDefaults(['todos'])
|
||||
useRenamedQueryClient().getQueryState(['todos'])
|
||||
useRenamedQueryClient().isFetching(['todos'])
|
||||
useRenamedQueryClient().setMutationDefaults(['todos'], {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
useRenamedQueryClient().setQueriesData(['todos'], () => null)
|
||||
useRenamedQueryClient().setQueryData(['todos'], () => null)
|
||||
useRenamedQueryClient().setQueryDefaults(['todos'], {
|
||||
queryFn: async () => null,
|
||||
})
|
||||
useRenamedQueryClient().cancelQueries(['todos'])
|
||||
useRenamedQueryClient().fetchInfiniteQuery(['todos'])
|
||||
useRenamedQueryClient().fetchQuery(['todos'])
|
||||
useRenamedQueryClient().invalidateQueries(['todos'])
|
||||
useRenamedQueryClient().prefetchInfiniteQuery(['todos'])
|
||||
useRenamedQueryClient().prefetchQuery(['todos'])
|
||||
useRenamedQueryClient().refetchQueries(['todos'])
|
||||
useRenamedQueryClient().removeQueries(['todos'])
|
||||
useRenamedQueryClient().resetQueries(['todos'])
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new RenamedQueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find(['todos'])
|
||||
queryCache1.findAll(['todos'])
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = useRenamedQueryClient()
|
||||
queryClient1.getQueryCache().find(['todos'])
|
||||
queryClient1.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryClient2 = new RenamedQueryClient({})
|
||||
queryClient2.getQueryCache().find(['todos'])
|
||||
queryClient2.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find(['todos'])
|
||||
queryCache2.findAll(['todos'])
|
||||
// --- Direct hook call.
|
||||
useRenamedQueryClient().getQueryCache().find(['todos'])
|
||||
useRenamedQueryClient().getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache3 = useRenamedQueryClient().getQueryCache()
|
||||
queryCache3.find(['todos'])
|
||||
queryCache3.findAll(['todos'])
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import * as React from 'react'
|
||||
import * as RQ from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
RQ.useQuery('todos')
|
||||
RQ.useInfiniteQuery('todos')
|
||||
RQ.useMutation('todos')
|
||||
RQ.useIsFetching('todos')
|
||||
RQ.useIsMutating('todos')
|
||||
RQ.useQueries([query1, query2])
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = RQ.useQueryClient()
|
||||
queryClient.getMutationDefaults('todos')
|
||||
queryClient.getQueriesData('todos')
|
||||
queryClient.getQueryData('todos')
|
||||
queryClient.getQueryDefaults('todos')
|
||||
queryClient.getQueryState('todos')
|
||||
queryClient.isFetching('todos')
|
||||
queryClient.setMutationDefaults('todos', { mutationFn: async () => null })
|
||||
queryClient.setQueriesData('todos', () => null)
|
||||
queryClient.setQueryData('todos', () => null)
|
||||
queryClient.setQueryDefaults('todos', { queryFn: async () => null })
|
||||
queryClient.cancelQueries('todos')
|
||||
queryClient.fetchInfiniteQuery('todos')
|
||||
queryClient.fetchQuery('todos')
|
||||
queryClient.invalidateQueries('todos')
|
||||
queryClient.prefetchInfiniteQuery('todos')
|
||||
queryClient.prefetchQuery('todos')
|
||||
queryClient.refetchQueries('todos')
|
||||
queryClient.removeQueries('todos')
|
||||
queryClient.resetQueries('todos')
|
||||
// --- Direct hook call.
|
||||
RQ.useQueryClient().getMutationDefaults('todos')
|
||||
RQ.useQueryClient().getQueriesData('todos')
|
||||
RQ.useQueryClient().getQueryData('todos')
|
||||
RQ.useQueryClient().getQueryDefaults('todos')
|
||||
RQ.useQueryClient().getQueryState('todos')
|
||||
RQ.useQueryClient().isFetching('todos')
|
||||
RQ.useQueryClient().setMutationDefaults('todos', {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
RQ.useQueryClient().setQueriesData('todos', () => null)
|
||||
RQ.useQueryClient().setQueryData('todos', () => null)
|
||||
RQ.useQueryClient().setQueryDefaults('todos', {
|
||||
queryFn: async () => null,
|
||||
})
|
||||
RQ.useQueryClient().cancelQueries('todos')
|
||||
RQ.useQueryClient().fetchInfiniteQuery('todos')
|
||||
RQ.useQueryClient().fetchQuery('todos')
|
||||
RQ.useQueryClient().invalidateQueries('todos')
|
||||
RQ.useQueryClient().prefetchInfiniteQuery('todos')
|
||||
RQ.useQueryClient().prefetchQuery('todos')
|
||||
RQ.useQueryClient().refetchQueries('todos')
|
||||
RQ.useQueryClient().removeQueries('todos')
|
||||
RQ.useQueryClient().resetQueries('todos')
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new RQ.QueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find('todos')
|
||||
queryCache1.findAll('todos')
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = RQ.useQueryClient()
|
||||
queryClient1.getQueryCache().find('todos')
|
||||
queryClient1.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryClient2 = new RQ.QueryClient({})
|
||||
queryClient2.getQueryCache().find('todos')
|
||||
queryClient2.getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find('todos')
|
||||
queryCache2.findAll('todos')
|
||||
// --- Direct hook call.
|
||||
RQ.useQueryClient().getQueryCache().find('todos')
|
||||
RQ.useQueryClient().getQueryCache().findAll('todos')
|
||||
//
|
||||
const queryCache3 = RQ.useQueryClient().getQueryCache()
|
||||
queryCache3.find('todos')
|
||||
queryCache3.findAll('todos')
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import * as React from 'react'
|
||||
import * as RQ from 'react-query'
|
||||
|
||||
export const Examples = () => {
|
||||
RQ.useQuery(['todos'])
|
||||
RQ.useInfiniteQuery(['todos'])
|
||||
RQ.useMutation(['todos'])
|
||||
RQ.useIsFetching(['todos'])
|
||||
RQ.useIsMutating(['todos'])
|
||||
RQ.useQueries({
|
||||
queries: [query1, query2]
|
||||
})
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = RQ.useQueryClient()
|
||||
queryClient.getMutationDefaults(['todos'])
|
||||
queryClient.getQueriesData(['todos'])
|
||||
queryClient.getQueryData(['todos'])
|
||||
queryClient.getQueryDefaults(['todos'])
|
||||
queryClient.getQueryState(['todos'])
|
||||
queryClient.isFetching(['todos'])
|
||||
queryClient.setMutationDefaults(['todos'], { mutationFn: async () => null })
|
||||
queryClient.setQueriesData(['todos'], () => null)
|
||||
queryClient.setQueryData(['todos'], () => null)
|
||||
queryClient.setQueryDefaults(['todos'], { queryFn: async () => null })
|
||||
queryClient.cancelQueries(['todos'])
|
||||
queryClient.fetchInfiniteQuery(['todos'])
|
||||
queryClient.fetchQuery(['todos'])
|
||||
queryClient.invalidateQueries(['todos'])
|
||||
queryClient.prefetchInfiniteQuery(['todos'])
|
||||
queryClient.prefetchQuery(['todos'])
|
||||
queryClient.refetchQueries(['todos'])
|
||||
queryClient.removeQueries(['todos'])
|
||||
queryClient.resetQueries(['todos'])
|
||||
// --- Direct hook call.
|
||||
RQ.useQueryClient().getMutationDefaults(['todos'])
|
||||
RQ.useQueryClient().getQueriesData(['todos'])
|
||||
RQ.useQueryClient().getQueryData(['todos'])
|
||||
RQ.useQueryClient().getQueryDefaults(['todos'])
|
||||
RQ.useQueryClient().getQueryState(['todos'])
|
||||
RQ.useQueryClient().isFetching(['todos'])
|
||||
RQ.useQueryClient().setMutationDefaults(['todos'], {
|
||||
mutationFn: async () => null,
|
||||
})
|
||||
RQ.useQueryClient().setQueriesData(['todos'], () => null)
|
||||
RQ.useQueryClient().setQueryData(['todos'], () => null)
|
||||
RQ.useQueryClient().setQueryDefaults(['todos'], {
|
||||
queryFn: async () => null,
|
||||
})
|
||||
RQ.useQueryClient().cancelQueries(['todos'])
|
||||
RQ.useQueryClient().fetchInfiniteQuery(['todos'])
|
||||
RQ.useQueryClient().fetchQuery(['todos'])
|
||||
RQ.useQueryClient().invalidateQueries(['todos'])
|
||||
RQ.useQueryClient().prefetchInfiniteQuery(['todos'])
|
||||
RQ.useQueryClient().prefetchQuery(['todos'])
|
||||
RQ.useQueryClient().refetchQueries(['todos'])
|
||||
RQ.useQueryClient().removeQueries(['todos'])
|
||||
RQ.useQueryClient().resetQueries(['todos'])
|
||||
// QueryCache
|
||||
// --- NewExpression
|
||||
const queryCache1 = new RQ.QueryCache({
|
||||
onError: (error) => console.log(error),
|
||||
onSuccess: (success) => console.log(success)
|
||||
})
|
||||
queryCache1.find(['todos'])
|
||||
queryCache1.findAll(['todos'])
|
||||
// --- Instantiated hook call.
|
||||
const queryClient1 = RQ.useQueryClient()
|
||||
queryClient1.getQueryCache().find(['todos'])
|
||||
queryClient1.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryClient2 = new RQ.QueryClient({})
|
||||
queryClient2.getQueryCache().find(['todos'])
|
||||
queryClient2.getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache2 = queryClient1.getQueryCache()
|
||||
queryCache2.find(['todos'])
|
||||
queryCache2.findAll(['todos'])
|
||||
// --- Direct hook call.
|
||||
RQ.useQueryClient().getQueryCache().find(['todos'])
|
||||
RQ.useQueryClient().getQueryCache().findAll(['todos'])
|
||||
//
|
||||
const queryCache3 = RQ.useQueryClient().getQueryCache()
|
||||
queryCache3.find(['todos'])
|
||||
queryCache3.findAll(['todos'])
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as React from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
export const ExampleWithStringLiteralKey = () => {
|
||||
const stringLiteralKey = 'todos'
|
||||
useQuery(stringLiteralKey)
|
||||
useMutation(stringLiteralKey)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(stringLiteralKey)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries(stringLiteralKey)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteral = () => {
|
||||
const templateLiteralKey = `todos`
|
||||
useQuery(templateLiteralKey)
|
||||
useMutation(templateLiteralKey)
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpressionKey = () => {
|
||||
const arrayExpressionKey = ['todos']
|
||||
useQuery(arrayExpressionKey)
|
||||
useMutation(arrayExpressionKey)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(queryKey2)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries(queryKey2)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownKey = () => {
|
||||
useQuery(unknownQueryKey)
|
||||
useMutation(unknownQueryKey)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(unknownQueryKey)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries(unknownQueryKey)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as React from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
export const ExampleWithStringLiteralKey = () => {
|
||||
const stringLiteralKey = 'todos'
|
||||
useQuery([stringLiteralKey])
|
||||
useMutation([stringLiteralKey])
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries([stringLiteralKey])
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries([stringLiteralKey])
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteral = () => {
|
||||
const templateLiteralKey = `todos`
|
||||
useQuery([templateLiteralKey])
|
||||
useMutation([templateLiteralKey])
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpressionKey = () => {
|
||||
const arrayExpressionKey = ['todos']
|
||||
useQuery(arrayExpressionKey)
|
||||
useMutation(arrayExpressionKey)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(queryKey2)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries(queryKey2)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownKey = () => {
|
||||
useQuery(unknownQueryKey)
|
||||
useMutation(unknownQueryKey)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(unknownQueryKey)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries(unknownQueryKey)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
import * as React from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
const options = {}
|
||||
|
||||
export const ExampleWithStringLiteral = () => {
|
||||
useQuery({ queryKey: 'todos', exact: true }, options)
|
||||
useMutation({ mutationKey: 'todos', exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: 'todos', exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: 'todos', exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithStringLiteralIdentifier = () => {
|
||||
const stringLiteralKey = 'todos'
|
||||
useQuery({ queryKey: stringLiteralKey, exact: true }, options)
|
||||
useMutation({ mutationKey: stringLiteralKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: stringLiteralKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: stringLiteralKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteral = () => {
|
||||
useQuery({ queryKey: `todos`, exact: true }, options)
|
||||
useMutation({ mutationKey: `todos`, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: `todos`, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: `todos`, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteralIdentifier = () => {
|
||||
const templateLiteralKey = `todos`
|
||||
useQuery({ queryKey: templateLiteralKey, exact: true }, options)
|
||||
useMutation({ mutationKey: templateLiteralKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: templateLiteralKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: templateLiteralKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpression = () => {
|
||||
useQuery({ queryKey: ['todos'], exact: true }, options)
|
||||
useMutation({ mutationKey: ['todos'], exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: ['todos'], exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: ['todos'], exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpressionIdentifier = () => {
|
||||
const arrayExpressionKey = ['todos']
|
||||
useQuery({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
useMutation({ mutationKey: arrayExpressionKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier1 = () => {
|
||||
const createKey = (id) => ['todos', id]
|
||||
const createdKey1 = createKey(1)
|
||||
useQuery({ queryKey: createdKey1, exact: true }, options)
|
||||
useMutation({ mutationKey: createdKey1, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: createdKey1, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: createdKey1, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier2 = () => {
|
||||
const createdKey2 = createKey()
|
||||
useQuery({ queryKey: createdKey2, exact: true }, options)
|
||||
useMutation({ mutationKey: createdKey2, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: createdKey2, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: createdKey2, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier3 = () => {
|
||||
useQuery({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
useMutation({ mutationKey: unknownQueryKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import * as React from 'react'
|
||||
import { useMutation, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
const options = {}
|
||||
|
||||
export const ExampleWithStringLiteral = () => {
|
||||
useQuery({
|
||||
queryKey: ['todos'],
|
||||
exact: true
|
||||
}, options)
|
||||
useMutation({
|
||||
mutationKey: ['todos'],
|
||||
exact: true
|
||||
}, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['todos'],
|
||||
exact: true
|
||||
}, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({
|
||||
queryKey: ['todos'],
|
||||
exact: true
|
||||
}, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithStringLiteralIdentifier = () => {
|
||||
const stringLiteralKey = 'todos'
|
||||
useQuery({
|
||||
queryKey: [stringLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
useMutation({
|
||||
mutationKey: [stringLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: [stringLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({
|
||||
queryKey: [stringLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteral = () => {
|
||||
useQuery({
|
||||
queryKey: [`todos`],
|
||||
exact: true
|
||||
}, options)
|
||||
useMutation({
|
||||
mutationKey: [`todos`],
|
||||
exact: true
|
||||
}, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: [`todos`],
|
||||
exact: true
|
||||
}, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({
|
||||
queryKey: [`todos`],
|
||||
exact: true
|
||||
}, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithTemplateLiteralIdentifier = () => {
|
||||
const templateLiteralKey = `todos`
|
||||
useQuery({
|
||||
queryKey: [templateLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
useMutation({
|
||||
mutationKey: [templateLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: [templateLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({
|
||||
queryKey: [templateLiteralKey],
|
||||
exact: true
|
||||
}, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpression = () => {
|
||||
useQuery({ queryKey: ['todos'], exact: true }, options)
|
||||
useMutation({ mutationKey: ['todos'], exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: ['todos'], exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: ['todos'], exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithArrayExpressionIdentifier = () => {
|
||||
const arrayExpressionKey = ['todos']
|
||||
useQuery({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
useMutation({ mutationKey: arrayExpressionKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: arrayExpressionKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier1 = () => {
|
||||
const createKey = (id) => ['todos', id]
|
||||
const createdKey1 = createKey(1)
|
||||
useQuery({ queryKey: createdKey1, exact: true }, options)
|
||||
useMutation({ mutationKey: createdKey1, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: createdKey1, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: createdKey1, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier2 = () => {
|
||||
const createdKey2 = createKey()
|
||||
useQuery({ queryKey: createdKey2, exact: true }, options)
|
||||
useMutation({ mutationKey: createdKey2, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: createdKey2, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: createdKey2, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
export const ExampleWithUnknownIdentifier3 = () => {
|
||||
useQuery({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
useMutation({ mutationKey: unknownQueryKey, exact: true }, options)
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
// --- Direct hook call.
|
||||
useQueryClient().cancelQueries({ queryKey: unknownQueryKey, exact: true }, options)
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// React Query
|
||||
import { useQuery, useQueryClient } from 'react-query'
|
||||
import { useQuery as RenamedUseQuery, useQueryClient as RenamedUseQueryClient } from 'react-query'
|
||||
import DefaultReactQuery from 'react-query'
|
||||
import * as NamespacedReactQuery from 'react-query'
|
||||
// Devtools
|
||||
import { ReactQueryDevtools } from 'react-query/devtools'
|
||||
import { ReactQueryDevtools as RenamedReactQueryDevtools } from 'react-query/devtools'
|
||||
import DefaultReactQueryDevtools from 'react-query/devtools'
|
||||
import * as NamespacedReactQueryDevtools from 'react-query/devtools'
|
||||
@@ -0,0 +1,10 @@
|
||||
// React Query
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useQuery as RenamedUseQuery, useQueryClient as RenamedUseQueryClient } from '@tanstack/react-query'
|
||||
import DefaultReactQuery from '@tanstack/react-query'
|
||||
import * as NamespacedReactQuery from '@tanstack/react-query'
|
||||
// Devtools
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
import { ReactQueryDevtools as RenamedReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
import DefaultReactQueryDevtools from '@tanstack/react-query-devtools'
|
||||
import * as NamespacedReactQueryDevtools from '@tanstack/react-query-devtools'
|
||||
@@ -0,0 +1,25 @@
|
||||
import * as React from 'react'
|
||||
import { useQueries, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
type Todos = {
|
||||
items: ReadonlyArray<{
|
||||
id: string
|
||||
text: string
|
||||
}>
|
||||
ts: number
|
||||
}
|
||||
|
||||
export const Examples = () => {
|
||||
useQuery<Todos>('todos')
|
||||
useQueries<Array<Todos>>([query1, query2])
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.getQueriesData<Todos>('todos')
|
||||
queryClient.getQueriesData<Todos>({ queryKey: 'todos' })
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getQueriesData<Todos>('todos')
|
||||
useQueryClient().getQueriesData<Todos>({ queryKey: 'todos' })
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react'
|
||||
import { useQueries, useQuery, useQueryClient } from 'react-query'
|
||||
|
||||
type Todos = {
|
||||
items: ReadonlyArray<{
|
||||
id: string
|
||||
text: string
|
||||
}>
|
||||
ts: number
|
||||
}
|
||||
|
||||
export const Examples = () => {
|
||||
useQuery<Todos>(['todos'])
|
||||
useQueries<Array<Todos>>({
|
||||
queries: [query1, query2]
|
||||
})
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.getQueriesData<Todos>(['todos'])
|
||||
queryClient.getQueriesData<Todos>({
|
||||
queryKey: ['todos']
|
||||
})
|
||||
// --- Direct hook call.
|
||||
useQueryClient().getQueriesData<Todos>(['todos'])
|
||||
useQueryClient().getQueriesData<Todos>({
|
||||
queryKey: ['todos']
|
||||
})
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'key-transformation.cjs', null, 'default-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'key-transformation.cjs', null, 'named-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'key-transformation.cjs', null, 'namespaced-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(
|
||||
__dirname,
|
||||
'key-transformation.cjs',
|
||||
null,
|
||||
'parameter-is-identifier',
|
||||
{
|
||||
parser: 'tsx',
|
||||
},
|
||||
)
|
||||
|
||||
defineTest(
|
||||
__dirname,
|
||||
'key-transformation.cjs',
|
||||
null,
|
||||
'parameter-is-object-expression',
|
||||
{
|
||||
parser: 'tsx',
|
||||
},
|
||||
)
|
||||
|
||||
defineTest(__dirname, 'key-transformation.cjs', null, 'type-arguments', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(
|
||||
__dirname,
|
||||
'replace-import-specifier.cjs',
|
||||
null,
|
||||
'replace-import-specifier',
|
||||
{
|
||||
parser: 'tsx',
|
||||
},
|
||||
)
|
||||
181
packages/query-codemods/src/v4/key-transformation.cjs
Normal file
181
packages/query-codemods/src/v4/key-transformation.cjs
Normal file
@@ -0,0 +1,181 @@
|
||||
const createUtilsObject = require('../utils/index.cjs')
|
||||
const createKeyReplacer = require('./utils/replacers/key-replacer.cjs')
|
||||
const createUseQueryLikeTransformer = require('../utils/transformers/use-query-like-transformer.cjs')
|
||||
const createQueryClientTransformer = require('../utils/transformers/query-client-transformer.cjs')
|
||||
const createQueryCacheTransformer = require('../utils/transformers/query-cache-transformer.cjs')
|
||||
|
||||
const transformQueryClientUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
packageName,
|
||||
}) => {
|
||||
const transformer = createQueryClientTransformer({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
})
|
||||
const replacer = createKeyReplacer({ jscodeshift, root, filePath })
|
||||
|
||||
transformer.execute(
|
||||
[
|
||||
// Not object syntax-aware methods.
|
||||
'getMutationDefaults',
|
||||
'getQueriesData',
|
||||
'getQueryData',
|
||||
'getQueryDefaults',
|
||||
'getQueryState',
|
||||
'isFetching',
|
||||
'setMutationDefaults',
|
||||
'setQueriesData',
|
||||
'setQueryData',
|
||||
'setQueryDefaults',
|
||||
// Object syntax-aware methods.
|
||||
'cancelQueries',
|
||||
'fetchInfiniteQuery',
|
||||
'fetchQuery',
|
||||
'invalidateQueries',
|
||||
'prefetchInfiniteQuery',
|
||||
'prefetchQuery',
|
||||
'refetchQueries',
|
||||
'removeQueries',
|
||||
'resetQueries',
|
||||
],
|
||||
replacer,
|
||||
)
|
||||
}
|
||||
|
||||
const transformUseQueriesUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
}) => {
|
||||
const transformer = createUseQueryLikeTransformer({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
})
|
||||
const replacer = ({ node }) => {
|
||||
/**
|
||||
* When the node doesn't have the 'original' property, that means the codemod has been already applied,
|
||||
* so we don't need to do any changes.
|
||||
*/
|
||||
if (!node.original) {
|
||||
return node
|
||||
}
|
||||
|
||||
const newCallExpression = jscodeshift.callExpression(node.original.callee, [
|
||||
jscodeshift.objectExpression([
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier('queries'),
|
||||
node.original.arguments[0],
|
||||
),
|
||||
]),
|
||||
])
|
||||
|
||||
// TODO: This should be part of one function!
|
||||
if (node.typeParameters) {
|
||||
newCallExpression.typeArguments = node.typeParameters
|
||||
}
|
||||
|
||||
return newCallExpression
|
||||
}
|
||||
|
||||
transformer.execute(['useQueries'], replacer)
|
||||
}
|
||||
|
||||
const transformUseQueryLikeUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
packageName,
|
||||
}) => {
|
||||
const transformer = createUseQueryLikeTransformer({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
})
|
||||
|
||||
transformer.execute(
|
||||
['useQuery', 'useInfiniteQuery', 'useIsFetching', 'useIsMutating'],
|
||||
createKeyReplacer({
|
||||
jscodeshift,
|
||||
root,
|
||||
filePath,
|
||||
keyName: 'queryKey',
|
||||
}),
|
||||
)
|
||||
transformer.execute(
|
||||
['useMutation'],
|
||||
createKeyReplacer({
|
||||
jscodeshift,
|
||||
root,
|
||||
filePath,
|
||||
keyName: 'mutationKey',
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const transformQueryCacheUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
packageName,
|
||||
}) => {
|
||||
const transformer = createQueryCacheTransformer({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
})
|
||||
const replacer = createKeyReplacer({ jscodeshift, root, filePath })
|
||||
|
||||
transformer.execute(replacer)
|
||||
}
|
||||
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
|
||||
// TODO: Execute the transformers only when it contains a `react-query` import!
|
||||
|
||||
const utils = createUtilsObject({ root, jscodeshift })
|
||||
const filePath = file.path
|
||||
const packageName = 'react-query'
|
||||
|
||||
// This function transforms usages like `useQuery` and `useMutation`.
|
||||
transformUseQueryLikeUsages({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
packageName,
|
||||
})
|
||||
// This function transforms usages of `useQueries`.
|
||||
transformUseQueriesUsages({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
packageName,
|
||||
})
|
||||
// This function transforms usages of `QueryClient`.
|
||||
transformQueryClientUsages({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
packageName,
|
||||
})
|
||||
// This function transforms usages of `QueryCache`.
|
||||
transformQueryCacheUsages({ jscodeshift, utils, root, filePath, packageName })
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
25
packages/query-codemods/src/v4/replace-import-specifier.cjs
Normal file
25
packages/query-codemods/src/v4/replace-import-specifier.cjs
Normal file
@@ -0,0 +1,25 @@
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
|
||||
const replacements = [
|
||||
{ from: 'react-query', to: '@tanstack/react-query' },
|
||||
{ from: 'react-query/devtools', to: '@tanstack/react-query-devtools' },
|
||||
]
|
||||
|
||||
replacements.forEach(({ from, to }) => {
|
||||
root
|
||||
.find(jscodeshift.ImportDeclaration, {
|
||||
source: {
|
||||
value: from,
|
||||
},
|
||||
})
|
||||
.replaceWith(({ node }) => {
|
||||
node.source.value = to
|
||||
|
||||
return node
|
||||
})
|
||||
})
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
164
packages/query-codemods/src/v4/utils/replacers/key-replacer.cjs
Normal file
164
packages/query-codemods/src/v4/utils/replacers/key-replacer.cjs
Normal file
@@ -0,0 +1,164 @@
|
||||
class UnprocessableKeyError extends Error {
|
||||
constructor(message) {
|
||||
super(message)
|
||||
this.name = 'UnprocessableKeyError'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ({ jscodeshift, root, filePath, keyName = 'queryKey' }) => {
|
||||
const isArrayExpression = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.ArrayExpression.name })
|
||||
|
||||
const isStringLiteral = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.StringLiteral.name }) ||
|
||||
jscodeshift.match(node, { type: jscodeshift.Literal.name })
|
||||
|
||||
const isTemplateLiteral = (node) =>
|
||||
jscodeshift.match(node, { type: jscodeshift.TemplateLiteral.name })
|
||||
|
||||
const findVariableDeclaration = (node) => {
|
||||
const declarations = root
|
||||
.find(jscodeshift.VariableDeclarator, {
|
||||
id: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: node.name,
|
||||
},
|
||||
})
|
||||
.paths()
|
||||
|
||||
return declarations.length > 0 ? declarations[0] : null
|
||||
}
|
||||
|
||||
const createKeyValue = (node) => {
|
||||
// When the node is a string literal we convert it into an array of strings.
|
||||
if (isStringLiteral(node)) {
|
||||
return jscodeshift.arrayExpression([
|
||||
jscodeshift.stringLiteral(node.value),
|
||||
])
|
||||
}
|
||||
|
||||
// When the node is a template literal we convert it into an array of template literals.
|
||||
if (isTemplateLiteral(node)) {
|
||||
return jscodeshift.arrayExpression([
|
||||
jscodeshift.templateLiteral(node.quasis, node.expressions),
|
||||
])
|
||||
}
|
||||
|
||||
if (jscodeshift.match(node, { type: jscodeshift.Identifier.name })) {
|
||||
// When the node is an identifier at first, we try to find its declaration, because we will try
|
||||
// to guess its type.
|
||||
const variableDeclaration = findVariableDeclaration(node)
|
||||
|
||||
if (!variableDeclaration) {
|
||||
throw new UnprocessableKeyError(
|
||||
`In file ${filePath} at line ${node.loc.start.line} the type of identifier \`${node.name}\` couldn't be recognized, so the codemod couldn't be applied. Please migrate manually.`,
|
||||
)
|
||||
}
|
||||
|
||||
const initializer = variableDeclaration.value.init
|
||||
|
||||
// When it's a string, we just wrap it into an array expression.
|
||||
if (isStringLiteral(initializer) || isTemplateLiteral(initializer)) {
|
||||
return jscodeshift.arrayExpression([node])
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnprocessableKeyError(
|
||||
`In file ${filePath} at line ${node.loc.start.line} the type of the \`${keyName}\` couldn't be recognized, so the codemod couldn't be applied. Please migrate manually.`,
|
||||
)
|
||||
}
|
||||
|
||||
const createKeyProperty = (node) =>
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(keyName),
|
||||
createKeyValue(node),
|
||||
)
|
||||
|
||||
const getPropertyFromObjectExpression = (objectExpression, propertyName) =>
|
||||
objectExpression.properties.find(
|
||||
(property) => property.key.name === propertyName,
|
||||
) ?? null
|
||||
|
||||
const buildWithTypeArguments = (node, builder) => {
|
||||
const newNode = builder(node)
|
||||
|
||||
if (node.typeParameters) {
|
||||
newNode.typeArguments = node.typeParameters
|
||||
}
|
||||
|
||||
return newNode
|
||||
}
|
||||
|
||||
return ({ node }) => {
|
||||
// When the node doesn't have the 'original' property, that means the codemod has been already applied,
|
||||
// so we don't need to do any changes.
|
||||
if (!node.original) {
|
||||
return node
|
||||
}
|
||||
|
||||
const methodArguments = node.arguments
|
||||
|
||||
// The method call doesn't have any arguments, we have nothing to do in this case.
|
||||
if (methodArguments.length === 0) {
|
||||
return node
|
||||
}
|
||||
|
||||
try {
|
||||
const [firstArgument, ...restOfTheArguments] = methodArguments
|
||||
|
||||
if (
|
||||
jscodeshift.match(firstArgument, {
|
||||
type: jscodeshift.ObjectExpression.name,
|
||||
})
|
||||
) {
|
||||
const originalKey = getPropertyFromObjectExpression(
|
||||
firstArgument,
|
||||
keyName,
|
||||
)
|
||||
|
||||
if (!originalKey) {
|
||||
throw new UnprocessableKeyError(
|
||||
`In file ${filePath} at line ${node.loc.start.line} the \`${keyName}\` couldn't be found. Did you forget to add it?`,
|
||||
)
|
||||
}
|
||||
|
||||
const restOfTheProperties = firstArgument.properties.filter(
|
||||
(item) => item.key.name !== keyName,
|
||||
)
|
||||
|
||||
return buildWithTypeArguments(node, (originalNode) =>
|
||||
jscodeshift.callExpression(originalNode.original.callee, [
|
||||
jscodeshift.objectExpression([
|
||||
createKeyProperty(originalKey.value),
|
||||
...restOfTheProperties,
|
||||
]),
|
||||
...restOfTheArguments,
|
||||
]),
|
||||
)
|
||||
}
|
||||
|
||||
// When the node is an array expression we just simply return it because we want query keys to be arrays.
|
||||
if (isArrayExpression(firstArgument)) {
|
||||
return node
|
||||
}
|
||||
|
||||
return buildWithTypeArguments(node, (originalNode) =>
|
||||
jscodeshift.callExpression(originalNode.original.callee, [
|
||||
createKeyValue(firstArgument),
|
||||
...restOfTheArguments,
|
||||
]),
|
||||
)
|
||||
} catch (error) {
|
||||
if (error.name === 'UnprocessableKeyError') {
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
console.warn(error.message)
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import * as React from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
export const WithObjectPattern = () => {
|
||||
const { isError, isLoading, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoading || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRename = () => {
|
||||
const { isError, isLoading: isLoadingRenamed, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoadingRenamed || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoadingRenamed, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRestElement = () => {
|
||||
const { isError, ...rest } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || rest.isLoading || rest.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading: rest.isLoading, isSuccess: rest.isSuccess })}</div>
|
||||
}
|
||||
|
||||
export const WithIdentifier = () => {
|
||||
const queryResult = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (queryResult.isError || queryResult.isLoading || queryResult.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify(queryResult)}</div>
|
||||
}
|
||||
|
||||
export const WithCombinations = () => {
|
||||
function useSomethingElse() {
|
||||
const { isError, isLoading, isSuccess, status } = useQuery({
|
||||
queryKey: ['somethingElse'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return { isError, isLoading, isSuccess, status }
|
||||
}
|
||||
|
||||
function useAnotherThing() {
|
||||
const { isLoading, ...rest } = useQuery({
|
||||
queryKey: ['anotherThing'],
|
||||
queryFn: () => ['anotherData'],
|
||||
})
|
||||
|
||||
return { isLoading: rest.isLoading, ...rest }
|
||||
}
|
||||
|
||||
const { isError, isLoading: isLoadingRenamed, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return isLoadingRenamed
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
import * as React from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
export const WithObjectPattern = () => {
|
||||
const { isError, isPending, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isPending || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isPending, isSuccess, status })}</div>;
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRename = () => {
|
||||
const { isError, isPending: isLoadingRenamed, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoadingRenamed || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoadingRenamed, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRestElement = () => {
|
||||
const { isError, ...rest } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || rest.isPending || rest.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading: rest.isPending, isSuccess: rest.isSuccess })}</div>;
|
||||
}
|
||||
|
||||
export const WithIdentifier = () => {
|
||||
const queryResult = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (queryResult.isError || queryResult.isPending || queryResult.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify(queryResult)}</div>
|
||||
}
|
||||
|
||||
export const WithCombinations = () => {
|
||||
function useSomethingElse() {
|
||||
const { isError, isPending, isSuccess, status } = useQuery({
|
||||
queryKey: ['somethingElse'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return { isError, isPending, isSuccess, status };
|
||||
}
|
||||
|
||||
function useAnotherThing() {
|
||||
const { isPending, ...rest } = useQuery({
|
||||
queryKey: ['anotherThing'],
|
||||
queryFn: () => ['anotherData'],
|
||||
})
|
||||
|
||||
return { isLoading: rest.isPending, ...rest };
|
||||
}
|
||||
|
||||
const { isError, isPending: isLoadingRenamed, isSuccess, status } = useQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return isLoadingRenamed
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import * as React from 'react'
|
||||
import { useQuery as useRenamedUseQuery } from '@tanstack/react-query'
|
||||
|
||||
export const WithObjectPattern = () => {
|
||||
const { isError, isLoading, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoading || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRename = () => {
|
||||
const { isError, isLoading: isLoadingRenamed, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoadingRenamed || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoadingRenamed, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRestElement = () => {
|
||||
const { isError, ...rest } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || rest.isLoading || rest.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading: rest.isLoading, isSuccess: rest.isSuccess })}</div>
|
||||
}
|
||||
|
||||
export const WithIdentifier = () => {
|
||||
const queryResult = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (queryResult.isError || queryResult.isLoading || queryResult.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify(queryResult)}</div>
|
||||
}
|
||||
|
||||
export const WithCombinations = () => {
|
||||
function useSomethingElse() {
|
||||
const { isError, isLoading, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['somethingElse'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return { isError, isLoading, isSuccess, status }
|
||||
}
|
||||
|
||||
function useAnotherThing() {
|
||||
const { isLoading, ...rest } = useRenamedUseQuery({
|
||||
queryKey: ['anotherThing'],
|
||||
queryFn: () => ['anotherData'],
|
||||
})
|
||||
|
||||
return { isLoading: rest.isLoading, ...rest }
|
||||
}
|
||||
|
||||
const { isError, isLoading: isLoadingRenamed, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return isLoadingRenamed
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import * as React from 'react'
|
||||
import { useQuery as useRenamedUseQuery } from '@tanstack/react-query'
|
||||
|
||||
export const WithObjectPattern = () => {
|
||||
const { isError, isPending, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isPending || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isPending, isSuccess, status })}</div>;
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRename = () => {
|
||||
const { isError, isPending: isLoadingRenamed, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || isLoadingRenamed || isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoadingRenamed, isSuccess, status })}</div>
|
||||
}
|
||||
|
||||
export const WithObjectPatternAndRestElement = () => {
|
||||
const { isError, ...rest } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (isError || rest.isPending || rest.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify({ isError, isLoading: rest.isPending, isSuccess: rest.isSuccess })}</div>;
|
||||
}
|
||||
|
||||
export const WithIdentifier = () => {
|
||||
const queryResult = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
if (queryResult.isError || queryResult.isPending || queryResult.isSuccess) {
|
||||
console.log('Do something')
|
||||
}
|
||||
|
||||
return <div>{JSON.stringify(queryResult)}</div>
|
||||
}
|
||||
|
||||
export const WithCombinations = () => {
|
||||
function useSomethingElse() {
|
||||
const { isError, isPending, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['somethingElse'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return { isError, isPending, isSuccess, status };
|
||||
}
|
||||
|
||||
function useAnotherThing() {
|
||||
const { isPending, ...rest } = useRenamedUseQuery({
|
||||
queryKey: ['anotherThing'],
|
||||
queryFn: () => ['anotherData'],
|
||||
})
|
||||
|
||||
return { isLoading: rest.isPending, ...rest };
|
||||
}
|
||||
|
||||
const { isError, isPending: isLoadingRenamed, isSuccess, status } = useRenamedUseQuery({
|
||||
queryKey: ['queryKey'],
|
||||
queryFn: () => ['data'],
|
||||
})
|
||||
|
||||
return isLoadingRenamed
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'is-loading.cjs', null, 'default-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'is-loading.cjs', null, 'named-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
244
packages/query-codemods/src/v5/is-loading/is-loading.cjs
Normal file
244
packages/query-codemods/src/v5/is-loading/is-loading.cjs
Normal file
@@ -0,0 +1,244 @@
|
||||
const createUtilsObject = require('../../utils/index.cjs')
|
||||
const createUseQueryLikeTransformer = require('../../utils/transformers/use-query-like-transformer.cjs')
|
||||
const createQueryClientTransformer = require('../../utils/transformers/query-client-transformer.cjs')
|
||||
|
||||
const originalName = 'isLoading'
|
||||
const newName = 'isPending'
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift')} jscodeshift
|
||||
* @param {Object} utils
|
||||
* @param {import('jscodeshift').Collection} root
|
||||
* @param {string} filePath
|
||||
* @param {{keyName: "mutationKey"|"queryKey", queryClientMethods: ReadonlyArray<string>, hooks: ReadonlyArray<string>}} config
|
||||
*/
|
||||
const transformUsages = ({ jscodeshift, utils, root, filePath, config }) => {
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression | import('jscodeshift').ExpressionStatement} node
|
||||
* @returns {{start: number, end: number}}
|
||||
*/
|
||||
const getNodeLocation = (node) => {
|
||||
const location = utils.isCallExpression(node) ? node.callee.loc : node.loc
|
||||
const start = location.start.line
|
||||
const end = location.end.line
|
||||
|
||||
return { start, end }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ASTNode} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isObjectExpression = (node) => {
|
||||
return jscodeshift.match(node, {
|
||||
type: jscodeshift.ObjectExpression.name,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ASTNode} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isObjectPattern = (node) => {
|
||||
return jscodeshift.match(node, {
|
||||
type: jscodeshift.ObjectPattern.name,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ASTNode} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isVariableDeclarator = (node) => {
|
||||
return jscodeshift.match(node, {
|
||||
type: jscodeshift.VariableDeclarator.name,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').Node} node
|
||||
* @param {import('jscodeshift').Identifier} identifier
|
||||
* @returns {Collection<import('jscodeshift').MemberExpression>}
|
||||
*/
|
||||
const findIsLoadingPropertiesOfIdentifier = (node, identifier) => {
|
||||
return jscodeshift(node).find(jscodeshift.MemberExpression, {
|
||||
object: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: identifier.name,
|
||||
},
|
||||
property: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: originalName,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectPattern} node
|
||||
* @returns {import('jscodeshift').ObjectProperty|null}
|
||||
*/
|
||||
const findIsLoadingObjectPropertyInObjectPattern = (node) => {
|
||||
return (
|
||||
node.properties.find((property) =>
|
||||
jscodeshift.match(property, {
|
||||
key: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: originalName,
|
||||
},
|
||||
}),
|
||||
) ?? null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectPattern} node
|
||||
* @returns {import('jscodeshift').RestElement|null}
|
||||
*/
|
||||
const findRestElementInObjectPattern = (node) => {
|
||||
return (
|
||||
node.properties.find((property) =>
|
||||
jscodeshift.match(property, {
|
||||
type: jscodeshift.RestElement.name,
|
||||
}),
|
||||
) ?? null
|
||||
)
|
||||
}
|
||||
|
||||
const replacer = (path, transformNode) => {
|
||||
const node = path.node
|
||||
const parentNode = path.parentPath.value
|
||||
const { start, end } = getNodeLocation(node)
|
||||
|
||||
try {
|
||||
if (!isVariableDeclarator(parentNode)) {
|
||||
// The parent node is not a variable declarator, the transformation will be skipped.
|
||||
return node
|
||||
}
|
||||
|
||||
const lookupNode = path.scope.node
|
||||
const variableDeclaratorId = parentNode.id
|
||||
|
||||
if (isObjectPattern(variableDeclaratorId)) {
|
||||
const isLoadingObjectProperty =
|
||||
findIsLoadingObjectPropertyInObjectPattern(variableDeclaratorId)
|
||||
|
||||
if (isLoadingObjectProperty) {
|
||||
jscodeshift(lookupNode)
|
||||
.find(jscodeshift.ObjectProperty, {
|
||||
key: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: originalName,
|
||||
},
|
||||
})
|
||||
.replaceWith((mutablePath) => {
|
||||
if (isObjectPattern(mutablePath.parent)) {
|
||||
const affectedProperty = mutablePath.value.value.shorthand
|
||||
? 'value'
|
||||
: 'key'
|
||||
|
||||
mutablePath.value[affectedProperty].name = newName
|
||||
|
||||
return mutablePath.value
|
||||
}
|
||||
|
||||
if (isObjectExpression(mutablePath.parent)) {
|
||||
const affectedProperty = mutablePath.value.value.shorthand
|
||||
? 'key'
|
||||
: 'value'
|
||||
|
||||
mutablePath.value[affectedProperty].name = newName
|
||||
|
||||
return mutablePath.value
|
||||
}
|
||||
|
||||
return mutablePath.value
|
||||
})
|
||||
|
||||
// Renaming all other 'isLoading' references that are object properties.
|
||||
jscodeshift(lookupNode)
|
||||
.find(jscodeshift.Identifier, { name: originalName })
|
||||
.replaceWith((mutablePath) => {
|
||||
if (
|
||||
!jscodeshift.match(mutablePath.parent, {
|
||||
type: jscodeshift.ObjectProperty.name,
|
||||
})
|
||||
) {
|
||||
mutablePath.value.name = newName
|
||||
}
|
||||
|
||||
return mutablePath.value
|
||||
})
|
||||
}
|
||||
|
||||
const restElement = findRestElementInObjectPattern(variableDeclaratorId)
|
||||
|
||||
if (restElement) {
|
||||
findIsLoadingPropertiesOfIdentifier(
|
||||
lookupNode,
|
||||
restElement.argument,
|
||||
).replaceWith(({ node: mutableNode }) => {
|
||||
mutableNode.property.name = newName
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
if (utils.isIdentifier(variableDeclaratorId)) {
|
||||
findIsLoadingPropertiesOfIdentifier(
|
||||
lookupNode,
|
||||
variableDeclaratorId,
|
||||
).replaceWith(({ node: mutableNode }) => {
|
||||
mutableNode.property.name = newName
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
utils.warn(
|
||||
`The usage in file "${filePath}" at line ${start}:${end} could not be transformed. Please migrate this usage manually.`,
|
||||
)
|
||||
|
||||
return node
|
||||
} catch (error) {
|
||||
utils.warn(
|
||||
`An unknown error occurred while processing the "${filePath}" file. Please review this file, because the codemod couldn't be applied.`,
|
||||
)
|
||||
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
createUseQueryLikeTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.hooks,
|
||||
replacer,
|
||||
)
|
||||
|
||||
createQueryClientTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.queryClientMethods,
|
||||
replacer,
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
const utils = createUtilsObject({ root, jscodeshift })
|
||||
const filePath = file.path
|
||||
|
||||
const dependencies = { jscodeshift, utils, root, filePath }
|
||||
|
||||
transformUsages({
|
||||
...dependencies,
|
||||
config: {
|
||||
hooks: ['useQuery', 'useMutation'],
|
||||
queryClientMethods: [],
|
||||
},
|
||||
})
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
32
packages/query-codemods/src/v5/keep-previous-data/README.md
Normal file
32
packages/query-codemods/src/v5/keep-previous-data/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
### Intro
|
||||
|
||||
The prerequisite for this code mod is to migrate your usages to the new syntax, so overloads for hooks and `QueryClient` methods shouldn't be available anymore.
|
||||
|
||||
### Affected usages
|
||||
|
||||
Please note, this code mod transforms usages only where the first argument is an object expression.
|
||||
|
||||
The following usage should be transformed by the code mod:
|
||||
|
||||
```ts
|
||||
const { data } = useQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
})
|
||||
```
|
||||
|
||||
But the following usage won't be transformed by the code mod, because the first argument an identifier:
|
||||
|
||||
```ts
|
||||
const hookArgument = {
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
}
|
||||
const { data } = useQuery(hookArgument)
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
In case of any errors, feel free to reach us out via Discord or open an issue. If you open an issue, please provide a code snippet as well, because without a snippet we cannot find the bug in the code mod.
|
||||
@@ -0,0 +1,284 @@
|
||||
import * as React from 'react'
|
||||
import axios from 'axios'
|
||||
import { QueryClient, useQueries, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
|
||||
type Post = {
|
||||
id: number
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const queryFn = async (): Promise<Array<Post>> => {
|
||||
const { data } = await axios.get(
|
||||
'https://jsonplaceholder.typicode.com/posts',
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example1 = () => {
|
||||
const { data } = useQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example2 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example3 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example4 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example5 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example6 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example7 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example8 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example9 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example10 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
const keepPreviousDataIdentifier = false
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example11 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example12 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example13 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example14 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example15 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
import * as React from 'react'
|
||||
import axios from 'axios'
|
||||
import { keepPreviousData, QueryClient, useQueries, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
|
||||
type Post = {
|
||||
id: number
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const queryFn = async (): Promise<Array<Post>> => {
|
||||
const { data } = await axios.get(
|
||||
'https://jsonplaceholder.typicode.com/posts',
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example1 = () => {
|
||||
const { data } = useQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example2 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example3 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example4 = () => {
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example5 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
const { data } = useQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example6 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example7 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example8 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example9 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example10 = () => {
|
||||
const queryClient = new QueryClient()
|
||||
const keepPreviousDataIdentifier = false
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example11 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
placeholderData: keepPreviousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example12 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example13 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example14 = () => {
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example15 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
import * as React from 'react'
|
||||
import axios from 'axios'
|
||||
import {
|
||||
QueryClient as RenamedQueryClient,
|
||||
useQueries as useRenamedUseQueries,
|
||||
useQuery as useRenamedUseQuery,
|
||||
useQueryClient as useRenamedUseQueryClient
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
type Post = {
|
||||
id: number
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const queryFn = async (): Promise<Array<Post>> => {
|
||||
const { data } = await axios.get(
|
||||
'https://jsonplaceholder.typicode.com/posts',
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example1 = () => {
|
||||
const { data } = useRenamedUseQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example2 = () => {
|
||||
const { data } = useRenamedUseQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example3 = () => {
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example4 = () => {
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example5 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example6 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example7 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example8 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example9 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example10 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
const keepPreviousDataIdentifier = false
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example11 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example12 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example13 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example14 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example15 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
import * as React from 'react'
|
||||
import axios from 'axios'
|
||||
import {
|
||||
keepPreviousData,
|
||||
QueryClient as RenamedQueryClient,
|
||||
useQueries as useRenamedUseQueries,
|
||||
useQuery as useRenamedUseQuery,
|
||||
useQueryClient as useRenamedUseQueryClient,
|
||||
} from '@tanstack/react-query';
|
||||
|
||||
type Post = {
|
||||
id: number
|
||||
title: string
|
||||
body: string
|
||||
}
|
||||
|
||||
const queryFn = async (): Promise<Array<Post>> => {
|
||||
const { data } = await axios.get(
|
||||
'https://jsonplaceholder.typicode.com/posts',
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example1 = () => {
|
||||
const { data } = useRenamedUseQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example2 = () => {
|
||||
const { data } = useRenamedUseQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example3 = () => {
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example4 = () => {
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example5 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
const { data } = useRenamedUseQueries({
|
||||
queryKey: ['posts'],
|
||||
queryFn: queryFn,
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
return <div>{JSON.stringify(data)}</div>
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example6 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
placeholderData: keepPreviousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example7 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example8 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example9 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example10 = () => {
|
||||
const queryClient = new RenamedQueryClient()
|
||||
const keepPreviousDataIdentifier = false
|
||||
|
||||
queryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
useRenamedUseQueryClient().setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
|
||||
const anotherQueryClient = useRenamedUseQueryClient()
|
||||
|
||||
anotherQueryClient.setQueryDefaults(['key'], {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, so the codemod should transform
|
||||
* this usage.
|
||||
*/
|
||||
export const Example11 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
placeholderData: keepPreviousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a function.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example12 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `true`, but the `placeholderData` is a string.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example13 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: true,
|
||||
placeholderData: 'somePlaceholderData'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with value `false`.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example14 = () => {
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The object expression has a `keepPreviousData` property with which is an identifier.
|
||||
* The codemod shouldn't transform this case, only warn the user about the manual migration.
|
||||
*/
|
||||
export const Example15 = () => {
|
||||
const keepPreviousDataIdentifier = false
|
||||
new RenamedQueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
keepPreviousData: keepPreviousDataIdentifier,
|
||||
placeholderData: () => previousData
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'keep-previous-data.cjs', null, 'default', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'keep-previous-data.cjs', null, 'named', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
@@ -0,0 +1,271 @@
|
||||
const createUtilsObject = require('../../utils/index.cjs')
|
||||
const createUseQueryLikeTransformer = require('../../utils/transformers/use-query-like-transformer.cjs')
|
||||
const createQueryClientTransformer = require('../../utils/transformers/query-client-transformer.cjs')
|
||||
const AlreadyHasPlaceholderDataProperty = require('./utils/already-has-placeholder-data-property.cjs')
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift')} jscodeshift
|
||||
* @param {Object} utils
|
||||
* @param {import('jscodeshift').Collection} root
|
||||
* @param {string} filePath
|
||||
* @param {{keyName: "mutationKey"|"queryKey", queryClientMethods: ReadonlyArray<string>, hooks: ReadonlyArray<string>}} config
|
||||
*/
|
||||
const transformUsages = ({ jscodeshift, utils, root, filePath, config }) => {
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression | import('jscodeshift').ExpressionStatement} node
|
||||
* @returns {{start: number, end: number}}
|
||||
*/
|
||||
const getNodeLocation = (node) => {
|
||||
const location = utils.isCallExpression(node) ? node.callee.loc : node.loc
|
||||
const start = location.start.line
|
||||
const end = location.end.line
|
||||
|
||||
return { start, end }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectProperty} objectProperty
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isKeepPreviousDataObjectProperty = (objectProperty) => {
|
||||
return jscodeshift.match(objectProperty.key, {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: 'keepPreviousData',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectProperty} objectProperty
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isObjectPropertyHasTrueBooleanLiteralValue = (objectProperty) => {
|
||||
return jscodeshift.match(objectProperty.value, {
|
||||
type: jscodeshift.BooleanLiteral.name,
|
||||
value: true,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
||||
* @returns {Array<import('jscodeshift').ObjectProperty>}
|
||||
*/
|
||||
const filterKeepPreviousDataProperty = (objectExpression) => {
|
||||
return objectExpression.properties.filter((objectProperty) => {
|
||||
return !isKeepPreviousDataObjectProperty(objectProperty)
|
||||
})
|
||||
}
|
||||
|
||||
const createPlaceholderDataObjectProperty = () => {
|
||||
return jscodeshift.objectProperty(
|
||||
jscodeshift.identifier('placeholderData'),
|
||||
jscodeshift.identifier('keepPreviousData'),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasPlaceholderDataProperty = (objectExpression) => {
|
||||
return (
|
||||
objectExpression.properties.findIndex((objectProperty) => {
|
||||
return jscodeshift.match(objectProperty.key, {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: 'placeholderData',
|
||||
})
|
||||
}) !== -1
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').ObjectExpression} objectExpression
|
||||
* @returns {import('jscodeshift').ObjectProperty | undefined}
|
||||
*/
|
||||
const getKeepPreviousDataProperty = (objectExpression) => {
|
||||
return objectExpression.properties.find(isKeepPreviousDataObjectProperty)
|
||||
}
|
||||
|
||||
let shouldAddKeepPreviousDataImport = false
|
||||
|
||||
const replacer = (path, resolveTargetArgument, transformNode) => {
|
||||
const node = path.node
|
||||
const { start, end } = getNodeLocation(node)
|
||||
|
||||
try {
|
||||
const targetArgument = resolveTargetArgument(node)
|
||||
|
||||
if (targetArgument && utils.isObjectExpression(targetArgument)) {
|
||||
const isPlaceholderDataPropertyPresent =
|
||||
hasPlaceholderDataProperty(targetArgument)
|
||||
|
||||
if (hasPlaceholderDataProperty(targetArgument)) {
|
||||
throw new AlreadyHasPlaceholderDataProperty(node, filePath)
|
||||
}
|
||||
|
||||
const keepPreviousDataProperty =
|
||||
getKeepPreviousDataProperty(targetArgument)
|
||||
|
||||
const keepPreviousDataPropertyHasTrueValue =
|
||||
isObjectPropertyHasTrueBooleanLiteralValue(keepPreviousDataProperty)
|
||||
|
||||
if (!keepPreviousDataPropertyHasTrueValue) {
|
||||
utils.warn(
|
||||
`The usage in file "${filePath}" at line ${start}:${end} already contains a "keepPreviousData" property but its value is not "true". Please migrate this usage manually.`,
|
||||
)
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
if (keepPreviousDataPropertyHasTrueValue) {
|
||||
// Removing the `keepPreviousData` property from the object.
|
||||
const mutableObjectExpressionProperties =
|
||||
filterKeepPreviousDataProperty(targetArgument)
|
||||
|
||||
if (!isPlaceholderDataPropertyPresent) {
|
||||
shouldAddKeepPreviousDataImport = true
|
||||
|
||||
// When the `placeholderData` property is not present, the `placeholderData: keepPreviousData` property will be added.
|
||||
mutableObjectExpressionProperties.push(
|
||||
createPlaceholderDataObjectProperty(),
|
||||
)
|
||||
}
|
||||
|
||||
return transformNode(
|
||||
node,
|
||||
jscodeshift.objectExpression(mutableObjectExpressionProperties),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
utils.warn(
|
||||
`The usage in file "${filePath}" at line ${start}:${end} could not be transformed, because the first parameter is not an object expression. Please migrate this usage manually.`,
|
||||
)
|
||||
|
||||
return node
|
||||
} catch (error) {
|
||||
utils.warn(
|
||||
error.name === AlreadyHasPlaceholderDataProperty.name
|
||||
? error.message
|
||||
: `An unknown error occurred while processing the "${filePath}" file. Please review this file, because the codemod couldn't be applied.`,
|
||||
)
|
||||
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
createUseQueryLikeTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.hooks,
|
||||
(path) => {
|
||||
const resolveTargetArgument = (node) => node.arguments[0] ?? null
|
||||
const transformNode = (node, transformedArgument) =>
|
||||
jscodeshift.callExpression(node.original.callee, [transformedArgument])
|
||||
|
||||
return replacer(path, resolveTargetArgument, transformNode)
|
||||
},
|
||||
)
|
||||
|
||||
createQueryClientTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.queryClientMethods,
|
||||
(path) => {
|
||||
const resolveTargetArgument = (node) => node.arguments[1] ?? null
|
||||
const transformNode = (node, transformedArgument) => {
|
||||
return jscodeshift.callExpression(node.original.callee, [
|
||||
node.arguments[0],
|
||||
transformedArgument,
|
||||
...node.arguments.slice(2, 0),
|
||||
])
|
||||
}
|
||||
|
||||
return replacer(path, resolveTargetArgument, transformNode)
|
||||
},
|
||||
)
|
||||
|
||||
const importIdentifierOfQueryClient = utils.getSelectorByImports(
|
||||
utils.locateImports(['QueryClient']),
|
||||
'QueryClient',
|
||||
)
|
||||
|
||||
root
|
||||
.find(jscodeshift.ExpressionStatement, {
|
||||
expression: {
|
||||
type: jscodeshift.NewExpression.name,
|
||||
callee: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: importIdentifierOfQueryClient,
|
||||
},
|
||||
},
|
||||
})
|
||||
.filter((path) => path.node.expression)
|
||||
.replaceWith((path) => {
|
||||
const resolveTargetArgument = (node) => {
|
||||
const paths = jscodeshift(node)
|
||||
.find(jscodeshift.ObjectProperty, {
|
||||
key: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: 'keepPreviousData',
|
||||
},
|
||||
})
|
||||
.paths()
|
||||
|
||||
return paths.length > 0 ? paths[0].parent.node : null
|
||||
}
|
||||
const transformNode = (node, transformedArgument) => {
|
||||
jscodeshift(node.expression)
|
||||
.find(jscodeshift.ObjectProperty, {
|
||||
key: {
|
||||
type: jscodeshift.Identifier.name,
|
||||
name: 'queries',
|
||||
},
|
||||
})
|
||||
.replaceWith(({ node: mutableNode }) => {
|
||||
mutableNode.value.properties = transformedArgument.properties
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
return replacer(path, resolveTargetArgument, transformNode)
|
||||
})
|
||||
|
||||
return { shouldAddKeepPreviousDataImport }
|
||||
}
|
||||
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
const utils = createUtilsObject({ root, jscodeshift })
|
||||
const filePath = file.path
|
||||
|
||||
const dependencies = { jscodeshift, utils, root, filePath }
|
||||
|
||||
const { shouldAddKeepPreviousDataImport } = transformUsages({
|
||||
...dependencies,
|
||||
config: {
|
||||
hooks: ['useInfiniteQuery', 'useQueries', 'useQuery'],
|
||||
queryClientMethods: ['setQueryDefaults'],
|
||||
},
|
||||
})
|
||||
|
||||
if (shouldAddKeepPreviousDataImport) {
|
||||
root
|
||||
.find(jscodeshift.ImportDeclaration, {
|
||||
source: {
|
||||
value: '@tanstack/react-query',
|
||||
},
|
||||
})
|
||||
.replaceWith(({ node: mutableNode }) => {
|
||||
mutableNode.specifiers = [
|
||||
jscodeshift.importSpecifier(
|
||||
jscodeshift.identifier('keepPreviousData'),
|
||||
),
|
||||
...mutableNode.specifiers,
|
||||
]
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
}
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
class AlreadyHasPlaceholderDataProperty extends Error {
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression} callExpression
|
||||
* @param {string} filePath
|
||||
*/
|
||||
constructor(callExpression, filePath) {
|
||||
super('')
|
||||
this.message = this.buildMessage(callExpression, filePath)
|
||||
this.name = 'AlreadyHasPlaceholderDataProperty'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression} callExpression
|
||||
* @param {string} filePath
|
||||
* @returns {string}
|
||||
*/
|
||||
buildMessage(callExpression, filePath) {
|
||||
const location = callExpression.callee.loc
|
||||
const start = location.start.line
|
||||
const end = location.end.line
|
||||
|
||||
return `The usage in file "${filePath}" at line ${start}:${end} already contains a "placeholderData" property. Please migrate this usage manually.`
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AlreadyHasPlaceholderDataProperty
|
||||
@@ -0,0 +1,56 @@
|
||||
// From: https://github.com/TanStack/query/issues/6204
|
||||
export function useDetails({ groupId }: { groupId?: string }): any {
|
||||
const cacheKey = ["details", groupId];
|
||||
const query = () => fetch(`/group/${groupId}`);
|
||||
const queryObject = useQuery(cacheKey, query, {
|
||||
enabled: !!groupId,
|
||||
});
|
||||
return queryObject;
|
||||
}
|
||||
|
||||
// Based on: https://github.com/TanStack/query/issues/6204
|
||||
export function useDetailsContainsIdentifierAsThirdArgument({ groupId }: { groupId?: string }): any {
|
||||
const cacheKey = ["details", groupId];
|
||||
const query = () => fetch(`/group/${groupId}`);
|
||||
const opts = { enabled: !!groupId }
|
||||
const queryObject = useQuery(cacheKey, query, opts);
|
||||
return queryObject;
|
||||
}
|
||||
|
||||
// From: https://twitter.com/samcook_/status/1715063150184132902
|
||||
export function useWhatever({ thing }: { thing: string }) {
|
||||
return useQuery(
|
||||
['some-string', someVar],
|
||||
async () => 'foo',
|
||||
{ enabled: Boolean(thing) },
|
||||
);
|
||||
}
|
||||
|
||||
// From: https://github.com/TanStack/query/issues/6548
|
||||
export function useDeleteSomething(): any {
|
||||
return useMutation(({ groupId }: { groupId: string }) => {
|
||||
return fetch(`/api/groups/${groupId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// From: https://github.com/TanStack/query/issues/6548
|
||||
export function useDeleteSomethingWithOnError(): any {
|
||||
return useMutation(
|
||||
({ groupId }: { groupId: string }) => {
|
||||
return fetch(`/api/groups/${groupId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
},
|
||||
{
|
||||
onError: (_error, _variables, context) => {
|
||||
// An error happened!
|
||||
console.log(
|
||||
`rolling back optimistic delete with id ${context.id}`
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// From: https://github.com/TanStack/query/issues/6204
|
||||
export function useDetails({ groupId }: { groupId?: string }): any {
|
||||
const cacheKey = ["details", groupId];
|
||||
const query = () => fetch(`/group/${groupId}`);
|
||||
const queryObject = useQuery({
|
||||
queryKey: cacheKey,
|
||||
queryFn: query,
|
||||
enabled: !!groupId
|
||||
});
|
||||
return queryObject;
|
||||
}
|
||||
|
||||
// Based on: https://github.com/TanStack/query/issues/6204
|
||||
export function useDetailsContainsIdentifierAsThirdArgument({ groupId }: { groupId?: string }): any {
|
||||
const cacheKey = ["details", groupId];
|
||||
const query = () => fetch(`/group/${groupId}`);
|
||||
const opts = { enabled: !!groupId }
|
||||
const queryObject = useQuery({
|
||||
queryKey: cacheKey,
|
||||
queryFn: query,
|
||||
...opts
|
||||
});
|
||||
return queryObject;
|
||||
}
|
||||
|
||||
// From: https://twitter.com/samcook_/status/1715063150184132902
|
||||
export function useWhatever({ thing }: { thing: string }) {
|
||||
return useQuery({
|
||||
queryKey: ['some-string', someVar],
|
||||
queryFn: async () => 'foo',
|
||||
enabled: Boolean(thing)
|
||||
});
|
||||
}
|
||||
|
||||
// From: https://github.com/TanStack/query/issues/6548
|
||||
export function useDeleteSomething(): any {
|
||||
return useMutation({
|
||||
mutationFn: ({ groupId }: { groupId: string }) => {
|
||||
return fetch(`/api/groups/${groupId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// From: https://github.com/TanStack/query/issues/6548
|
||||
export function useDeleteSomethingWithOnError(): any {
|
||||
return useMutation({
|
||||
mutationFn: ({ groupId }: { groupId: string }) => {
|
||||
return fetch(`/api/groups/${groupId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
},
|
||||
|
||||
onError: (_error, _variables, context) => {
|
||||
// An error happened!
|
||||
console.log(
|
||||
`rolling back optimistic delete with id ${context.id}`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
useIsFetching,
|
||||
useIsMutating,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import { queryKeysFromAnotherModule } from '../another/module'
|
||||
|
||||
export const WithKnownParameters = () => {
|
||||
useIsFetching(['foo', 'bar'])
|
||||
useIsFetching(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
useIsFetching(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true }, { context: undefined })
|
||||
useIsFetching(['foo', 'bar'], { type: 'all', exact: true })
|
||||
useIsFetching(['foo', 'bar'], { type: 'all', exact: true }, { context: undefined })
|
||||
useIsFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
useIsFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { context: undefined })
|
||||
|
||||
useIsMutating(['foo', 'bar'])
|
||||
useIsMutating(['foo', 'bar'], { exact: true })
|
||||
useIsMutating(['foo', 'bar'], { exact: true }, { context: undefined })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true }, { context: undefined })
|
||||
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(['foo', 'bar'])
|
||||
queryClient.cancelQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.cancelQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true }, { silent: true })
|
||||
queryClient.cancelQueries(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryClient.cancelQueries(['foo', 'bar'], { type: 'all', exact: true }, { silent: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { silent: true })
|
||||
|
||||
queryClient.getQueriesData(['foo', 'bar'])
|
||||
queryClient.getQueriesData({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.invalidateQueries(['foo', 'bar'])
|
||||
queryClient.invalidateQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.invalidateQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.invalidateQueries(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryClient.invalidateQueries(['foo', 'bar'], { type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.invalidateQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.invalidateQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.isFetching(['foo', 'bar'])
|
||||
queryClient.isFetching(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.isFetching(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryClient.isFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.refetchQueries(['foo', 'bar'])
|
||||
queryClient.refetchQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.refetchQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.refetchQueries(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryClient.refetchQueries(['foo', 'bar'], { type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.refetchQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.refetchQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.removeQueries(['foo', 'bar'])
|
||||
queryClient.removeQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.removeQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.resetQueries(['foo', 'bar'])
|
||||
queryClient.resetQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.resetQueries(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.resetQueries(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryClient.resetQueries(['foo', 'bar'], { type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.resetQueries({ queryKey: ['foo', 'bar'], exact: true })
|
||||
queryClient.resetQueries({ queryKey: ['foo', 'bar'], exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.setQueriesData(['foo', 'bar'], null)
|
||||
queryClient.setQueriesData(['foo', 'bar'], null, { updatedAt: 1000 })
|
||||
queryClient.setQueriesData({ queryKey: ['foo', 'bar'] }, null)
|
||||
queryClient.setQueriesData({ queryKey: ['foo', 'bar'] }, null, { updatedAt: 1000 })
|
||||
|
||||
queryClient.fetchQuery(['foo', 'bar'])
|
||||
queryClient.fetchQuery(['foo', 'bar'], { queryKey: ['todos'], staleTime: 1000 })
|
||||
queryClient.fetchQuery(['foo', 'bar'], { queryKey: ['todos'], queryFn: () => 'data', staleTime: 1000 })
|
||||
queryClient.fetchQuery(['foo', 'bar'], () => 'data', { queryKey: ['todos'], staleTime: 1000 })
|
||||
queryClient.fetchQuery(['foo', 'bar'], function myFn() { return 'data' }, { queryKey: ['todos'], staleTime: 1000 })
|
||||
queryClient.fetchQuery({ queryKey: ['foo', 'bar'], queryFn: () => 'data', retry: true })
|
||||
|
||||
const queryCache = queryClient.getQueryCache()
|
||||
|
||||
queryCache.find(['foo', 'bar'])
|
||||
queryCache.find(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryCache.find(['foo', 'bar'], { type: 'all', exact: true })
|
||||
|
||||
queryCache.findAll(['foo', 'bar'])
|
||||
queryCache.findAll(['foo', 'bar'], { type: 'all', exact: true })
|
||||
queryCache.findAll(['foo', 'bar'], { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryCache.findAll({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
const globalQueryKey = ['module', 'level']
|
||||
|
||||
export const WithIdentifiers = () => {
|
||||
const queryKey = ['foo', 'bar']
|
||||
const mutationKey = ['posts', 'articles']
|
||||
const filters = { type: 'all', exact: true } as const
|
||||
const options = { context: undefined } as const
|
||||
const mutationOptions = { exact: true, fetching: false } as const
|
||||
const cancelOptions = { silent: true } as const
|
||||
const invalidateOptions = { cancelRefetch: true, throwOnError: true } as const
|
||||
const refetchOptions = { cancelRefetch: false, throwOnError: true } as const
|
||||
const resetOptions = { cancelRefetch: false, throwOnError: true } as const
|
||||
const fetchOptions = { queryFn: () => 'data', retry: true } as const
|
||||
const queryFn = () => 'data'
|
||||
|
||||
useIsFetching(queryKey)
|
||||
useIsFetching(queryKey, filters)
|
||||
useIsFetching(queryKey, filters, options)
|
||||
useIsFetching(queryKey, { type: 'all', exact: true })
|
||||
useIsFetching(queryKey, { type: 'all', exact: true }, { context: undefined })
|
||||
useIsFetching(queryKey, { queryKey: ['todos'], ...filters }, options)
|
||||
useIsFetching({ queryKey: queryKey, ...filters })
|
||||
useIsFetching({ queryKey: queryKey, ...filters }, { context: undefined })
|
||||
|
||||
useIsMutating(mutationKey)
|
||||
useIsMutating(mutationKey, { exact: true, status: 'idle' })
|
||||
useIsMutating(mutationKey, { ...mutationOptions, exact: false })
|
||||
useIsMutating({ mutationKey, ...mutationOptions })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true, status: 'idle' })
|
||||
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries(queryKey)
|
||||
queryClient.cancelQueries(queryKey, filters)
|
||||
queryClient.cancelQueries(queryKey, filters, cancelOptions)
|
||||
queryClient.cancelQueries(queryKey, { type: 'all', exact: true })
|
||||
queryClient.cancelQueries(queryKey, { type: 'all', exact: true }, { revert: true })
|
||||
queryClient.cancelQueries(queryKey, { queryKey: ['todos'], ...filters }, cancelOptions)
|
||||
queryClient.cancelQueries({ queryKey: queryKey, type: 'all', exact: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], ...filters }, cancelOptions)
|
||||
|
||||
queryClient.getQueriesData(globalQueryKey)
|
||||
queryClient.getQueriesData({ queryKey: globalQueryKey, ...filters })
|
||||
queryClient.getQueriesData({ queryKey: ['foo', 'bar'], type: 'all' })
|
||||
|
||||
queryClient.invalidateQueries(queryKey)
|
||||
queryClient.invalidateQueries(queryKey, filters)
|
||||
queryClient.invalidateQueries(queryKey, filters, invalidateOptions)
|
||||
queryClient.invalidateQueries(queryKey, { queryKey: ['todos'], stale: true, ...filters })
|
||||
queryClient.invalidateQueries(queryKey, { queryKey: ['todos'], stale: true, ...filters }, invalidateOptions)
|
||||
queryClient.invalidateQueries({ queryKey: globalQueryKey, ...filters, stale: true })
|
||||
queryClient.invalidateQueries({ queryKey: globalQueryKey, ...filters, stale: true }, invalidateOptions)
|
||||
|
||||
queryClient.isFetching(globalQueryKey)
|
||||
queryClient.isFetching(globalQueryKey, filters)
|
||||
queryClient.isFetching(globalQueryKey, { queryKey: ['todos'], type: 'all', exact: true })
|
||||
queryClient.isFetching(globalQueryKey, { queryKey: ['todos'], ...filters })
|
||||
queryClient.isFetching({ queryKey: globalQueryKey, ...filters, stale: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.isFetching(queryKeysFromAnotherModule)
|
||||
|
||||
queryClient.refetchQueries(queryKey)
|
||||
queryClient.refetchQueries(queryKey, filters)
|
||||
queryClient.refetchQueries(queryKey, filters, refetchOptions)
|
||||
queryClient.refetchQueries(queryKey, { queryKey: ['todos'], ...filters }, { ...refetchOptions, cancelRefetch: true })
|
||||
queryClient.refetchQueries({ queryKey: queryKey, ...filters })
|
||||
queryClient.refetchQueries({ queryKey: queryKey, ...filters }, { ...refetchOptions, cancelRefetch: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule)
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule, filters)
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule, filters, refetchOptions)
|
||||
|
||||
queryClient.removeQueries(queryKey)
|
||||
queryClient.removeQueries(queryKey, filters)
|
||||
queryClient.removeQueries(queryKey, { queryKey: ['todos'], ...filters, stale: true })
|
||||
queryClient.removeQueries({ queryKey, ...filters, stale: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.removeQueries(queryKeysFromAnotherModule)
|
||||
queryClient.removeQueries(queryKeysFromAnotherModule, filters)
|
||||
|
||||
queryClient.resetQueries(queryKey)
|
||||
queryClient.resetQueries(queryKey, filters)
|
||||
queryClient.resetQueries(queryKey, filters, resetOptions)
|
||||
queryClient.resetQueries(queryKey, { queryKey: ['todos'], ...filters, stale: true })
|
||||
queryClient.resetQueries(queryKey, { queryKey: ['todos'], ...filters, stale: true }, resetOptions)
|
||||
queryClient.resetQueries({ queryKey, ...filters, stale: true })
|
||||
queryClient.resetQueries({ queryKey, ...filters, stale: true }, resetOptions)
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule)
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule, filters)
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule, filters, resetOptions)
|
||||
|
||||
queryClient.fetchQuery(queryKey)
|
||||
queryClient.fetchQuery(queryKey, fetchOptions)
|
||||
queryClient.fetchQuery(queryKey, { networkMode: 'always', ...fetchOptions })
|
||||
queryClient.fetchQuery(queryKey, queryFn, fetchOptions)
|
||||
queryClient.fetchQuery(queryKey, () => 'data', { networkMode: 'always', ...fetchOptions })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule)
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule, fetchOptions)
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule, queryFn, fetchOptions)
|
||||
}
|
||||
|
||||
export const SecondArgumentIsAFunctionExample = () => {
|
||||
useQuery(ordersCacheKeys.groupOrders(id), () => api.getPatientGroupOrders(id).then((r) => r.data))
|
||||
|
||||
const rest = 'rest'
|
||||
const of = 1
|
||||
const functionArguments = { foo: 'bar' }
|
||||
|
||||
useQuery(ordersCacheKeys.groupOrders(id), () => api.getPatientGroupOrders(id).then((r) => r.data), rest, of, functionArguments)
|
||||
}
|
||||
@@ -0,0 +1,501 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
useIsFetching,
|
||||
useIsMutating,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
import { queryKeysFromAnotherModule } from '../another/module'
|
||||
|
||||
export const WithKnownParameters = () => {
|
||||
useIsFetching({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { context: undefined })
|
||||
useIsFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { context: undefined })
|
||||
useIsFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
useIsFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { context: undefined })
|
||||
|
||||
useIsMutating({
|
||||
mutationKey: ['foo', 'bar']
|
||||
})
|
||||
useIsMutating({
|
||||
mutationKey: ['foo', 'bar'],
|
||||
exact: true
|
||||
})
|
||||
useIsMutating({
|
||||
mutationKey: ['foo', 'bar'],
|
||||
exact: true
|
||||
}, { context: undefined })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true }, { context: undefined })
|
||||
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { silent: true })
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { silent: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { silent: true })
|
||||
|
||||
queryClient.getQueriesData({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.getQueriesData({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.invalidateQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.invalidateQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.isFetching({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.isFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.isFetching({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.isFetching({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.refetchQueries({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.refetchQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.refetchQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.refetchQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.refetchQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.refetchQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
queryClient.refetchQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.removeQueries({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.removeQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.removeQueries({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
queryClient.resetQueries({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.resetQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { cancelRefetch: false, throwOnError: true })
|
||||
queryClient.resetQueries({ queryKey: ['foo', 'bar'], exact: true })
|
||||
queryClient.resetQueries({ queryKey: ['foo', 'bar'], exact: true }, { cancelRefetch: false, throwOnError: true })
|
||||
|
||||
queryClient.setQueriesData(['foo', 'bar'], null)
|
||||
queryClient.setQueriesData(['foo', 'bar'], null, { updatedAt: 1000 })
|
||||
queryClient.setQueriesData({ queryKey: ['foo', 'bar'] }, null)
|
||||
queryClient.setQueriesData({ queryKey: ['foo', 'bar'] }, null, { updatedAt: 1000 })
|
||||
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['foo', 'bar'],
|
||||
staleTime: 1000
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['foo', 'bar'],
|
||||
queryFn: () => 'data',
|
||||
staleTime: 1000
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['foo', 'bar'],
|
||||
queryFn: () => 'data',
|
||||
staleTime: 1000
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: ['foo', 'bar'],
|
||||
queryFn: function myFn() { return 'data' },
|
||||
staleTime: 1000
|
||||
})
|
||||
queryClient.fetchQuery({ queryKey: ['foo', 'bar'], queryFn: () => 'data', retry: true })
|
||||
|
||||
const queryCache = queryClient.getQueryCache()
|
||||
|
||||
queryCache.find({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryCache.find({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryCache.find({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
|
||||
queryCache.findAll({
|
||||
queryKey: ['foo', 'bar']
|
||||
})
|
||||
queryCache.findAll({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryCache.findAll({
|
||||
queryKey: ['foo', 'bar'],
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryCache.findAll({ queryKey: ['foo', 'bar'], type: 'all', exact: true })
|
||||
|
||||
return <div>Example Component</div>
|
||||
}
|
||||
|
||||
const globalQueryKey = ['module', 'level']
|
||||
|
||||
export const WithIdentifiers = () => {
|
||||
const queryKey = ['foo', 'bar']
|
||||
const mutationKey = ['posts', 'articles']
|
||||
const filters = { type: 'all', exact: true } as const
|
||||
const options = { context: undefined } as const
|
||||
const mutationOptions = { exact: true, fetching: false } as const
|
||||
const cancelOptions = { silent: true } as const
|
||||
const invalidateOptions = { cancelRefetch: true, throwOnError: true } as const
|
||||
const refetchOptions = { cancelRefetch: false, throwOnError: true } as const
|
||||
const resetOptions = { cancelRefetch: false, throwOnError: true } as const
|
||||
const fetchOptions = { queryFn: () => 'data', retry: true } as const
|
||||
const queryFn = () => 'data'
|
||||
|
||||
useIsFetching({
|
||||
queryKey: queryKey
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, options)
|
||||
useIsFetching({
|
||||
queryKey: queryKey,
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
useIsFetching({
|
||||
queryKey: queryKey,
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { context: undefined })
|
||||
useIsFetching({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, options)
|
||||
useIsFetching({ queryKey: queryKey, ...filters })
|
||||
useIsFetching({ queryKey: queryKey, ...filters }, { context: undefined })
|
||||
|
||||
useIsMutating({
|
||||
mutationKey: mutationKey
|
||||
})
|
||||
useIsMutating({
|
||||
mutationKey: mutationKey,
|
||||
exact: true,
|
||||
status: 'idle'
|
||||
})
|
||||
useIsMutating({
|
||||
mutationKey: mutationKey,
|
||||
...mutationOptions,
|
||||
exact: false
|
||||
})
|
||||
useIsMutating({ mutationKey, ...mutationOptions })
|
||||
useIsMutating({ mutationKey: ['foo', 'bar'], exact: true, status: 'idle' })
|
||||
|
||||
// QueryClient methods
|
||||
// --- Instantiated hook call.
|
||||
const queryClient = useQueryClient()
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, cancelOptions)
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey,
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey,
|
||||
type: 'all',
|
||||
exact: true
|
||||
}, { revert: true })
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, cancelOptions)
|
||||
queryClient.cancelQueries({ queryKey: queryKey, type: 'all', exact: true })
|
||||
queryClient.cancelQueries({ queryKey: ['foo', 'bar'], ...filters }, cancelOptions)
|
||||
|
||||
queryClient.getQueriesData({
|
||||
queryKey: globalQueryKey
|
||||
})
|
||||
queryClient.getQueriesData({ queryKey: globalQueryKey, ...filters })
|
||||
queryClient.getQueriesData({ queryKey: ['foo', 'bar'], type: 'all' })
|
||||
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, invalidateOptions)
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKey,
|
||||
stale: true,
|
||||
...filters
|
||||
})
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: queryKey,
|
||||
stale: true,
|
||||
...filters
|
||||
}, invalidateOptions)
|
||||
queryClient.invalidateQueries({ queryKey: globalQueryKey, ...filters, stale: true })
|
||||
queryClient.invalidateQueries({ queryKey: globalQueryKey, ...filters, stale: true }, invalidateOptions)
|
||||
|
||||
queryClient.isFetching({
|
||||
queryKey: globalQueryKey
|
||||
})
|
||||
queryClient.isFetching({
|
||||
queryKey: globalQueryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.isFetching({
|
||||
queryKey: globalQueryKey,
|
||||
type: 'all',
|
||||
exact: true
|
||||
})
|
||||
queryClient.isFetching({
|
||||
queryKey: globalQueryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.isFetching({ queryKey: globalQueryKey, ...filters, stale: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.isFetching(queryKeysFromAnotherModule)
|
||||
|
||||
queryClient.refetchQueries({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.refetchQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.refetchQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, refetchOptions)
|
||||
queryClient.refetchQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, { ...refetchOptions, cancelRefetch: true })
|
||||
queryClient.refetchQueries({ queryKey: queryKey, ...filters })
|
||||
queryClient.refetchQueries({ queryKey: queryKey, ...filters }, { ...refetchOptions, cancelRefetch: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule)
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule, filters)
|
||||
queryClient.refetchQueries(queryKeysFromAnotherModule, filters, refetchOptions)
|
||||
|
||||
queryClient.removeQueries({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.removeQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.removeQueries({
|
||||
queryKey: queryKey,
|
||||
...filters,
|
||||
stale: true
|
||||
})
|
||||
queryClient.removeQueries({ queryKey, ...filters, stale: true })
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.removeQueries(queryKeysFromAnotherModule)
|
||||
queryClient.removeQueries(queryKeysFromAnotherModule, filters)
|
||||
|
||||
queryClient.resetQueries({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: queryKey,
|
||||
...filters
|
||||
}, resetOptions)
|
||||
queryClient.resetQueries({
|
||||
queryKey: queryKey,
|
||||
...filters,
|
||||
stale: true
|
||||
})
|
||||
queryClient.resetQueries({
|
||||
queryKey: queryKey,
|
||||
...filters,
|
||||
stale: true
|
||||
}, resetOptions)
|
||||
queryClient.resetQueries({ queryKey, ...filters, stale: true })
|
||||
queryClient.resetQueries({ queryKey, ...filters, stale: true }, resetOptions)
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule)
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule, filters)
|
||||
queryClient.resetQueries(queryKeysFromAnotherModule, filters, resetOptions)
|
||||
|
||||
queryClient.fetchQuery({
|
||||
queryKey: queryKey
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: queryKey,
|
||||
...fetchOptions
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: queryKey,
|
||||
networkMode: 'always',
|
||||
...fetchOptions
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: queryKey,
|
||||
queryFn: queryFn,
|
||||
...fetchOptions
|
||||
})
|
||||
queryClient.fetchQuery({
|
||||
queryKey: queryKey,
|
||||
queryFn: () => 'data',
|
||||
networkMode: 'always',
|
||||
...fetchOptions
|
||||
})
|
||||
// Stays as it is because the code couldn't infer the type of the "queryKeysFromAnotherModule" identifier.
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule)
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule, fetchOptions)
|
||||
queryClient.fetchQuery(queryKeysFromAnotherModule, queryFn, fetchOptions)
|
||||
}
|
||||
|
||||
export const SecondArgumentIsAFunctionExample = () => {
|
||||
useQuery({
|
||||
queryKey: ordersCacheKeys.groupOrders(id),
|
||||
queryFn: () => api.getPatientGroupOrders(id).then((r) => r.data)
|
||||
})
|
||||
|
||||
const rest = 'rest'
|
||||
const of = 1
|
||||
const functionArguments = { foo: 'bar' }
|
||||
|
||||
useQuery({
|
||||
queryKey: ordersCacheKeys.groupOrders(id),
|
||||
queryFn: () => api.getPatientGroupOrders(id).then((r) => r.data)
|
||||
}, rest, of, functionArguments)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'remove-overloads.cjs', null, 'default-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'remove-overloads.cjs', null, 'bug-reports', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
@@ -0,0 +1,58 @@
|
||||
const createUtilsObject = require('../../utils/index.cjs')
|
||||
const transformFilterAwareUsages = require('./transformers/filter-aware-usage-transformer.cjs')
|
||||
const transformQueryFnAwareUsages = require('./transformers/query-fn-aware-usage-transformer.cjs')
|
||||
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
const utils = createUtilsObject({ root, jscodeshift })
|
||||
const filePath = file.path
|
||||
|
||||
const dependencies = { jscodeshift, utils, root, filePath }
|
||||
|
||||
transformFilterAwareUsages({
|
||||
...dependencies,
|
||||
config: {
|
||||
keyName: 'queryKey',
|
||||
fnName: 'queryFn',
|
||||
queryClientMethods: [
|
||||
'cancelQueries',
|
||||
'getQueriesData',
|
||||
'invalidateQueries',
|
||||
'isFetching',
|
||||
'refetchQueries',
|
||||
'removeQueries',
|
||||
'resetQueries',
|
||||
// 'setQueriesData',
|
||||
],
|
||||
hooks: ['useIsFetching', 'useQuery'],
|
||||
},
|
||||
})
|
||||
|
||||
transformFilterAwareUsages({
|
||||
...dependencies,
|
||||
config: {
|
||||
keyName: 'mutationKey',
|
||||
fnName: 'mutationFn',
|
||||
queryClientMethods: [],
|
||||
hooks: ['useIsMutating', 'useMutation'],
|
||||
},
|
||||
})
|
||||
|
||||
transformQueryFnAwareUsages({
|
||||
...dependencies,
|
||||
config: {
|
||||
keyName: 'queryKey',
|
||||
queryClientMethods: [
|
||||
'ensureQueryData',
|
||||
'fetchQuery',
|
||||
'prefetchQuery',
|
||||
'fetchInfiniteQuery',
|
||||
'prefetchInfiniteQuery',
|
||||
],
|
||||
hooks: [],
|
||||
},
|
||||
})
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
const createV5UtilsObject = require('../utils/index.cjs')
|
||||
const UnknownUsageError = require('../utils/unknown-usage-error.cjs')
|
||||
const createQueryClientTransformer = require('../../../utils/transformers/query-client-transformer.cjs')
|
||||
const createQueryCacheTransformer = require('../../../utils/transformers/query-cache-transformer.cjs')
|
||||
const createUseQueryLikeTransformer = require('../../../utils/transformers/use-query-like-transformer.cjs')
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').api} jscodeshift
|
||||
* @param {Object} utils
|
||||
* @param {import('jscodeshift').Collection} root
|
||||
* @param {string} filePath
|
||||
* @param {{keyName: "mutationKey"|"queryKey", fnName: "mutationFn"|"queryFn", queryClientMethods: ReadonlyArray<string>, hooks: ReadonlyArray<string>}} config
|
||||
*/
|
||||
const transformFilterAwareUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
config,
|
||||
}) => {
|
||||
const v5Utils = createV5UtilsObject({ jscodeshift, utils })
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression} node
|
||||
* @param {"mutationKey"|"queryKey"} keyName
|
||||
* @param {"mutationFn"|"queryFn"} fnName
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const canSkipReplacement = (node, keyName, fnName) => {
|
||||
const callArguments = node.arguments
|
||||
|
||||
const hasKeyOrFnProperty = () =>
|
||||
callArguments[0].properties.some(
|
||||
(property) =>
|
||||
utils.isObjectProperty(property) &&
|
||||
property.key.name !== keyName &&
|
||||
property.key.name !== fnName,
|
||||
)
|
||||
|
||||
/**
|
||||
* This call has at least one argument. If it's an object expression and contains the "queryKey" or "mutationKey"
|
||||
* field, the transformation can be skipped, because it's already matching the expected signature.
|
||||
*/
|
||||
return (
|
||||
callArguments.length > 0 &&
|
||||
utils.isObjectExpression(callArguments[0]) &&
|
||||
hasKeyOrFnProperty()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks whether the given object property is a spread element or a property that's not named
|
||||
* "queryKey" or "mutationKey".
|
||||
*
|
||||
* @param {import('jscodeshift').ObjectProperty} property
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const predicate = (property) => {
|
||||
const isSpreadElement = utils.isSpreadElement(property)
|
||||
const isObjectProperty = utils.isObjectProperty(property)
|
||||
|
||||
return (
|
||||
isSpreadElement ||
|
||||
(isObjectProperty && property.key.name !== config.keyName)
|
||||
)
|
||||
}
|
||||
|
||||
const replacer = (path) => {
|
||||
const node = path.node
|
||||
|
||||
const isFunctionDefinition = (functionArgument) => {
|
||||
if (utils.isFunctionDefinition(functionArgument)) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (utils.isIdentifier(functionArgument)) {
|
||||
const binding = v5Utils.getBindingFromScope(
|
||||
path,
|
||||
functionArgument.name,
|
||||
filePath,
|
||||
)
|
||||
|
||||
const isVariableDeclarator = jscodeshift.match(binding, {
|
||||
type: jscodeshift.VariableDeclarator.name,
|
||||
})
|
||||
|
||||
return isVariableDeclarator && utils.isFunctionDefinition(binding.init)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// If the given method/function call matches certain criteria, the node doesn't need to be replaced, this step can be skipped.
|
||||
if (canSkipReplacement(node, config.keyName, config.fnName)) {
|
||||
return node
|
||||
}
|
||||
|
||||
/**
|
||||
* Here we attempt to determine the first parameter of the function call.
|
||||
* If it's a function definition, we can create an object property from it (the mutation fn).
|
||||
*/
|
||||
const firstArgument = node.arguments[0]
|
||||
if (isFunctionDefinition(firstArgument)) {
|
||||
const objectExpression = jscodeshift.objectExpression([
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(config.fnName),
|
||||
firstArgument,
|
||||
),
|
||||
])
|
||||
|
||||
const secondArgument = node.arguments[1]
|
||||
|
||||
if (secondArgument) {
|
||||
// If it's an object expression, we can copy the properties from it to the newly created object expression.
|
||||
if (utils.isObjectExpression(secondArgument)) {
|
||||
v5Utils.copyPropertiesFromSource(
|
||||
secondArgument,
|
||||
objectExpression,
|
||||
predicate,
|
||||
)
|
||||
} else {
|
||||
// Otherwise, we simply spread the second argument in the newly created object expression.
|
||||
objectExpression.properties.push(
|
||||
jscodeshift.spreadElement(secondArgument),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, [
|
||||
objectExpression,
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* If, instead, the first parameter is an array expression or an identifier that references
|
||||
* an array expression, then we create an object property from it (the query or mutation key).
|
||||
*
|
||||
* @type {import('jscodeshift').Property|undefined}
|
||||
*/
|
||||
const keyProperty = v5Utils.transformArgumentToKey(
|
||||
path,
|
||||
node.arguments[0],
|
||||
config.keyName,
|
||||
filePath,
|
||||
)
|
||||
|
||||
/**
|
||||
* The first parameter couldn't be transformed into an object property, so it's time to throw an exception,
|
||||
* it will notify the consumers that they need to rewrite this usage manually.
|
||||
*/
|
||||
if (!keyProperty) {
|
||||
const secondArgument =
|
||||
node.arguments.length > 1 ? node.arguments[1] : null
|
||||
|
||||
if (!secondArgument) {
|
||||
throw new UnknownUsageError(node, filePath)
|
||||
}
|
||||
|
||||
if (utils.isFunctionDefinition(secondArgument)) {
|
||||
const originalArguments = node.arguments
|
||||
const firstArgument = jscodeshift.objectExpression([
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(config.keyName),
|
||||
originalArguments[0],
|
||||
),
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(config.fnName),
|
||||
secondArgument,
|
||||
),
|
||||
])
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, [
|
||||
firstArgument,
|
||||
...originalArguments.slice(2),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
const functionArguments = [jscodeshift.objectExpression([keyProperty])]
|
||||
const secondParameter = node.arguments[1]
|
||||
|
||||
if (secondParameter) {
|
||||
const createdObjectExpression = functionArguments[0]
|
||||
|
||||
if (isFunctionDefinition(secondParameter)) {
|
||||
const objectExpression = jscodeshift.objectExpression([
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(config.keyName),
|
||||
node.arguments[0],
|
||||
),
|
||||
jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(config.fnName),
|
||||
secondParameter,
|
||||
),
|
||||
])
|
||||
|
||||
const thirdArgument = node.arguments[2]
|
||||
|
||||
if (thirdArgument) {
|
||||
// If it's an object expression, we can copy the properties from it to the newly created object expression.
|
||||
if (utils.isObjectExpression(thirdArgument)) {
|
||||
v5Utils.copyPropertiesFromSource(
|
||||
thirdArgument,
|
||||
objectExpression,
|
||||
predicate,
|
||||
)
|
||||
} else {
|
||||
// Otherwise, we simply spread the third argument in the newly created object expression.
|
||||
objectExpression.properties.push(
|
||||
jscodeshift.spreadElement(thirdArgument),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, [
|
||||
objectExpression,
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* If it has a second argument, and it's an object expression, then we get the properties from it
|
||||
* (except the "queryKey" or "mutationKey" properties), because these arguments will also be moved to the
|
||||
* newly created object expression.
|
||||
*/
|
||||
if (utils.isObjectExpression(secondParameter)) {
|
||||
v5Utils.copyPropertiesFromSource(
|
||||
secondParameter,
|
||||
createdObjectExpression,
|
||||
predicate,
|
||||
)
|
||||
} else {
|
||||
// Otherwise, we simply spread the second parameter in the newly created object expression.
|
||||
createdObjectExpression.properties.push(
|
||||
jscodeshift.spreadElement(secondParameter),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of the function arguments can be simply pushed to the function arguments object so all will be kept.
|
||||
functionArguments.push(...node.arguments.slice(2))
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, functionArguments)
|
||||
} catch (error) {
|
||||
utils.warn(
|
||||
error.name === UnknownUsageError.name
|
||||
? error.message
|
||||
: `An unknown error occurred while processing the "${filePath}" file. Please review this file, because the codemod couldn't be applied.`,
|
||||
)
|
||||
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
createQueryClientTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.queryClientMethods,
|
||||
replacer,
|
||||
)
|
||||
|
||||
createUseQueryLikeTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.hooks,
|
||||
replacer,
|
||||
)
|
||||
|
||||
createQueryCacheTransformer({ jscodeshift, utils, root }).execute(replacer)
|
||||
}
|
||||
|
||||
module.exports = transformFilterAwareUsages
|
||||
@@ -0,0 +1,185 @@
|
||||
const createV5UtilsObject = require('../utils/index.cjs')
|
||||
const UnknownUsageError = require('../utils/unknown-usage-error.cjs')
|
||||
const createQueryClientTransformer = require('../../../utils/transformers/query-client-transformer.cjs')
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').api} jscodeshift
|
||||
* @param {Object} utils
|
||||
* @param {import('jscodeshift').Collection} root
|
||||
* @param {string} filePath
|
||||
* @param {{keyName: "mutationKey"|"queryKey", queryClientMethods: ReadonlyArray<string>, hooks: ReadonlyArray<string>}} config
|
||||
*/
|
||||
const transformQueryFnAwareUsages = ({
|
||||
jscodeshift,
|
||||
utils,
|
||||
root,
|
||||
filePath,
|
||||
config,
|
||||
}) => {
|
||||
const v5Utils = createV5UtilsObject({ jscodeshift, utils })
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const canSkipReplacement = (node) => {
|
||||
const callArguments = node.arguments
|
||||
|
||||
const hasKeyProperty = () =>
|
||||
callArguments[0].properties.some(
|
||||
(property) =>
|
||||
utils.isObjectProperty(property) &&
|
||||
[config.keyName, 'queryFn'].includes(property.key.name),
|
||||
)
|
||||
|
||||
return (
|
||||
callArguments.length > 0 &&
|
||||
utils.isObjectExpression(callArguments[0]) &&
|
||||
hasKeyProperty()
|
||||
)
|
||||
}
|
||||
|
||||
const predicate = (property) => {
|
||||
const isSpreadElement = utils.isSpreadElement(property)
|
||||
const isObjectProperty = utils.isObjectProperty(property)
|
||||
|
||||
return (
|
||||
isSpreadElement ||
|
||||
(isObjectProperty && property.key.name !== config.keyName)
|
||||
)
|
||||
}
|
||||
|
||||
const transformArgumentToQueryFunction = (path, node) => {
|
||||
const isIdentifier = utils.isIdentifier(node)
|
||||
const isFunctionDefinition = utils.isFunctionDefinition(node)
|
||||
|
||||
if (!isIdentifier && !isFunctionDefinition) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (isFunctionDefinition) {
|
||||
return jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier('queryFn'),
|
||||
node,
|
||||
)
|
||||
}
|
||||
|
||||
const binding = v5Utils.getBindingFromScope(path, node.name, filePath)
|
||||
const initializer = v5Utils.getInitializerByDeclarator(binding)
|
||||
|
||||
if (!utils.isFunctionDefinition(initializer)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier('queryFn'),
|
||||
binding.id,
|
||||
)
|
||||
}
|
||||
|
||||
const transformArgumentToOptionsObject = (path, node) => {
|
||||
if (!utils.isIdentifier(node)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const binding = v5Utils.getBindingFromScope(path, node.name, filePath)
|
||||
const initializer = v5Utils.getInitializerByDeclarator(binding)
|
||||
|
||||
if (utils.isObjectExpression(initializer)) {
|
||||
return jscodeshift.spreadElement(binding.id)
|
||||
}
|
||||
}
|
||||
|
||||
const replacer = (path) => {
|
||||
const node = path.node
|
||||
|
||||
try {
|
||||
// If the given method/function call matches certain criteria, the node doesn't need to be replaced, this step can be skipped.
|
||||
if (canSkipReplacement(node)) {
|
||||
return node
|
||||
}
|
||||
|
||||
const keyProperty = v5Utils.transformArgumentToKey(
|
||||
path,
|
||||
node.arguments[0],
|
||||
config.keyName,
|
||||
filePath,
|
||||
)
|
||||
|
||||
if (!keyProperty) {
|
||||
throw new UnknownUsageError(node, filePath)
|
||||
}
|
||||
|
||||
const parameters = [jscodeshift.objectExpression([keyProperty])]
|
||||
const createdObjectExpression = parameters[0]
|
||||
const secondParameter = node.arguments[1]
|
||||
|
||||
if (secondParameter) {
|
||||
const queryFnProperty = transformArgumentToQueryFunction(
|
||||
path,
|
||||
secondParameter,
|
||||
)
|
||||
|
||||
if (queryFnProperty) {
|
||||
createdObjectExpression.properties.push(queryFnProperty)
|
||||
|
||||
const thirdParameter = node.arguments[2]
|
||||
|
||||
if (utils.isObjectExpression(thirdParameter)) {
|
||||
v5Utils.copyPropertiesFromSource(
|
||||
thirdParameter,
|
||||
createdObjectExpression,
|
||||
predicate,
|
||||
)
|
||||
} else {
|
||||
createdObjectExpression.properties.push(
|
||||
jscodeshift.spreadElement(thirdParameter),
|
||||
)
|
||||
}
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, parameters)
|
||||
}
|
||||
|
||||
const optionsProperty = transformArgumentToOptionsObject(
|
||||
path,
|
||||
secondParameter,
|
||||
)
|
||||
|
||||
if (optionsProperty) {
|
||||
createdObjectExpression.properties.push(optionsProperty)
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, parameters)
|
||||
}
|
||||
|
||||
if (utils.isObjectExpression(secondParameter)) {
|
||||
v5Utils.copyPropertiesFromSource(
|
||||
secondParameter,
|
||||
createdObjectExpression,
|
||||
predicate,
|
||||
)
|
||||
}
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, parameters)
|
||||
}
|
||||
|
||||
return jscodeshift.callExpression(node.original.callee, parameters)
|
||||
} catch (error) {
|
||||
utils.warn(
|
||||
error.name === UnknownUsageError.name
|
||||
? error.message
|
||||
: `An unknown error occurred while processing the "${filePath}" file. Please review this file, because the codemod couldn't be applied.`,
|
||||
)
|
||||
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
createQueryClientTransformer({ jscodeshift, utils, root }).execute(
|
||||
config.queryClientMethods,
|
||||
replacer,
|
||||
)
|
||||
}
|
||||
|
||||
module.exports = transformQueryFnAwareUsages
|
||||
123
packages/query-codemods/src/v5/remove-overloads/utils/index.cjs
Normal file
123
packages/query-codemods/src/v5/remove-overloads/utils/index.cjs
Normal file
@@ -0,0 +1,123 @@
|
||||
const UnknownUsageError = require('./unknown-usage-error.cjs')
|
||||
|
||||
module.exports = ({ jscodeshift, utils }) => {
|
||||
/**
|
||||
*
|
||||
* @param {import('jscodeshift').ObjectExpression} source
|
||||
* @param {import('jscodeshift').ObjectExpression} target
|
||||
* @param {(node: import('jscodeshift').Node) => boolean} predicate
|
||||
*/
|
||||
const copyPropertiesFromSource = (source, target, predicate) => {
|
||||
source.properties.forEach((property) => {
|
||||
if (predicate(property)) {
|
||||
target.properties.push(property)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').NodePath} path
|
||||
* @param {string} argumentName
|
||||
* @param {string} filePath
|
||||
* @returns {*}
|
||||
*/
|
||||
const getBindingFromScope = (path, argumentName, filePath) => {
|
||||
/**
|
||||
* If the current scope contains the declaration then we can use the actual one else we attempt to find the
|
||||
* binding from above.
|
||||
*/
|
||||
const scope = path.scope.declares(argumentName)
|
||||
? path.scope
|
||||
: path.scope.lookup(argumentName)
|
||||
|
||||
/**
|
||||
* The declaration couldn't be found for some reason, time to move on. We warn the user it needs to be rewritten
|
||||
* by themselves.
|
||||
*/
|
||||
if (!scope) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const binding = scope.bindings[argumentName]
|
||||
.filter((item) => utils.isIdentifier(item.value))
|
||||
.map((item) => item.parentPath.value)
|
||||
.at(0)
|
||||
|
||||
if (!binding) {
|
||||
throw new UnknownUsageError(path.node, filePath)
|
||||
}
|
||||
|
||||
return binding
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').VariableDeclarator} binding
|
||||
* @returns {import('jscodeshift').Node|undefined}
|
||||
*/
|
||||
const getInitializerByDeclarator = (binding) => {
|
||||
const isVariableDeclaration = jscodeshift.match(binding, {
|
||||
type: jscodeshift.VariableDeclarator.name,
|
||||
})
|
||||
|
||||
if (!isVariableDeclaration) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const isTSAsExpression = jscodeshift.match(binding.init, {
|
||||
type: jscodeshift.TSAsExpression.name,
|
||||
})
|
||||
|
||||
return isTSAsExpression ? binding.init.expression : binding.init
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isArrayExpressionVariable = (node) =>
|
||||
jscodeshift.match(node, {
|
||||
type: jscodeshift.VariableDeclarator.name,
|
||||
init: {
|
||||
type: jscodeshift.ArrayExpression.name,
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').NodePath} path
|
||||
* @param {import('jscodeshift').Node} node
|
||||
* @param {"queryKey"|"mutationKey"} keyName
|
||||
* @param {string} filePath
|
||||
* @returns {import('jscodeshift').Property|undefined}
|
||||
*/
|
||||
const transformArgumentToKey = (path, node, keyName, filePath) => {
|
||||
// If the first argument is an identifier we have to infer its type if possible.
|
||||
if (utils.isIdentifier(node)) {
|
||||
const binding = getBindingFromScope(path, node.name, filePath)
|
||||
|
||||
if (isArrayExpressionVariable(binding)) {
|
||||
return jscodeshift.property(
|
||||
'init',
|
||||
jscodeshift.identifier(keyName),
|
||||
jscodeshift.identifier(binding.id.name),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// If the first argument is an array, then it matches the following overload:
|
||||
// methodName(queryKey?: QueryKey, firstObject?: TFirstObject, secondObject?: TSecondObject)
|
||||
if (utils.isArrayExpression(node)) {
|
||||
// Then we create the 'queryKey' property based on it, because it will be passed to the first argument
|
||||
// that should be an object according to the new signature.
|
||||
return jscodeshift.property('init', jscodeshift.identifier(keyName), node)
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
return {
|
||||
copyPropertiesFromSource,
|
||||
getInitializerByDeclarator,
|
||||
getBindingFromScope,
|
||||
transformArgumentToKey,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
class UnknownUsageError extends Error {
|
||||
/**
|
||||
* @param {import('jscodeshift').CallExpression} callExpression
|
||||
* @param {string} filePath
|
||||
*/
|
||||
constructor(callExpression, filePath) {
|
||||
super('')
|
||||
this.message = this.buildMessage(callExpression, filePath)
|
||||
this.name = 'UnknownUsageError'
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('jscodeshift').CallExpression} callExpression
|
||||
* @param {string} filePath
|
||||
* @returns {string}
|
||||
*/
|
||||
buildMessage(callExpression, filePath) {
|
||||
const location = callExpression.callee.loc
|
||||
const start = location.start.line
|
||||
const end = location.end.line
|
||||
|
||||
return `The usage in file "${filePath}" at line ${start}:${end} could not be transformed into the new syntax. Please do this manually.`
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UnknownUsageError
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
Hydrate,
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
} from '@tanstack/react-query'
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
export default function MyApp({ Component, pageProps }) {
|
||||
const [queryClient] = React.useState(() => new QueryClient())
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Hydrate state={pageProps.dehydratedState}>
|
||||
<Component {...pageProps} />
|
||||
</Hydrate>
|
||||
<ReactQueryDevtools />
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
HydrationBoundary,
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
} from '@tanstack/react-query'
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
export default function MyApp({ Component, pageProps }) {
|
||||
const [queryClient] = React.useState(() => new QueryClient())
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<HydrationBoundary state={pageProps.dehydratedState}>
|
||||
<Component {...pageProps} />
|
||||
</HydrationBoundary>
|
||||
<ReactQueryDevtools />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
Hydrate as RenamedHydrate,
|
||||
QueryClient as RenamedQueryClient,
|
||||
QueryClientProvider as RenamedQueryClientProvider,
|
||||
} from '@tanstack/react-query'
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
export default function MyApp({ Component, pageProps }) {
|
||||
const [queryClient] = React.useState(() => new RenamedQueryClient())
|
||||
|
||||
return (
|
||||
<RenamedQueryClientProvider client={queryClient}>
|
||||
<RenamedHydrate state={pageProps.dehydratedState}>
|
||||
<Component {...pageProps} />
|
||||
</RenamedHydrate>
|
||||
<ReactQueryDevtools />
|
||||
</RenamedQueryClientProvider>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
HydrationBoundary as RenamedHydrate,
|
||||
QueryClient as RenamedQueryClient,
|
||||
QueryClientProvider as RenamedQueryClientProvider,
|
||||
} from '@tanstack/react-query'
|
||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
|
||||
|
||||
export default function MyApp({ Component, pageProps }) {
|
||||
const [queryClient] = React.useState(() => new RenamedQueryClient())
|
||||
|
||||
return (
|
||||
<RenamedQueryClientProvider client={queryClient}>
|
||||
<RenamedHydrate state={pageProps.dehydratedState}>
|
||||
<Component {...pageProps} />
|
||||
</RenamedHydrate>
|
||||
<ReactQueryDevtools />
|
||||
</RenamedQueryClientProvider>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'rename-hydrate.cjs', null, 'default-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(__dirname, 'rename-hydrate.cjs', null, 'named-import', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
@@ -0,0 +1,55 @@
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
|
||||
const importSpecifiers = root
|
||||
.find(jscodeshift.ImportDeclaration, {
|
||||
source: {
|
||||
value: '@tanstack/react-query',
|
||||
},
|
||||
})
|
||||
.find(jscodeshift.ImportSpecifier, {
|
||||
imported: {
|
||||
name: 'Hydrate',
|
||||
},
|
||||
})
|
||||
|
||||
if (importSpecifiers.length > 0) {
|
||||
const names = {
|
||||
searched: 'Hydrate', // By default, we want to replace the `Hydrate` usages.
|
||||
target: 'HydrationBoundary', // We want to replace them with `HydrationBoundary`.
|
||||
}
|
||||
|
||||
importSpecifiers.replaceWith(({ node: mutableNode }) => {
|
||||
/**
|
||||
* When the local and imported names match which means the code doesn't contain import aliases, we need
|
||||
* to replace only the import specifier.
|
||||
* @type {boolean}
|
||||
*/
|
||||
const usesDefaultImport =
|
||||
mutableNode.local.name === mutableNode.imported.name
|
||||
|
||||
if (!usesDefaultImport) {
|
||||
// If the code uses import aliases, we must re-use the alias.
|
||||
names.searched = mutableNode.local.name
|
||||
names.target = mutableNode.local.name
|
||||
}
|
||||
|
||||
// Override the import specifier.
|
||||
mutableNode.imported.name = 'HydrationBoundary'
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
|
||||
root
|
||||
.findJSXElements(names.searched)
|
||||
.replaceWith(({ node: mutableNode }) => {
|
||||
mutableNode.openingElement.name.name = names.target
|
||||
mutableNode.closingElement.name.name = names.target
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
}
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import * as React from 'react'
|
||||
import { QueryClient, useInfiniteQuery } from '@tanstack/react-query'
|
||||
import { search } from './algolia'
|
||||
|
||||
// Since the `cacheTime` property is string literal and not computed, the codemod should change it.
|
||||
export type UseAlgoliaOptionsButWithStringLiterals = {
|
||||
'indexName': string
|
||||
'query': string
|
||||
'hitsPerPage'?: number
|
||||
'staleTime'?: number
|
||||
'cacheTime'?: number
|
||||
'enabled'?: boolean
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, the codemod should change it.
|
||||
export type UseAlgoliaOptions = {
|
||||
indexName: string
|
||||
query: string
|
||||
hitsPerPage?: number
|
||||
staleTime?: number
|
||||
cacheTime?: number
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, and shorthand, the codemod should change it.
|
||||
export function useAlgolia<TData>({
|
||||
indexName,
|
||||
query,
|
||||
hitsPerPage = 10,
|
||||
staleTime,
|
||||
cacheTime,
|
||||
enabled,
|
||||
}: UseAlgoliaOptions) {
|
||||
const queryInfo = useInfiniteQuery({
|
||||
queryKey: ['algolia', indexName, query, hitsPerPage],
|
||||
queryFn: ({ pageParam }) =>
|
||||
search<TData>({ indexName, query, pageParam, hitsPerPage }),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage?.nextPage,
|
||||
staleTime,
|
||||
cacheTime,
|
||||
enabled,
|
||||
})
|
||||
|
||||
const hits = queryInfo.data?.pages.map((page) => page.hits).flat()
|
||||
|
||||
return { ...queryInfo, hits }
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, the codemod should change it.
|
||||
export const asIdentifierExample = () =>
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
cacheTime: 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Since the `cacheTime` property is a string literal and not computed, the codemod should change it.
|
||||
export const asStringLiteralExample = () =>
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
'cacheTime': 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Since the `cacheTime` property is computed, the codemod shouldn't touch this example.
|
||||
export const asComputedExample = () => {
|
||||
const cacheTime = 'foo'
|
||||
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
[cacheTime]: 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import * as React from 'react'
|
||||
import { QueryClient, useInfiniteQuery } from '@tanstack/react-query'
|
||||
import { search } from './algolia'
|
||||
|
||||
// Since the `cacheTime` property is string literal and not computed, the codemod should change it.
|
||||
export type UseAlgoliaOptionsButWithStringLiterals = {
|
||||
'indexName': string
|
||||
'query': string
|
||||
'hitsPerPage'?: number
|
||||
'staleTime'?: number
|
||||
'gcTime'?: number
|
||||
'enabled'?: boolean
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, the codemod should change it.
|
||||
export type UseAlgoliaOptions = {
|
||||
indexName: string
|
||||
query: string
|
||||
hitsPerPage?: number
|
||||
staleTime?: number
|
||||
gcTime?: number
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, and shorthand, the codemod should change it.
|
||||
export function useAlgolia<TData>({
|
||||
indexName,
|
||||
query,
|
||||
hitsPerPage = 10,
|
||||
staleTime,
|
||||
gcTime,
|
||||
enabled,
|
||||
}: UseAlgoliaOptions) {
|
||||
const queryInfo = useInfiniteQuery({
|
||||
queryKey: ['algolia', indexName, query, hitsPerPage],
|
||||
queryFn: ({ pageParam }) =>
|
||||
search<TData>({ indexName, query, pageParam, hitsPerPage }),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage?.nextPage,
|
||||
staleTime,
|
||||
gcTime,
|
||||
enabled,
|
||||
})
|
||||
|
||||
const hits = queryInfo.data?.pages.map((page) => page.hits).flat()
|
||||
|
||||
return { ...queryInfo, hits }
|
||||
}
|
||||
|
||||
// Since the `cacheTime` property is an identifier and not computed, the codemod should change it.
|
||||
export const asIdentifierExample = () =>
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
gcTime: 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Since the `cacheTime` property is a string literal and not computed, the codemod should change it.
|
||||
export const asStringLiteralExample = () =>
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
'gcTime': 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// Since the `cacheTime` property is computed, the codemod shouldn't touch this example.
|
||||
export const asComputedExample = () => {
|
||||
const cacheTime = 'foo'
|
||||
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
[cacheTime]: 1000 * 60 * 60 * 24, // 24 hours
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import * as React from 'react'
|
||||
|
||||
// Since the `useErrorBoundary` property is string literal and not computed, the codemod should change it.
|
||||
export type Type1 = {
|
||||
'useErrorBoundary'?: boolean
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, the codemod should change it.
|
||||
export type Type2 = {
|
||||
useErrorBoundary?: boolean
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, and shorthand, the codemod should change it.
|
||||
export function useSomething() {
|
||||
const queryInfo = useSomethingElse({
|
||||
useErrorBoundary,
|
||||
enabled,
|
||||
})
|
||||
|
||||
return queryInfo
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, the codemod should change it.
|
||||
export const asIdentifierExample = () => {
|
||||
return {
|
||||
useErrorBoundary: true
|
||||
}
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is a string literal and not computed, the codemod should change it.
|
||||
export const asStringLiteralExample = () => {
|
||||
return {
|
||||
'useErrorBoundary': true
|
||||
}
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is computed, the codemod shouldn't touch this example.
|
||||
export const asComputedExample = () => {
|
||||
const useErrorBoundary = 'foo'
|
||||
|
||||
return {
|
||||
[useErrorBoundary]: false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import * as React from 'react'
|
||||
|
||||
// Since the `useErrorBoundary` property is string literal and not computed, the codemod should change it.
|
||||
export type Type1 = {
|
||||
'throwOnError'?: boolean
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, the codemod should change it.
|
||||
export type Type2 = {
|
||||
throwOnError?: boolean
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, and shorthand, the codemod should change it.
|
||||
export function useSomething() {
|
||||
const queryInfo = useSomethingElse({
|
||||
throwOnError,
|
||||
enabled,
|
||||
})
|
||||
|
||||
return queryInfo
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is an identifier and not computed, the codemod should change it.
|
||||
export const asIdentifierExample = () => {
|
||||
return {
|
||||
throwOnError: true
|
||||
};
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is a string literal and not computed, the codemod should change it.
|
||||
export const asStringLiteralExample = () => {
|
||||
return {
|
||||
'throwOnError': true
|
||||
};
|
||||
}
|
||||
|
||||
// Since the `useErrorBoundary` property is computed, the codemod shouldn't touch this example.
|
||||
export const asComputedExample = () => {
|
||||
const useErrorBoundary = 'foo'
|
||||
|
||||
return {
|
||||
[useErrorBoundary]: false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
const defineTest = require('jscodeshift/dist/testUtils').defineTest
|
||||
|
||||
defineTest(__dirname, 'rename-properties.cjs', null, 'rename-cache-time', {
|
||||
parser: 'tsx',
|
||||
})
|
||||
|
||||
defineTest(
|
||||
__dirname,
|
||||
'rename-properties.cjs',
|
||||
null,
|
||||
'rename-use-error-boundary',
|
||||
{
|
||||
parser: 'tsx',
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
module.exports = (file, api) => {
|
||||
const jscodeshift = api.jscodeshift
|
||||
const root = jscodeshift(file.source)
|
||||
|
||||
const baseRenameLogic = (kind, from, to) => {
|
||||
root
|
||||
.find(kind, (node) => {
|
||||
return (
|
||||
node.computed === false &&
|
||||
(node.key?.name === from || node.key?.value === from)
|
||||
)
|
||||
})
|
||||
.replaceWith(({ node: mutableNode }) => {
|
||||
if (mutableNode.key.name !== undefined) {
|
||||
mutableNode.key.name = to
|
||||
}
|
||||
|
||||
if (mutableNode.key.value !== undefined) {
|
||||
mutableNode.key.value = to
|
||||
}
|
||||
|
||||
return mutableNode
|
||||
})
|
||||
}
|
||||
|
||||
const renameObjectProperty = (from, to) => {
|
||||
baseRenameLogic(jscodeshift.ObjectProperty, from, to)
|
||||
}
|
||||
|
||||
const renameTypeScriptPropertySignature = (from, to) => {
|
||||
baseRenameLogic(jscodeshift.TSPropertySignature, from, to)
|
||||
}
|
||||
|
||||
renameObjectProperty('cacheTime', 'gcTime')
|
||||
renameObjectProperty('useErrorBoundary', 'throwOnError')
|
||||
|
||||
renameTypeScriptPropertySignature('cacheTime', 'gcTime')
|
||||
renameTypeScriptPropertySignature('useErrorBoundary', 'throwOnError')
|
||||
|
||||
return root.toSource({ quote: 'single', lineTerminator: '\n' })
|
||||
}
|
||||
8
packages/query-codemods/tsconfig.json
Normal file
8
packages/query-codemods/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist-ts",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": ["src", "*.config.ts", "*.config.js", "package.json"]
|
||||
}
|
||||
30
packages/query-codemods/vite.config.ts
Normal file
30
packages/query-codemods/vite.config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
import packageJson from './package.json'
|
||||
|
||||
export default defineConfig({
|
||||
// fix from https://github.com/vitest-dev/vitest/issues/6992#issuecomment-2509408660
|
||||
resolve: {
|
||||
conditions: ['@tanstack/custom-condition'],
|
||||
},
|
||||
environments: {
|
||||
ssr: {
|
||||
resolve: {
|
||||
conditions: ['@tanstack/custom-condition'],
|
||||
},
|
||||
},
|
||||
},
|
||||
test: {
|
||||
name: packageJson.name,
|
||||
dir: './src',
|
||||
watch: false,
|
||||
globals: true,
|
||||
coverage: {
|
||||
enabled: !!process.env.CI,
|
||||
provider: 'istanbul',
|
||||
include: ['src/**/*.{js,ts,cjs,mjs,jsx,tsx}'],
|
||||
},
|
||||
typecheck: { enabled: true },
|
||||
restoreMocks: true,
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user