@orval/query 8.18.0 → 8.19.0

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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { GetterPropType, OutputClient, OutputHttpClient, Verbs, camel, compareVersions, generateFormDataAndUrlEncodedFunction, generateMutator, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, getAngularFilteredParamsCallExpression, getAngularFilteredParamsHelperBody, getFullRoute, getRouteAsArray, getSuccessResponseType, isObject, isString, isSyntheticDefaultImportsAllow, jsDoc, kebab, logWarning, makeRouteSafe, mergeDeep, pascal, stringify, toObjectString } from "@orval/core";
1
+ import { GetterPropType, OutputClient, OutputHttpClient, Verbs, camel, compareVersions, generateFormDataAndUrlEncodedFunction, generateMutator, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, getAngularFilteredParamsCallExpression, getAngularFilteredParamsHelperBody, getFullRoute, getRouteAsArray, getSuccessResponseType, isObject, isOperationInTagBucket, isString, isSyntheticDefaultImportsAllow, jsDoc, logWarning, makeRouteSafe, mergeDeep, pascal, stringify, toObjectString } from "@orval/core";
2
2
  import { generateFetchHeader, generateRequestFunction } from "@orval/fetch";
3
3
  import nodePath from "node:path";
4
4
  import { styleText } from "node:util";
@@ -159,7 +159,6 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
159
159
  hasSignal,
160
160
  hasSignalParam,
161
161
  isExactOptionalPropertyTypes,
162
- isVue: false,
163
162
  isAngular: context.output.httpClient === OutputHttpClient.ANGULAR
164
163
  });
165
164
  const requestOptions = isRequestOptions ? generateMutatorRequestOptions(override.requestOptions, mutator.hasSecondArg) : "";
@@ -228,11 +227,11 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
228
227
  }
229
228
  `;
230
229
  };
231
- const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer }, { route: _route, context }, isVue) => {
232
- let props = _props;
230
+ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer }, { route: _route, context }, adapter) => {
231
+ const props = adapter.transformProps(_props);
233
232
  let route = _route;
234
- if (isVue) props = vueWrapTypeWithMaybeRef(_props);
235
233
  if (context.output.urlEncodeParameters) route = makeRouteSafe(route);
234
+ const unrefStatements = adapter.getRequestUnrefStatements(props);
236
235
  const isRequestOptions = override.requestOptions !== false;
237
236
  const isFormData = !override.formData.disabled;
238
237
  const isFormUrlEncoded = override.formUrlEncoded !== false;
@@ -258,46 +257,34 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
258
257
  isFormUrlEncoded,
259
258
  hasSignal,
260
259
  hasSignalParam,
261
- isExactOptionalPropertyTypes,
262
- isVue
260
+ isExactOptionalPropertyTypes
263
261
  });
264
262
  const bodyDefinition = body.definition.replace("[]", String.raw`\[\]`);
265
263
  const propsImplementation = mutator.bodyTypeName && body.definition ? toObjectString(props, "implementation").replace(new RegExp(String.raw`(\w*):\s?${bodyDefinition}`), `$1: ${mutator.bodyTypeName}<${body.definition}>`) : toObjectString(props, "implementation");
266
264
  const requestOptions = isRequestOptions ? generateMutatorRequestOptions(override.requestOptions, mutator.hasSecondArg) : "";
267
265
  if (mutator.isHook) {
268
- const ret = `${override.query.shouldExportMutatorHooks ? "export " : ""}const use${pascal(operationName)}Hook = () => {
269
- const ${operationName} = ${mutator.name}<${response.definition.success || "unknown"}>();
270
-
271
- return useCallback((\n ${propsImplementation}\n ${isRequestOptions && mutator.hasSecondArg ? `options${context.output.optionsParamRequired ? "" : "?"}: SecondParameter<ReturnType<typeof ${mutator.name}>>,` : ""}${getSignalDefinition({
266
+ const callback = `(\n ${propsImplementation}\n ${isRequestOptions && mutator.hasSecondArg ? `options${context.output.optionsParamRequired ? "" : "?"}: SecondParameter<ReturnType<typeof ${mutator.name}>>,` : ""}${getSignalDefinition({
272
267
  hasSignal,
273
268
  hasSignalParam
274
- })}) => {${bodyForm}
269
+ })}) => {
270
+ ${unrefStatements}
271
+ ${bodyForm}
275
272
  return ${operationName}(
276
273
  ${mutatorConfig},
277
274
  ${requestOptions});
278
- }, [${operationName}])
279
- }
280
- `;
281
- const vueRet = `${override.query.shouldExportMutatorHooks ? "export " : ""}const use${pascal(operationName)}Hook = () => {
275
+ }`;
276
+ return `${override.query.shouldExportMutatorHooks ? "export " : ""}const use${pascal(operationName)}Hook = () => {
282
277
  const ${operationName} = ${mutator.name}<${response.definition.success || "unknown"}>();
283
278
 
284
- return (\n ${propsImplementation}\n ${isRequestOptions && mutator.hasSecondArg ? `options${context.output.optionsParamRequired ? "" : "?"}: SecondParameter<ReturnType<typeof ${mutator.name}>>,` : ""}${getSignalDefinition({
285
- hasSignal,
286
- hasSignalParam
287
- })}) => {${bodyForm}
288
- return ${operationName}(
289
- ${mutatorConfig},
290
- ${requestOptions});
291
- }
279
+ return ${adapter.wrapHookMutatorCallback(callback, operationName)}
292
280
  }
293
281
  `;
294
- return isVue ? vueRet : ret;
295
282
  }
296
283
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (\n ${propsImplementation}\n ${isRequestOptions && mutator.hasSecondArg ? `options${context.output.optionsParamRequired ? "" : "?"}: SecondParameter<typeof ${mutator.name}>,` : ""}${getSignalDefinition({
297
284
  hasSignal,
298
285
  hasSignalParam
299
286
  })}) => {
300
- ${isVue ? vueUnRefParams(props) : ""}
287
+ ${unrefStatements}
301
288
  ${bodyForm}
302
289
  return ${mutator.name}<${response.definition.success || "unknown"}>(
303
290
  ${mutatorConfig},
@@ -320,8 +307,7 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
320
307
  paramsSerializerOptions: override.paramsSerializerOptions,
321
308
  isExactOptionalPropertyTypes,
322
309
  hasSignal,
323
- hasSignalParam,
324
- isVue
310
+ hasSignalParam
325
311
  });
326
312
  const optionsArgs = generateRequestOptionsArguments({
327
313
  isRequestOptions,
@@ -330,7 +316,7 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
330
316
  });
331
317
  const queryProps = toObjectString(props, "implementation");
332
318
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (\n ${queryProps} ${optionsArgs} ): Promise<AxiosResponse<${response.definition.success || "unknown"}>> => {
333
- ${isVue ? vueUnRefParams(props) : ""}
319
+ ${unrefStatements}
334
320
  ${bodyForm}
335
321
  return axios${isSyntheticDefaultImportsAllowed ? "" : ".default"}.${verb}(${options});
336
322
  }
@@ -420,7 +406,7 @@ const getMutationRequestArgs = (isRequestOptions, httpClient, mutator, useRuntim
420
406
  };
421
407
  const getQueryHeader = (params) => {
422
408
  if (params.output.httpClient === OutputHttpClient.FETCH) return generateFetchHeader(params);
423
- if (params.output.httpClient === OutputHttpClient.ANGULAR) return (params.tag ? Object.values(params.verbOptions).filter((verbOption) => kebab(verbOption.tags[0] ?? "default") === params.tag) : Object.values(params.verbOptions)).some((v) => v.queryParams) ? getAngularFilteredParamsHelperBody() : "";
409
+ if (params.output.httpClient === OutputHttpClient.ANGULAR) return Object.values(params.verbOptions).filter((verbOption) => isOperationInTagBucket(verbOption, params.tag)).some((v) => v.queryParams) ? getAngularFilteredParamsHelperBody() : "";
424
410
  return "";
425
411
  };
426
412
  //#endregion
@@ -1140,9 +1126,6 @@ const createReactAdapter = ({ hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5
1140
1126
  },
1141
1127
  generateMutationHookBody({ operationPrefix, mutationImplementation, hasInvalidation, optionalQueryClientArgument }) {
1142
1128
  return ` ${hasInvalidation ? `const backupQueryClient = useQueryClient();\n ` : ""}return ${operationPrefix}Mutation(${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""});`;
1143
- },
1144
- generateRequestFunction(verbOptions, options) {
1145
- return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1146
1129
  }
1147
1130
  });
1148
1131
  //#endregion
@@ -1210,9 +1193,6 @@ const createSolidAdapter = ({ hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5
1210
1193
  },
1211
1194
  getOptionalQueryClientArgument() {
1212
1195
  return ", queryClient?: () => QueryClient";
1213
- },
1214
- generateRequestFunction(verbOptions, options) {
1215
- return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1216
1196
  }
1217
1197
  });
1218
1198
  //#endregion
@@ -1309,9 +1289,6 @@ const createSvelteAdapter = ({ hasSvelteQueryV4, hasSvelteQueryV6, hasQueryV5, h
1309
1289
  getQueryType(type) {
1310
1290
  if (hasSvelteQueryV4) return getQueryTypeForFramework(type);
1311
1291
  return type;
1312
- },
1313
- generateRequestFunction(verbOptions, options) {
1314
- return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1315
1292
  }
1316
1293
  };
1317
1294
  };
@@ -1365,9 +1342,15 @@ const createVueAdapter = ({ hasVueQueryV4, hasQueryV5, hasQueryV5WithDataTagErro
1365
1342
  shouldAnnotateQueryKey() {
1366
1343
  return false;
1367
1344
  },
1368
- getUnrefStatements(props) {
1345
+ getRequestUnrefStatements(props) {
1346
+ return vueUnRefParams(props);
1347
+ },
1348
+ getQueryOptionsUnrefStatements(props) {
1369
1349
  return vueUnRefParams(props.filter((prop) => prop.type === GetterPropType.NAMED_PATH_PARAMS));
1370
1350
  },
1351
+ wrapHookMutatorCallback(callback) {
1352
+ return callback;
1353
+ },
1371
1354
  generateEnabledOption(params, options) {
1372
1355
  if (params.length === 0) return "";
1373
1356
  if (!isObject(options) || !Object.hasOwn(options, "enabled")) return `enabled: computed(() => ${params.map(({ name }) => `unref(${name}) !== null && unref(${name}) !== undefined`).join(" && ")}),`;
@@ -1410,9 +1393,6 @@ const createVueAdapter = ({ hasVueQueryV4, hasQueryV5, hasQueryV5WithDataTagErro
1410
1393
  generateMutationHookBody({ operationPrefix, mutationImplementation, hasInvalidation, optionalQueryClientArgument }) {
1411
1394
  return ` ${hasInvalidation ? `const backupQueryClient = useQueryClient();\n ` : ""}return ${operationPrefix}Mutation(${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""});`;
1412
1395
  },
1413
- generateRequestFunction(verbOptions, options) {
1414
- return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, true) : generateRequestFunction(verbOptions, options);
1415
- },
1416
1396
  getQueryPropertyForProp(prop, body) {
1417
1397
  return prop.type === GetterPropType.BODY ? body.implementation : prop.name;
1418
1398
  }
@@ -1420,100 +1400,108 @@ const createVueAdapter = ({ hasVueQueryV4, hasQueryV5, hasQueryV5WithDataTagErro
1420
1400
  //#endregion
1421
1401
  //#region src/frameworks/index.ts
1422
1402
  /** Fill in defaults for fields that most adapters leave empty or share a common implementation. */
1423
- const withDefaults = (adapter) => ({
1424
- isAngularHttp: false,
1425
- getHttpFirstParam: () => "",
1426
- getMutationHttpPrefix: () => "",
1427
- getUnrefStatements: () => "",
1428
- getQueryInvocationSuffix: () => "",
1429
- transformProps: (props) => props,
1430
- getHttpFunctionQueryProps: (qp) => qp,
1431
- getQueryType: (type) => type,
1432
- shouldDestructureNamedPathParams: () => true,
1433
- shouldAnnotateQueryKey: () => true,
1434
- shouldGenerateOverrideTypes: () => false,
1435
- shouldCastQueryResult: () => true,
1436
- shouldCastQueryOptions: () => true,
1437
- getQueryKeyPrefix: () => "queryOptions?.queryKey ?? ",
1438
- getQueryOptionsDefinitionPrefix: () => "Use",
1439
- getHookPropsDefinitions: (props) => toObjectString(props, "implementation"),
1440
- getQueryKeyRouteString(route, shouldSplitQueryKey) {
1441
- if (shouldSplitQueryKey) return getRouteAsArray(route);
1442
- return `\`${route}\``;
1443
- },
1444
- generateEnabledOption(params, options) {
1445
- if (params.length === 0) return "";
1446
- if (!isObject(options) || !Object.hasOwn(options, "enabled")) return `enabled: ${params.map(({ name }) => `${name} !== null && ${name} !== undefined`).join(" && ")},`;
1447
- return "";
1448
- },
1449
- getQueryPropertyForProp(prop, body) {
1450
- if (prop.type === GetterPropType.NAMED_PATH_PARAMS) return prop.destructured;
1451
- return prop.type === GetterPropType.BODY ? body.implementation : prop.name;
1452
- },
1453
- getInfiniteQueryHttpProps(props, queryParam) {
1454
- return props.map((param) => {
1455
- if (param.type === GetterPropType.NAMED_PATH_PARAMS) return param.destructured;
1456
- return param.name === "params" ? `{...params, '${queryParam}': pageParam ?? params?.['${queryParam}']}` : param.name;
1457
- }).join(",");
1458
- },
1459
- generateQueryInit({ queryOptionsFnName, queryProperties, isRequestOptions }) {
1460
- return `const ${isRequestOptions ? "queryOptions" : "options"} = ${queryOptionsFnName}(${queryProperties}${queryProperties ? "," : ""}${isRequestOptions ? "options" : "queryOptions"})`;
1461
- },
1462
- generateQueryInvocationArgs({ queryOptionsVarName, optionalQueryClientArgument }) {
1463
- return `${queryOptionsVarName}${optionalQueryClientArgument ? ", queryClient" : ""}`;
1464
- },
1465
- getOptionalQueryClientArgument() {
1466
- return adapter.hasQueryV5 ? ", queryClient?: QueryClient" : "";
1467
- },
1468
- generateQueryArguments({ operationName, definitions, mutator, isRequestOptions, type, queryParams, queryParam, initialData, httpClient, hasInvalidation, useRuntimeFetcher }) {
1469
- const definition = getQueryOptionsDefinition({
1470
- operationName,
1471
- mutator,
1472
- definitions,
1473
- type,
1474
- prefix: adapter.getQueryOptionsDefinitionPrefix?.() ?? "Use",
1475
- hasQueryV5: adapter.hasQueryV5,
1476
- hasQueryV5WithInfiniteQueryOptionsError: adapter.hasQueryV5WithInfiniteQueryOptionsError,
1477
- queryParams,
1478
- queryParam,
1479
- isReturnType: false,
1480
- initialData,
1481
- adapter
1482
- });
1483
- if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
1484
- const requestType = getQueryArgumentsRequestType(httpClient, mutator, useRuntimeFetcher);
1485
- const isQueryRequired = initialData === "defined";
1486
- const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1487
- return `options${isQueryRequired ? "" : "?"}: ${optionsType}\n`;
1488
- },
1489
- generateMutationOnSuccess({ operationName, definitions, isRequestOptions, generateInvalidateCall, uniqueInvalidates }) {
1490
- const invalidateCalls = uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n");
1491
- if (adapter.hasQueryV5WithMutationContextOnSuccess) {
1492
- if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1403
+ const withDefaults = (adapter) => {
1404
+ const composed = {
1405
+ isAngularHttp: false,
1406
+ getHttpFirstParam: () => "",
1407
+ getMutationHttpPrefix: () => "",
1408
+ getRequestUnrefStatements: () => "",
1409
+ getQueryOptionsUnrefStatements: () => "",
1410
+ wrapHookMutatorCallback: (callback, operationName) => `useCallback(${callback}, [${operationName}])`,
1411
+ getQueryInvocationSuffix: () => "",
1412
+ transformProps: (props) => props,
1413
+ getHttpFunctionQueryProps: (qp) => qp,
1414
+ getQueryType: (type) => type,
1415
+ shouldDestructureNamedPathParams: () => true,
1416
+ shouldAnnotateQueryKey: () => true,
1417
+ shouldGenerateOverrideTypes: () => false,
1418
+ shouldCastQueryResult: () => true,
1419
+ shouldCastQueryOptions: () => true,
1420
+ getQueryKeyPrefix: () => "queryOptions?.queryKey ?? ",
1421
+ getQueryOptionsDefinitionPrefix: () => "Use",
1422
+ getHookPropsDefinitions: (props) => toObjectString(props, "implementation"),
1423
+ getQueryKeyRouteString(route, shouldSplitQueryKey) {
1424
+ if (shouldSplitQueryKey) return getRouteAsArray(route);
1425
+ return `\`${route}\``;
1426
+ },
1427
+ generateEnabledOption(params, options) {
1428
+ if (params.length === 0) return "";
1429
+ if (!isObject(options) || !Object.hasOwn(options, "enabled")) return `enabled: ${params.map(({ name }) => `${name} !== null && ${name} !== undefined`).join(" && ")},`;
1430
+ return "";
1431
+ },
1432
+ getQueryPropertyForProp(prop, body) {
1433
+ if (prop.type === GetterPropType.NAMED_PATH_PARAMS) return prop.destructured;
1434
+ return prop.type === GetterPropType.BODY ? body.implementation : prop.name;
1435
+ },
1436
+ generateRequestFunction(verbOptions, options) {
1437
+ return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, composed) : generateRequestFunction(verbOptions, options);
1438
+ },
1439
+ getInfiniteQueryHttpProps(props, queryParam) {
1440
+ return props.map((param) => {
1441
+ if (param.type === GetterPropType.NAMED_PATH_PARAMS) return param.destructured;
1442
+ return param.name === "params" ? `{...params, '${queryParam}': pageParam ?? params?.['${queryParam}']}` : param.name;
1443
+ }).join(",");
1444
+ },
1445
+ generateQueryInit({ queryOptionsFnName, queryProperties, isRequestOptions }) {
1446
+ return `const ${isRequestOptions ? "queryOptions" : "options"} = ${queryOptionsFnName}(${queryProperties}${queryProperties ? "," : ""}${isRequestOptions ? "options" : "queryOptions"})`;
1447
+ },
1448
+ generateQueryInvocationArgs({ queryOptionsVarName, optionalQueryClientArgument }) {
1449
+ return `${queryOptionsVarName}${optionalQueryClientArgument ? ", queryClient" : ""}`;
1450
+ },
1451
+ getOptionalQueryClientArgument() {
1452
+ return composed.hasQueryV5 ? ", queryClient?: QueryClient" : "";
1453
+ },
1454
+ generateQueryArguments({ operationName, definitions, mutator, isRequestOptions, type, queryParams, queryParam, initialData, httpClient, hasInvalidation, useRuntimeFetcher }) {
1455
+ const definition = getQueryOptionsDefinition({
1456
+ operationName,
1457
+ mutator,
1458
+ definitions,
1459
+ type,
1460
+ prefix: composed.getQueryOptionsDefinitionPrefix(),
1461
+ hasQueryV5: composed.hasQueryV5,
1462
+ hasQueryV5WithInfiniteQueryOptionsError: composed.hasQueryV5WithInfiniteQueryOptionsError,
1463
+ queryParams,
1464
+ queryParam,
1465
+ isReturnType: false,
1466
+ initialData,
1467
+ adapter: composed
1468
+ });
1469
+ if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
1470
+ const requestType = getQueryArgumentsRequestType(httpClient, mutator, useRuntimeFetcher);
1471
+ const isQueryRequired = initialData === "defined";
1472
+ const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1473
+ return `options${isQueryRequired ? "" : "?"}: ${optionsType}\n`;
1474
+ },
1475
+ generateMutationOnSuccess({ operationName, definitions, isRequestOptions, generateInvalidateCall, uniqueInvalidates }) {
1476
+ const invalidateCalls = uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n");
1477
+ if (composed.hasQueryV5WithMutationContextOnSuccess) {
1478
+ if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1493
1479
  if (!options?.skipInvalidation) {
1494
1480
  ${invalidateCalls}
1495
1481
  }
1496
1482
  mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1497
1483
  };`;
1498
- return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1484
+ return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1499
1485
  ${invalidateCalls}
1500
1486
  mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1501
1487
  };`;
1502
- } else {
1503
- if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${adapter.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1488
+ } else {
1489
+ if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${composed.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1504
1490
  if (!options?.skipInvalidation) {
1505
1491
  ${invalidateCalls}
1506
1492
  }
1507
1493
  mutationOptions?.onSuccess?.(data, variables, context);
1508
1494
  };`;
1509
- return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${adapter.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1495
+ return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${composed.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1510
1496
  ${invalidateCalls}
1511
1497
  mutationOptions?.onSuccess?.(data, variables, context);
1512
1498
  };`;
1513
- }
1514
- },
1515
- ...adapter
1516
- });
1499
+ }
1500
+ },
1501
+ ...adapter
1502
+ };
1503
+ return composed;
1504
+ };
1517
1505
  /**
1518
1506
  * Create a FrameworkAdapter for the given output client, resolving version flags
1519
1507
  * from the packageJson and query config.
@@ -1594,6 +1582,33 @@ const HTTP_METHODS = [
1594
1582
  "head",
1595
1583
  "trace"
1596
1584
  ];
1585
+ const MUTATION_OPERATION_LOCAL_NAMES = new Set([
1586
+ "backupQueryClient",
1587
+ "context",
1588
+ "customOptions",
1589
+ "data",
1590
+ "fetchOptions",
1591
+ "http",
1592
+ "mutationFn",
1593
+ "mutationKey",
1594
+ "mutationOptions",
1595
+ "onMutateResult",
1596
+ "onSuccess",
1597
+ "options",
1598
+ "props",
1599
+ "queryClient",
1600
+ "variables"
1601
+ ]);
1602
+ const getMutationOperationReferenceName = (operationName, localNames) => {
1603
+ if (!localNames.has(operationName)) return operationName;
1604
+ let candidate = camel(`${operationName}-request-fn`);
1605
+ let index = 2;
1606
+ while (localNames.has(candidate)) {
1607
+ candidate = camel(`${operationName}-request-fn-${index}`);
1608
+ index += 1;
1609
+ }
1610
+ return candidate;
1611
+ };
1597
1612
  /**
1598
1613
  * Look up an operation's route and path-parameter metadata from the OpenAPI
1599
1614
  * spec. Matches against both the raw `operationId` and its camelCase form
@@ -1739,10 +1754,14 @@ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, ht
1739
1754
  const bodyOptionalMark = body.isOptional ? "?" : "";
1740
1755
  const definitions = props.map(({ definition, type }) => type === GetterPropType.BODY ? mutator?.bodyTypeName ? `data${bodyOptionalMark}: ${mutator.bodyTypeName}<${body.definition}>` : `data${bodyOptionalMark}: ${body.definition}` : definition).join(";");
1741
1756
  const properties = props.map(({ name, type }) => type === GetterPropType.BODY ? "data" : name).join(",");
1757
+ const operationLocalNames = new Set(MUTATION_OPERATION_LOCAL_NAMES);
1758
+ for (const { name, type } of props) operationLocalNames.add(type === GetterPropType.BODY ? "data" : name);
1742
1759
  const errorType = getQueryErrorType(operationName, response, httpClient, mutator, override.fetch.forceSuccessResponse);
1743
- const dataType = mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`;
1760
+ const operationReferenceName = getMutationOperationReferenceName(operationName, operationLocalNames);
1761
+ const dataType = mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationReferenceName}`;
1762
+ const operationTypeReferenceName = mutator?.isHook ? operationName : operationReferenceName;
1744
1763
  const mutationOptionFnReturnType = getQueryOptionsDefinition({
1745
- operationName,
1764
+ operationName: operationTypeReferenceName,
1746
1765
  mutator,
1747
1766
  definitions,
1748
1767
  prefix: adapter.getQueryOptionsDefinitionPrefix(),
@@ -1762,7 +1781,7 @@ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, ht
1762
1781
  const hasInvalidation = uniqueInvalidates.length > 0 && adapter.supportsMutationInvalidation();
1763
1782
  const useRuntimeFetcher = override.fetch.useRuntimeFetcher;
1764
1783
  const mutationArguments = adapter.generateQueryArguments({
1765
- operationName,
1784
+ operationName: operationTypeReferenceName,
1766
1785
  definitions,
1767
1786
  mutator,
1768
1787
  isRequestOptions,
@@ -1771,7 +1790,7 @@ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, ht
1771
1790
  useRuntimeFetcher
1772
1791
  });
1773
1792
  const mutationArgumentsForOptions = adapter.generateQueryArguments({
1774
- operationName,
1793
+ operationName: operationTypeReferenceName,
1775
1794
  definitions,
1776
1795
  mutator,
1777
1796
  isRequestOptions,
@@ -1787,13 +1806,13 @@ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, ht
1787
1806
 
1788
1807
  ${hooksOptionImplementation}
1789
1808
 
1790
- ${mutator?.isHook ? `const ${operationName} = use${pascal(operationName)}Hook()` : ""}
1809
+ ${mutator?.isHook ? `const ${operationReferenceName} = use${pascal(operationName)}Hook()` : ""}
1791
1810
 
1792
1811
 
1793
1812
  const mutationFn: MutationFunction<Awaited<ReturnType<${dataType}>>, ${definitions ? `{${definitions}}` : "void"}> = (${properties ? "props" : ""}) => {
1794
1813
  ${properties ? `const {${properties}} = props ?? {};` : ""}
1795
1814
 
1796
- return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${properties}${properties ? "," : ""}${getMutationRequestArgs(isRequestOptions, httpClient, mutator, useRuntimeFetcher)})
1815
+ return ${operationReferenceName}(${adapter.getMutationHttpPrefix(mutator)}${properties}${properties ? "," : ""}${getMutationRequestArgs(isRequestOptions, httpClient, mutator, useRuntimeFetcher)})
1797
1816
  }
1798
1817
 
1799
1818
  ${hasInvalidation ? adapter.generateMutationOnSuccess({
@@ -1832,6 +1851,7 @@ ${hasInvalidation ? adapter.generateMutationOnSuccess({
1832
1851
  });
1833
1852
  return {
1834
1853
  implementation: `
1854
+ ${!mutator?.isHook && operationReferenceName !== operationName ? `const ${operationReferenceName} = ${operationName};` : ""}
1835
1855
  ${mutationOptionsFn}
1836
1856
 
1837
1857
  export type ${pascal(operationName)}MutationResult = NonNullable<Awaited<ReturnType<${dataType}>>>
@@ -2154,7 +2174,7 @@ ${hookOptions}
2154
2174
 
2155
2175
  const queryFn: QueryFunction<Awaited<ReturnType<${mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>${hasQueryV5 && hasInfiniteQueryParam ? `, QueryKey, ${infiniteQueryParamType}` : ""}> = (${queryFnArguments}) => ${operationName}(${httpFunctionProps}${httpFunctionProps ? ", " : ""}${queryOptions});
2156
2176
 
2157
- ${adapter.getUnrefStatements(props)}
2177
+ ${adapter.getQueryOptionsUnrefStatements(props)}
2158
2178
 
2159
2179
  ${queryOptionsMutator ? `const customOptions = ${queryOptionsMutator.name}({ queryKey, queryFn, ${queryOptionsImp}}${queryOptionsMutator.hasSecondArg ? `, { ${queryProperties} }` : ""}${queryOptionsMutator.hasThirdArg ? `, { url: \`${route}\`, operationId: '${operationId}', operationName: '${operationName}' }` : ""});` : ""}
2160
2180
 
@@ -2467,11 +2487,19 @@ const WITH_QUERY_KEY_HELPER = `const withQueryKey = <T extends object, K>(query:
2467
2487
  };`;
2468
2488
  const generateQueryHeader = (params) => {
2469
2489
  const needsWithQueryKey = params.clientImplementation.includes("withQueryKey(");
2470
- return `${params.hasAwaitedType ? "" : `type AwaitedInput<T> = PromiseLike<T> | T;\n
2490
+ const innerHeader = getQueryHeader(params);
2491
+ const innerImpl = typeof innerHeader === "string" ? innerHeader : innerHeader.implementation;
2492
+ const innerSharedTypes = typeof innerHeader === "string" ? void 0 : innerHeader.sharedTypes;
2493
+ const ownImplementation = `${params.hasAwaitedType ? "" : `type AwaitedInput<T> = PromiseLike<T> | T;\n
2471
2494
  type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;\n\n`}
2472
2495
  ${params.isRequestOptions && params.isMutator ? `type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];\n\n` : ""}
2473
- ${getQueryHeader(params)}
2496
+ ${innerImpl}
2474
2497
  ${needsWithQueryKey ? `${WITH_QUERY_KEY_HELPER}\n\n` : ""}`;
2498
+ if (innerSharedTypes && innerSharedTypes.length > 0) return {
2499
+ implementation: ownImplementation,
2500
+ sharedTypes: innerSharedTypes
2501
+ };
2502
+ return ownImplementation;
2475
2503
  };
2476
2504
  const generateQuery = async (verbOptions, options, outputClient) => {
2477
2505
  const isZodOutput = typeof options.context.output.schemas === "object" && options.context.output.schemas.type === "zod";