Skip to content

Commit 1e1c40b

Browse files
authored
Merge pull request #2167 from hey-api/fix/tanstack-query-name-builder
fix(tanstack-query): add name builder options for all generated artifacts
2 parents 67125d3 + a46259e commit 1e1c40b

File tree

96 files changed

+5433
-215
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+5433
-215
lines changed

.changeset/hip-chefs-drop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(tanstack-query): add name builder options for all generated artifacts

.changeset/unlucky-kiwis-smile.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
fix(parser): set correct subscription context for plugins

docs/openapi-ts/configuration.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,23 @@ export default {
493493
};
494494
```
495495

496+
## Pagination
497+
498+
Paginated operations are detected by having a pagination keyword in its parameters or request body. By default, we consider the following to be pagination keywords: `after`, `before`, `cursor`, `offset`, `page`, and `start`. You can override these keywords by providing your own keywords array using `input.pagination.keywords`.
499+
500+
```js
501+
export default {
502+
input: {
503+
pagination: {
504+
keywords: ['custom', 'pagination', 'keywords'], // [!code ++]
505+
},
506+
path: 'https://get.heyapi.dev/hey-api/backend',
507+
},
508+
output: 'src/client',
509+
plugins: ['@hey-api/client-fetch'],
510+
};
511+
```
512+
496513
## Patch
497514

498515
There are times when you need to modify your input before it's processed further. A common use case is fixing an invalid specification or adding a missing field. You can apply custom patches with `input.patch`.

docs/openapi-ts/plugins/tanstack-query.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ The TanStack Query plugin will generate the following artifacts, depending on th
114114

115115
## Queries
116116

117-
Queries are generated from GET and POST endpoints. The generated functions follow the naming convention of SDK functions and append `Options`, e.g. `getPetByIdOptions()`.
117+
Queries are generated from GET and POST endpoints. The generated query functions follow the naming convention of SDK functions and by default append `Options`, e.g. `getPetByIdOptions()`.
118118

119119
```ts
120120
const { data, error } = useQuery({
@@ -126,9 +126,11 @@ const { data, error } = useQuery({
126126
});
127127
```
128128

129+
You can customize query function names using `queryOptionsNameBuilder`.
130+
129131
## Infinite Queries
130132

131-
Infinite queries are generated from GET and POST endpoints if we detect a pagination parameter. The generated functions follow the naming convention of SDK functions and append `InfiniteOptions`, e.g. `getFooInfiniteOptions()`.
133+
Infinite queries are generated from GET and POST endpoints if we detect a [pagination](/openapi-ts/configuration#pagination) parameter. The generated infinite query functions follow the naming convention of SDK functions and by default append `InfiniteOptions`, e.g. `getFooInfiniteOptions()`.
132134

133135
```ts
134136
const { data, error } = useInfiniteQuery({
@@ -142,18 +144,11 @@ const { data, error } = useInfiniteQuery({
142144
});
143145
```
144146

145-
Infinite queries are recognized by having one of these keywords in the endpoint's parameters:
146-
147-
- after
148-
- before
149-
- cursor
150-
- offset
151-
- page
152-
- start
147+
You can customize infinite query function names using `infiniteQueryOptionsNameBuilder`.
153148

154149
## Mutations
155150

156-
Mutations are generated from DELETE, PATCH, POST, and PUT endpoints. The generated functions follow the naming convention of SDK functions and append `Mutation`, e.g. `addPetMutation()`.
151+
Mutations are generated from DELETE, PATCH, POST, and PUT endpoints. The generated mutation functions follow the naming convention of SDK functions and by default append `Mutation`, e.g. `addPetMutation()`.
157152

158153
```ts
159154
const addPet = useMutation({
@@ -170,6 +165,8 @@ addPet.mutate({
170165
});
171166
```
172167

168+
You can customize mutation function names using `mutationOptionsNameBuilder`.
169+
173170
## Query Keys
174171

175172
Query keys are generated for both queries and infinite queries. If you have access to the result of query or infinite query options function, you can get the query key from the `queryKey` field.
@@ -182,7 +179,7 @@ const { queryKey } = getPetByIdOptions({
182179
});
183180
```
184181

185-
Alternatively, you can access the same query key by calling `QueryKey` or `InfiniteQueryKey` function.
182+
Alternatively, you can access the same query key by calling query key functions. The generated query key functions follow the naming convention of SDK functions and by default append `QueryKey` or `InfiniteQueryKey`, e.g. `getPetByIdQueryKey()` or `getPetByIdInfiniteQueryKey()`.
186183

187184
```ts
188185
const queryKey = getPetByIdQueryKey({
@@ -192,5 +189,7 @@ const queryKey = getPetByIdQueryKey({
192189
});
193190
```
194191

192+
You can customize query key function names using `queryKeyNameBuilder` and `infiniteQueryKeyNameBuilder`.
193+
195194
<!--@include: ../../examples.md-->
196195
<!--@include: ../../sponsors.md-->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
import { type Options, getFoo, fooPost, fooPut, getFooBar, fooBarPost, fooBarPut } from '../sdk.gen';
4+
import { queryOptions, type MutationOptions, type DefaultError } from '@tanstack/angular-query-experimental';
5+
import type { GetFooData, FooPostData, FooPostResponse, FooPutData, FooPutResponse, GetFooBarData, FooBarPostData, FooBarPostResponse, FooBarPutData, FooBarPutResponse } from '../types.gen';
6+
import { client as _heyApiClient } from '../client.gen';
7+
8+
export type QueryKey<TOptions extends Options> = [
9+
Pick<TOptions, 'baseUrl' | 'body' | 'headers' | 'path' | 'query'> & {
10+
_id: string;
11+
_infinite?: boolean;
12+
}
13+
];
14+
15+
const createQueryKey = <TOptions extends Options>(id: string, options?: TOptions, infinite?: boolean): [
16+
QueryKey<TOptions>[0]
17+
] => {
18+
const params: QueryKey<TOptions>[0] = { _id: id, baseUrl: (options?.client ?? _heyApiClient).getConfig().baseUrl } as QueryKey<TOptions>[0];
19+
if (infinite) {
20+
params._infinite = infinite;
21+
}
22+
if (options?.body) {
23+
params.body = options.body;
24+
}
25+
if (options?.headers) {
26+
params.headers = options.headers;
27+
}
28+
if (options?.path) {
29+
params.path = options.path;
30+
}
31+
if (options?.query) {
32+
params.query = options.query;
33+
}
34+
return [
35+
params
36+
];
37+
};
38+
39+
export const getFooD = (options?: Options<GetFooData>) => createQueryKey('getFoo', options);
40+
41+
export const getFooE = (options?: Options<GetFooData>) => {
42+
return queryOptions({
43+
queryFn: async ({ queryKey, signal }) => {
44+
const { data } = await getFoo({
45+
...options,
46+
...queryKey[0],
47+
signal,
48+
throwOnError: true
49+
});
50+
return data;
51+
},
52+
queryKey: getFooD(options)
53+
});
54+
};
55+
56+
export const fooPostD = (options?: Options<FooPostData>) => createQueryKey('fooPost', options);
57+
58+
export const fooPostE = (options?: Options<FooPostData>) => {
59+
return queryOptions({
60+
queryFn: async ({ queryKey, signal }) => {
61+
const { data } = await fooPost({
62+
...options,
63+
...queryKey[0],
64+
signal,
65+
throwOnError: true
66+
});
67+
return data;
68+
},
69+
queryKey: fooPostD(options)
70+
});
71+
};
72+
73+
export const fooPostC = (options?: Partial<Options<FooPostData>>): MutationOptions<FooPostResponse, DefaultError, Options<FooPostData>> => {
74+
const mutationOptions: MutationOptions<FooPostResponse, DefaultError, Options<FooPostData>> = {
75+
mutationFn: async (localOptions) => {
76+
const { data } = await fooPost({
77+
...options,
78+
...localOptions,
79+
throwOnError: true
80+
});
81+
return data;
82+
}
83+
};
84+
return mutationOptions;
85+
};
86+
87+
export const fooPutC = (options?: Partial<Options<FooPutData>>): MutationOptions<FooPutResponse, DefaultError, Options<FooPutData>> => {
88+
const mutationOptions: MutationOptions<FooPutResponse, DefaultError, Options<FooPutData>> = {
89+
mutationFn: async (localOptions) => {
90+
const { data } = await fooPut({
91+
...options,
92+
...localOptions,
93+
throwOnError: true
94+
});
95+
return data;
96+
}
97+
};
98+
return mutationOptions;
99+
};
100+
101+
export const getFooBarD = (options?: Options<GetFooBarData>) => createQueryKey('getFooBar', options);
102+
103+
export const getFooBarE = (options?: Options<GetFooBarData>) => {
104+
return queryOptions({
105+
queryFn: async ({ queryKey, signal }) => {
106+
const { data } = await getFooBar({
107+
...options,
108+
...queryKey[0],
109+
signal,
110+
throwOnError: true
111+
});
112+
return data;
113+
},
114+
queryKey: getFooBarD(options)
115+
});
116+
};
117+
118+
export const fooBarPostD = (options?: Options<FooBarPostData>) => createQueryKey('fooBarPost', options);
119+
120+
export const fooBarPostE = (options?: Options<FooBarPostData>) => {
121+
return queryOptions({
122+
queryFn: async ({ queryKey, signal }) => {
123+
const { data } = await fooBarPost({
124+
...options,
125+
...queryKey[0],
126+
signal,
127+
throwOnError: true
128+
});
129+
return data;
130+
},
131+
queryKey: fooBarPostD(options)
132+
});
133+
};
134+
135+
export const fooBarPostC = (options?: Partial<Options<FooBarPostData>>): MutationOptions<FooBarPostResponse, DefaultError, Options<FooBarPostData>> => {
136+
const mutationOptions: MutationOptions<FooBarPostResponse, DefaultError, Options<FooBarPostData>> = {
137+
mutationFn: async (localOptions) => {
138+
const { data } = await fooBarPost({
139+
...options,
140+
...localOptions,
141+
throwOnError: true
142+
});
143+
return data;
144+
}
145+
};
146+
return mutationOptions;
147+
};
148+
149+
export const fooBarPutC = (options?: Partial<Options<FooBarPutData>>): MutationOptions<FooBarPutResponse, DefaultError, Options<FooBarPutData>> => {
150+
const mutationOptions: MutationOptions<FooBarPutResponse, DefaultError, Options<FooBarPutData>> = {
151+
mutationFn: async (localOptions) => {
152+
const { data } = await fooBarPut({
153+
...options,
154+
...localOptions,
155+
throwOnError: true
156+
});
157+
return data;
158+
}
159+
};
160+
return mutationOptions;
161+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch';
4+
import type { GetFooData, GetFooResponses, FooPostData, FooPostResponses, FooPutData, FooPutResponses, GetFooBarData, GetFooBarResponses, FooBarPostData, FooBarPostResponses, FooBarPutData, FooBarPutResponses } from './types.gen';
5+
import { client as _heyApiClient } from './client.gen';
6+
7+
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<TData, ThrowOnError> & {
8+
/**
9+
* You can provide a client instance returned by `createClient()` instead of
10+
* individual options. This might be also useful if you want to implement a
11+
* custom client.
12+
*/
13+
client?: Client;
14+
/**
15+
* You can pass arbitrary values through the `meta` object. This can be
16+
* used to access values that aren't defined as part of the SDK function.
17+
*/
18+
meta?: Record<string, unknown>;
19+
};
20+
21+
export const getFoo = <ThrowOnError extends boolean = false>(options?: Options<GetFooData, ThrowOnError>) => {
22+
return (options?.client ?? _heyApiClient).get<GetFooResponses, unknown, ThrowOnError>({
23+
url: '/foo',
24+
...options
25+
});
26+
};
27+
28+
export const fooPost = <ThrowOnError extends boolean = false>(options?: Options<FooPostData, ThrowOnError>) => {
29+
return (options?.client ?? _heyApiClient).post<FooPostResponses, unknown, ThrowOnError>({
30+
url: '/foo',
31+
...options
32+
});
33+
};
34+
35+
export const fooPut = <ThrowOnError extends boolean = false>(options?: Options<FooPutData, ThrowOnError>) => {
36+
return (options?.client ?? _heyApiClient).put<FooPutResponses, unknown, ThrowOnError>({
37+
url: '/foo',
38+
...options
39+
});
40+
};
41+
42+
export const getFooBar = <ThrowOnError extends boolean = false>(options?: Options<GetFooBarData, ThrowOnError>) => {
43+
return (options?.client ?? _heyApiClient).get<GetFooBarResponses, unknown, ThrowOnError>({
44+
url: '/foo/bar',
45+
...options
46+
});
47+
};
48+
49+
export const fooBarPost = <ThrowOnError extends boolean = false>(options?: Options<FooBarPostData, ThrowOnError>) => {
50+
return (options?.client ?? _heyApiClient).post<FooBarPostResponses, unknown, ThrowOnError>({
51+
url: '/foo/bar',
52+
...options
53+
});
54+
};
55+
56+
export const fooBarPut = <ThrowOnError extends boolean = false>(options?: Options<FooBarPutData, ThrowOnError>) => {
57+
return (options?.client ?? _heyApiClient).put<FooBarPutResponses, unknown, ThrowOnError>({
58+
url: '/foo/bar',
59+
...options
60+
});
61+
};

0 commit comments

Comments
 (0)