@@ -5,13 +5,16 @@ import {
5
5
type UseQueryResult ,
6
6
type UseSuspenseQueryOptions ,
7
7
type UseSuspenseQueryResult ,
8
+ type UseInfiniteQueryOptions ,
9
+ type UseInfiniteQueryResult ,
8
10
type QueryClient ,
9
11
useMutation ,
10
12
useQuery ,
11
13
useSuspenseQuery ,
14
+ useInfiniteQuery ,
12
15
} from "@tanstack/react-query" ;
13
16
import type { ClientMethod , FetchResponse , MaybeOptionalInit , Client as FetchClient } from "openapi-fetch" ;
14
- import type { HttpMethod , MediaType , PathsWithMethod , RequiredKeysOf } from "openapi-typescript-helpers" ;
17
+ import type { HttpMethod , MediaType , PathsWithMethod , RequiredKeysOf , ResponseObjectMap } from "openapi-typescript-helpers" ;
15
18
16
19
export type UseQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
17
20
Method extends HttpMethod ,
@@ -54,10 +57,25 @@ export type UseMutationMethod<Paths extends Record<string, Record<HttpMethod, {}
54
57
queryClient ?: QueryClient ,
55
58
) => UseMutationResult < Response [ "data" ] , Response [ "error" ] , Init > ;
56
59
60
+ export type UseInfinityQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
61
+ Method extends HttpMethod ,
62
+ Path extends PathsWithMethod < Paths , Method > ,
63
+ Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
64
+ Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
65
+ Options extends Omit < UseInfiniteQueryOptions < Response [ "data" ] , Response [ "error" ] > , "queryKey" | "queryFn" > ,
66
+ > (
67
+ method : Method ,
68
+ url : Path ,
69
+ ...[ init , options , queryClient ] : RequiredKeysOf < Init > extends never
70
+ ? [ ( Init & { [ key : string ] : unknown } ) ?, Options ?, QueryClient ?]
71
+ : [ Init & { [ key : string ] : unknown } , Options ?, QueryClient ?]
72
+ ) => UseInfiniteQueryResult < Response [ "data" ] , Response [ "error" ] > ;
73
+
57
74
export interface OpenapiQueryClient < Paths extends { } , Media extends MediaType = MediaType > {
58
75
useQuery : UseQueryMethod < Paths , Media > ;
59
76
useSuspenseQuery : UseSuspenseQueryMethod < Paths , Media > ;
60
77
useMutation : UseMutationMethod < Paths , Media > ;
78
+ useInfiniteQuery : UseInfinityQueryMethod < Paths , Media > ;
61
79
}
62
80
63
81
// TODO: Move the client[method]() fn outside for reusability
@@ -121,5 +139,28 @@ export default function createClient<Paths extends {}, Media extends MediaType =
121
139
queryClient ,
122
140
) ;
123
141
} ,
142
+ useInfiniteQuery : ( method , path , ...[ init , options , queryClient ] ) => {
143
+ return useInfiniteQuery (
144
+ {
145
+ queryKey : [ method , path , init ] ,
146
+ queryFn : async ( { pageParam = 0 } ) => {
147
+ const mth = method . toUpperCase ( ) as keyof typeof client ;
148
+ const fn = client [ mth ] as ClientMethod < Paths , typeof method , Media > ;
149
+
150
+ const params = pageParam === 0 ? init : { ...init , page : pageParam } ;
151
+
152
+ const { data, error } = await fn ( path , params as any ) ; // TODO: find a way to avoid as any
153
+ if ( error || ! data ) {
154
+ throw error ;
155
+ }
156
+ return data ;
157
+ } ,
158
+ getNextPageParam : ( lastPage : ResponseObjectMap < any > ) => lastPage . nextPage ?? false ,
159
+ initialPageParam : 0 ,
160
+ ...options ,
161
+ } ,
162
+ queryClient ,
163
+ ) ;
164
+ } ,
124
165
} ;
125
166
}
0 commit comments