Skip to content

Commit ceb36e9

Browse files
committed
feat: support useInfiniteQuery
1 parent 2a4b067 commit ceb36e9

File tree

1 file changed

+42
-1
lines changed
  • packages/openapi-react-query/src

1 file changed

+42
-1
lines changed

packages/openapi-react-query/src/index.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import {
55
type UseQueryResult,
66
type UseSuspenseQueryOptions,
77
type UseSuspenseQueryResult,
8+
type UseInfiniteQueryOptions,
9+
type UseInfiniteQueryResult,
810
type QueryClient,
911
useMutation,
1012
useQuery,
1113
useSuspenseQuery,
14+
useInfiniteQuery,
1215
} from "@tanstack/react-query";
1316
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";
1518

1619
export type UseQueryMethod<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <
1720
Method extends HttpMethod,
@@ -54,10 +57,25 @@ export type UseMutationMethod<Paths extends Record<string, Record<HttpMethod, {}
5457
queryClient?: QueryClient,
5558
) => UseMutationResult<Response["data"], Response["error"], Init>;
5659

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+
5774
export interface OpenapiQueryClient<Paths extends {}, Media extends MediaType = MediaType> {
5875
useQuery: UseQueryMethod<Paths, Media>;
5976
useSuspenseQuery: UseSuspenseQueryMethod<Paths, Media>;
6077
useMutation: UseMutationMethod<Paths, Media>;
78+
useInfiniteQuery: UseInfinityQueryMethod<Paths, Media>;
6179
}
6280

6381
// TODO: Move the client[method]() fn outside for reusability
@@ -121,5 +139,28 @@ export default function createClient<Paths extends {}, Media extends MediaType =
121139
queryClient,
122140
);
123141
},
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+
},
124165
};
125166
}

0 commit comments

Comments
 (0)