Skip to content

Commit 94a03e9

Browse files
committed
Migrate current react-query impl to typescript
1 parent e3781fd commit 94a03e9

File tree

4 files changed

+132
-118
lines changed

4 files changed

+132
-118
lines changed

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

Lines changed: 0 additions & 83 deletions
This file was deleted.

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

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import {
2+
UseMutationOptions,
3+
UseMutationResult,
4+
UseQueryOptions,
5+
UseQueryResult,
6+
UseSuspenseQueryOptions,
7+
UseSuspenseQueryResult,
8+
useMutation,
9+
useQuery,
10+
} from "@tanstack/react-query";
11+
import {
12+
ClientMethod,
13+
FetchResponse,
14+
MaybeOptionalInit,
15+
OpenapiClient,
16+
} from "openapi-fetch";
17+
import {
18+
HasRequiredKeys,
19+
HttpMethod,
20+
MediaType,
21+
PathsWithMethod,
22+
} from "openapi-typescript-helpers";
23+
24+
export type UseQueryMethod<
25+
Paths extends Record<string, Record<HttpMethod, {}>>,
26+
Media extends MediaType,
27+
> = {
28+
<
29+
Method extends HttpMethod,
30+
Path extends PathsWithMethod<Paths, Method>,
31+
Init extends MaybeOptionalInit<Paths[Path], Method>,
32+
Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types
33+
Options extends Omit<
34+
UseQueryOptions<Response["data"], Response["error"]>,
35+
"queryKey" | "queryFn"
36+
>,
37+
>(
38+
method: Method,
39+
url: Path,
40+
...[init, options]: HasRequiredKeys<Init> extends never
41+
? [(Init & { [key: string]: unknown })?, Options?]
42+
: [Init & { [key: string]: unknown }, Options?]
43+
): UseQueryResult<Response["data"], Response["error"]>;
44+
};
45+
46+
export type UseSuspenseQueryMethod<
47+
Paths extends Record<string, Record<HttpMethod, {}>>,
48+
Media extends MediaType,
49+
> = {
50+
<
51+
Method extends HttpMethod,
52+
Path extends PathsWithMethod<Paths, Method>,
53+
Init extends MaybeOptionalInit<Paths[Path], Method>,
54+
Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types
55+
Options extends Omit<
56+
UseSuspenseQueryOptions<Response["data"], Response["error"]>,
57+
"queryKey" | "queryFn"
58+
>,
59+
>(
60+
method: Method,
61+
url: Path,
62+
...[init, options]: HasRequiredKeys<Init> extends never
63+
? [(Init & { [key: string]: unknown })?, Options?]
64+
: [Init & { [key: string]: unknown }, Options?]
65+
): UseSuspenseQueryResult<Response["data"], Response["error"]>;
66+
};
67+
68+
export type UseMutationMethod<
69+
Paths extends Record<string, Record<HttpMethod, {}>>,
70+
Media extends MediaType,
71+
> = {
72+
<
73+
Method extends HttpMethod,
74+
Path extends PathsWithMethod<Paths, Method>,
75+
Init extends MaybeOptionalInit<Paths[Path], Method>,
76+
Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types
77+
Options extends Omit<
78+
UseMutationOptions<Response["data"], Response["error"], Init>,
79+
"mutationKey" | "mutationFn"
80+
>,
81+
>(
82+
method: Method,
83+
url: Path,
84+
options?: Options,
85+
// TODO: Add support for Partial request options that become optional in UseMutationResult Context
86+
): UseMutationResult<Response["data"], Response["error"], Init>;
87+
};
88+
89+
export interface OpenapiQueryClient<
90+
Paths extends {},
91+
Media extends MediaType = MediaType,
92+
> {
93+
useQuery: UseQueryMethod<Paths, Media>;
94+
useSuspenseQery: any;
95+
useMutation: UseMutationMethod<Paths, Media>;
96+
}
97+
98+
export default function createClient<
99+
Paths extends {},
100+
Media extends MediaType = MediaType,
101+
>(client: OpenapiClient<Paths, Media>): OpenapiQueryClient<Paths, Media> {
102+
return {
103+
useQuery: (method, path, ...[init, options]) => {
104+
return useQuery({
105+
queryKey: [method, path, init],
106+
queryFn: async () => {
107+
const mth = method.toUpperCase() as keyof typeof client;
108+
const fn = client[mth] as ClientMethod<Paths, typeof method, Media>;
109+
const { data, error } = await fn(path, init as any); // TODO: find a way to avoid as any
110+
if (error || !data) throw error;
111+
return data;
112+
},
113+
...options,
114+
});
115+
},
116+
useSuspenseQery: () => {},
117+
useMutation: (method, path, options) => {
118+
return useMutation({
119+
mutationKey: [method, path],
120+
mutationFn: async (init) => {
121+
const mth = method.toUpperCase() as keyof typeof client;
122+
const fn = client[mth] as ClientMethod<Paths, typeof method, Media>;
123+
const { data, error } = await fn(path, init as any); // TODO: find a way to avoid as any
124+
if (error || !data) throw error;
125+
return data;
126+
},
127+
...options,
128+
});
129+
},
130+
};
131+
}

packages/openapi-react-query/test/index.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe("client", () => {
5252
body: { message: "OK" },
5353
});
5454

55-
const { result } = renderHook(() => client.useQuery("get", "/self", {}), {
55+
const { result } = renderHook(() => client.useQuery("get", "/self"), {
5656
wrapper,
5757
});
5858

0 commit comments

Comments
 (0)