@@ -15,20 +15,15 @@ import {
1515 useQuery ,
1616 useSuspenseQuery ,
1717 useInfiniteQuery ,
18- } from ' @tanstack/react-query' ;
18+ } from " @tanstack/react-query" ;
1919import type {
2020 ClientMethod ,
2121 FetchResponse ,
2222 MaybeOptionalInit ,
2323 Client as FetchClient ,
2424 DefaultParamsOption ,
25- } from 'openapi-fetch' ;
26- import type {
27- HttpMethod ,
28- MediaType ,
29- PathsWithMethod ,
30- RequiredKeysOf ,
31- } from 'openapi-typescript-helpers' ;
25+ } from "openapi-fetch" ;
26+ import type { HttpMethod , MediaType , PathsWithMethod , RequiredKeysOf } from "openapi-typescript-helpers" ;
3227
3328// Helper type to dynamically infer the type from the `select` property
3429type InferSelectReturnType < TData , TSelect > = TSelect extends ( data : TData ) => infer R ? R : TData ;
@@ -42,22 +37,19 @@ export type QueryKey<
4237 Init = MaybeOptionalInit < Paths [ Path ] , Method > ,
4338> = Init extends undefined ? readonly [ Method , Path ] : readonly [ Method , Path , Init ] ;
4439
45- export type QueryOptionsFunction <
46- Paths extends Record < string , Record < HttpMethod , { } > > ,
47- Media extends MediaType ,
48- > = <
40+ export type QueryOptionsFunction < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
4941 Method extends HttpMethod ,
5042 Path extends PathsWithMethod < Paths , Method > ,
5143 Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
5244 Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
5345 Options extends Omit <
5446 UseQueryOptions <
55- Response [ ' data' ] ,
56- Response [ ' error' ] ,
57- InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > ,
47+ Response [ " data" ] ,
48+ Response [ " error" ] ,
49+ InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > ,
5850 QueryKey < Paths , Method , Path >
5951 > ,
60- ' queryKey' | ' queryFn'
52+ " queryKey" | " queryFn"
6153 > ,
6254> (
6355 method : Method ,
@@ -68,129 +60,113 @@ export type QueryOptionsFunction<
6860) => NoInfer <
6961 Omit <
7062 UseQueryOptions <
71- Response [ ' data' ] ,
72- Response [ ' error' ] ,
73- InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > ,
63+ Response [ " data" ] ,
64+ Response [ " error" ] ,
65+ InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > ,
7466 QueryKey < Paths , Method , Path >
7567 > ,
76- ' queryFn'
68+ " queryFn"
7769 > & {
7870 queryFn : Exclude <
7971 UseQueryOptions <
80- Response [ ' data' ] ,
81- Response [ ' error' ] ,
82- InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > ,
72+ Response [ " data" ] ,
73+ Response [ " error" ] ,
74+ InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > ,
8375 QueryKey < Paths , Method , Path >
84- > [ ' queryFn' ] ,
76+ > [ " queryFn" ] ,
8577 SkipToken | undefined
8678 > ;
8779 }
8880> ;
8981
90- export type UseQueryMethod <
91- Paths extends Record < string , Record < HttpMethod , { } > > ,
92- Media extends MediaType ,
93- > = <
82+ export type UseQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
9483 Method extends HttpMethod ,
9584 Path extends PathsWithMethod < Paths , Method > ,
9685 Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
9786 Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
9887 Options extends Omit <
9988 UseQueryOptions <
100- Response [ ' data' ] ,
101- Response [ ' error' ] ,
102- InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > ,
89+ Response [ " data" ] ,
90+ Response [ " error" ] ,
91+ InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > ,
10392 QueryKey < Paths , Method , Path >
10493 > ,
105- ' queryKey' | ' queryFn'
94+ " queryKey" | " queryFn"
10695 > ,
10796> (
10897 method : Method ,
10998 url : Path ,
11099 ...[ init , options , queryClient ] : RequiredKeysOf < Init > extends never
111100 ? [ InitWithUnknowns < Init > ?, Options ?, QueryClient ?]
112101 : [ InitWithUnknowns < Init > , Options ?, QueryClient ?]
113- ) => UseQueryResult < InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > , Response [ ' error' ] > ;
102+ ) => UseQueryResult < InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > , Response [ " error" ] > ;
114103
115- export type UseInfiniteQueryMethod <
116- Paths extends Record < string , Record < HttpMethod , { } > > ,
117- Media extends MediaType ,
118- > = <
104+ // Helper type to infer TPageParam type
105+ type InferPageParamType < T > = T extends { initialPageParam : infer P } ? P : unknown ;
106+
107+ export type UseInfiniteQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
119108 Method extends HttpMethod ,
120109 Path extends PathsWithMethod < Paths , Method > ,
121110 Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
122111 Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > ,
123- Select = undefined ,
124112 Options extends Omit <
125113 UseInfiniteQueryOptions <
126- Response [ ' data' ] ,
127- Response [ ' error' ] ,
128- InferSelectReturnType < InfiniteData < Response [ ' data' ] > , Select > ,
114+ Response [ " data" ] ,
115+ Response [ " error" ] ,
116+ InferSelectReturnType < InfiniteData < Response [ " data" ] > , Options [ "select" ] > ,
129117 QueryKey < Paths , Method , Path > ,
130- unknown
118+ InferPageParamType < Options >
131119 > ,
132- ' queryKey' | ' queryFn'
120+ " queryKey" | " queryFn"
133121 > & {
134122 pageParamName ?: string ;
135- select ?: Select ;
136- } = any ,
123+ initialPageParam : InferPageParamType < Options > ;
124+ } ,
137125> (
138126 method : Method ,
139127 url : Path ,
140128 init : InitWithUnknowns < Init > ,
141129 options : Options ,
142- queryClient ?: QueryClient
130+ queryClient ?: QueryClient ,
143131) => UseInfiniteQueryResult <
144- InferSelectReturnType < InfiniteData < Response [ ' data' ] > , Select > ,
145- Response [ ' error' ]
132+ InferSelectReturnType < InfiniteData < Response [ " data" ] > , Options [ "select" ] > ,
133+ Response [ " error" ]
146134> ;
147135
148- export type UseSuspenseQueryMethod <
149- Paths extends Record < string , Record < HttpMethod , { } > > ,
150- Media extends MediaType ,
151- > = <
136+ export type UseSuspenseQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
152137 Method extends HttpMethod ,
153138 Path extends PathsWithMethod < Paths , Method > ,
154139 Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
155140 Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
156141 Options extends Omit <
157142 UseSuspenseQueryOptions <
158- Response [ ' data' ] ,
159- Response [ ' error' ] ,
160- InferSelectReturnType < Response [ ' data' ] , Options [ ' select' ] > ,
143+ Response [ " data" ] ,
144+ Response [ " error" ] ,
145+ InferSelectReturnType < Response [ " data" ] , Options [ " select" ] > ,
161146 QueryKey < Paths , Method , Path >
162147 > ,
163- ' queryKey' | ' queryFn'
148+ " queryKey" | " queryFn"
164149 > ,
165150> (
166151 method : Method ,
167152 url : Path ,
168153 ...[ init , options , queryClient ] : RequiredKeysOf < Init > extends never
169154 ? [ InitWithUnknowns < Init > ?, Options ?, QueryClient ?]
170155 : [ InitWithUnknowns < Init > , Options ?, QueryClient ?]
171- ) => UseSuspenseQueryResult <
172- InferSelectReturnType < Response [ 'data' ] , Options [ 'select' ] > ,
173- Response [ 'error' ]
174- > ;
156+ ) => UseSuspenseQueryResult < InferSelectReturnType < Response [ "data" ] , Options [ "select" ] > , Response [ "error" ] > ;
175157
176- export type UseMutationMethod <
177- Paths extends Record < string , Record < HttpMethod , { } > > ,
178- Media extends MediaType ,
179- > = <
158+ export type UseMutationMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
180159 Method extends HttpMethod ,
181160 Path extends PathsWithMethod < Paths , Method > ,
182161 Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
183162 Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
184- Options extends Omit <
185- UseMutationOptions < Response [ 'data' ] , Response [ 'error' ] , Init > ,
186- 'mutationKey' | 'mutationFn'
187- > ,
163+ Options extends Omit < UseMutationOptions < Response [ "data" ] , Response [ "error" ] , Init > , "mutationKey" | "mutationFn" > ,
188164> (
189165 method : Method ,
190166 url : Path ,
191167 options ?: Options ,
192- queryClient ?: QueryClient
193- ) => UseMutationResult < Response [ ' data' ] , Response [ ' error' ] , Init > ;
168+ queryClient ?: QueryClient ,
169+ ) => UseMutationResult < Response [ " data" ] , Response [ " error" ] , Init > ;
194170
195171export interface OpenapiQueryClient < Paths extends { } , Media extends MediaType = MediaType > {
196172 queryOptions : QueryOptionsFunction < Paths , Media > ;
@@ -207,62 +183,59 @@ export type MethodResponse<
207183 ? PathsWithMethod < Paths , Method >
208184 : never ,
209185 Options = object ,
210- > =
211- CreatedClient extends OpenapiQueryClient <
212- infer Paths extends { [ key : string ] : any } ,
213- infer Media extends MediaType
214- >
215- ? NonNullable < FetchResponse < Paths [ Path ] [ Method ] , Options , Media > [ 'data' ] >
216- : never ;
186+ > = CreatedClient extends OpenapiQueryClient < infer Paths extends { [ key : string ] : any } , infer Media extends MediaType >
187+ ? NonNullable < FetchResponse < Paths [ Path ] [ Method ] , Options , Media > [ "data" ] >
188+ : never ;
217189
218190// TODO: Add the ability to bring queryClient as argument
219191export default function createClient < Paths extends { } , Media extends MediaType = MediaType > (
220- client : FetchClient < Paths , Media >
192+ client : FetchClient < Paths , Media > ,
221193) : OpenapiQueryClient < Paths , Media > {
222194 const queryFn = async < Method extends HttpMethod , Path extends PathsWithMethod < Paths , Method > > ( {
223195 queryKey : [ method , path , init ] ,
224196 signal,
225197 } : QueryFunctionContext < QueryKey < Paths , Method , Path > > ) => {
226198 const mth = method . toUpperCase ( ) as Uppercase < typeof method > ;
227199 const fn = client [ mth ] as ClientMethod < Paths , typeof method , Media > ;
228- const { data, error, response } = await fn ( path , { signal, ...( init as any ) } ) ; // TODO: find a way to avoid as any
200+ const { data, error, response } = await fn ( path , {
201+ signal,
202+ ...( init as any ) ,
203+ } ) ; // TODO: find a way to avoid as any
229204 if ( error ) {
230205 throw error ;
231206 }
232- if ( response . status === 204 || response . headers . get ( ' Content-Length' ) === '0' ) {
207+ if ( response . status === 204 || response . headers . get ( " Content-Length" ) === "0" ) {
233208 return data ?? null ;
234209 }
235210
236211 return data ;
237212 } ;
238213
239214 const queryOptions : QueryOptionsFunction < Paths , Media > = ( method , path , ...[ init , options ] ) => ( {
240- queryKey : ( init === undefined
241- ? ( [ method , path ] as const )
242- : ( [ method , path , init ] as const ) ) as QueryKey < Paths , typeof method , typeof path > ,
215+ queryKey : ( init === undefined ? ( [ method , path ] as const ) : ( [ method , path , init ] as const ) ) as QueryKey <
216+ Paths ,
217+ typeof method ,
218+ typeof path
219+ > ,
243220 queryFn,
244221 ...options ,
245222 } ) ;
246223
247224 return {
248225 queryOptions,
249226 useQuery : ( method , path , ...[ init , options , queryClient ] ) =>
250- useQuery (
251- queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) ,
252- queryClient
253- ) ,
227+ useQuery ( queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
254228 useSuspenseQuery : ( method , path , ...[ init , options , queryClient ] ) =>
255- useSuspenseQuery (
256- queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) ,
257- queryClient
258- ) ,
229+ useSuspenseQuery ( queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
259230 useInfiniteQuery : ( method , path , init , options , queryClient ) => {
260- const { pageParamName = ' cursor' , ...restOptions } = options ;
231+ const { pageParamName = " cursor" , initialPageParam , ...restOptions } = options ;
261232 const { queryKey } = queryOptions ( method , path , init ) ;
233+
262234 return useInfiniteQuery (
263235 {
264236 queryKey,
265- queryFn : async ( { queryKey : [ method , path , init ] , pageParam = 0 , signal } ) => {
237+ initialPageParam,
238+ queryFn : async ( { queryKey : [ method , path , init ] , pageParam, signal } ) => {
266239 const mth = method . toUpperCase ( ) as Uppercase < typeof method > ;
267240 const fn = client [ mth ] as ClientMethod < Paths , typeof method , Media > ;
268241 const mergedInit = {
@@ -285,7 +258,7 @@ export default function createClient<Paths extends {}, Media extends MediaType =
285258 } ,
286259 ...restOptions ,
287260 } ,
288- queryClient
261+ queryClient ,
289262 ) ;
290263 } ,
291264 useMutation : ( method , path , options , queryClient ) =>
@@ -304,7 +277,7 @@ export default function createClient<Paths extends {}, Media extends MediaType =
304277 } ,
305278 ...options ,
306279 } ,
307- queryClient
280+ queryClient ,
308281 ) ,
309282 } ;
310283}
0 commit comments