@7nohe/openapi-react-query-codegen 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/dist/common.mjs +2 -0
- package/dist/createExports.mjs +6 -1
- package/dist/createUseQuery.mjs +50 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -160,6 +160,75 @@ function App() {
|
|
|
160
160
|
export default App;
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
+
##### Using Mutation hooks
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
// App.tsx
|
|
167
|
+
import { usePetServiceAddPet } from "../openapi/queries";
|
|
168
|
+
|
|
169
|
+
function App() {
|
|
170
|
+
const { mutate } = usePetServiceAddPet();
|
|
171
|
+
|
|
172
|
+
const handleAddPet = () => {
|
|
173
|
+
mutate({ name: "Fluffy", status: "available" });
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div className="App">
|
|
178
|
+
<h1>Add Pet</h1>
|
|
179
|
+
<button onClick={handleAddPet}>Add Pet</button>
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export default App;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
##### Invalidating queries after mutation
|
|
188
|
+
|
|
189
|
+
Invalidating queries after a mutation is important to ensure the cache is updated with the new data. This is done by calling the `queryClient.invalidateQueries` function with the query key used by the query hook.
|
|
190
|
+
|
|
191
|
+
Learn more about invalidating queries [here](https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation).
|
|
192
|
+
|
|
193
|
+
To ensure the query key is created the same way as the query hook, you can use the query key function exported by the generated query hooks.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
import {
|
|
197
|
+
usePetServiceFindPetsByStatus,
|
|
198
|
+
usePetServiceAddPet,
|
|
199
|
+
UsePetServiceFindPetsByStatusKeyFn,
|
|
200
|
+
} from "../openapi/queries";
|
|
201
|
+
|
|
202
|
+
// App.tsx
|
|
203
|
+
function App() {
|
|
204
|
+
const { data } = usePetServiceFindPetsByStatus({ status: ["available"] });
|
|
205
|
+
const { mutate } = usePetServiceAddPet({
|
|
206
|
+
onSuccess: () => {
|
|
207
|
+
queryClient.invalidateQueries({
|
|
208
|
+
// Call the query key function to get the query key, this is important to ensure the query key is created the same way as the query hook, this insures the cache is invalidated correctly and is typed correctly
|
|
209
|
+
queryKey: [UsePetServiceFindPetsByStatusKeyFn()],
|
|
210
|
+
});
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
return (
|
|
215
|
+
<div className="App">
|
|
216
|
+
<h1>Pet List</h1>
|
|
217
|
+
<ul>{data?.map((pet) => <li key={pet.id}>{pet.name}</li>)}</ul>
|
|
218
|
+
<button
|
|
219
|
+
onClick={() => {
|
|
220
|
+
mutate({ name: "Fluffy", status: "available" });
|
|
221
|
+
}}
|
|
222
|
+
>
|
|
223
|
+
Add Pet
|
|
224
|
+
</button>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export default App;
|
|
230
|
+
```
|
|
231
|
+
|
|
163
232
|
##### Runtime Configuration
|
|
164
233
|
|
|
165
234
|
You can modify the default values used by the generated service calls by modifying the OpenAPI configuration singleton object.
|
package/dist/common.mjs
CHANGED
|
@@ -5,6 +5,8 @@ import { queriesOutputPath, requestsOutputPath } from "./constants.mjs";
|
|
|
5
5
|
export const TData = ts.factory.createIdentifier("TData");
|
|
6
6
|
export const TError = ts.factory.createIdentifier("TError");
|
|
7
7
|
export const TContext = ts.factory.createIdentifier("TContext");
|
|
8
|
+
export const EqualsOrGreaterThanToken = ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken);
|
|
9
|
+
export const QuestionToken = ts.factory.createToken(ts.SyntaxKind.QuestionToken);
|
|
8
10
|
export const queryKeyGenericType = ts.factory.createTypeReferenceNode("TQueryKey");
|
|
9
11
|
export const queryKeyConstraint = ts.factory.createTypeReferenceNode("Array", [
|
|
10
12
|
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),
|
package/dist/createExports.mjs
CHANGED
|
@@ -23,7 +23,12 @@ export const createExports = (service) => {
|
|
|
23
23
|
...allDeleteMutations,
|
|
24
24
|
];
|
|
25
25
|
const commonInQueries = allQueries
|
|
26
|
-
.map(({ apiResponse, returnType, key }) => [
|
|
26
|
+
.map(({ apiResponse, returnType, key, queryKeyFn }) => [
|
|
27
|
+
apiResponse,
|
|
28
|
+
returnType,
|
|
29
|
+
key,
|
|
30
|
+
queryKeyFn,
|
|
31
|
+
])
|
|
27
32
|
.flat();
|
|
28
33
|
const commonInMutations = allMutations
|
|
29
34
|
.map(({ mutationResult }) => [mutationResult])
|
package/dist/createUseQuery.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
-
import { BuildCommonTypeName, capitalizeFirstLetter, extractPropertiesFromObjectParam, getNameFromMethod, getShortType, queryKeyConstraint, queryKeyGenericType, TData, TError, } from "./common.mjs";
|
|
2
|
+
import { BuildCommonTypeName, capitalizeFirstLetter, EqualsOrGreaterThanToken, extractPropertiesFromObjectParam, getNameFromMethod, getShortType, queryKeyConstraint, queryKeyGenericType, QuestionToken, TData, TError, } from "./common.mjs";
|
|
3
3
|
import { addJSDocToNode } from "./util.mjs";
|
|
4
4
|
export const createApiResponseType = ({ className, methodName, }) => {
|
|
5
5
|
/** Awaited<ReturnType<typeof myClass.myMethod>> */
|
|
@@ -14,12 +14,15 @@ export const createApiResponseType = ({ className, methodName, }) => {
|
|
|
14
14
|
const apiResponse = ts.factory.createTypeAliasDeclaration([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(`${capitalizeFirstLetter(className)}${capitalizeFirstLetter(methodName)}DefaultResponse`), undefined, awaitedResponseDataType);
|
|
15
15
|
const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData.text, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(apiResponse.name)));
|
|
16
16
|
return {
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* DefaultResponseDataType
|
|
19
|
+
*
|
|
18
20
|
* export type MyClassMethodDefaultResponse = Awaited<ReturnType<typeof myClass.myMethod>>
|
|
19
21
|
*/
|
|
20
22
|
apiResponse,
|
|
21
23
|
/**
|
|
22
|
-
* will be the name of the type of the response type of the method
|
|
24
|
+
* This will be the name of the type of the response type of the method
|
|
25
|
+
*
|
|
23
26
|
* MyClassMethodDefaultResponse
|
|
24
27
|
*/
|
|
25
28
|
responseDataType,
|
|
@@ -54,6 +57,7 @@ export function getRequestParamFromMethod(method) {
|
|
|
54
57
|
}
|
|
55
58
|
/**
|
|
56
59
|
* Return Type
|
|
60
|
+
*
|
|
57
61
|
* export const classNameMethodNameQueryResult<TData = MyClassMethodDefaultResponse, TError = unknown> = UseQueryResult<TData, TError>;
|
|
58
62
|
*/
|
|
59
63
|
export function createReturnTypeExport({ className, methodName, defaultApiResponse, }) {
|
|
@@ -109,23 +113,21 @@ export function createQueryHook({ queryString, suffix, responseDataType, request
|
|
|
109
113
|
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral("queryFn")),
|
|
110
114
|
]),
|
|
111
115
|
])),
|
|
112
|
-
], undefined,
|
|
116
|
+
], undefined, EqualsOrGreaterThanToken, ts.factory.createCallExpression(ts.factory.createIdentifier(queryString), [
|
|
113
117
|
ts.factory.createTypeReferenceNode(TData),
|
|
114
118
|
ts.factory.createTypeReferenceNode(TError),
|
|
115
119
|
], [
|
|
116
120
|
ts.factory.createObjectLiteralExpression([
|
|
117
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
ts.factory.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
], false)),
|
|
128
|
-
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, [], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length
|
|
121
|
+
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryKey"), ts.factory.createCallExpression(BuildCommonTypeName(getQueryKeyFnName(queryKey)), undefined, method.getParameters().length
|
|
122
|
+
? [
|
|
123
|
+
ts.factory.createObjectLiteralExpression(method
|
|
124
|
+
.getParameters()
|
|
125
|
+
.map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
|
|
126
|
+
.flat()),
|
|
127
|
+
ts.factory.createIdentifier("queryKey"),
|
|
128
|
+
]
|
|
129
|
+
: [])),
|
|
130
|
+
ts.factory.createPropertyAssignment(ts.factory.createIdentifier("queryFn"), ts.factory.createArrowFunction(undefined, undefined, [], undefined, EqualsOrGreaterThanToken, ts.factory.createAsExpression(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(className), ts.factory.createIdentifier(methodName)), undefined, method.getParameters().length
|
|
129
131
|
? [
|
|
130
132
|
ts.factory.createObjectLiteralExpression(method
|
|
131
133
|
.getParameters()
|
|
@@ -176,11 +178,43 @@ export const createUseQuery = ({ className, method, jsDoc, }) => {
|
|
|
176
178
|
methodName,
|
|
177
179
|
queryKey,
|
|
178
180
|
});
|
|
181
|
+
const queryKeyFn = createQueryKeyFnExport(queryKey, method);
|
|
179
182
|
return {
|
|
180
183
|
apiResponse: defaultApiResponse,
|
|
181
184
|
returnType: returnTypeExport,
|
|
182
185
|
key: queryKeyExport,
|
|
183
186
|
queryHook: hookWithJsDoc,
|
|
184
187
|
suspenseQueryHook: suspenseHookWithJsDoc,
|
|
188
|
+
queryKeyFn,
|
|
185
189
|
};
|
|
186
190
|
};
|
|
191
|
+
function getQueryKeyFnName(queryKey) {
|
|
192
|
+
return `${capitalizeFirstLetter(queryKey)}Fn`;
|
|
193
|
+
}
|
|
194
|
+
function createQueryKeyFnExport(queryKey, method) {
|
|
195
|
+
const params = getRequestParamFromMethod(method);
|
|
196
|
+
// override key is used to allow the user to override the the queryKey values
|
|
197
|
+
const overrideKey = ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("queryKey"), QuestionToken, ts.factory.createTypeReferenceNode("Array<unknown>", []));
|
|
198
|
+
return ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
|
|
199
|
+
ts.factory.createVariableDeclaration(ts.factory.createIdentifier(getQueryKeyFnName(queryKey)), undefined, undefined, ts.factory.createArrowFunction(undefined, undefined, params ? [params, overrideKey] : [], undefined, EqualsOrGreaterThanToken, queryKeyFn(queryKey, method))),
|
|
200
|
+
], ts.NodeFlags.Const));
|
|
201
|
+
}
|
|
202
|
+
function queryKeyFn(queryKey, method) {
|
|
203
|
+
const params = getRequestParamFromMethod(method);
|
|
204
|
+
if (!params) {
|
|
205
|
+
return ts.factory.createArrayLiteralExpression([
|
|
206
|
+
ts.factory.createIdentifier(queryKey),
|
|
207
|
+
]);
|
|
208
|
+
}
|
|
209
|
+
return ts.factory.createArrayLiteralExpression([
|
|
210
|
+
ts.factory.createIdentifier(queryKey),
|
|
211
|
+
ts.factory.createSpreadElement(ts.factory.createParenthesizedExpression(ts.factory.createBinaryExpression(ts.factory.createIdentifier("queryKey"), ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken), method.getParameters().length
|
|
212
|
+
? ts.factory.createArrayLiteralExpression([
|
|
213
|
+
ts.factory.createObjectLiteralExpression(method
|
|
214
|
+
.getParameters()
|
|
215
|
+
.map((param) => extractPropertiesFromObjectParam(param).map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name))))
|
|
216
|
+
.flat()),
|
|
217
|
+
])
|
|
218
|
+
: ts.factory.createArrayLiteralExpression([])))),
|
|
219
|
+
], false);
|
|
220
|
+
}
|