Skip to content

Commit 2b2e2b7

Browse files
committedMay 23, 2023
feat(query): add useMutation options
1 parent 5c1670c commit 2b2e2b7

File tree

5 files changed

+124
-88
lines changed

5 files changed

+124
-88
lines changed
 

‎packages/core/src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ export type OverrideOutputContentType = {
289289

290290
export type NormalizedQueryOptions = {
291291
useQuery?: boolean;
292+
useMutation?: boolean;
292293
useInfinite?: boolean;
293294
useInfiniteQueryParam?: string;
294295
options?: any;
@@ -300,6 +301,7 @@ export type NormalizedQueryOptions = {
300301

301302
export type QueryOptions = {
302303
useQuery?: boolean;
304+
useMutation?: boolean;
303305
useInfinite?: boolean;
304306
useInfiniteQueryParam?: string;
305307
options?: any;

‎packages/orval/src/utils/options.ts

+4
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ export const normalizeOptions = async (
180180
},
181181
query: {
182182
useQuery: true,
183+
useMutation: true,
183184
signal: true,
184185
...normalizeQueryOptions(outputOptions.override?.query, workspace),
185186
},
@@ -361,6 +362,9 @@ const normalizeQueryOptions = (
361362
...(!isUndefined(queryOptions.useQuery)
362363
? { useQuery: queryOptions.useQuery }
363364
: {}),
365+
...(!isUndefined(queryOptions.useMutation)
366+
? { useMutation: queryOptions.useMutation }
367+
: {}),
364368
...(!isUndefined(queryOptions.useInfinite)
365369
? { useInfinite: queryOptions.useInfinite }
366370
: {}),

‎packages/query/src/index.ts

+99-87
Original file line numberDiff line numberDiff line change
@@ -931,11 +931,16 @@ const generateQueryHook = async (
931931

932932
const doc = jsDoc({ summary, deprecated });
933933

934-
if (
935-
verb === Verbs.GET ||
934+
let implementation = '';
935+
let mutators = undefined;
936+
937+
const isQuery =
938+
(Verbs.GET === verb &&
939+
(override.query.useQuery || override.query.useInfinite)) ||
936940
operationQueryOptions?.useInfinite ||
937-
operationQueryOptions?.useQuery
938-
) {
941+
operationQueryOptions?.useQuery;
942+
943+
if (isQuery) {
939944
const queryKeyMutator = query.queryKey
940945
? await generateMutator({
941946
output,
@@ -1009,7 +1014,7 @@ const generateQueryHook = async (
10091014
queryParams ? ', ...(params ? [params]: [])' : ''
10101015
}${body.implementation ? `, ${body.implementation}` : ''}] as const;`;
10111016

1012-
const implementation = `${!queryKeyMutator ? queryKeyFn : ''}
1017+
implementation += `${!queryKeyMutator ? queryKeyFn : ''}
10131018
10141019
10151020
${queries.reduce(
@@ -1040,82 +1045,84 @@ const generateQueryHook = async (
10401045
)}
10411046
`;
10421047

1043-
return {
1044-
implementation,
1045-
mutators:
1046-
queryOptionsMutator || queryKeyMutator
1047-
? [
1048-
...(queryOptionsMutator ? [queryOptionsMutator] : []),
1049-
...(queryKeyMutator ? [queryKeyMutator] : []),
1050-
]
1051-
: undefined,
1052-
};
1048+
mutators =
1049+
queryOptionsMutator || queryKeyMutator
1050+
? [
1051+
...(queryOptionsMutator ? [queryOptionsMutator] : []),
1052+
...(queryKeyMutator ? [queryKeyMutator] : []),
1053+
]
1054+
: undefined;
10531055
}
10541056

1055-
const mutationOptionsMutator = query.mutationOptions
1056-
? await generateMutator({
1057-
output,
1058-
mutator: query.mutationOptions,
1059-
name: `${operationName}MutationOptions`,
1060-
workspace: context.workspace,
1061-
tsconfig: context.tsconfig,
1062-
})
1063-
: undefined;
1064-
1065-
const definitions = props
1066-
.map(({ definition, type }) =>
1067-
type === GetterPropType.BODY
1068-
? mutator?.bodyTypeName
1069-
? `data: ${mutator.bodyTypeName}<${body.definition}>`
1070-
: `data: ${body.definition}`
1071-
: definition,
1072-
)
1073-
.join(';');
1074-
1075-
const properties = props
1076-
.map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name))
1077-
.join(',');
1057+
const isMutation =
1058+
(verb !== Verbs.GET && override.query.useMutation) ||
1059+
operationQueryOptions?.useMutation;
10781060

1079-
let errorType = `AxiosError<${response.definition.errors || 'unknown'}>`;
1061+
if (isMutation) {
1062+
const mutationOptionsMutator = query.mutationOptions
1063+
? await generateMutator({
1064+
output,
1065+
mutator: query.mutationOptions,
1066+
name: `${operationName}MutationOptions`,
1067+
workspace: context.workspace,
1068+
tsconfig: context.tsconfig,
1069+
})
1070+
: undefined;
10801071

1081-
if (mutator) {
1082-
errorType = mutator.hasErrorType
1083-
? `${mutator.default ? pascal(operationName) : ''}ErrorType<${
1084-
response.definition.errors || 'unknown'
1085-
}>`
1086-
: response.definition.errors || 'unknown';
1087-
}
1072+
const definitions = props
1073+
.map(({ definition, type }) =>
1074+
type === GetterPropType.BODY
1075+
? mutator?.bodyTypeName
1076+
? `data: ${mutator.bodyTypeName}<${body.definition}>`
1077+
: `data: ${body.definition}`
1078+
: definition,
1079+
)
1080+
.join(';');
10881081

1089-
const dataType = mutator?.isHook
1090-
? `ReturnType<typeof use${pascal(operationName)}Hook>`
1091-
: `typeof ${operationName}`;
1082+
const properties = props
1083+
.map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name))
1084+
.join(',');
10921085

1093-
const mutationOptionFnReturnType = getQueryOptionsDefinition({
1094-
operationName,
1095-
definitions,
1096-
mutator,
1097-
hasSvelteQueryV4,
1098-
});
1086+
let errorType = `AxiosError<${response.definition.errors || 'unknown'}>`;
10991087

1100-
const mutationArguments = generateQueryArguments({
1101-
operationName,
1102-
definitions,
1103-
mutator,
1104-
isRequestOptions,
1105-
hasSvelteQueryV4,
1106-
});
1088+
if (mutator) {
1089+
errorType = mutator.hasErrorType
1090+
? `${mutator.default ? pascal(operationName) : ''}ErrorType<${
1091+
response.definition.errors || 'unknown'
1092+
}>`
1093+
: response.definition.errors || 'unknown';
1094+
}
11071095

1108-
const mutationOptionsFnName = camel(
1109-
mutationOptionsMutator || mutator?.isHook
1110-
? `use-${operationName}-mutationOptions`
1111-
: `get-${operationName}-mutationOptions`,
1112-
);
1096+
const dataType = mutator?.isHook
1097+
? `ReturnType<typeof use${pascal(operationName)}Hook>`
1098+
: `typeof ${operationName}`;
11131099

1114-
const mutationOptionsVarName = isRequestOptions
1115-
? 'mutationOptions'
1116-
: 'options';
1100+
const mutationOptionFnReturnType = getQueryOptionsDefinition({
1101+
operationName,
1102+
definitions,
1103+
mutator,
1104+
hasSvelteQueryV4,
1105+
});
11171106

1118-
const mutationOptionsFn = `export const ${mutationOptionsFnName} = <TError = ${errorType},
1107+
const mutationArguments = generateQueryArguments({
1108+
operationName,
1109+
definitions,
1110+
mutator,
1111+
isRequestOptions,
1112+
hasSvelteQueryV4,
1113+
});
1114+
1115+
const mutationOptionsFnName = camel(
1116+
mutationOptionsMutator || mutator?.isHook
1117+
? `use-${operationName}-mutationOptions`
1118+
: `get-${operationName}-mutationOptions`,
1119+
);
1120+
1121+
const mutationOptionsVarName = isRequestOptions
1122+
? 'mutationOptions'
1123+
: 'options';
1124+
1125+
const mutationOptionsFn = `export const ${mutationOptionsFnName} = <TError = ${errorType},
11191126
${!definitions ? `TVariables = void,` : ''}
11201127
TContext = unknown>(${mutationArguments}): ${mutationOptionFnReturnType} => {
11211128
${
@@ -1138,19 +1145,19 @@ const generateQueryHook = async (
11381145
11391146
11401147
const mutationFn: MutationFunction<Awaited<ReturnType<${dataType}>>, ${
1141-
definitions ? `{${definitions}}` : 'TVariables'
1142-
}> = (${properties ? 'props' : ''}) => {
1148+
definitions ? `{${definitions}}` : 'TVariables'
1149+
}> = (${properties ? 'props' : ''}) => {
11431150
${properties ? `const {${properties}} = props ?? {};` : ''}
11441151
11451152
return ${operationName}(${properties}${properties ? ',' : ''}${
1146-
isRequestOptions
1147-
? !mutator
1148-
? `axiosOptions`
1149-
: mutator?.hasSecondArg
1150-
? 'requestOptions'
1153+
isRequestOptions
1154+
? !mutator
1155+
? `axiosOptions`
1156+
: mutator?.hasSecondArg
1157+
? 'requestOptions'
1158+
: ''
11511159
: ''
1152-
: ''
1153-
})
1160+
})
11541161
}
11551162
11561163
${
@@ -1172,9 +1179,9 @@ const generateQueryHook = async (
11721179
: 'customOptions'
11731180
}}`;
11741181

1175-
const operationPrefix = hasSvelteQueryV4 ? 'create' : 'use';
1182+
const operationPrefix = hasSvelteQueryV4 ? 'create' : 'use';
11761183

1177-
const implementation = `
1184+
implementation += `
11781185
${mutationOptionsFn}
11791186
11801187
export type ${pascal(
@@ -1192,22 +1199,27 @@ ${mutationOptionsFn}
11921199
export type ${pascal(operationName)}MutationError = ${errorType}
11931200
11941201
${doc}export const ${camel(
1195-
`${operationPrefix}-${operationName}`,
1196-
)} = <TError = ${errorType},
1202+
`${operationPrefix}-${operationName}`,
1203+
)} = <TError = ${errorType},
11971204
${!definitions ? `TVariables = void,` : ''}
11981205
TContext = unknown>(${mutationArguments}) => {
11991206
12001207
const ${mutationOptionsVarName} = ${mutationOptionsFnName}(${
1201-
isRequestOptions ? 'options' : 'mutationOptions'
1202-
});
1208+
isRequestOptions ? 'options' : 'mutationOptions'
1209+
});
12031210
12041211
return ${operationPrefix}Mutation(${mutationOptionsVarName});
12051212
}
12061213
`;
12071214

1215+
mutators = mutationOptionsMutator
1216+
? [...(mutators ?? []), mutationOptionsMutator]
1217+
: mutators;
1218+
}
1219+
12081220
return {
12091221
implementation,
1210-
mutators: mutationOptionsMutator ? [mutationOptionsMutator] : undefined,
1222+
mutators,
12111223
};
12121224
};
12131225

‎samples/react-query/basic/src/api/endpoints/petstoreFromFileSpecWithTransformer.ts

+18
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ export type ListPetsInfiniteQueryResult = NonNullable<
115115
>;
116116
export type ListPetsInfiniteQueryError = ErrorType<Error>;
117117

118+
/**
119+
* @summary List all pets
120+
*/
118121
export const useListPetsInfinite = <
119122
TData = Awaited<ReturnType<typeof listPets>>,
120123
TError = ErrorType<Error>,
@@ -178,6 +181,9 @@ export type ListPetsQueryResult = NonNullable<
178181
>;
179182
export type ListPetsQueryError = ErrorType<Error>;
180183

184+
/**
185+
* @summary List all pets
186+
*/
181187
export const useListPets = <
182188
TData = Awaited<ReturnType<typeof listPets>>,
183189
TError = ErrorType<Error>,
@@ -251,6 +257,9 @@ export type CreatePetsMutationResult = NonNullable<
251257
export type CreatePetsMutationBody = CreatePetsBody;
252258
export type CreatePetsMutationError = ErrorType<Error>;
253259

260+
/**
261+
* @summary Create a pet
262+
*/
254263
export const useCreatePets = <
255264
TError = ErrorType<Error>,
256265
TContext = unknown,
@@ -315,6 +324,9 @@ export type UpdatePetsMutationResult = NonNullable<
315324
export type UpdatePetsMutationBody = NonReadonly<Pet>;
316325
export type UpdatePetsMutationError = ErrorType<Error>;
317326

327+
/**
328+
* @summary Update a pet
329+
*/
318330
export const useUpdatePets = <
319331
TError = ErrorType<Error>,
320332
TContext = unknown,
@@ -384,6 +396,9 @@ export type ShowPetByIdInfiniteQueryResult = NonNullable<
384396
>;
385397
export type ShowPetByIdInfiniteQueryError = ErrorType<Error>;
386398

399+
/**
400+
* @summary Info for a specific pet
401+
*/
387402
export const useShowPetByIdInfinite = <
388403
TData = Awaited<ReturnType<typeof showPetById>>,
389404
TError = ErrorType<Error>,
@@ -447,6 +462,9 @@ export type ShowPetByIdQueryResult = NonNullable<
447462
>;
448463
export type ShowPetByIdQueryError = ErrorType<Error>;
449464

465+
/**
466+
* @summary Info for a specific pet
467+
*/
450468
export const useShowPetById = <
451469
TData = Awaited<ReturnType<typeof showPetById>>,
452470
TError = ErrorType<Error>,

‎samples/react-query/basic/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"target": "es5",
3+
"target": "es6",
44
"lib": ["dom", "dom.iterable", "esnext"],
55
"allowJs": true,
66
"skipLibCheck": true,

1 commit comments

Comments
 (1)

vercel[bot] commented on May 23, 2023

@vercel[bot]
Please sign in to comment.