@orval/query 8.27.0 → 8.28.1

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, generateResponseDateDeserializer, generateVerbImports, getAngularFilteredParamsCallExpression, getAngularFilteredParamsHelperBody, getFullRoute, getRoute, getRouteAsArray, getSuccessResponseType, isObject, isOperationInTagBucket, isString, isSyntheticDefaultImportsAllow, jsDoc, logWarning, makeRouteSafe, mergeDeep, pascal, stringify, toObjectString } from "@orval/core";
1
+ import { GetterPropType, OutputClient, OutputHttpClient, Verbs, camel, compareVersions, emitResponseValidation, generateFormDataAndUrlEncodedFunction, generateMutator, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateResponseDateDeserializer, generateVerbImports, getAngularFilteredParamsCallExpression, getAngularFilteredParamsHelperBody, getFullRoute, getRoute, getRouteAsArray, getSchemaOutputTypeRef, getSchemaValueRef, getSuccessResponseType, hasSchemaImport, isObject, isOperationInTagBucket, isPrimitiveResponseType, isString, isSyntheticDefaultImportsAllow, jsDoc, logWarning, makeRouteSafe, mergeDeep, pascal, rewriteImportsForResponseValidation, 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";
@@ -22,7 +22,7 @@ const normalizeQueryOptions = (queryOptions = {}, outputWorkspace) => {
22
22
  ...queryOptions.mutationOptions ? { mutationOptions: normalizeMutator(outputWorkspace, queryOptions.mutationOptions) } : {},
23
23
  ...queryOptions.signal ? { signal: true } : {},
24
24
  ...queryOptions.shouldExportMutatorHooks ? { shouldExportMutatorHooks: true } : {},
25
- ...queryOptions.shouldExportQueryKey ? { shouldExportQueryKey: true } : {},
25
+ ...queryOptions.shouldExportKeys ?? queryOptions.shouldExportQueryKey ? { shouldExportKeys: true } : {},
26
26
  ...queryOptions.shouldFilterQueryKey ? { shouldFilterQueryKey: true } : {},
27
27
  ...queryOptions.queryKeyFilter ? { queryKeyFilter: queryOptions.queryKeyFilter } : {},
28
28
  ...queryOptions.shouldExportHttpClient ? { shouldExportHttpClient: true } : {},
@@ -117,9 +117,12 @@ const ANGULAR_HTTP_DEPENDENCIES = [
117
117
  dependency: "rxjs/operators"
118
118
  }
119
119
  ];
120
- const generateAngularHttpRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props, verb, formData, formUrlEncoded, override }, { route: _route, context }) => {
120
+ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props, verb, formData, formUrlEncoded, override, params }, { route: _route, context }) => {
121
121
  let route = _route;
122
- if (context.output.urlEncodeParameters) route = makeRouteSafe(route);
122
+ if (context.output.urlEncodeParameters) {
123
+ const skip = new Set(params.filter((p) => p.allowReserved).map((p) => p.name));
124
+ route = makeRouteSafe(route, skip);
125
+ }
123
126
  const isRequestOptions = override.requestOptions !== false;
124
127
  const isFormData = !override.formData.disabled;
125
128
  const isFormUrlEncoded = override.formUrlEncoded !== false;
@@ -162,7 +165,10 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
162
165
  `;
163
166
  }
164
167
  const queryProps = toObjectString(props, "implementation").replace(/,\s*$/, "");
165
- const dataType = response.definition.success || "unknown";
168
+ const responseType = response.definition.success || "unknown";
169
+ const isZodOutput = isObject(context.output.schemas) && context.output.schemas.type === "zod";
170
+ const shouldValidateResponse = override.query.runtimeValidation?.enabled && isZodOutput && !isPrimitiveResponseType(responseType) && hasSchemaImport(response.imports, responseType);
171
+ const dataType = shouldValidateResponse ? getSchemaOutputTypeRef(responseType) : responseType;
166
172
  const hasQueryParams = queryParams?.schema.name;
167
173
  const filteredParamsExpression = getAngularFilteredParamsCallExpression("params", queryParams?.requiredNullableKeys);
168
174
  const urlConstruction = hasQueryParams ? `const httpParams = params ? new HttpParams({ fromObject: ${filteredParamsExpression} }) : undefined;
@@ -187,17 +193,15 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
187
193
  break;
188
194
  default: httpCall = `http.${verb}${httpGeneric}(url, ${bodyArg || "undefined"}${optionsStr})`;
189
195
  }
190
- const responseType = response.definition.success;
191
- const isPrimitiveType = [
192
- "string",
193
- "number",
194
- "boolean",
195
- "void",
196
- "unknown"
197
- ].includes(responseType);
198
- const hasSchema = response.imports.some((imp) => imp.name === responseType);
199
- const isZodOutput = isObject(context.output.schemas) && context.output.schemas.type === "zod";
200
- if (override.query.runtimeValidation && isZodOutput && !isPrimitiveType && hasSchema) httpCall = `${httpCall}.pipe(map(data => ${responseType === "Error" ? "ErrorSchema" : responseType}.parse(data)))`;
196
+ if (shouldValidateResponse) {
197
+ const schemaValueRef = getSchemaValueRef(responseType);
198
+ httpCall = `${httpCall}${emitResponseValidation({
199
+ schemaRef: schemaValueRef,
200
+ operationName,
201
+ strategy: override.query.runtimeValidation?.strategy ?? "throw",
202
+ context: "rxjs-map"
203
+ })}`;
204
+ }
201
205
  const additionalParams = [queryProps, hasSignal ? "options?: { signal?: AbortSignal | null }" : ""].filter(Boolean).join(", ");
202
206
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (
203
207
  http: HttpClient${additionalParams ? `,\n ${additionalParams}` : ""}
@@ -212,10 +216,13 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
212
216
  }
213
217
  `;
214
218
  };
215
- const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer }, { route: _route, context }, adapter) => {
219
+ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer, params }, { route: _route, context }, adapter) => {
216
220
  const props = adapter.transformProps(_props);
217
221
  let route = _route;
218
- if (context.output.urlEncodeParameters) route = makeRouteSafe(route);
222
+ if (context.output.urlEncodeParameters) {
223
+ const skip = new Set(params.filter((p) => p.allowReserved).map((p) => p.name));
224
+ route = makeRouteSafe(route, skip);
225
+ }
219
226
  const unrefStatements = adapter.getRequestUnrefStatements(props);
220
227
  const isRequestOptions = override.requestOptions !== false;
221
228
  const isFormData = !override.formData.disabled;
@@ -488,7 +495,11 @@ const SVELTE_QUERY_DEPENDENCIES = [{
488
495
  { name: "CreateMutationResult" },
489
496
  { name: "DataTag" },
490
497
  { name: "QueryClient" },
491
- { name: "InvalidateOptions" }
498
+ { name: "InvalidateOptions" },
499
+ {
500
+ name: "matchQuery",
501
+ values: true
502
+ }
492
503
  ],
493
504
  dependency: "@tanstack/svelte-query"
494
505
  }];
@@ -587,7 +598,11 @@ const REACT_QUERY_DEPENDENCIES = [{
587
598
  { name: "InfiniteData" },
588
599
  { name: "UseMutationResult" },
589
600
  { name: "DataTag" },
590
- { name: "InvalidateOptions" }
601
+ { name: "InvalidateOptions" },
602
+ {
603
+ name: "matchQuery",
604
+ values: true
605
+ }
591
606
  ],
592
607
  dependency: "@tanstack/react-query"
593
608
  }];
@@ -682,7 +697,11 @@ const VUE_QUERY_DEPENDENCIES = [{
682
697
  { name: "UseMutationReturnType" },
683
698
  { name: "DataTag" },
684
699
  { name: "QueryClient" },
685
- { name: "InvalidateOptions" }
700
+ { name: "InvalidateOptions" },
701
+ {
702
+ name: "matchQuery",
703
+ values: true
704
+ }
686
705
  ],
687
706
  dependency: "@tanstack/vue-query"
688
707
  }, {
@@ -786,7 +805,11 @@ const ANGULAR_QUERY_DEPENDENCIES = [{
786
805
  name: "QueryClient",
787
806
  values: true
788
807
  },
789
- { name: "InvalidateOptions" }
808
+ { name: "InvalidateOptions" },
809
+ {
810
+ name: "matchQuery",
811
+ values: true
812
+ }
790
813
  ],
791
814
  dependency: "@tanstack/angular-query-experimental"
792
815
  }, {
@@ -1483,8 +1506,8 @@ const createVueAdapter = ({ hasVueQueryV4, hasQueryV5, hasQueryV5WithDataTagErro
1483
1506
  supportsMutationInvalidation() {
1484
1507
  return hasQueryV5;
1485
1508
  },
1486
- generateMutationOnSuccess({ operationName, definitions, mutationVariablesType, isRequestOptions, generateInvalidateCall, uniqueInvalidates }) {
1487
- const invalidateCalls = uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n");
1509
+ generateMutationOnSuccess({ operationName, definitions, mutationVariablesType, isRequestOptions, generateInvalidateCalls, uniqueInvalidates }) {
1510
+ const invalidateCalls = generateInvalidateCalls(uniqueInvalidates);
1488
1511
  const variablesType = mutationVariablesType ?? (definitions ? `{${definitions}}` : "void");
1489
1512
  if (hasQueryV5WithMutationContextOnSuccess) {
1490
1513
  if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${variablesType}, onMutateResult: TContext, context: MutationFunctionContext) => {
@@ -1595,8 +1618,8 @@ const withDefaults = (adapter) => {
1595
1618
  const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1596
1619
  return `options${isQueryRequired ? "" : "?"}: ${optionsType}\n`;
1597
1620
  },
1598
- generateMutationOnSuccess({ operationName, definitions, mutationVariablesType, isRequestOptions, generateInvalidateCall, uniqueInvalidates }) {
1599
- const invalidateCalls = uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n");
1621
+ generateMutationOnSuccess({ operationName, definitions, mutationVariablesType, isRequestOptions, generateInvalidateCalls, uniqueInvalidates }) {
1622
+ const invalidateCalls = generateInvalidateCalls(uniqueInvalidates);
1600
1623
  const variablesType = mutationVariablesType ?? (definitions ? `{${definitions}}` : "void");
1601
1624
  if (composed.hasQueryV5WithMutationContextOnSuccess) {
1602
1625
  if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${variablesType}, onMutateResult: TContext, context: MutationFunctionContext) => {
@@ -1846,14 +1869,18 @@ const generateParamArgs = (params) => {
1846
1869
  */
1847
1870
  const toPrefixLiteral = (prefix) => prefix.includes("${") ? `\`${prefix}\`` : `'${prefix}'`;
1848
1871
  /**
1849
- * Create a generateInvalidateCall function that has access to the OpenAPI spec
1850
- * for intelligent route-based invalidation when params are not specified.
1872
+ * Create a function resolving one invalidate target to its filter, using the
1873
+ * OpenAPI spec for intelligent route-based invalidation when params are not
1874
+ * specified.
1851
1875
  */
1852
- const createGenerateInvalidateCall = (spec, shouldSplitQueryKey, useOperationIdAsQueryKey, baseUrl, servers) => {
1876
+ const createGenerateInvalidateFilter = (spec, shouldSplitQueryKey, useOperationIdAsQueryKey, baseUrl, servers) => {
1853
1877
  return (target) => {
1854
1878
  const method = target.invalidateMode === "reset" ? "resetQueries" : "invalidateQueries";
1855
1879
  const queryKeyFn = camel(`get-${target.query}-query-key`);
1856
- if (hasNonEmptyParams(target.params)) return ` queryClient.${method}({ queryKey: ${queryKeyFn}(${generateParamArgs(target.params)}) });`;
1880
+ if (hasNonEmptyParams(target.params)) return {
1881
+ method,
1882
+ key: `${queryKeyFn}(${generateParamArgs(target.params)})`
1883
+ };
1857
1884
  const info = findOperationInfo(spec, target.query);
1858
1885
  if (info?.hasRequiredPathParams) {
1859
1886
  const prefix = getStaticRoutePrefix(info.route);
@@ -1865,14 +1892,60 @@ const createGenerateInvalidateCall = (spec, shouldSplitQueryKey, useOperationIdA
1865
1892
  });
1866
1893
  if (shouldSplitQueryKey) {
1867
1894
  const segments = getRouteAsArray(prefixWithBase);
1868
- return ` queryClient.${method}({ queryKey: ${verbPrefix ? `['${verbPrefix}', ${segments}]` : `[${segments}]`} });`;
1895
+ return {
1896
+ method,
1897
+ key: verbPrefix ? `['${verbPrefix}', ${segments}]` : `[${segments}]`
1898
+ };
1869
1899
  }
1870
1900
  const prefixLiteral = toPrefixLiteral(prefixWithBase);
1871
- if (verbPrefix) return ` queryClient.${method}({ predicate: (query) => query.queryKey[0] === '${verbPrefix}' && typeof query.queryKey[1] === 'string' && query.queryKey[1].startsWith(${prefixLiteral}) });`;
1872
- return ` queryClient.${method}({ predicate: (query) => typeof query.queryKey[0] === 'string' && query.queryKey[0].startsWith(${prefixLiteral}) });`;
1901
+ if (verbPrefix) return {
1902
+ method,
1903
+ predicate: `query.queryKey[0] === '${verbPrefix}' && typeof query.queryKey[1] === 'string' && query.queryKey[1].startsWith(${prefixLiteral})`
1904
+ };
1905
+ return {
1906
+ method,
1907
+ predicate: `typeof query.queryKey[0] === 'string' && query.queryKey[0].startsWith(${prefixLiteral})`
1908
+ };
1873
1909
  }
1874
1910
  }
1875
- return ` queryClient.${method}({ queryKey: ${queryKeyFn}() });`;
1911
+ return {
1912
+ method,
1913
+ key: `${queryKeyFn}()`
1914
+ };
1915
+ };
1916
+ };
1917
+ /**
1918
+ * Fold every invalidate target of one mutation into a single `queryClient` call
1919
+ * per method.
1920
+ *
1921
+ * `invalidateQueries` defaults to `cancelRefetch: true`, so one call per target
1922
+ * makes the calls fight each other as soon as two targets cover the same query –
1923
+ * and they routinely do, because keys are derived from the URL path and `/pets`
1924
+ * partially matches `/pets/{petId}`. The later call aborts the refetch the
1925
+ * earlier one has just started, which costs a wasted round trip and surfaces as
1926
+ * an unhandled `AbortError: signal is aborted without reason`.
1927
+ *
1928
+ * One predicate covering the same set keeps `cancelRefetch: true` in force for a
1929
+ * genuinely stale in-flight fetch, while invalidating and refetching each matched
1930
+ * query exactly once. A lone target still emits the plain `queryKey` form, so
1931
+ * single-target output is byte-identical to before.
1932
+ *
1933
+ * `matchQuery` is what `invalidateQueries({ queryKey })` resolves a key filter
1934
+ * with internally, and unlike `partialMatchKey` it is exported by every
1935
+ * supported adapter package, back to `@tanstack/svelte-query` v4.
1936
+ */
1937
+ const createGenerateInvalidateCalls = (spec, shouldSplitQueryKey, useOperationIdAsQueryKey, baseUrl, servers) => {
1938
+ const generateFilter = createGenerateInvalidateFilter(spec, shouldSplitQueryKey, useOperationIdAsQueryKey, baseUrl, servers);
1939
+ return (targets) => {
1940
+ const filters = targets.map((target) => generateFilter(target));
1941
+ return ["invalidateQueries", "resetQueries"].flatMap((method) => {
1942
+ const group = filters.filter((filter) => filter.method === method);
1943
+ if (group.length === 0) return [];
1944
+ const keys = group.flatMap((filter) => filter.key ?? []);
1945
+ const predicates = group.flatMap((filter) => filter.predicate ?? []);
1946
+ if (predicates.length === 0 && keys.length === 1) return ` queryClient.${method}({ queryKey: ${keys[0]} });`;
1947
+ return ` queryClient.${method}({ predicate: (query) => ${[...keys.length > 0 ? [`[${keys.join(", ")}].some((queryKey) => matchQuery({ queryKey }, query))`] : [], ...predicates.map((predicate) => `(${predicate})`)].join(" || ")} });`;
1948
+ }).join("\n");
1876
1949
  };
1877
1950
  };
1878
1951
  const generateMutationHook = async ({ verbOptions, options, isRequestOptions, httpClient, doc, adapter }) => {
@@ -1944,7 +2017,7 @@ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, ht
1944
2017
  mutator
1945
2018
  }) ? `use-${operationName}-mutationOptions` : `get-${operationName}-mutationOptions`);
1946
2019
  const mutationKeyFnName = camel(`get-${operationName}-mutation-key`);
1947
- const mutationKeyFn = query.shouldExportQueryKey || isRequestOptions ? `${query.shouldExportQueryKey ? "export " : ""}const ${mutationKeyFnName} = () => ['${camel(operationName)}'] as const;` : "";
2020
+ const mutationKeyFn = query.shouldExportKeys || isRequestOptions ? `${query.shouldExportKeys ? "export " : ""}const ${mutationKeyFnName} = () => ['${camel(operationName)}'] as const;` : "";
1948
2021
  const hooksOptionImplementation = getHooksOptionImplementation(isRequestOptions, httpClient, mutationKeyFnName, mutator, useRuntimeFetcher);
1949
2022
  const mutationOptionsFn = `export const ${mutationOptionsFnName} = <TError = ${errorType},
1950
2023
  TContext = unknown>(${adapter.getHttpFirstParam(mutator)}${hasInvalidation ? "queryClient: QueryClient, " : ""}${mutationArgumentsForOptions}): ${mutationOptionFnReturnType} => {
@@ -1965,7 +2038,7 @@ ${hasInvalidation ? adapter.generateMutationOnSuccess({
1965
2038
  definitions,
1966
2039
  mutationVariablesType,
1967
2040
  isRequestOptions,
1968
- generateInvalidateCall: createGenerateInvalidateCall(context.spec, !!query.shouldSplitQueryKey, !!query.useOperationIdAsQueryKey, context.output.baseUrl, context.spec.servers),
2041
+ generateInvalidateCalls: createGenerateInvalidateCalls(context.spec, !!query.shouldSplitQueryKey, !!query.useOperationIdAsQueryKey, context.output.baseUrl, context.spec.servers),
1969
2042
  uniqueInvalidates
1970
2043
  }) : ""}
1971
2044
 
@@ -2215,7 +2288,7 @@ const generatePrefetch = ({ usePrefetch, type, useQuery, useInfinite, operationN
2215
2288
  return queryClient;
2216
2289
  }\n`;
2217
2290
  };
2218
- const generateQueryImplementation = ({ queryOption: { name, typeName: optionTypeName, queryParam, options, type, queryKeyFnName }, operationId, operationName, typeName, queryProperties, queryKeyProperties, queryParams, params, props, body, mutator, queryOptionsMutator, queryKeyMutator, isRequestOptions, response, httpClient, isExactOptionalPropertyTypes, hasSignal, useRuntimeFetcher, forceSuccessResponse, route, doc, usePrefetch, useQuery, useInfinite, useInvalidate, useSetQueryData, useGetQueryData, adapter }) => {
2291
+ const generateQueryImplementation = ({ queryOption: { name, typeName: optionTypeName, queryParam, options, type, queryKeyFnName }, operationId, operationName, typeName, queryProperties, queryKeyProperties, queryParams, params, props, body, mutator, queryOptionsMutator, queryKeyMutator, isRequestOptions, response, httpClient, isExactOptionalPropertyTypes, hasSignal, useRuntimeFetcher, forceSuccessResponse, route, doc, deprecated, usePrefetch, useQuery, useInfinite, useInvalidate, useSetQueryData, useGetQueryData, adapter }) => {
2219
2292
  const { hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError } = adapter;
2220
2293
  const hasSignalParam = props.some((prop) => prop.name === "signal");
2221
2294
  const requiresUserQueryOptions = requiresUserSuppliedQueryOptions(adapter, type, options);
@@ -2378,6 +2451,10 @@ ${hookOptions}
2378
2451
  const operationPrefix = adapter.hookPrefix;
2379
2452
  const optionalQueryClientArgument = adapter.getOptionalQueryClientArgument();
2380
2453
  const queryHookName = camel(`${operationPrefix}-${name}`);
2454
+ const invalidateDoc = jsDoc({
2455
+ summary: `Invalidates the {@link ${queryHookName}} query`,
2456
+ deprecated
2457
+ });
2381
2458
  const overrideTypes = `
2382
2459
  export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${definedInitialDataQueryPropsDefinitions} ${definedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${definedInitialDataReturnType}
2383
2460
  export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${queryPropDefinitions} ${undefinedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${returnType}
@@ -2469,7 +2546,7 @@ export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${w
2469
2546
  })}
2470
2547
  }\n
2471
2548
  ${prefetch}
2472
- ${shouldGenerateInvalidate ? `${doc}export const ${invalidateFnName} = async (\n queryClient: QueryClient, ${queryProps} options?: InvalidateOptions\n ): Promise<QueryClient> => {
2549
+ ${shouldGenerateInvalidate ? `${invalidateDoc}export const ${invalidateFnName} = async (\n queryClient: QueryClient, ${queryProps} options?: InvalidateOptions\n ): Promise<QueryClient> => {
2473
2550
 
2474
2551
  await queryClient.invalidateQueries({ queryKey: ${invalidateQueryKeyExpr} }, options);
2475
2552
 
@@ -2595,7 +2672,7 @@ const generateQueryHook = async (verbOptions, options, outputClient, adapter) =>
2595
2672
  useOperationIdAsQueryKey: override.query.useOperationIdAsQueryKey
2596
2673
  });
2597
2674
  queryKeyFns += `
2598
- ${override.query.shouldExportQueryKey ? "export " : ""}const ${queryOption.queryKeyFnName} = (${queryKeyProps}) => {
2675
+ ${override.query.shouldExportKeys ? "export " : ""}const ${queryOption.queryKeyFnName} = (${queryKeyProps}) => {
2599
2676
  return [
2600
2677
  ${[
2601
2678
  queryOption.type === QueryType.INFINITE || queryOption.type === QueryType.SUSPENSE_INFINITE ? `'infinite'` : "",
@@ -2608,7 +2685,7 @@ ${override.query.shouldExportQueryKey ? "export " : ""}const ${queryOption.query
2608
2685
  }
2609
2686
  `;
2610
2687
  }
2611
- else if (override.query.shouldExportQueryKey) for (const queryOption of uniqueQueryOptionsByKeys) {
2688
+ else if (override.query.shouldExportKeys) for (const queryOption of uniqueQueryOptionsByKeys) {
2612
2689
  const queryKeyProps = buildKeyShapedProps({
2613
2690
  props,
2614
2691
  body,
@@ -2647,6 +2724,7 @@ ${queryKeyFns}`;
2647
2724
  queryKeyMutator,
2648
2725
  route,
2649
2726
  doc,
2727
+ deprecated,
2650
2728
  usePrefetch: query.usePrefetch,
2651
2729
  useQuery: effectiveUseQuery,
2652
2730
  useInfinite: effectiveUseInfinite,
@@ -2716,30 +2794,20 @@ ${needsWithQueryKey ? `${WITH_QUERY_KEY_HELPER}\n\n` : ""}`;
2716
2794
  return ownImplementation;
2717
2795
  };
2718
2796
  const generateQuery = async (verbOptions, options, outputClient) => {
2797
+ const adapter = createFrameworkAdapter({
2798
+ outputClient,
2799
+ packageJson: options.context.output.packageJson,
2800
+ queryVersion: verbOptions.override.query.version
2801
+ });
2719
2802
  const isZodOutput = typeof options.context.output.schemas === "object" && options.context.output.schemas.type === "zod";
2720
2803
  const responseType = verbOptions.response.definition.success;
2721
- const isPrimitiveResponse = [
2722
- "string",
2723
- "number",
2724
- "boolean",
2725
- "void",
2726
- "unknown"
2727
- ].includes(responseType);
2728
- const normalizedVerbOptions = verbOptions.override.query.runtimeValidation && isZodOutput && !isPrimitiveResponse && verbOptions.response.imports.some((imp) => imp.name === responseType) ? {
2804
+ const normalizedVerbOptions = verbOptions.override.query.runtimeValidation?.enabled && isZodOutput && !verbOptions.mutator && !isPrimitiveResponseType(responseType) && hasSchemaImport(verbOptions.response.imports, responseType) ? {
2729
2805
  ...verbOptions,
2730
2806
  response: {
2731
2807
  ...verbOptions.response,
2732
- imports: verbOptions.response.imports.map((imp) => imp.name === responseType ? {
2733
- ...imp,
2734
- values: true
2735
- } : imp)
2808
+ imports: rewriteImportsForResponseValidation(verbOptions.response.imports, responseType, { includeOutputType: adapter.isAngularHttp })
2736
2809
  }
2737
2810
  } : verbOptions;
2738
- const adapter = createFrameworkAdapter({
2739
- outputClient,
2740
- packageJson: options.context.output.packageJson,
2741
- queryVersion: normalizedVerbOptions.override.query.version
2742
- });
2743
2811
  const imports = generateVerbImports(normalizedVerbOptions);
2744
2812
  const functionImplementation = adapter.generateRequestFunction(normalizedVerbOptions, options);
2745
2813
  const { implementation: hookImplementation, imports: hookImports, mutators } = await generateQueryHook(normalizedVerbOptions, options, outputClient, adapter);