@tanstack/react-query 5.24.1 → 5.24.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/codemods/coverage/clover.xml +2 -2
- package/build/codemods/coverage/index.html +1 -1
- package/build/codemods/coverage/utils/index.html +1 -1
- package/build/codemods/coverage/utils/index.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/index.html +1 -1
- package/build/codemods/coverage/utils/transformers/query-cache-transformer.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/query-client-transformer.js.html +1 -1
- package/build/codemods/coverage/utils/transformers/use-query-like-transformer.js.html +1 -1
- package/build/codemods/coverage/v4/index.html +1 -1
- package/build/codemods/coverage/v4/key-transformation.js.html +1 -1
- package/build/codemods/coverage/v4/replace-import-specifier.js.html +1 -1
- package/build/codemods/coverage/v4/utils/replacers/index.html +1 -1
- package/build/codemods/coverage/v4/utils/replacers/key-replacer.js.html +1 -1
- package/build/codemods/coverage/v5/is-loading/index.html +1 -1
- package/build/codemods/coverage/v5/is-loading/is-loading.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/index.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/keep-previous-data.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/utils/already-has-placeholder-data-property.js.html +1 -1
- package/build/codemods/coverage/v5/keep-previous-data/utils/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/remove-overloads.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/filter-aware-usage-transformer.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/transformers/query-fn-aware-usage-transformer.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/index.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/index.js.html +1 -1
- package/build/codemods/coverage/v5/remove-overloads/utils/unknown-usage-error.js.html +1 -1
- package/build/codemods/coverage/v5/rename-hydrate/index.html +1 -1
- package/build/codemods/coverage/v5/rename-hydrate/rename-hydrate.js.html +1 -1
- package/build/codemods/coverage/v5/rename-properties/index.html +1 -1
- package/build/codemods/coverage/v5/rename-properties/rename-properties.js.html +1 -1
- package/build/legacy/suspense.cjs +1 -1
- package/build/legacy/suspense.cjs.map +1 -1
- package/build/legacy/suspense.js +1 -1
- package/build/legacy/suspense.js.map +1 -1
- package/build/legacy/useMutation.cjs +1 -3
- package/build/legacy/useMutation.cjs.map +1 -1
- package/build/legacy/useMutation.js +1 -3
- package/build/legacy/useMutation.js.map +1 -1
- package/build/legacy/useSuspenseQueries.cjs +2 -1
- package/build/legacy/useSuspenseQueries.cjs.map +1 -1
- package/build/legacy/useSuspenseQueries.js +2 -1
- package/build/legacy/useSuspenseQueries.js.map +1 -1
- package/build/legacy/useSuspenseQuery.cjs +2 -1
- package/build/legacy/useSuspenseQuery.cjs.map +1 -1
- package/build/legacy/useSuspenseQuery.js +2 -1
- package/build/legacy/useSuspenseQuery.js.map +1 -1
- package/build/legacy/utils.cjs +4 -0
- package/build/legacy/utils.cjs.map +1 -1
- package/build/legacy/utils.d.cts +2 -1
- package/build/legacy/utils.d.ts +2 -1
- package/build/legacy/utils.js +3 -0
- package/build/legacy/utils.js.map +1 -1
- package/build/modern/suspense.cjs +1 -1
- package/build/modern/suspense.cjs.map +1 -1
- package/build/modern/suspense.js +1 -1
- package/build/modern/suspense.js.map +1 -1
- package/build/modern/useMutation.cjs +1 -3
- package/build/modern/useMutation.cjs.map +1 -1
- package/build/modern/useMutation.js +1 -3
- package/build/modern/useMutation.js.map +1 -1
- package/build/modern/useSuspenseQueries.cjs +2 -1
- package/build/modern/useSuspenseQueries.cjs.map +1 -1
- package/build/modern/useSuspenseQueries.js +2 -1
- package/build/modern/useSuspenseQueries.js.map +1 -1
- package/build/modern/useSuspenseQuery.cjs +2 -1
- package/build/modern/useSuspenseQuery.cjs.map +1 -1
- package/build/modern/useSuspenseQuery.js +2 -1
- package/build/modern/useSuspenseQuery.js.map +1 -1
- package/build/modern/utils.cjs +4 -0
- package/build/modern/utils.cjs.map +1 -1
- package/build/modern/utils.d.cts +2 -1
- package/build/modern/utils.d.ts +2 -1
- package/build/modern/utils.js +3 -0
- package/build/modern/utils.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/infiniteQueryOptions.test-d.tsx +142 -0
- package/src/__tests__/queryOptions.test-d.tsx +150 -0
- package/src/__tests__/suspense.test-d.tsx +124 -0
- package/src/__tests__/suspense.test.tsx +102 -0
- package/src/__tests__/useInfiniteQuery.test-d.tsx +140 -0
- package/src/__tests__/useMutation.test.tsx +3 -1
- package/src/__tests__/useQueries.test-d.tsx +126 -0
- package/src/__tests__/useQuery.test-d.tsx +140 -0
- package/src/__tests__/utils.tsx +0 -8
- package/src/suspense.ts +1 -1
- package/src/useMutation.ts +1 -3
- package/src/useSuspenseQueries.ts +1 -0
- package/src/useSuspenseQuery.ts +1 -0
- package/src/utils.ts +2 -0
- package/src/__tests__/infiniteQueryOptions.types.test.tsx +0 -177
- package/src/__tests__/queryOptions.types.test.tsx +0 -192
- package/src/__tests__/suspense.types.test.tsx +0 -147
- package/src/__tests__/useInfiniteQuery.type.test.tsx +0 -224
- package/src/__tests__/useQueries.types.test.tsx +0 -148
- package/src/__tests__/useQuery.types.test.tsx +0 -179
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { useQuery } from '../useQuery'
|
|
3
|
+
import { queryOptions } from '../queryOptions'
|
|
4
|
+
import type { UseQueryOptions } from '../types'
|
|
5
|
+
|
|
6
|
+
describe('initialData', () => {
|
|
7
|
+
describe('Config object overload', () => {
|
|
8
|
+
it('TData should always be defined when initialData is provided as an object', () => {
|
|
9
|
+
const { data } = useQuery({
|
|
10
|
+
queryKey: ['key'],
|
|
11
|
+
queryFn: () => ({ wow: true }),
|
|
12
|
+
initialData: { wow: true },
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('TData should be defined when passed through queryOptions', () => {
|
|
19
|
+
const options = queryOptions({
|
|
20
|
+
queryKey: ['key'],
|
|
21
|
+
queryFn: () => {
|
|
22
|
+
return {
|
|
23
|
+
wow: true,
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
initialData: {
|
|
27
|
+
wow: true,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
const { data } = useQuery(options)
|
|
31
|
+
|
|
32
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('it should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => {
|
|
36
|
+
const options = queryOptions({
|
|
37
|
+
queryKey: ['key'],
|
|
38
|
+
queryFn: () => Promise.resolve(1),
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const query = useQuery({
|
|
42
|
+
...options,
|
|
43
|
+
select: (data) => data > 1,
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
expectTypeOf(query.data).toEqualTypeOf<boolean | undefined>()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
|
|
50
|
+
const { data } = useQuery({
|
|
51
|
+
queryKey: ['key'],
|
|
52
|
+
queryFn: () => {
|
|
53
|
+
return {
|
|
54
|
+
wow: true,
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
initialData: () => ({
|
|
58
|
+
wow: true,
|
|
59
|
+
}),
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('TData should have undefined in the union when initialData is NOT provided', () => {
|
|
66
|
+
const { data } = useQuery({
|
|
67
|
+
queryKey: ['key'],
|
|
68
|
+
queryFn: () => {
|
|
69
|
+
return {
|
|
70
|
+
wow: true,
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean } | undefined>()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('TData should have undefined in the union when initialData is provided as a function which can return undefined', () => {
|
|
79
|
+
const { data } = useQuery({
|
|
80
|
+
queryKey: ['key'],
|
|
81
|
+
queryFn: () => {
|
|
82
|
+
return {
|
|
83
|
+
wow: true,
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
initialData: () => undefined as { wow: boolean } | undefined,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean } | undefined>()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => {
|
|
93
|
+
const { data, isSuccess } = useQuery({
|
|
94
|
+
queryKey: ['key'],
|
|
95
|
+
queryFn: () => {
|
|
96
|
+
return {
|
|
97
|
+
wow: true,
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
initialData: () => undefined as { wow: boolean } | undefined,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
if (isSuccess) {
|
|
104
|
+
expectTypeOf(data).toEqualTypeOf<{ wow: boolean }>()
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('custom hook', () => {
|
|
110
|
+
it('should allow custom hooks using UseQueryOptions', () => {
|
|
111
|
+
type Data = string
|
|
112
|
+
|
|
113
|
+
const useCustomQuery = (
|
|
114
|
+
options?: Omit<UseQueryOptions<Data>, 'queryKey' | 'queryFn'>,
|
|
115
|
+
) => {
|
|
116
|
+
return useQuery({
|
|
117
|
+
...options,
|
|
118
|
+
queryKey: ['todos-key'],
|
|
119
|
+
queryFn: () => Promise.resolve('data'),
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const { data } = useCustomQuery()
|
|
124
|
+
|
|
125
|
+
expectTypeOf(data).toEqualTypeOf<Data | undefined>()
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
describe('structuralSharing', () => {
|
|
130
|
+
it('should restrict to same types', () => {
|
|
131
|
+
useQuery({
|
|
132
|
+
queryKey: ['key'],
|
|
133
|
+
queryFn: () => 5,
|
|
134
|
+
structuralSharing: (_oldData, newData) => {
|
|
135
|
+
return newData
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
})
|
package/src/__tests__/utils.tsx
CHANGED
|
@@ -78,14 +78,6 @@ export function setActTimeout(fn: () => void, ms?: number) {
|
|
|
78
78
|
}, ms)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
export type Equal<TTargetA, TTargetB> = (<T>() => T extends TTargetA
|
|
82
|
-
? 1
|
|
83
|
-
: 2) extends <T>() => T extends TTargetB ? 1 : 2
|
|
84
|
-
? true
|
|
85
|
-
: false
|
|
86
|
-
|
|
87
|
-
export type Expect<T extends true> = T
|
|
88
|
-
|
|
89
81
|
/**
|
|
90
82
|
* Assert the parameter is not typed as `any`
|
|
91
83
|
*/
|
package/src/suspense.ts
CHANGED
|
@@ -16,7 +16,7 @@ export const defaultThrowOnError = <
|
|
|
16
16
|
>(
|
|
17
17
|
_error: TError,
|
|
18
18
|
query: Query<TQueryFnData, TError, TData, TQueryKey>,
|
|
19
|
-
) =>
|
|
19
|
+
) => query.state.data === undefined
|
|
20
20
|
|
|
21
21
|
export const ensureStaleTime = (
|
|
22
22
|
defaultedOptions: DefaultedQueryObserverOptions<any, any, any, any, any>,
|
package/src/useMutation.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
import { MutationObserver, notifyManager } from '@tanstack/query-core'
|
|
4
4
|
import { useQueryClient } from './QueryClientProvider'
|
|
5
|
-
import { shouldThrowError } from './utils'
|
|
5
|
+
import { noop, shouldThrowError } from './utils'
|
|
6
6
|
import type {
|
|
7
7
|
UseMutateFunction,
|
|
8
8
|
UseMutationOptions,
|
|
@@ -63,5 +63,3 @@ export function useMutation<
|
|
|
63
63
|
|
|
64
64
|
return { ...result, mutate, mutateAsync: result.mutate }
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
function noop() {}
|
package/src/useSuspenseQuery.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'vitest'
|
|
2
|
-
import { QueryClient } from '@tanstack/query-core'
|
|
3
|
-
import { infiniteQueryOptions } from '../infiniteQueryOptions'
|
|
4
|
-
import { useInfiniteQuery } from '../useInfiniteQuery'
|
|
5
|
-
import { useSuspenseInfiniteQuery } from '../useSuspenseInfiniteQuery'
|
|
6
|
-
import { doNotExecute } from './utils'
|
|
7
|
-
import type { InfiniteData, dataTagSymbol } from '@tanstack/query-core'
|
|
8
|
-
import type { Equal, Expect } from './utils'
|
|
9
|
-
|
|
10
|
-
describe('queryOptions', () => {
|
|
11
|
-
it('should not allow excess properties', () => {
|
|
12
|
-
doNotExecute(() => {
|
|
13
|
-
return infiniteQueryOptions({
|
|
14
|
-
queryKey: ['key'],
|
|
15
|
-
queryFn: () => Promise.resolve('data'),
|
|
16
|
-
getNextPageParam: () => 1,
|
|
17
|
-
initialPageParam: 1,
|
|
18
|
-
// @ts-expect-error this is a good error, because stallTime does not exist!
|
|
19
|
-
stallTime: 1000,
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
it('should infer types for callbacks', () => {
|
|
24
|
-
doNotExecute(() => {
|
|
25
|
-
return infiniteQueryOptions({
|
|
26
|
-
queryKey: ['key'],
|
|
27
|
-
queryFn: () => Promise.resolve('data'),
|
|
28
|
-
staleTime: 1000,
|
|
29
|
-
getNextPageParam: () => 1,
|
|
30
|
-
initialPageParam: 1,
|
|
31
|
-
select: (data) => {
|
|
32
|
-
const result: Expect<
|
|
33
|
-
Equal<InfiniteData<string, number>, typeof data>
|
|
34
|
-
> = true
|
|
35
|
-
return result
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
it('should work when passed to useInfiniteQuery', () => {
|
|
41
|
-
doNotExecute(() => {
|
|
42
|
-
const options = infiniteQueryOptions({
|
|
43
|
-
queryKey: ['key'],
|
|
44
|
-
queryFn: () => Promise.resolve('string'),
|
|
45
|
-
getNextPageParam: () => 1,
|
|
46
|
-
initialPageParam: 1,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
const { data } = useInfiniteQuery(options)
|
|
50
|
-
|
|
51
|
-
// known issue: type of pageParams is unknown when returned from useInfiniteQuery
|
|
52
|
-
const result: Expect<
|
|
53
|
-
Equal<typeof data, InfiniteData<string, unknown> | undefined>
|
|
54
|
-
> = true
|
|
55
|
-
return result
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
it('should work when passed to useSuspenseInfiniteQuery', () => {
|
|
59
|
-
doNotExecute(() => {
|
|
60
|
-
const options = infiniteQueryOptions({
|
|
61
|
-
queryKey: ['key'],
|
|
62
|
-
queryFn: () => Promise.resolve('string'),
|
|
63
|
-
getNextPageParam: () => 1,
|
|
64
|
-
initialPageParam: 1,
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
const { data } = useSuspenseInfiniteQuery(options)
|
|
68
|
-
|
|
69
|
-
const result: Expect<Equal<typeof data, InfiniteData<string, unknown>>> =
|
|
70
|
-
true
|
|
71
|
-
return result
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
it('should work when passed to fetchInfiniteQuery', () => {
|
|
75
|
-
doNotExecute(async () => {
|
|
76
|
-
const options = infiniteQueryOptions({
|
|
77
|
-
queryKey: ['key'],
|
|
78
|
-
queryFn: () => Promise.resolve('string'),
|
|
79
|
-
getNextPageParam: () => 1,
|
|
80
|
-
initialPageParam: 1,
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
const data = await new QueryClient().fetchInfiniteQuery(options)
|
|
84
|
-
|
|
85
|
-
const result: Expect<Equal<typeof data, InfiniteData<string, number>>> =
|
|
86
|
-
true
|
|
87
|
-
return result
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
it('should tag the queryKey with the result type of the QueryFn', () => {
|
|
91
|
-
doNotExecute(() => {
|
|
92
|
-
const { queryKey } = infiniteQueryOptions({
|
|
93
|
-
queryKey: ['key'],
|
|
94
|
-
queryFn: () => Promise.resolve('string'),
|
|
95
|
-
getNextPageParam: () => 1,
|
|
96
|
-
initialPageParam: 1,
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
const result: Expect<
|
|
100
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], InfiniteData<string>>
|
|
101
|
-
> = true
|
|
102
|
-
return result
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
it('should tag the queryKey even if no promise is returned', () => {
|
|
106
|
-
doNotExecute(() => {
|
|
107
|
-
const { queryKey } = infiniteQueryOptions({
|
|
108
|
-
queryKey: ['key'],
|
|
109
|
-
queryFn: () => 'string',
|
|
110
|
-
getNextPageParam: () => 1,
|
|
111
|
-
initialPageParam: 1,
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
const result: Expect<
|
|
115
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], InfiniteData<string>>
|
|
116
|
-
> = true
|
|
117
|
-
return result
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
it('should tag the queryKey with the result type of the QueryFn if select is used', () => {
|
|
121
|
-
doNotExecute(() => {
|
|
122
|
-
const { queryKey } = infiniteQueryOptions({
|
|
123
|
-
queryKey: ['key'],
|
|
124
|
-
queryFn: () => Promise.resolve('string'),
|
|
125
|
-
select: (data) => data.pages,
|
|
126
|
-
getNextPageParam: () => 1,
|
|
127
|
-
initialPageParam: 1,
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
const result: Expect<
|
|
131
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], InfiniteData<string>>
|
|
132
|
-
> = true
|
|
133
|
-
return result
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
it('should return the proper type when passed to getQueryData', () => {
|
|
137
|
-
doNotExecute(() => {
|
|
138
|
-
const { queryKey } = infiniteQueryOptions({
|
|
139
|
-
queryKey: ['key'],
|
|
140
|
-
queryFn: () => Promise.resolve('string'),
|
|
141
|
-
getNextPageParam: () => 1,
|
|
142
|
-
initialPageParam: 1,
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
const queryClient = new QueryClient()
|
|
146
|
-
const data = queryClient.getQueryData(queryKey)
|
|
147
|
-
|
|
148
|
-
const result: Expect<
|
|
149
|
-
Equal<typeof data, InfiniteData<string, unknown> | undefined>
|
|
150
|
-
> = true
|
|
151
|
-
return result
|
|
152
|
-
})
|
|
153
|
-
})
|
|
154
|
-
it('should properly type when passed to setQueryData', () => {
|
|
155
|
-
doNotExecute(() => {
|
|
156
|
-
const { queryKey } = infiniteQueryOptions({
|
|
157
|
-
queryKey: ['key'],
|
|
158
|
-
queryFn: () => Promise.resolve('string'),
|
|
159
|
-
getNextPageParam: () => 1,
|
|
160
|
-
initialPageParam: 1,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
const queryClient = new QueryClient()
|
|
164
|
-
const data = queryClient.setQueryData(queryKey, (prev) => {
|
|
165
|
-
const result: Expect<
|
|
166
|
-
Equal<typeof prev, InfiniteData<string, unknown> | undefined>
|
|
167
|
-
> = true
|
|
168
|
-
return result ? prev : { pages: ['foo'], pageParams: [1] }
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const result: Expect<
|
|
172
|
-
Equal<typeof data, InfiniteData<string, unknown> | undefined>
|
|
173
|
-
> = true
|
|
174
|
-
return result
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
})
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'vitest'
|
|
2
|
-
import { QueryClient } from '@tanstack/query-core'
|
|
3
|
-
import { queryOptions } from '../queryOptions'
|
|
4
|
-
import { useQuery } from '../useQuery'
|
|
5
|
-
import { useQueries } from '../useQueries'
|
|
6
|
-
import { useSuspenseQuery } from '../useSuspenseQuery'
|
|
7
|
-
import { doNotExecute } from './utils'
|
|
8
|
-
import type { dataTagSymbol } from '@tanstack/query-core'
|
|
9
|
-
import type { Equal, Expect } from './utils'
|
|
10
|
-
|
|
11
|
-
describe('queryOptions', () => {
|
|
12
|
-
it('should not allow excess properties', () => {
|
|
13
|
-
doNotExecute(() => {
|
|
14
|
-
return queryOptions({
|
|
15
|
-
queryKey: ['key'],
|
|
16
|
-
queryFn: () => Promise.resolve(5),
|
|
17
|
-
// @ts-expect-error this is a good error, because stallTime does not exist!
|
|
18
|
-
stallTime: 1000,
|
|
19
|
-
})
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
it('should infer types for callbacks', () => {
|
|
23
|
-
doNotExecute(() => {
|
|
24
|
-
return queryOptions({
|
|
25
|
-
queryKey: ['key'],
|
|
26
|
-
queryFn: () => Promise.resolve(5),
|
|
27
|
-
staleTime: 1000,
|
|
28
|
-
select: (data) => {
|
|
29
|
-
const result: Expect<Equal<number, typeof data>> = true
|
|
30
|
-
return result
|
|
31
|
-
},
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
})
|
|
35
|
-
it('should work when passed to useQuery', () => {
|
|
36
|
-
doNotExecute(() => {
|
|
37
|
-
const options = queryOptions({
|
|
38
|
-
queryKey: ['key'],
|
|
39
|
-
queryFn: () => Promise.resolve(5),
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
const { data } = useQuery(options)
|
|
43
|
-
|
|
44
|
-
const result: Expect<Equal<typeof data, number | undefined>> = true
|
|
45
|
-
return result
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
it('should work when passed to useSuspenseQuery', () => {
|
|
49
|
-
doNotExecute(() => {
|
|
50
|
-
const options = queryOptions({
|
|
51
|
-
queryKey: ['key'],
|
|
52
|
-
queryFn: () => Promise.resolve(5),
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const { data } = useSuspenseQuery(options)
|
|
56
|
-
|
|
57
|
-
const result: Expect<Equal<typeof data, number>> = true
|
|
58
|
-
return result
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
it('should work when passed to fetchQuery', () => {
|
|
62
|
-
doNotExecute(async () => {
|
|
63
|
-
const options = queryOptions({
|
|
64
|
-
queryKey: ['key'],
|
|
65
|
-
queryFn: () => Promise.resolve(5),
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
const data = await new QueryClient().fetchQuery(options)
|
|
69
|
-
|
|
70
|
-
const result: Expect<Equal<typeof data, number>> = true
|
|
71
|
-
return result
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
it('should work when passed to useQueries', () => {
|
|
75
|
-
doNotExecute(() => {
|
|
76
|
-
const options = queryOptions({
|
|
77
|
-
queryKey: ['key'],
|
|
78
|
-
queryFn: () => Promise.resolve(5),
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const [{ data }] = useQueries({
|
|
82
|
-
queries: [options],
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
const result: Expect<Equal<typeof data, number | undefined>> = true
|
|
86
|
-
return result
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
it('should tag the queryKey with the result type of the QueryFn', () => {
|
|
90
|
-
doNotExecute(() => {
|
|
91
|
-
const { queryKey } = queryOptions({
|
|
92
|
-
queryKey: ['key'],
|
|
93
|
-
queryFn: () => Promise.resolve(5),
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
const result: Expect<
|
|
97
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], number>
|
|
98
|
-
> = true
|
|
99
|
-
return result
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
it('should tag the queryKey even if no promise is returned', () => {
|
|
103
|
-
doNotExecute(() => {
|
|
104
|
-
const { queryKey } = queryOptions({
|
|
105
|
-
queryKey: ['key'],
|
|
106
|
-
queryFn: () => 5,
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
const result: Expect<
|
|
110
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], number>
|
|
111
|
-
> = true
|
|
112
|
-
return result
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
it('should tag the queryKey with unknown if there is no queryFn', () => {
|
|
116
|
-
doNotExecute(() => {
|
|
117
|
-
const { queryKey } = queryOptions({
|
|
118
|
-
queryKey: ['key'],
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
const result: Expect<
|
|
122
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], unknown>
|
|
123
|
-
> = true
|
|
124
|
-
return result
|
|
125
|
-
})
|
|
126
|
-
})
|
|
127
|
-
it('should tag the queryKey with the result type of the QueryFn if select is used', () => {
|
|
128
|
-
doNotExecute(() => {
|
|
129
|
-
const { queryKey } = queryOptions({
|
|
130
|
-
queryKey: ['key'],
|
|
131
|
-
queryFn: () => Promise.resolve(5),
|
|
132
|
-
select: (data) => data.toString(),
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
const result: Expect<
|
|
136
|
-
Equal<(typeof queryKey)[typeof dataTagSymbol], number>
|
|
137
|
-
> = true
|
|
138
|
-
return result
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
it('should return the proper type when passed to getQueryData', () => {
|
|
142
|
-
doNotExecute(() => {
|
|
143
|
-
const { queryKey } = queryOptions({
|
|
144
|
-
queryKey: ['key'],
|
|
145
|
-
queryFn: () => Promise.resolve(5),
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
const queryClient = new QueryClient()
|
|
149
|
-
const data = queryClient.getQueryData(queryKey)
|
|
150
|
-
|
|
151
|
-
const result: Expect<Equal<typeof data, number | undefined>> = true
|
|
152
|
-
return result
|
|
153
|
-
})
|
|
154
|
-
})
|
|
155
|
-
it('should properly type updaterFn when passed to setQueryData', () => {
|
|
156
|
-
doNotExecute(() => {
|
|
157
|
-
const { queryKey } = queryOptions({
|
|
158
|
-
queryKey: ['key'],
|
|
159
|
-
queryFn: () => Promise.resolve(5),
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
const queryClient = new QueryClient()
|
|
163
|
-
const data = queryClient.setQueryData(queryKey, (prev) => {
|
|
164
|
-
const result: Expect<Equal<typeof prev, number | undefined>> = true
|
|
165
|
-
return result ? prev : 1
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
const result: Expect<Equal<typeof data, number | undefined>> = true
|
|
169
|
-
return result
|
|
170
|
-
})
|
|
171
|
-
})
|
|
172
|
-
it('should properly type value when passed to setQueryData', () => {
|
|
173
|
-
doNotExecute(() => {
|
|
174
|
-
const { queryKey } = queryOptions({
|
|
175
|
-
queryKey: ['key'],
|
|
176
|
-
queryFn: () => Promise.resolve(5),
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
const queryClient = new QueryClient()
|
|
180
|
-
|
|
181
|
-
// @ts-expect-error value should be a number
|
|
182
|
-
queryClient.setQueryData(queryKey, '5')
|
|
183
|
-
// @ts-expect-error value should be a number
|
|
184
|
-
queryClient.setQueryData(queryKey, () => '5')
|
|
185
|
-
|
|
186
|
-
const data = queryClient.setQueryData(queryKey, 5)
|
|
187
|
-
|
|
188
|
-
const result: Expect<Equal<typeof data, number | undefined>> = true
|
|
189
|
-
return result
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
})
|