Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/slimy-taxes-make.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/eslint-plugin-query': patch
---

exhaustive-deps rule fixed for vue files
109 changes: 109 additions & 0 deletions packages/eslint-plugin-query/src/__tests__/exhaustive-deps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,45 @@ ruleTester.run('exhaustive-deps', rule, {
}
`,
},
{
name: 'should pass in Vue file when deps are correctly included (script setup)',
filename: 'Component.vue',
code: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const id = 1
useQuery({
queryKey: ['entity', id],
queryFn: () => fetchEntity(id),
})
`,
},
{
name: 'should not require imports in queryKey for Vue files',
filename: 'Component.vue',
code: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'
import { fetchTodos } from './api'

useQuery({
queryKey: ['todos'],
queryFn: () => fetchTodos(),
})
`,
},
{
name: 'should not require global fetch in queryKey for Vue files',
filename: 'Component.vue',
code: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const id = 1
useQuery({
queryKey: ['entity', id],
queryFn: () => fetch('/api/entity/' + id),
})
`,
},
],
invalid: [
{
Expand Down Expand Up @@ -975,5 +1014,75 @@ ruleTester.run('exhaustive-deps', rule, {
},
],
},
{
name: 'should fail in Vue file when deps are missing (script setup)',
filename: 'Component.vue',
code: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const id = 1
useQuery({
queryKey: ['entity'],
queryFn: () => fetchEntity(id),
})
`,
errors: [
{
messageId: 'missingDeps',
data: { deps: 'id' },
suggestions: [
{
messageId: 'fixTo',
data: { result: "['entity', id]" },
output: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const id = 1
useQuery({
queryKey: ['entity', id],
queryFn: () => fetchEntity(id),
})
`,
},
],
},
],
},
{
name: 'should fail in Vue file when multiple deps are missing',
filename: 'Component.vue',
code: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const userId = 1
const orgId = 2
useQuery({
queryKey: ['users'],
queryFn: () => fetchUser(userId, orgId),
})
`,
errors: [
{
messageId: 'missingDeps',
data: { deps: 'userId, orgId' },
suggestions: [
{
messageId: 'fixTo',
data: { result: "['users', userId, orgId]" },
output: normalizeIndent`
import { useQuery } from '@tanstack/vue-query'

const userId = 1
const orgId = 2
useQuery({
queryKey: ['users', userId, orgId],
queryFn: () => fetchUser(userId, orgId),
})
`,
},
],
},
],
},
],
})
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const rule = createRule({
reference,
scopeManager,
node: getQueryFnRelevantNode(queryFn),
filename: context.filename,
}),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,35 @@ export const ExhaustiveDepsUtils = {
reference: TSESLint.Scope.Reference
scopeManager: TSESLint.Scope.ScopeManager
node: TSESTree.Node
filename: string
}) {
const { sourceCode, reference, scopeManager, node } = params
const { sourceCode, reference, scopeManager, node, filename } = params
const component = ASTUtils.getFunctionAncestor(sourceCode, node)

if (component === undefined) {
return false
}
if (component !== undefined) {
if (
!ASTUtils.isDeclaredInNode({
scopeManager,
reference,
functionNode: component,
})
) {
return false
}
} else {
const isVueFile = filename.endsWith('.vue')

if (!isVueFile) {
return false
}

const definition = reference.resolved?.defs[0]
const isGlobalVariable = definition === undefined
const isImport = definition?.type === 'ImportBinding'

if (
!ASTUtils.isDeclaredInNode({
scopeManager,
reference,
functionNode: component,
})
) {
return false
if (isGlobalVariable || isImport) {
return false
}
}

return (
Expand Down
Loading