@orval/query 8.2.0 → 8.4.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, TEMPLATE_TAG_REGEX, Verbs, camel, compareVersions, generateFormDataAndUrlEncodedFunction, generateMutator, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, getRouteAsArray, isObject, isString, isSyntheticDefaultImportsAllow, jsDoc, mergeDeep, pascal, stringify, toObjectString, upath } from "@orval/core";
1
+ import { GetterPropType, OutputClient, OutputHttpClient, TEMPLATE_TAG_REGEX, Verbs, camel, compareVersions, generateFormDataAndUrlEncodedFunction, generateMutator, generateMutatorConfig, generateMutatorRequestOptions, generateOptions, generateVerbImports, getAngularFilteredParamsCallExpression, getAngularFilteredParamsHelperBody, getRouteAsArray, getSuccessResponseType, isObject, isString, isSyntheticDefaultImportsAllow, jsDoc, mergeDeep, pascal, stringify, toObjectString, upath } from "@orval/core";
2
2
  import { generateFetchHeader, generateRequestFunction } from "@orval/fetch";
3
3
  import chalk from "chalk";
4
4
  import { omitBy } from "remeda";
@@ -58,11 +58,6 @@ const vueUnRefParams = (props) => {
58
58
  };
59
59
  const wrapRouteParameters = (route, prepend, append) => route.replaceAll(TEMPLATE_TAG_REGEX, `\${${prepend}$1${append}}`);
60
60
  const makeRouteSafe = (route) => wrapRouteParameters(route, "encodeURIComponent(String(", "))");
61
- const isVue = (client) => OutputClient.VUE_QUERY === client;
62
- const isSolid = (client) => OutputClient.SOLID_QUERY === client;
63
- const isAngular = (client) => OutputClient.ANGULAR_QUERY === client;
64
- const isReact = (client) => OutputClient.REACT_QUERY === client;
65
- const isSvelte = (client) => OutputClient.SVELTE_QUERY === client;
66
61
  const getQueryTypeForFramework = (type) => {
67
62
  switch (type) {
68
63
  case "suspenseQuery": return "query";
@@ -121,14 +116,13 @@ const ANGULAR_HTTP_DEPENDENCIES = [
121
116
  exports: [{
122
117
  name: "takeUntil",
123
118
  values: true
119
+ }, {
120
+ name: "map",
121
+ values: true
124
122
  }],
125
123
  dependency: "rxjs/operators"
126
124
  }
127
125
  ];
128
- const generateQueryRequestFunction = (verbOptions, options, isVue$1, isAngularClient = false) => {
129
- if (isAngularClient || options.context.output.httpClient === OutputHttpClient.ANGULAR) return generateAngularHttpRequestFunction(verbOptions, options);
130
- return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, isVue$1) : generateRequestFunction(verbOptions, options);
131
- };
132
126
  const generateAngularHttpRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props, verb, formData, formUrlEncoded, override }, { route, context }) => {
133
127
  const isRequestOptions = override.requestOptions !== false;
134
128
  const isFormData = !override.formData.disabled;
@@ -173,26 +167,42 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
173
167
  const queryProps = toObjectString(props, "implementation").replace(/,\s*$/, "");
174
168
  const dataType = response.definition.success || "unknown";
175
169
  const hasQueryParams = queryParams?.schema.name;
176
- const urlConstruction = hasQueryParams ? `const httpParams = params ? new HttpParams({ fromObject: params as Record<string, string> }) : undefined;
170
+ const filteredParamsExpression = getAngularFilteredParamsCallExpression("params", queryParams?.requiredNullableKeys);
171
+ const urlConstruction = hasQueryParams ? `const httpParams = params ? new HttpParams({ fromObject: ${filteredParamsExpression} }) : undefined;
177
172
  const url = \`${route}\`;` : `const url = \`${route}\`;`;
178
173
  const httpOptions = [];
179
174
  if (hasQueryParams) httpOptions.push("params: httpParams");
180
175
  if (headers) httpOptions.push("headers: new HttpHeaders(headers)");
176
+ const successResponseType = getSuccessResponseType(response);
177
+ const responseTypeOption = successResponseType ? `'${successResponseType}'` : void 0;
178
+ if (responseTypeOption) httpOptions.push(`responseType: ${responseTypeOption}`);
181
179
  const optionsStr = httpOptions.length > 0 ? `, { ${httpOptions.join(", ")} }` : "";
182
180
  let httpCall;
183
- const bodyArg = body.definition ? toObjectString([body], "implementation").replace(/,\s*$/, "") : "";
181
+ const httpGeneric = responseTypeOption ? "" : `<${dataType}>`;
182
+ const bodyArg = isFormData && body.formData ? "formData" : isFormUrlEncoded && body.formUrlEncoded ? "formUrlEncoded" : body.definition ? toObjectString([body], "implementation").replace(/,\s*$/, "") : "";
184
183
  switch (verb) {
185
184
  case "get":
186
185
  case "head":
187
- httpCall = `http.${verb}<${dataType}>(url${optionsStr})`;
186
+ httpCall = `http.${verb}${httpGeneric}(url${optionsStr})`;
188
187
  break;
189
188
  case "delete":
190
- httpCall = bodyArg ? `http.${verb}<${dataType}>(url, { ${httpOptions.length > 0 ? httpOptions.join(", ") + ", " : ""}body: ${bodyArg} })` : `http.${verb}<${dataType}>(url${optionsStr})`;
189
+ httpCall = bodyArg ? `http.${verb}${httpGeneric}(url, { ${httpOptions.length > 0 ? httpOptions.join(", ") + ", " : ""}body: ${bodyArg} })` : `http.${verb}${httpGeneric}(url${optionsStr})`;
191
190
  break;
192
191
  default:
193
- httpCall = `http.${verb}<${dataType}>(url, ${bodyArg || "undefined"}${optionsStr})`;
192
+ httpCall = `http.${verb}${httpGeneric}(url, ${bodyArg || "undefined"}${optionsStr})`;
194
193
  break;
195
194
  }
195
+ const responseType = response.definition.success;
196
+ const isPrimitiveType = [
197
+ "string",
198
+ "number",
199
+ "boolean",
200
+ "void",
201
+ "unknown"
202
+ ].includes(responseType);
203
+ const hasSchema = response.imports.some((imp) => imp.name === responseType);
204
+ const isZodOutput = isObject(context.output.schemas) && context.output.schemas.type === "zod";
205
+ if (override.query.runtimeValidation && isZodOutput && !isPrimitiveType && hasSchema) httpCall = `${httpCall}.pipe(map(data => ${responseType === "Error" ? "ErrorSchema" : responseType}.parse(data)))`;
196
206
  const additionalParams = [queryProps, hasSignal ? "options?: { signal?: AbortSignal | null }" : ""].filter(Boolean).join(", ");
197
207
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (
198
208
  http: HttpClient${additionalParams ? `,\n ${additionalParams}` : ""}
@@ -207,10 +217,10 @@ const generateAngularHttpRequestFunction = ({ headers, queryParams, operationNam
207
217
  }
208
218
  `;
209
219
  };
210
- const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer }, { route: _route, context }, isVue$1) => {
220
+ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, response, mutator, body, props: _props, verb, formData, formUrlEncoded, override, paramsSerializer }, { route: _route, context }, isVue) => {
211
221
  let props = _props;
212
222
  let route = _route;
213
- if (isVue$1) props = vueWrapTypeWithMaybeRef(_props);
223
+ if (isVue) props = vueWrapTypeWithMaybeRef(_props);
214
224
  if (context.output.urlEncodeParameters) route = makeRouteSafe(route);
215
225
  const isRequestOptions = override.requestOptions !== false;
216
226
  const isFormData = !override.formData.disabled;
@@ -238,7 +248,7 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
238
248
  hasSignal,
239
249
  hasSignalParam,
240
250
  isExactOptionalPropertyTypes,
241
- isVue: isVue$1
251
+ isVue
242
252
  });
243
253
  const bodyDefinition = body.definition.replace("[]", String.raw`\[\]`);
244
254
  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");
@@ -270,13 +280,13 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
270
280
  }
271
281
  }
272
282
  `;
273
- return isVue$1 ? vueRet : ret;
283
+ return isVue ? vueRet : ret;
274
284
  }
275
285
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (\n ${propsImplementation}\n ${isRequestOptions && mutator.hasSecondArg ? `options${context.output.optionsParamRequired ? "" : "?"}: SecondParameter<typeof ${mutator.name}>,` : ""}${getSignalDefinition({
276
286
  hasSignal,
277
287
  hasSignalParam
278
288
  })}) => {
279
- ${isVue$1 ? vueUnRefParams(props) : ""}
289
+ ${isVue ? vueUnRefParams(props) : ""}
280
290
  ${bodyForm}
281
291
  return ${mutator.name}<${response.definition.success || "unknown"}>(
282
292
  ${mutatorConfig},
@@ -300,7 +310,7 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
300
310
  isExactOptionalPropertyTypes,
301
311
  hasSignal,
302
312
  hasSignalParam,
303
- isVue: isVue$1
313
+ isVue
304
314
  });
305
315
  const optionsArgs = generateRequestOptionsArguments({
306
316
  isRequestOptions,
@@ -309,7 +319,7 @@ const generateAxiosRequestFunction = ({ headers, queryParams, operationName, res
309
319
  });
310
320
  const queryProps = toObjectString(props, "implementation");
311
321
  return `${override.query.shouldExportHttpClient ? "export " : ""}const ${operationName} = (\n ${queryProps} ${optionsArgs} ): Promise<AxiosResponse<${response.definition.success || "unknown"}>> => {
312
- ${isVue$1 ? vueUnRefParams(props) : ""}
322
+ ${isVue ? vueUnRefParams(props) : ""}
313
323
  ${bodyForm}
314
324
  return axios${isSyntheticDefaultImportsAllowed ? "" : ".default"}.${verb}(${options});
315
325
  }
@@ -389,13 +399,10 @@ const getMutationRequestArgs = (isRequestOptions, httpClient, mutator) => {
389
399
  if (mutator?.hasSecondArg && httpClient === OutputHttpClient.ANGULAR) return "http";
390
400
  return isRequestOptions ? mutator ? mutator.hasSecondArg ? "requestOptions" : "" : options : "";
391
401
  };
392
- const getHttpFunctionQueryProps = (isVue$1, httpClient, queryProperties, isAngular$1 = false, hasMutator = false) => {
393
- const result = isVue$1 && httpClient === OutputHttpClient.FETCH && queryProperties ? queryProperties.split(",").map((prop) => `unref(${prop})`).join(",") : queryProperties;
394
- if ((isAngular$1 || httpClient === OutputHttpClient.ANGULAR) && !hasMutator) return result ? `http, ${result}` : "http";
395
- return result;
396
- };
397
402
  const getQueryHeader = (params) => {
398
- return params.output.httpClient === OutputHttpClient.FETCH ? generateFetchHeader(params) : "";
403
+ if (params.output.httpClient === OutputHttpClient.FETCH) return generateFetchHeader(params);
404
+ if (params.output.httpClient === OutputHttpClient.ANGULAR) return Object.values(params.verbOptions).some((v) => v.queryParams) ? getAngularFilteredParamsHelperBody() : "";
405
+ return "";
399
406
  };
400
407
 
401
408
  //#endregion
@@ -565,6 +572,7 @@ const REACT_QUERY_DEPENDENCIES = [{
565
572
  { name: "UseMutationOptions" },
566
573
  { name: "QueryFunction" },
567
574
  { name: "MutationFunction" },
575
+ { name: "MutationFunctionContext" },
568
576
  { name: "UseQueryResult" },
569
577
  { name: "DefinedUseQueryResult" },
570
578
  { name: "UseSuspenseQueryResult" },
@@ -583,7 +591,8 @@ const REACT_QUERY_DEPENDENCIES = [{
583
591
  const getReactQueryDependencies = (hasGlobalMutator, hasParamsSerializerOptions, packageJson, httpClient, hasTagsMutator, override) => {
584
592
  const hasReactQuery = packageJson?.dependencies?.["react-query"] ?? packageJson?.devDependencies?.["react-query"] ?? packageJson?.peerDependencies?.["react-query"];
585
593
  const hasReactQueryV4 = packageJson?.dependencies?.["@tanstack/react-query"] ?? packageJson?.devDependencies?.["@tanstack/react-query"] ?? packageJson?.peerDependencies?.["@tanstack/react-query"];
586
- const useReactQueryV3 = override.query.version === void 0 ? hasReactQuery && !hasReactQueryV4 : override.query.version <= 3;
594
+ const queryVersion = override?.query.version;
595
+ const useReactQueryV3 = queryVersion === void 0 ? hasReactQuery && !hasReactQueryV4 : queryVersion <= 3;
587
596
  return [
588
597
  ...hasGlobalMutator || hasTagsMutator ? REACT_DEPENDENCIES : [],
589
598
  ...!hasGlobalMutator && httpClient === OutputHttpClient.AXIOS ? AXIOS_DEPENDENCIES : [],
@@ -682,36 +691,39 @@ const VUE_QUERY_DEPENDENCIES = [{
682
691
  ],
683
692
  dependency: "vue"
684
693
  }];
685
- const SOLID_QUERY_DEPENDENCIES = [{
686
- exports: [
687
- {
688
- name: "createQuery",
689
- values: true
690
- },
691
- {
692
- name: "createInfiniteQuery",
693
- values: true
694
- },
695
- {
696
- name: "createMutation",
697
- values: true
698
- },
699
- { name: "CreateQueryOptions" },
700
- { name: "CreateInfiniteQueryOptions" },
701
- { name: "CreateMutationOptions" },
702
- { name: "QueryFunction" },
703
- { name: "MutationFunction" },
704
- { name: "CreateQueryResult" },
705
- { name: "CreateInfiniteQueryResult" },
706
- { name: "QueryKey" },
707
- { name: "InfiniteData" },
708
- { name: "CreateMutationResult" },
709
- { name: "DataTag" },
710
- { name: "QueryClient" },
711
- { name: "InvalidateOptions" }
712
- ],
713
- dependency: "@tanstack/solid-query"
714
- }];
694
+ const getSolidQueryImports = (prefix) => {
695
+ const capitalized = prefix === "use" ? "Use" : "Create";
696
+ return [{
697
+ exports: [
698
+ {
699
+ name: `${prefix}Query`,
700
+ values: true
701
+ },
702
+ {
703
+ name: `${prefix}InfiniteQuery`,
704
+ values: true
705
+ },
706
+ {
707
+ name: `${prefix}Mutation`,
708
+ values: true
709
+ },
710
+ { name: `${capitalized}QueryOptions` },
711
+ { name: `${capitalized}InfiniteQueryOptions` },
712
+ { name: `${capitalized}MutationOptions` },
713
+ { name: "QueryFunction" },
714
+ { name: "MutationFunction" },
715
+ { name: `${capitalized}QueryResult` },
716
+ { name: `${capitalized}InfiniteQueryResult` },
717
+ { name: "QueryKey" },
718
+ { name: "InfiniteData" },
719
+ { name: `${capitalized}MutationResult` },
720
+ { name: "DataTag" },
721
+ { name: "QueryClient" },
722
+ { name: "InvalidateOptions" }
723
+ ],
724
+ dependency: "@tanstack/solid-query"
725
+ }];
726
+ };
715
727
  const ANGULAR_QUERY_DEPENDENCIES = [{
716
728
  exports: [
717
729
  {
@@ -778,7 +790,7 @@ const getSolidQueryDependencies = (hasGlobalMutator, hasParamsSerializerOptions,
778
790
  return [
779
791
  ...!hasGlobalMutator && httpClient === OutputHttpClient.AXIOS ? AXIOS_DEPENDENCIES : [],
780
792
  ...hasParamsSerializerOptions ? PARAMS_SERIALIZER_DEPENDENCIES : [],
781
- ...SOLID_QUERY_DEPENDENCIES
793
+ ...getSolidQueryImports(isSolidQueryWithUsePrefix(packageJson) ? "use" : "create")
782
794
  ];
783
795
  };
784
796
  const getAngularQueryDependencies = (hasGlobalMutator, hasParamsSerializerOptions, packageJson, httpClient) => {
@@ -811,6 +823,18 @@ const isQueryV5WithDataTagError = (packageJson, queryClient) => {
811
823
  const withoutRc = version.split("-")[0];
812
824
  return compareVersions(withoutRc, "5.62.0");
813
825
  };
826
+ const isQueryV5WithRequiredContextOnSuccess = (packageJson, queryClient) => {
827
+ const version = getPackageByQueryClient(packageJson, queryClient);
828
+ if (!version) return false;
829
+ const withoutRc = version.split("-")[0];
830
+ return compareVersions(withoutRc, "5.14.1");
831
+ };
832
+ const isQueryV5WithMutationContextOnSuccess = (packageJson, queryClient) => {
833
+ const version = getPackageByQueryClient(packageJson, queryClient);
834
+ if (!version) return false;
835
+ const withoutRc = version.split("-")[0];
836
+ return compareVersions(withoutRc, "5.89.0");
837
+ };
814
838
  const isQueryV5WithInfiniteQueryOptionsError = (packageJson, queryClient) => {
815
839
  if (queryClient === "angular-query") return true;
816
840
  const version = getPackageByQueryClient(packageJson, queryClient);
@@ -818,13 +842,34 @@ const isQueryV5WithInfiniteQueryOptionsError = (packageJson, queryClient) => {
818
842
  const withoutRc = version.split("-")[0];
819
843
  return compareVersions(withoutRc, "5.80.0");
820
844
  };
845
+ const isSolidQueryWithUsePrefix = (packageJson) => {
846
+ const version = getPackageByQueryClient(packageJson, "solid-query");
847
+ if (!version) return false;
848
+ const withoutRc = version.split("-")[0];
849
+ return compareVersions(withoutRc, "5.71.5");
850
+ };
821
851
  const getPackageByQueryClient = (packageJson, queryClient) => {
822
852
  switch (queryClient) {
823
- case "react-query": return packageJson?.dependencies?.["@tanstack/react-query"] ?? packageJson?.devDependencies?.["@tanstack/react-query"] ?? packageJson?.peerDependencies?.["@tanstack/react-query"];
824
- case "svelte-query": return packageJson?.dependencies?.["@tanstack/svelte-query"] ?? packageJson?.devDependencies?.["@tanstack/svelte-query"] ?? packageJson?.peerDependencies?.["@tanstack/svelte-query"];
825
- case "vue-query": return packageJson?.dependencies?.["@tanstack/vue-query"] ?? packageJson?.devDependencies?.["@tanstack/vue-query"] ?? packageJson?.peerDependencies?.["@tanstack/vue-query"];
826
- case "angular-query": return packageJson?.dependencies?.["@tanstack/angular-query-experimental"] ?? packageJson?.devDependencies?.["@tanstack/angular-query-experimental"] ?? packageJson?.peerDependencies?.["@tanstack/angular-query-experimental"];
827
- case "solid-query": return packageJson?.dependencies?.["@tanstack/solid-query"] ?? packageJson?.devDependencies?.["@tanstack/solid-query"] ?? packageJson?.peerDependencies?.["@tanstack/solid-query"];
853
+ case "react-query": {
854
+ const pkgName = "@tanstack/react-query";
855
+ return packageJson?.resolvedVersions?.[pkgName] ?? packageJson?.dependencies?.[pkgName] ?? packageJson?.devDependencies?.[pkgName] ?? packageJson?.peerDependencies?.[pkgName];
856
+ }
857
+ case "svelte-query": {
858
+ const pkgName = "@tanstack/svelte-query";
859
+ return packageJson?.resolvedVersions?.[pkgName] ?? packageJson?.dependencies?.[pkgName] ?? packageJson?.devDependencies?.[pkgName] ?? packageJson?.peerDependencies?.[pkgName];
860
+ }
861
+ case "vue-query": {
862
+ const pkgName = "@tanstack/vue-query";
863
+ return packageJson?.resolvedVersions?.[pkgName] ?? packageJson?.dependencies?.[pkgName] ?? packageJson?.devDependencies?.[pkgName] ?? packageJson?.peerDependencies?.[pkgName];
864
+ }
865
+ case "angular-query": {
866
+ const pkgName = "@tanstack/angular-query-experimental";
867
+ return packageJson?.resolvedVersions?.[pkgName] ?? packageJson?.dependencies?.[pkgName] ?? packageJson?.devDependencies?.[pkgName] ?? packageJson?.peerDependencies?.[pkgName];
868
+ }
869
+ case "solid-query": {
870
+ const pkgName = "@tanstack/solid-query";
871
+ return packageJson?.resolvedVersions?.[pkgName] ?? packageJson?.dependencies?.[pkgName] ?? packageJson?.devDependencies?.[pkgName] ?? packageJson?.peerDependencies?.[pkgName];
872
+ }
828
873
  }
829
874
  };
830
875
 
@@ -837,21 +882,20 @@ const QueryType = {
837
882
  SUSPENSE_INFINITE: "suspenseInfiniteQuery"
838
883
  };
839
884
  const INFINITE_QUERY_PROPERTIES = new Set(["getNextPageParam", "getPreviousPageParam"]);
840
- const generateQueryOptions = ({ params, options, type, outputClient }) => {
885
+ const generateQueryOptions = ({ params, options, type, adapter }) => {
841
886
  if (options === false) return "";
842
887
  const queryConfig = isObject(options) ? ` ${stringify(omitBy(options, (_, key) => type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE && INFINITE_QUERY_PROPERTIES.has(key)))?.slice(1, -1)}` : "";
843
888
  if (params.length === 0 || isSuspenseQuery(type)) {
844
889
  if (options) return `${queryConfig} ...queryOptions`;
845
890
  return "...queryOptions";
846
891
  }
847
- return `${!isObject(options) || !Object.hasOwn(options, "enabled") ? isVue(outputClient) ? `enabled: computed(() => !!(${params.map(({ name }) => `unref(${name})`).join(" && ")})),` : `enabled: !!(${params.map(({ name }) => name).join(" && ")}),` : ""}${queryConfig} ...queryOptions`;
892
+ return `${adapter ? adapter.generateEnabledOption(params, options) : !isObject(options) || !Object.hasOwn(options, "enabled") ? `enabled: !!(${params.map(({ name }) => name).join(" && ")}),` : ""}${queryConfig} ...queryOptions`;
848
893
  };
849
894
  const isSuspenseQuery = (type) => {
850
895
  return [QueryType.SUSPENSE_INFINITE, QueryType.SUSPENSE_QUERY].includes(type);
851
896
  };
852
- const getQueryOptionsDefinition = ({ operationName, mutator, definitions, type, hasSvelteQueryV4, hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError, queryParams, queryParam, isReturnType, initialData, isAngularClient }) => {
897
+ const getQueryOptionsDefinition = ({ operationName, mutator, definitions, type, prefix, hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError, queryParams, queryParam, isReturnType, initialData }) => {
853
898
  const isMutatorHook = mutator?.isHook;
854
- const prefix = !hasSvelteQueryV4 && !isAngularClient ? "Use" : "Create";
855
899
  const partialOptions = !isReturnType && hasQueryV5;
856
900
  if (type) {
857
901
  const funcReturnType = `Awaited<ReturnType<${isMutatorHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>`;
@@ -867,109 +911,560 @@ const getQueryOptionsDefinition = ({ operationName, mutator, definitions, type,
867
911
  }
868
912
  return `${prefix}MutationOptions<Awaited<ReturnType<${isMutatorHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>, TError,${definitions ? `{${definitions}}` : "void"}, TContext>`;
869
913
  };
870
- const generateQueryArguments = ({ operationName, definitions, mutator, isRequestOptions, type, hasSvelteQueryV4, hasSvelteQueryV6, hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError, queryParams, queryParam, initialData, httpClient, isAngularClient, forQueryOptions = false, forAngularInject = false }) => {
871
- const definition = getQueryOptionsDefinition({
872
- operationName,
873
- mutator,
874
- definitions,
875
- type,
876
- hasSvelteQueryV4,
877
- hasQueryV5,
878
- hasQueryV5WithInfiniteQueryOptionsError,
879
- queryParams,
880
- queryParam,
881
- isReturnType: false,
882
- initialData,
883
- isAngularClient
884
- });
885
- if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
886
- const requestType = getQueryArgumentsRequestType(httpClient, mutator);
887
- const isQueryRequired = initialData === "defined";
888
- const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${requestType}}`;
889
- if (forAngularInject) return `options${isQueryRequired ? "" : "?"}: ${optionsType} | (() => ${optionsType})\n`;
890
- return `options${isQueryRequired ? "" : "?"}: ${hasSvelteQueryV6 && !forQueryOptions ? "() => " : ""}${optionsType}\n`;
891
- };
892
914
 
893
915
  //#endregion
894
- //#region src/return-types.ts
895
- const generateQueryReturnType = ({ outputClient, type, isMutatorHook, operationName, hasVueQueryV4, hasSvelteQueryV4, hasQueryV5, hasQueryV5WithDataTagError, isInitialDataDefined }) => {
896
- switch (outputClient) {
897
- case OutputClient.ANGULAR_QUERY:
916
+ //#region src/frameworks/angular.ts
917
+ const createAngularAdapter = ({ hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, hasQueryV5WithMutationContextOnSuccess, hasQueryV5WithRequiredContextOnSuccess }) => {
918
+ const prefix = "Create";
919
+ return {
920
+ outputClient: OutputClient.ANGULAR_QUERY,
921
+ hookPrefix: "inject",
922
+ isAngularHttp: true,
923
+ hasQueryV5,
924
+ hasQueryV5WithDataTagError,
925
+ hasQueryV5WithInfiniteQueryOptionsError,
926
+ hasQueryV5WithMutationContextOnSuccess,
927
+ hasQueryV5WithRequiredContextOnSuccess,
928
+ getHookPropsDefinitions(props) {
929
+ return toObjectString(props.map((prop) => {
930
+ const getterType = prop.definition.replace(/^(\w+)(\??): (.+)$/, (_match, name, optional, type) => `${name}${optional}: ${type} | (() => ${type.replace(" | undefined", "")}${optional ? " | undefined" : ""})`);
931
+ return {
932
+ ...prop,
933
+ definition: getterType
934
+ };
935
+ }), "definition");
936
+ },
937
+ getHttpFunctionQueryProps(queryProperties, _httpClient, hasMutator) {
938
+ if (!hasMutator) return queryProperties ? `http, ${queryProperties}` : "http";
939
+ return queryProperties;
940
+ },
941
+ getInfiniteQueryHttpProps(props, queryParam, hasMutator) {
942
+ let result = props.map((param) => {
943
+ if (param.type === GetterPropType.NAMED_PATH_PARAMS) return param.destructured;
944
+ return param.name === "params" ? `{...params, '${queryParam}': pageParam || params?.['${queryParam}']}` : param.name;
945
+ }).join(",");
946
+ if (!hasMutator) result = result ? `http, ${result}` : "http";
947
+ return result;
948
+ },
949
+ getHttpFirstParam(mutator) {
950
+ if (!mutator || mutator.hasSecondArg) return "http: HttpClient, ";
951
+ return "";
952
+ },
953
+ getMutationHttpPrefix(mutator) {
954
+ if (!mutator) return "http, ";
955
+ return "";
956
+ },
957
+ getQueryReturnType({ type }) {
898
958
  if (type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE) return `CreateQueryResult<TData, TError>`;
899
959
  return `CreateInfiniteQueryResult<TData, TError>`;
900
- case OutputClient.SOLID_QUERY:
901
- if (type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE) return `CreateQueryResult<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
902
- return `CreateInfiniteQueryResult<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
903
- case OutputClient.SVELTE_QUERY:
904
- if (!hasSvelteQueryV4) return `Use${pascal(type)}StoreResult<Awaited<ReturnType<${isMutatorHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>, TError, TData, QueryKey> & { queryKey: QueryKey }`;
905
- return `Create${pascal(type)}Result<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
906
- case OutputClient.VUE_QUERY:
907
- if (!hasVueQueryV4) return ` UseQueryReturnType<TData, TError, Use${pascal(type)}Result<TData, TError>> & { queryKey: QueryKey }`;
908
- if (type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE) return `UseQueryReturnType<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
909
- return `UseInfiniteQueryReturnType<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
910
- default: return ` ${isInitialDataDefined && !isSuspenseQuery(type) ? "Defined" : ""}Use${pascal(type)}Result<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
911
- }
912
- };
913
- const generateMutatorReturnType = ({ outputClient, dataType, variableType }) => {
914
- if (outputClient === OutputClient.ANGULAR_QUERY) return `: CreateMutationResult<
960
+ },
961
+ getMutationReturnType({ dataType, variableType }) {
962
+ return `: CreateMutationResult<
915
963
  Awaited<ReturnType<${dataType}>>,
916
964
  TError,
917
965
  ${variableType},
918
966
  TContext
919
967
  >`;
920
- if (outputClient === OutputClient.REACT_QUERY) return `: UseMutationResult<
968
+ },
969
+ getQueryReturnStatement({ queryResultVarName }) {
970
+ return `return ${queryResultVarName};`;
971
+ },
972
+ shouldAnnotateQueryKey() {
973
+ return false;
974
+ },
975
+ generateQueryInit({ mutator }) {
976
+ if (!mutator || mutator.hasSecondArg) return `const http = inject(HttpClient);`;
977
+ return "";
978
+ },
979
+ generateQueryInvocationArgs({ props, queryOptionsFnName, isRequestOptions, mutator }) {
980
+ return `() => {${props.length > 0 ? `
981
+ // Resolve params if getter function (for signal reactivity)
982
+ ${props.map((p) => `const _${p.name} = typeof ${p.name} === 'function' ? ${p.name}() : ${p.name};`).join("\n ")}` : ""}
983
+ // Resolve options if getter function (for signal reactivity)
984
+ const _options = typeof ${isRequestOptions ? "options" : "queryOptions"} === 'function' ? ${isRequestOptions ? "options" : "queryOptions"}() : ${isRequestOptions ? "options" : "queryOptions"};
985
+ return ${queryOptionsFnName}(${!mutator || mutator.hasSecondArg ? "http" : ""}${props.length > 0 ? `${!mutator || mutator.hasSecondArg ? ", " : ""}${props.map((p) => `_${p.name}`).join(", ")}` : ""}, _options);
986
+ }`;
987
+ },
988
+ getOptionalQueryClientArgument() {
989
+ return "";
990
+ },
991
+ getQueryOptionsDefinitionPrefix() {
992
+ return prefix;
993
+ },
994
+ generateQueryArguments({ operationName, definitions, mutator, isRequestOptions, type, queryParams, queryParam, initialData, httpClient, forQueryOptions = false, hasInvalidation }) {
995
+ const definition = getQueryOptionsDefinition({
996
+ operationName,
997
+ mutator,
998
+ definitions,
999
+ type,
1000
+ prefix,
1001
+ hasQueryV5,
1002
+ hasQueryV5WithInfiniteQueryOptionsError,
1003
+ queryParams,
1004
+ queryParam,
1005
+ isReturnType: false,
1006
+ initialData
1007
+ });
1008
+ if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
1009
+ const requestType = getQueryArgumentsRequestType(httpClient, mutator);
1010
+ const isQueryRequired = initialData === "defined";
1011
+ const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1012
+ if (type !== void 0 && !forQueryOptions) return `options${isQueryRequired ? "" : "?"}: ${optionsType} | (() => ${optionsType})\n`;
1013
+ return `options${isQueryRequired ? "" : "?"}: ${optionsType}\n`;
1014
+ },
1015
+ generateMutationImplementation({ mutationOptionsFnName, hasInvalidation, isRequestOptions }) {
1016
+ return `${mutationOptionsFnName}(${hasInvalidation ? `queryClient, ` : ""}${isRequestOptions ? "options" : "mutationOptions"})`;
1017
+ },
1018
+ supportsMutationInvalidation() {
1019
+ return true;
1020
+ },
1021
+ generateMutationHookBody({ operationPrefix, mutationOptionsFnName, mutationOptionsVarName, isRequestOptions, mutator, hasInvalidation }) {
1022
+ if (!mutator || mutator.hasSecondArg) return ` const http = inject(HttpClient);${hasInvalidation ? "\n const queryClient = inject(QueryClient);" : ""}
1023
+ const ${mutationOptionsVarName} = ${mutationOptionsFnName}(http${hasInvalidation ? ", queryClient" : ""}${isRequestOptions ? ", options" : ", mutationOptions"});
1024
+
1025
+ return ${operationPrefix}Mutation(() => ${mutationOptionsVarName});`;
1026
+ return ` const ${mutationOptionsVarName} = ${`${mutationOptionsFnName}(${hasInvalidation ? `queryClient, ` : ""}${isRequestOptions ? "options" : "mutationOptions"})`};
1027
+
1028
+ return ${operationPrefix}Mutation(() => ${mutationOptionsVarName});`;
1029
+ },
1030
+ getQueryType(type) {
1031
+ return getQueryTypeForFramework(type);
1032
+ },
1033
+ generateRequestFunction(verbOptions, options) {
1034
+ return generateAngularHttpRequestFunction(verbOptions, options);
1035
+ }
1036
+ };
1037
+ };
1038
+
1039
+ //#endregion
1040
+ //#region src/frameworks/react.ts
1041
+ const createReactAdapter = ({ hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, hasQueryV5WithMutationContextOnSuccess, hasQueryV5WithRequiredContextOnSuccess }) => ({
1042
+ outputClient: OutputClient.REACT_QUERY,
1043
+ hookPrefix: "use",
1044
+ hasQueryV5,
1045
+ hasQueryV5WithDataTagError,
1046
+ hasQueryV5WithInfiniteQueryOptionsError,
1047
+ hasQueryV5WithMutationContextOnSuccess,
1048
+ hasQueryV5WithRequiredContextOnSuccess,
1049
+ getQueryReturnType({ type, isInitialDataDefined }) {
1050
+ return ` ${isInitialDataDefined && !isSuspenseQuery(type) ? "Defined" : ""}Use${pascal(type)}Result<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
1051
+ },
1052
+ getMutationReturnType({ dataType, variableType }) {
1053
+ return `: UseMutationResult<
921
1054
  Awaited<ReturnType<${dataType}>>,
922
1055
  TError,
923
1056
  ${variableType},
924
1057
  TContext
925
1058
  >`;
926
- if (outputClient === OutputClient.SOLID_QUERY) return `: CreateMutationResult<
1059
+ },
1060
+ getQueryReturnStatement({ queryResultVarName, queryOptionsVarName }) {
1061
+ return `return { ...${queryResultVarName}, queryKey: ${queryOptionsVarName}.queryKey };`;
1062
+ },
1063
+ shouldGenerateOverrideTypes() {
1064
+ return hasQueryV5;
1065
+ },
1066
+ generateMutationImplementation({ mutationOptionsFnName, hasInvalidation, isRequestOptions }) {
1067
+ return `${mutationOptionsFnName}(${hasInvalidation ? `queryClient ?? backupQueryClient, ` : ""}${isRequestOptions ? "options" : "mutationOptions"})`;
1068
+ },
1069
+ supportsMutationInvalidation() {
1070
+ return true;
1071
+ },
1072
+ generateMutationHookBody({ operationPrefix, mutationImplementation, hasInvalidation, optionalQueryClientArgument }) {
1073
+ return ` ${hasInvalidation ? `const backupQueryClient = useQueryClient();\n ` : ""}return ${operationPrefix}Mutation(${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""});`;
1074
+ },
1075
+ generateRequestFunction(verbOptions, options) {
1076
+ return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1077
+ }
1078
+ });
1079
+
1080
+ //#endregion
1081
+ //#region src/frameworks/solid.ts
1082
+ const createSolidAdapter = ({ hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, hasQueryV5WithMutationContextOnSuccess, hasQueryV5WithRequiredContextOnSuccess, hasSolidQueryUsePrefix }) => ({
1083
+ outputClient: OutputClient.SOLID_QUERY,
1084
+ hookPrefix: hasSolidQueryUsePrefix ? "use" : "create",
1085
+ hasQueryV5,
1086
+ hasQueryV5WithDataTagError,
1087
+ hasQueryV5WithInfiniteQueryOptionsError,
1088
+ hasQueryV5WithMutationContextOnSuccess,
1089
+ hasQueryV5WithRequiredContextOnSuccess,
1090
+ getQueryOptionsDefinitionPrefix() {
1091
+ return hasSolidQueryUsePrefix ? "Use" : "Create";
1092
+ },
1093
+ getQueryReturnType({ type }) {
1094
+ const prefix = hasSolidQueryUsePrefix ? "Use" : "Create";
1095
+ const queryKeyType = hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey";
1096
+ if (type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE) return `${prefix}QueryResult<TData, TError> & { queryKey: ${queryKeyType} }`;
1097
+ return `${prefix}InfiniteQueryResult<TData, TError> & { queryKey: ${queryKeyType} }`;
1098
+ },
1099
+ getMutationReturnType({ dataType, variableType }) {
1100
+ return `: ${hasSolidQueryUsePrefix ? "Use" : "Create"}MutationResult<
927
1101
  Awaited<ReturnType<${dataType}>>,
928
1102
  TError,
929
1103
  ${variableType},
930
1104
  TContext
931
1105
  >`;
932
- if (outputClient === OutputClient.SVELTE_QUERY) return `: CreateMutationResult<
1106
+ },
1107
+ getQueryReturnStatement({ queryResultVarName, queryOptionsVarName }) {
1108
+ return `return { ...${queryResultVarName}, queryKey: ${queryOptionsVarName}.queryKey };`;
1109
+ },
1110
+ generateMutationImplementation({ mutationOptionsFnName, isRequestOptions }) {
1111
+ return `${mutationOptionsFnName}(${isRequestOptions ? "options" : "mutationOptions"})`;
1112
+ },
1113
+ supportsMutationInvalidation() {
1114
+ return false;
1115
+ },
1116
+ generateMutationOnSuccess() {
1117
+ return "";
1118
+ },
1119
+ generateMutationHookBody({ operationPrefix, mutationImplementation, optionalQueryClientArgument }) {
1120
+ return ` return ${operationPrefix}Mutation(${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""});`;
1121
+ },
1122
+ generateRequestFunction(verbOptions, options) {
1123
+ return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1124
+ }
1125
+ });
1126
+
1127
+ //#endregion
1128
+ //#region src/frameworks/svelte.ts
1129
+ const createSvelteAdapter = ({ hasSvelteQueryV4, hasSvelteQueryV6, hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, hasQueryV5WithMutationContextOnSuccess, hasQueryV5WithRequiredContextOnSuccess }) => {
1130
+ const prefix = hasSvelteQueryV4 ? "Create" : "Use";
1131
+ return {
1132
+ outputClient: OutputClient.SVELTE_QUERY,
1133
+ hookPrefix: hasSvelteQueryV4 ? "create" : "use",
1134
+ hasQueryV5,
1135
+ hasQueryV5WithDataTagError,
1136
+ hasQueryV5WithInfiniteQueryOptionsError,
1137
+ hasQueryV5WithMutationContextOnSuccess,
1138
+ hasQueryV5WithRequiredContextOnSuccess,
1139
+ getHookPropsDefinitions(props) {
1140
+ if (hasSvelteQueryV6) return toObjectString(props.map((p) => ({
1141
+ ...p,
1142
+ definition: p.definition.replace(":", ": () => ")
1143
+ })), "definition");
1144
+ return toObjectString(props, "implementation");
1145
+ },
1146
+ getQueryReturnType({ type, isMutatorHook, operationName }) {
1147
+ if (!hasSvelteQueryV4) return `Use${pascal(type)}StoreResult<Awaited<ReturnType<${isMutatorHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>, TError, TData, QueryKey> & { queryKey: QueryKey }`;
1148
+ return `Create${pascal(type)}Result<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
1149
+ },
1150
+ getMutationReturnType({ dataType, variableType }) {
1151
+ return `: CreateMutationResult<
933
1152
  Awaited<ReturnType<${dataType}>>,
934
1153
  TError,
935
1154
  ${variableType},
936
1155
  TContext
937
1156
  >`;
938
- if (outputClient === OutputClient.VUE_QUERY) return `: UseMutationReturnType<
1157
+ },
1158
+ getQueryReturnStatement({ queryResultVarName, queryOptionsVarName }) {
1159
+ if (hasSvelteQueryV6) return `return ${queryResultVarName}`;
1160
+ if (hasSvelteQueryV4) return `${queryResultVarName}.queryKey = ${queryOptionsVarName}.queryKey;
1161
+
1162
+ return ${queryResultVarName};`;
1163
+ return `return { ...${queryResultVarName}, queryKey: ${queryOptionsVarName}.queryKey };`;
1164
+ },
1165
+ generateQueryInit({ queryOptionsFnName, queryProperties, isRequestOptions }) {
1166
+ if (hasSvelteQueryV6) return "";
1167
+ return `const ${isRequestOptions ? "queryOptions" : "options"} = ${queryOptionsFnName}(${queryProperties}${queryProperties ? "," : ""}${isRequestOptions ? "options" : "queryOptions"})`;
1168
+ },
1169
+ generateQueryInvocationArgs({ props, queryOptionsFnName, isRequestOptions, queryOptionsVarName, optionalQueryClientArgument }) {
1170
+ if (hasSvelteQueryV6) return `() => ${queryOptionsFnName}(${toObjectString(props.map((p) => ({
1171
+ ...p,
1172
+ name: p.default || !p.required ? `${p.name}?.()` : `${p.name}()`
1173
+ })), "name")}${isRequestOptions ? "options?.()" : "queryOptions?.()"})`;
1174
+ return `${queryOptionsVarName}${optionalQueryClientArgument ? ", queryClient" : ""}`;
1175
+ },
1176
+ getQueryInvocationSuffix() {
1177
+ return hasSvelteQueryV6 ? `, queryClient` : "";
1178
+ },
1179
+ getOptionalQueryClientArgument(hasInvalidation) {
1180
+ if (hasSvelteQueryV6) return `, queryClient?: () => QueryClient`;
1181
+ if (hasQueryV5 || hasInvalidation) return ", queryClient?: QueryClient";
1182
+ return "";
1183
+ },
1184
+ getQueryOptionsDefinitionPrefix() {
1185
+ return prefix;
1186
+ },
1187
+ generateQueryArguments({ operationName, definitions, mutator, isRequestOptions, type, queryParams, queryParam, initialData, httpClient, forQueryOptions = false, hasInvalidation }) {
1188
+ const definition = getQueryOptionsDefinition({
1189
+ operationName,
1190
+ mutator,
1191
+ definitions,
1192
+ type,
1193
+ prefix,
1194
+ hasQueryV5,
1195
+ hasQueryV5WithInfiniteQueryOptionsError,
1196
+ queryParams,
1197
+ queryParam,
1198
+ isReturnType: false,
1199
+ initialData
1200
+ });
1201
+ if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
1202
+ const requestType = getQueryArgumentsRequestType(httpClient, mutator);
1203
+ const isQueryRequired = initialData === "defined";
1204
+ const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1205
+ return `options${isQueryRequired ? "" : "?"}: ${hasSvelteQueryV6 && !forQueryOptions ? "() => " : ""}${optionsType}\n`;
1206
+ },
1207
+ generateMutationImplementation({ mutationOptionsFnName, hasInvalidation, isRequestOptions }) {
1208
+ if (hasSvelteQueryV6) return `${mutationOptionsFnName}(${hasInvalidation ? `backupQueryClient, ` : ""}${isRequestOptions ? "options" : "mutationOptions"}?.())`;
1209
+ return `${mutationOptionsFnName}(${hasInvalidation ? `queryClient ?? backupQueryClient, ` : ""}${isRequestOptions ? "options" : "mutationOptions"})`;
1210
+ },
1211
+ supportsMutationInvalidation() {
1212
+ return true;
1213
+ },
1214
+ generateMutationHookBody({ operationPrefix, mutationImplementation, hasInvalidation, optionalQueryClientArgument }) {
1215
+ if (hasSvelteQueryV6) return ` ${hasInvalidation ? `const backupQueryClient = useQueryClient(${optionalQueryClientArgument ? "queryClient?.()" : ""});\n ` : ""}return ${operationPrefix}Mutation(() => ({ ...${mutationImplementation} })${optionalQueryClientArgument ? `, queryClient` : ""});`;
1216
+ return ` ${hasInvalidation ? `const backupQueryClient = useQueryClient();\n ` : ""}return ${operationPrefix}Mutation(${mutationImplementation});`;
1217
+ },
1218
+ getQueryType(type) {
1219
+ if (hasSvelteQueryV4) return getQueryTypeForFramework(type);
1220
+ return type;
1221
+ },
1222
+ generateRequestFunction(verbOptions, options) {
1223
+ return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, false) : generateRequestFunction(verbOptions, options);
1224
+ }
1225
+ };
1226
+ };
1227
+
1228
+ //#endregion
1229
+ //#region src/frameworks/vue.ts
1230
+ const createVueAdapter = ({ hasVueQueryV4, hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, hasQueryV5WithMutationContextOnSuccess, hasQueryV5WithRequiredContextOnSuccess }) => ({
1231
+ outputClient: OutputClient.VUE_QUERY,
1232
+ hookPrefix: "use",
1233
+ hasQueryV5,
1234
+ hasQueryV5WithDataTagError,
1235
+ hasQueryV5WithInfiniteQueryOptionsError,
1236
+ hasQueryV5WithMutationContextOnSuccess,
1237
+ hasQueryV5WithRequiredContextOnSuccess,
1238
+ transformProps(props) {
1239
+ return vueWrapTypeWithMaybeRef(props);
1240
+ },
1241
+ shouldDestructureNamedPathParams() {
1242
+ return false;
1243
+ },
1244
+ getHttpFunctionQueryProps(queryProperties, httpClient) {
1245
+ if (httpClient === OutputHttpClient.FETCH && queryProperties) return queryProperties.split(",").map((prop) => `unref(${prop})`).join(",");
1246
+ return queryProperties;
1247
+ },
1248
+ getInfiniteQueryHttpProps(props, queryParam) {
1249
+ return props.map((param) => {
1250
+ return param.name === "params" ? `{...unref(params), '${queryParam}': pageParam || unref(params)?.['${queryParam}']}` : param.name;
1251
+ }).join(",");
1252
+ },
1253
+ getQueryReturnType({ type }) {
1254
+ if (!hasVueQueryV4) return ` UseQueryReturnType<TData, TError, Use${pascal(type)}Result<TData, TError>> & { queryKey: QueryKey }`;
1255
+ if (type !== QueryType.INFINITE && type !== QueryType.SUSPENSE_INFINITE) return `UseQueryReturnType<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
1256
+ return `UseInfiniteQueryReturnType<TData, TError> & { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`;
1257
+ },
1258
+ getMutationReturnType({ dataType, variableType }) {
1259
+ return `: UseMutationReturnType<
939
1260
  Awaited<ReturnType<${dataType}>>,
940
1261
  TError,
941
1262
  ${variableType},
942
1263
  TContext
943
1264
  >`;
944
- return "";
945
- };
946
- const getQueryFnArguments = ({ hasQueryParam, hasSignal, hasSignalParam = false }) => {
947
- if (!hasQueryParam && !hasSignal) return "";
948
- const signalDestructure = hasSignalParam ? "signal: querySignal" : "signal";
949
- if (hasQueryParam) {
950
- if (hasSignal) return `{ ${signalDestructure}, pageParam }`;
951
- return "{ pageParam }";
952
- }
953
- return `{ ${signalDestructure} }`;
954
- };
955
- const getQueryReturnStatement = ({ outputClient, hasSvelteQueryV4, hasSvelteQueryV6, hasQueryV5, hasQueryV5WithDataTagError, queryResultVarName, queryOptionsVarName }) => {
956
- if (isAngular(outputClient)) return `return ${queryResultVarName};`;
957
- if (isVue(outputClient)) return `${queryResultVarName}.queryKey = unref(${queryOptionsVarName}).queryKey as ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"};
1265
+ },
1266
+ getQueryReturnStatement({ queryResultVarName, queryOptionsVarName }) {
1267
+ return `${queryResultVarName}.queryKey = unref(${queryOptionsVarName}).queryKey as ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"};
958
1268
 
959
1269
  return ${queryResultVarName};`;
960
- if (hasSvelteQueryV6) return `return ${queryResultVarName}`;
961
- if (hasSvelteQueryV4) return `${queryResultVarName}.queryKey = ${queryOptionsVarName}.queryKey;
1270
+ },
1271
+ getQueryKeyRouteString(route) {
1272
+ return getRouteAsArray(route);
1273
+ },
1274
+ shouldAnnotateQueryKey() {
1275
+ return false;
1276
+ },
1277
+ getUnrefStatements(props) {
1278
+ return vueUnRefParams(props.filter((prop) => prop.type === GetterPropType.NAMED_PATH_PARAMS));
1279
+ },
1280
+ generateEnabledOption(params, options) {
1281
+ if (!isObject(options) || !Object.hasOwn(options, "enabled")) return `enabled: computed(() => !!(${params.map(({ name }) => `unref(${name})`).join(" && ")})),`;
1282
+ return "";
1283
+ },
1284
+ getQueryKeyPrefix() {
1285
+ return hasVueQueryV4 ? "" : "queryOptions?.queryKey ?? ";
1286
+ },
1287
+ generateMutationImplementation({ mutationOptionsFnName, isRequestOptions }) {
1288
+ return `${mutationOptionsFnName}(${isRequestOptions ? "options" : "mutationOptions"})`;
1289
+ },
1290
+ supportsMutationInvalidation() {
1291
+ return false;
1292
+ },
1293
+ generateMutationOnSuccess() {
1294
+ return "";
1295
+ },
1296
+ generateMutationHookBody({ operationPrefix, mutationImplementation, optionalQueryClientArgument }) {
1297
+ return ` return ${operationPrefix}Mutation(${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""});`;
1298
+ },
1299
+ generateRequestFunction(verbOptions, options) {
1300
+ return options.context.output.httpClient === OutputHttpClient.AXIOS ? generateAxiosRequestFunction(verbOptions, options, true) : generateRequestFunction(verbOptions, options);
1301
+ },
1302
+ getQueryPropertyForProp(prop, body) {
1303
+ return prop.type === GetterPropType.BODY ? body.implementation : prop.name;
1304
+ }
1305
+ });
962
1306
 
963
- return ${queryResultVarName};`;
964
- return `return { ...${queryResultVarName}, queryKey: ${queryOptionsVarName}.queryKey };`;
1307
+ //#endregion
1308
+ //#region src/frameworks/index.ts
1309
+ /** Fill in defaults for fields that most adapters leave empty or share a common implementation. */
1310
+ const withDefaults = (adapter) => ({
1311
+ isAngularHttp: false,
1312
+ getHttpFirstParam: () => "",
1313
+ getMutationHttpPrefix: () => "",
1314
+ getUnrefStatements: () => "",
1315
+ getQueryInvocationSuffix: () => "",
1316
+ transformProps: (props) => props,
1317
+ getHttpFunctionQueryProps: (qp) => qp,
1318
+ getQueryType: (type) => type,
1319
+ shouldDestructureNamedPathParams: () => true,
1320
+ shouldAnnotateQueryKey: () => true,
1321
+ shouldGenerateOverrideTypes: () => false,
1322
+ getQueryKeyPrefix: () => "queryOptions?.queryKey ?? ",
1323
+ getQueryOptionsDefinitionPrefix: () => "Use",
1324
+ getHookPropsDefinitions: (props) => toObjectString(props, "implementation"),
1325
+ getQueryKeyRouteString(route, shouldSplitQueryKey) {
1326
+ if (shouldSplitQueryKey) return getRouteAsArray(route);
1327
+ return `\`${route}\``;
1328
+ },
1329
+ generateEnabledOption(params, options) {
1330
+ if (!isObject(options) || !Object.hasOwn(options, "enabled")) return `enabled: !!(${params.map(({ name }) => name).join(" && ")}),`;
1331
+ return "";
1332
+ },
1333
+ getQueryPropertyForProp(prop, body) {
1334
+ if (prop.type === GetterPropType.NAMED_PATH_PARAMS) return prop.destructured;
1335
+ return prop.type === GetterPropType.BODY ? body.implementation : prop.name;
1336
+ },
1337
+ getInfiniteQueryHttpProps(props, queryParam) {
1338
+ return props.map((param) => {
1339
+ if (param.type === GetterPropType.NAMED_PATH_PARAMS) return param.destructured;
1340
+ return param.name === "params" ? `{...params, '${queryParam}': pageParam || params?.['${queryParam}']}` : param.name;
1341
+ }).join(",");
1342
+ },
1343
+ generateQueryInit({ queryOptionsFnName, queryProperties, isRequestOptions }) {
1344
+ return `const ${isRequestOptions ? "queryOptions" : "options"} = ${queryOptionsFnName}(${queryProperties}${queryProperties ? "," : ""}${isRequestOptions ? "options" : "queryOptions"})`;
1345
+ },
1346
+ generateQueryInvocationArgs({ queryOptionsVarName, optionalQueryClientArgument }) {
1347
+ return `${queryOptionsVarName}${optionalQueryClientArgument ? ", queryClient" : ""}`;
1348
+ },
1349
+ getOptionalQueryClientArgument() {
1350
+ return adapter.hasQueryV5 ? ", queryClient?: QueryClient" : "";
1351
+ },
1352
+ generateQueryArguments({ operationName, definitions, mutator, isRequestOptions, type, queryParams, queryParam, initialData, httpClient, hasInvalidation }) {
1353
+ const definition = getQueryOptionsDefinition({
1354
+ operationName,
1355
+ mutator,
1356
+ definitions,
1357
+ type,
1358
+ prefix: adapter.getQueryOptionsDefinitionPrefix?.() ?? "Use",
1359
+ hasQueryV5: adapter.hasQueryV5,
1360
+ hasQueryV5WithInfiniteQueryOptionsError: adapter.hasQueryV5WithInfiniteQueryOptionsError,
1361
+ queryParams,
1362
+ queryParam,
1363
+ isReturnType: false,
1364
+ initialData
1365
+ });
1366
+ if (!isRequestOptions) return `${type ? "queryOptions" : "mutationOptions"}${initialData === "defined" ? "" : "?"}: ${definition}`;
1367
+ const requestType = getQueryArgumentsRequestType(httpClient, mutator);
1368
+ const isQueryRequired = initialData === "defined";
1369
+ const optionsType = `{ ${type ? "query" : "mutation"}${isQueryRequired ? "" : "?"}:${definition}, ${!type && hasInvalidation ? "skipInvalidation?: boolean, " : ""}${requestType}}`;
1370
+ return `options${isQueryRequired ? "" : "?"}: ${optionsType}\n`;
1371
+ },
1372
+ generateMutationOnSuccess({ operationName, definitions, isRequestOptions, generateInvalidateCall: generateInvalidateCall$1, uniqueInvalidates }) {
1373
+ const invalidateCalls = uniqueInvalidates.map((t) => generateInvalidateCall$1(t)).join("\n");
1374
+ if (adapter.hasQueryV5WithMutationContextOnSuccess) {
1375
+ if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1376
+ if (!options?.skipInvalidation) {
1377
+ ${invalidateCalls}
1378
+ }
1379
+ mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1380
+ };`;
1381
+ return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1382
+ ${invalidateCalls}
1383
+ mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1384
+ };`;
1385
+ } else {
1386
+ if (isRequestOptions) return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${adapter.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1387
+ if (!options?.skipInvalidation) {
1388
+ ${invalidateCalls}
1389
+ }
1390
+ mutationOptions?.onSuccess?.(data, variables, context);
1391
+ };`;
1392
+ return ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext${adapter.hasQueryV5WithRequiredContextOnSuccess ? "" : " | undefined"}) => {
1393
+ ${invalidateCalls}
1394
+ mutationOptions?.onSuccess?.(data, variables, context);
1395
+ };`;
1396
+ }
1397
+ },
1398
+ ...adapter
1399
+ });
1400
+ /**
1401
+ * Create a FrameworkAdapter for the given output client, resolving version flags
1402
+ * from the packageJson and query config.
1403
+ */
1404
+ const createFrameworkAdapter = ({ outputClient, packageJson, queryVersion }) => {
1405
+ const clientType = outputClient;
1406
+ const _hasQueryV5 = queryVersion === 5 || isQueryV5(packageJson, clientType);
1407
+ const _hasQueryV5WithDataTagError = queryVersion === 5 || isQueryV5WithDataTagError(packageJson, clientType);
1408
+ const _hasQueryV5WithInfiniteQueryOptionsError = queryVersion === 5 || isQueryV5WithInfiniteQueryOptionsError(packageJson, clientType);
1409
+ const _hasQueryV5WithMutationContextOnSuccess = isQueryV5WithMutationContextOnSuccess(packageJson, clientType);
1410
+ const _hasQueryV5WithRequiredContextOnSuccess = isQueryV5WithRequiredContextOnSuccess(packageJson, clientType);
1411
+ switch (outputClient) {
1412
+ case OutputClient.VUE_QUERY: return withDefaults(createVueAdapter({
1413
+ hasVueQueryV4: !isVueQueryV3(packageJson) || queryVersion === 4,
1414
+ hasQueryV5: _hasQueryV5,
1415
+ hasQueryV5WithDataTagError: _hasQueryV5WithDataTagError,
1416
+ hasQueryV5WithInfiniteQueryOptionsError: _hasQueryV5WithInfiniteQueryOptionsError,
1417
+ hasQueryV5WithMutationContextOnSuccess: _hasQueryV5WithMutationContextOnSuccess,
1418
+ hasQueryV5WithRequiredContextOnSuccess: _hasQueryV5WithRequiredContextOnSuccess
1419
+ }));
1420
+ case OutputClient.SVELTE_QUERY: return withDefaults(createSvelteAdapter({
1421
+ hasSvelteQueryV4: !isSvelteQueryV3(packageJson) || queryVersion === 4,
1422
+ hasSvelteQueryV6: isSvelteQueryV6(packageJson),
1423
+ hasQueryV5: _hasQueryV5,
1424
+ hasQueryV5WithDataTagError: _hasQueryV5WithDataTagError,
1425
+ hasQueryV5WithInfiniteQueryOptionsError: _hasQueryV5WithInfiniteQueryOptionsError,
1426
+ hasQueryV5WithMutationContextOnSuccess: _hasQueryV5WithMutationContextOnSuccess,
1427
+ hasQueryV5WithRequiredContextOnSuccess: _hasQueryV5WithRequiredContextOnSuccess
1428
+ }));
1429
+ case OutputClient.ANGULAR_QUERY: return withDefaults(createAngularAdapter({
1430
+ hasQueryV5: _hasQueryV5,
1431
+ hasQueryV5WithDataTagError: _hasQueryV5WithDataTagError,
1432
+ hasQueryV5WithInfiniteQueryOptionsError: _hasQueryV5WithInfiniteQueryOptionsError,
1433
+ hasQueryV5WithMutationContextOnSuccess: _hasQueryV5WithMutationContextOnSuccess,
1434
+ hasQueryV5WithRequiredContextOnSuccess: _hasQueryV5WithRequiredContextOnSuccess
1435
+ }));
1436
+ case OutputClient.SOLID_QUERY: return withDefaults(createSolidAdapter({
1437
+ hasQueryV5: _hasQueryV5,
1438
+ hasQueryV5WithDataTagError: _hasQueryV5WithDataTagError,
1439
+ hasQueryV5WithInfiniteQueryOptionsError: _hasQueryV5WithInfiniteQueryOptionsError,
1440
+ hasQueryV5WithMutationContextOnSuccess: _hasQueryV5WithMutationContextOnSuccess,
1441
+ hasQueryV5WithRequiredContextOnSuccess: _hasQueryV5WithRequiredContextOnSuccess,
1442
+ hasSolidQueryUsePrefix: isSolidQueryWithUsePrefix(packageJson)
1443
+ }));
1444
+ default: return withDefaults(createReactAdapter({
1445
+ hasQueryV5: _hasQueryV5,
1446
+ hasQueryV5WithDataTagError: _hasQueryV5WithDataTagError,
1447
+ hasQueryV5WithInfiniteQueryOptionsError: _hasQueryV5WithInfiniteQueryOptionsError,
1448
+ hasQueryV5WithMutationContextOnSuccess: _hasQueryV5WithMutationContextOnSuccess,
1449
+ hasQueryV5WithRequiredContextOnSuccess: _hasQueryV5WithRequiredContextOnSuccess
1450
+ }));
1451
+ }
965
1452
  };
966
1453
 
967
1454
  //#endregion
968
1455
  //#region src/mutation-generator.ts
969
- const normalizeTarget = (target) => typeof target === "string" ? { query: target } : target;
1456
+ const normalizeTarget = (target) => isString(target) ? {
1457
+ query: target,
1458
+ invalidateMode: "invalidate"
1459
+ } : {
1460
+ ...target,
1461
+ invalidateMode: target.invalidateMode ?? "invalidate"
1462
+ };
970
1463
  const serializeTarget = (target) => JSON.stringify({
971
1464
  query: target.query,
972
- params: target.params ?? []
1465
+ params: target.params ?? [],
1466
+ invalidateMode: target.invalidateMode,
1467
+ file: target.file ?? ""
973
1468
  });
974
1469
  const generateVariableRef = (varName) => {
975
1470
  const parts = varName.split(".");
@@ -981,9 +1476,11 @@ const generateParamArgs = (params) => {
981
1476
  return Object.values(params).map((v) => generateVariableRef(v)).join(", ");
982
1477
  };
983
1478
  const generateInvalidateCall = (target) => {
984
- return ` queryClient.invalidateQueries({ queryKey: ${camel(`get-${target.query}-query-key`)}(${target.params ? generateParamArgs(target.params) : ""}) });`;
1479
+ const queryKeyFn = camel(`get-${target.query}-query-key`);
1480
+ const args = target.params ? generateParamArgs(target.params) : "";
1481
+ return ` queryClient.${target.invalidateMode === "reset" ? "resetQueries" : "invalidateQueries"}({ queryKey: ${queryKeyFn}(${args}) });`;
985
1482
  };
986
- const generateMutationHook = async ({ verbOptions, options, outputClient, hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError, hasSvelteQueryV4, hasSvelteQueryV6, isRequestOptions, httpClient, doc, isAngularHttp }) => {
1483
+ const generateMutationHook = async ({ verbOptions, options, isRequestOptions, httpClient, doc, adapter }) => {
987
1484
  const { operationName, body, props, mutator, response, operationId, override } = verbOptions;
988
1485
  const { route, context, output } = options;
989
1486
  const query = override.query;
@@ -998,55 +1495,45 @@ const generateMutationHook = async ({ verbOptions, options, outputClient, hasQue
998
1495
  const properties = props.map(({ name, type }) => type === GetterPropType.BODY ? "data" : name).join(",");
999
1496
  const errorType = getQueryErrorType(operationName, response, httpClient, mutator);
1000
1497
  const dataType = mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`;
1001
- const isAngularClient = isAngular(outputClient);
1002
1498
  const mutationOptionFnReturnType = getQueryOptionsDefinition({
1003
1499
  operationName,
1004
1500
  mutator,
1005
1501
  definitions,
1006
- hasSvelteQueryV4,
1007
- hasQueryV5,
1008
- hasQueryV5WithInfiniteQueryOptionsError,
1009
- isReturnType: true,
1010
- isAngularClient
1502
+ prefix: adapter.getQueryOptionsDefinitionPrefix(),
1503
+ hasQueryV5: adapter.hasQueryV5,
1504
+ hasQueryV5WithInfiniteQueryOptionsError: adapter.hasQueryV5WithInfiniteQueryOptionsError,
1505
+ isReturnType: true
1506
+ });
1507
+ const invalidatesConfig = (query.mutationInvalidates ?? []).filter((rule) => rule.onMutations.includes(operationName)).flatMap((rule) => rule.invalidates).map((t) => normalizeTarget(t));
1508
+ const seenTargets = /* @__PURE__ */ new Set();
1509
+ const uniqueInvalidates = invalidatesConfig.filter((target) => {
1510
+ const key = serializeTarget(target);
1511
+ if (seenTargets.has(key)) return false;
1512
+ seenTargets.add(key);
1513
+ return true;
1011
1514
  });
1012
- const mutationArguments = generateQueryArguments({
1515
+ const hasInvalidation = uniqueInvalidates.length > 0 && adapter.supportsMutationInvalidation();
1516
+ const mutationArguments = adapter.generateQueryArguments({
1013
1517
  operationName,
1014
1518
  definitions,
1015
1519
  mutator,
1016
1520
  isRequestOptions,
1017
- hasSvelteQueryV4,
1018
- hasSvelteQueryV6,
1019
- hasQueryV5,
1020
- hasQueryV5WithInfiniteQueryOptionsError,
1021
1521
  httpClient,
1022
- isAngularClient
1522
+ hasInvalidation
1023
1523
  });
1024
- const mutationArgumentsForOptions = generateQueryArguments({
1524
+ const mutationArgumentsForOptions = adapter.generateQueryArguments({
1025
1525
  operationName,
1026
1526
  definitions,
1027
1527
  mutator,
1028
1528
  isRequestOptions,
1029
- hasSvelteQueryV4,
1030
- hasSvelteQueryV6,
1031
- hasQueryV5,
1032
- hasQueryV5WithInfiniteQueryOptionsError,
1033
1529
  httpClient,
1034
- isAngularClient,
1035
- forQueryOptions: true
1530
+ forQueryOptions: true,
1531
+ hasInvalidation
1036
1532
  });
1037
1533
  const mutationOptionsFnName = camel(mutationOptionsMutator || mutator?.isHook ? `use-${operationName}-mutationOptions` : `get-${operationName}-mutationOptions`);
1038
1534
  const hooksOptionImplementation = getHooksOptionImplementation(isRequestOptions, httpClient, camel(operationName), mutator);
1039
- const invalidatesConfig = (query.mutationInvalidates ?? []).filter((rule) => rule.onMutations.includes(operationName)).flatMap((rule) => rule.invalidates).map((t) => normalizeTarget(t));
1040
- const seenTargets = /* @__PURE__ */ new Set();
1041
- const uniqueInvalidates = invalidatesConfig.filter((target) => {
1042
- const key = serializeTarget(target);
1043
- if (seenTargets.has(key)) return false;
1044
- seenTargets.add(key);
1045
- return true;
1046
- });
1047
- const hasInvalidation = uniqueInvalidates.length > 0 && (isAngularClient || isReact(outputClient) || isSvelte(outputClient));
1048
1535
  const mutationOptionsFn = `export const ${mutationOptionsFnName} = <TError = ${errorType},
1049
- TContext = unknown>(${isAngularHttp && (!mutator || mutator.hasSecondArg) ? "http: HttpClient, " : ""}${hasInvalidation ? "queryClient: QueryClient, " : ""}${mutationArgumentsForOptions}): ${mutationOptionFnReturnType} => {
1536
+ TContext = unknown>(${adapter.getHttpFirstParam(mutator)}${hasInvalidation ? "queryClient: QueryClient, " : ""}${mutationArgumentsForOptions}): ${mutationOptionFnReturnType} => {
1050
1537
 
1051
1538
  ${hooksOptionImplementation}
1052
1539
 
@@ -1056,31 +1543,43 @@ ${hooksOptionImplementation}
1056
1543
  const mutationFn: MutationFunction<Awaited<ReturnType<${dataType}>>, ${definitions ? `{${definitions}}` : "void"}> = (${properties ? "props" : ""}) => {
1057
1544
  ${properties ? `const {${properties}} = props ?? {};` : ""}
1058
1545
 
1059
- return ${operationName}(${isAngularHttp && !mutator ? "http, " : ""}${properties}${properties ? "," : ""}${getMutationRequestArgs(isRequestOptions, httpClient, mutator)})
1546
+ return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${properties}${properties ? "," : ""}${getMutationRequestArgs(isRequestOptions, httpClient, mutator)})
1060
1547
  }
1061
1548
 
1062
- ${hasInvalidation ? isAngular(outputClient) ? ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1063
- ${uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n")}
1064
- mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1065
- };` : isReact(outputClient) ? ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext) => {
1066
- ${uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n")}
1067
- mutationOptions?.onSuccess?.(data, variables, context);
1068
- };` : isSvelte(outputClient) ? hasSvelteQueryV6 ? ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, onMutateResult: TContext, context: MutationFunctionContext) => {
1069
- ${uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n")}
1070
- mutationOptions?.onSuccess?.(data, variables, onMutateResult, context);
1071
- };` : ` const onSuccess = (data: Awaited<ReturnType<typeof ${operationName}>>, variables: ${definitions ? `{${definitions}}` : "void"}, context: TContext | undefined) => {
1072
- ${uniqueInvalidates.map((t) => generateInvalidateCall(t)).join("\n")}
1073
- mutationOptions?.onSuccess?.(data, variables, context);
1074
- };` : "" : ""}
1549
+ ${hasInvalidation ? adapter.generateMutationOnSuccess({
1550
+ operationName,
1551
+ definitions,
1552
+ isRequestOptions,
1553
+ generateInvalidateCall,
1554
+ uniqueInvalidates
1555
+ }) : ""}
1075
1556
 
1076
1557
  ${mutationOptionsMutator ? `const customOptions = ${mutationOptionsMutator.name}({...mutationOptions, mutationFn}${mutationOptionsMutator.hasSecondArg ? `, { url: \`${route.replaceAll("/${", "/{")}\` }` : ""}${mutationOptionsMutator.hasThirdArg ? `, { operationId: '${operationId}', operationName: '${operationName}' }` : ""});` : ""}
1077
1558
 
1078
1559
 
1079
- return ${mutationOptionsMutator ? "customOptions" : hasInvalidation ? "{ mutationFn, onSuccess, ...mutationOptions }" : "{ mutationFn, ...mutationOptions }"}}`;
1080
- const operationPrefix = getFrameworkPrefix(hasSvelteQueryV4, isAngular(outputClient), isSolid(outputClient));
1081
- const optionalQueryClientArgument = hasSvelteQueryV6 ? ", queryClient?: () => QueryClient" : (hasQueryV5 || isSvelte(outputClient) && hasInvalidation) && !isAngular(outputClient) ? ", queryClient?: QueryClient" : "";
1082
- const mutationImplementation = `${mutationOptionsFnName}(${hasInvalidation ? hasSvelteQueryV6 ? "backupQueryClient, " : `queryClient${isReact(outputClient) || isSvelte(outputClient) ? " ?? backupQueryClient" : ""}, ` : ""}${isRequestOptions ? "options" : "mutationOptions"}${hasSvelteQueryV6 ? "?.()" : ""})`;
1560
+ return ${mutationOptionsMutator ? "customOptions" : hasInvalidation ? "{ ...mutationOptions, mutationFn, onSuccess }" : "{ mutationFn, ...mutationOptions }"}}`;
1561
+ const operationPrefix = adapter.hookPrefix;
1562
+ const optionalQueryClientArgument = adapter.getOptionalQueryClientArgument(hasInvalidation);
1563
+ const mutationImplementation = adapter.generateMutationImplementation({
1564
+ mutationOptionsFnName,
1565
+ hasInvalidation,
1566
+ isRequestOptions
1567
+ });
1083
1568
  const mutationOptionsVarName = camel(`${operationName}-mutation-options`);
1569
+ const mutationReturnType = adapter.getMutationReturnType({
1570
+ dataType,
1571
+ variableType: definitions ? `{${definitions}}` : "void"
1572
+ });
1573
+ const mutationHookBody = adapter.generateMutationHookBody({
1574
+ operationPrefix,
1575
+ mutationOptionsFnName,
1576
+ mutationImplementation,
1577
+ mutationOptionsVarName,
1578
+ isRequestOptions,
1579
+ mutator,
1580
+ hasInvalidation,
1581
+ optionalQueryClientArgument
1582
+ });
1084
1583
  return {
1085
1584
  implementation: `
1086
1585
  ${mutationOptionsFn}
@@ -1090,39 +1589,29 @@ ${mutationOptionsFn}
1090
1589
  export type ${pascal(operationName)}MutationError = ${errorType}
1091
1590
 
1092
1591
  ${doc}export const ${camel(`${operationPrefix}-${operationName}`)} = <TError = ${errorType},
1093
- TContext = unknown>(${mutationArguments} ${optionalQueryClientArgument})${generateMutatorReturnType({
1094
- outputClient,
1095
- dataType,
1096
- variableType: definitions ? `{${definitions}}` : "void"
1097
- })} => {
1098
- ${isAngular(outputClient) ? isAngularHttp && (!mutator || mutator.hasSecondArg) ? ` const http = inject(HttpClient);${hasInvalidation ? "\n const queryClient = inject(QueryClient);" : ""}
1099
- const ${mutationOptionsVarName} = ${mutationOptionsFnName}(http${hasInvalidation ? ", queryClient" : ""}${isRequestOptions ? ", options" : ", mutationOptions"});
1100
-
1101
- return ${operationPrefix}Mutation(() => ${mutationOptionsVarName});` : ` const ${mutationOptionsVarName} = ${mutationImplementation};
1102
-
1103
- return ${operationPrefix}Mutation(() => ${mutationOptionsVarName});` : ` ${(isReact(outputClient) || isSvelte(outputClient)) && hasInvalidation ? `const backupQueryClient = useQueryClient(${hasSvelteQueryV6 && optionalQueryClientArgument ? "queryClient?.()" : ""});\n ` : ""}return ${operationPrefix}Mutation(${hasSvelteQueryV6 ? `() => ({ ...${mutationImplementation} })${optionalQueryClientArgument ? `, queryClient` : ""}` : isSvelte(outputClient) ? mutationImplementation : `${mutationImplementation}${optionalQueryClientArgument ? `, queryClient` : ""}`});`}
1592
+ TContext = unknown>(${mutationArguments} ${optionalQueryClientArgument})${mutationReturnType} => {
1593
+ ${mutationHookBody}
1104
1594
  }
1105
1595
  `,
1106
- mutators: mutationOptionsMutator ? [mutationOptionsMutator] : void 0
1596
+ mutators: mutationOptionsMutator ? [mutationOptionsMutator] : void 0,
1597
+ imports: hasInvalidation ? uniqueInvalidates.filter((i) => !!i.file).map((i) => ({
1598
+ name: camel(`get-${i.query}-query-key`),
1599
+ importPath: i.file,
1600
+ values: true
1601
+ })) : []
1107
1602
  };
1108
1603
  };
1109
1604
 
1110
1605
  //#endregion
1111
1606
  //#region src/query-generator.ts
1112
- /**
1113
- * Get framework-aware prefix for hook names and type definitions
1114
- * @param hasSvelteQueryV4 - Whether using Svelte Query v4
1115
- * @param isAngularClient - Whether using Angular client
1116
- * @param isSolidClient - Whether using Solid Query client
1117
- * @param capitalize - Whether to capitalize the prefix (for type definitions)
1118
- * @returns The appropriate prefix string
1119
- */
1120
- const getFrameworkPrefix = (hasSvelteQueryV4, isAngularClient, isSolidClient, capitalize = false) => {
1121
- let prefix;
1122
- if (hasSvelteQueryV4 || isSolidClient) prefix = "create";
1123
- else if (isAngularClient) prefix = "inject";
1124
- else prefix = "use";
1125
- return capitalize ? prefix.charAt(0).toUpperCase() + prefix.slice(1) : prefix;
1607
+ const getQueryFnArguments = ({ hasQueryParam, hasSignal, hasSignalParam = false }) => {
1608
+ if (!hasQueryParam && !hasSignal) return "";
1609
+ const signalDestructure = hasSignalParam ? "signal: querySignal" : "signal";
1610
+ if (hasQueryParam) {
1611
+ if (hasSignal) return `{ ${signalDestructure}, pageParam }`;
1612
+ return "{ pageParam }";
1613
+ }
1614
+ return `{ ${signalDestructure} }`;
1126
1615
  };
1127
1616
  const generatePrefetch = ({ usePrefetch, type, useQuery, useInfinite, operationName, mutator, doc, queryProps, dataType, errorType, queryArguments, queryOptionsVarName, queryOptionsFnName, queryProperties, isRequestOptions }) => {
1128
1617
  if (!(usePrefetch && (type === QueryType.QUERY || type === QueryType.INFINITE || type === QueryType.SUSPENSE_QUERY && !useQuery || type === QueryType.SUSPENSE_INFINITE && !useInfinite))) return "";
@@ -1145,7 +1634,8 @@ const generatePrefetch = ({ usePrefetch, type, useQuery, useInfinite, operationN
1145
1634
  return queryClient;
1146
1635
  }\n`;
1147
1636
  };
1148
- const generateQueryImplementation = ({ queryOption: { name, queryParam, options, type, queryKeyFnName }, operationName, queryProperties, queryKeyProperties, queryParams, params, props, mutator, queryOptionsMutator, queryKeyMutator, isRequestOptions, response, outputClient, httpClient, isExactOptionalPropertyTypes, hasSignal, route, hasVueQueryV4, hasSvelteQueryV4, hasSvelteQueryV6, hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError, doc, usePrefetch, useQuery, useInfinite, useInvalidate }) => {
1637
+ const generateQueryImplementation = ({ queryOption: { name, queryParam, options, type, queryKeyFnName }, operationName, queryProperties, queryKeyProperties, queryParams, params, props, mutator, queryOptionsMutator, queryKeyMutator, isRequestOptions, response, httpClient, isExactOptionalPropertyTypes, hasSignal, route, doc, usePrefetch, useQuery, useInfinite, useInvalidate, adapter }) => {
1638
+ const { hasQueryV5, hasQueryV5WithDataTagError, hasQueryV5WithInfiniteQueryOptionsError } = adapter;
1149
1639
  const hasSignalParam = props.some((prop) => prop.name === "signal");
1150
1640
  const queryPropDefinitions = toObjectString(props, "definition");
1151
1641
  const definedInitialDataQueryPropsDefinitions = toObjectString(props.map((prop) => {
@@ -1158,105 +1648,66 @@ const generateQueryImplementation = ({ queryOption: { name, queryParam, options,
1158
1648
  };
1159
1649
  }), "definition");
1160
1650
  const queryProps = toObjectString(props, "implementation");
1161
- const angularQueryPropsDefinitions = toObjectString(props.map((prop) => {
1162
- const getterType = prop.definition.replace(/^(\w+)(\??): (.+)$/, (_match, name$1, optional, type$1) => `${name$1}${optional}: ${type$1} | (() => ${type$1.replace(" | undefined", "")}${optional ? " | undefined" : ""})`);
1163
- return {
1164
- ...prop,
1165
- definition: getterType
1166
- };
1167
- }), "definition");
1168
1651
  const hasInfiniteQueryParam = queryParam && queryParams?.schema.name;
1169
- const isAngularHttp = isAngular(outputClient) || httpClient === OutputHttpClient.ANGULAR;
1170
- let httpFunctionProps = queryParam ? props.map((param) => {
1171
- if (param.type === GetterPropType.NAMED_PATH_PARAMS && !isVue(outputClient)) return param.destructured;
1172
- return param.name === "params" ? `{...${isVue(outputClient) ? `unref(params)` : "params"}, '${queryParam}': pageParam || ${isVue(outputClient) ? `unref(params)?.['${queryParam}']` : `params?.['${queryParam}']`}}` : param.name;
1173
- }).join(",") : getHttpFunctionQueryProps(isVue(outputClient), httpClient, queryProperties, isAngularHttp, !!mutator);
1174
- if (queryParam && isAngularHttp && !mutator) httpFunctionProps = httpFunctionProps ? `http, ${httpFunctionProps}` : "http";
1175
- const definedInitialDataReturnType = generateQueryReturnType({
1176
- outputClient,
1652
+ const httpFunctionProps = queryParam ? adapter.getInfiniteQueryHttpProps(props, queryParam, !!mutator) : adapter.getHttpFunctionQueryProps(queryProperties, httpClient, !!mutator);
1653
+ const definedInitialDataReturnType = adapter.getQueryReturnType({
1177
1654
  type,
1178
1655
  isMutatorHook: mutator?.isHook,
1179
1656
  operationName,
1180
- hasVueQueryV4,
1181
- hasSvelteQueryV4,
1182
1657
  hasQueryV5,
1183
1658
  hasQueryV5WithDataTagError,
1184
1659
  isInitialDataDefined: true
1185
1660
  });
1186
- const returnType = generateQueryReturnType({
1187
- outputClient,
1661
+ const returnType = adapter.getQueryReturnType({
1188
1662
  type,
1189
1663
  isMutatorHook: mutator?.isHook,
1190
1664
  operationName,
1191
- hasVueQueryV4,
1192
- hasSvelteQueryV4,
1193
1665
  hasQueryV5,
1194
1666
  hasQueryV5WithDataTagError
1195
1667
  });
1196
1668
  const errorType = getQueryErrorType(operationName, response, httpClient, mutator);
1197
1669
  const dataType = mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`;
1198
- const definedInitialDataQueryArguments = generateQueryArguments({
1670
+ const definedInitialDataQueryArguments = adapter.generateQueryArguments({
1199
1671
  operationName,
1200
1672
  mutator,
1201
1673
  definitions: "",
1202
1674
  isRequestOptions,
1203
1675
  type,
1204
- hasSvelteQueryV4,
1205
- hasSvelteQueryV6,
1206
- hasQueryV5,
1207
- hasQueryV5WithInfiniteQueryOptionsError,
1208
1676
  queryParams,
1209
1677
  queryParam,
1210
1678
  initialData: "defined",
1211
- httpClient,
1212
- isAngularClient: isAngular(outputClient)
1679
+ httpClient
1213
1680
  });
1214
- const undefinedInitialDataQueryArguments = generateQueryArguments({
1681
+ const undefinedInitialDataQueryArguments = adapter.generateQueryArguments({
1215
1682
  operationName,
1216
1683
  definitions: "",
1217
1684
  mutator,
1218
1685
  isRequestOptions,
1219
1686
  type,
1220
- hasSvelteQueryV4,
1221
- hasSvelteQueryV6,
1222
- hasQueryV5,
1223
- hasQueryV5WithInfiniteQueryOptionsError,
1224
1687
  queryParams,
1225
1688
  queryParam,
1226
1689
  initialData: "undefined",
1227
- httpClient,
1228
- isAngularClient: isAngular(outputClient)
1690
+ httpClient
1229
1691
  });
1230
- const queryArguments = generateQueryArguments({
1692
+ const queryArguments = adapter.generateQueryArguments({
1231
1693
  operationName,
1232
1694
  definitions: "",
1233
1695
  mutator,
1234
1696
  isRequestOptions,
1235
1697
  type,
1236
- hasSvelteQueryV4,
1237
- hasSvelteQueryV6,
1238
- hasQueryV5,
1239
- hasQueryV5WithInfiniteQueryOptionsError,
1240
1698
  queryParams,
1241
1699
  queryParam,
1242
- httpClient,
1243
- isAngularClient: isAngular(outputClient),
1244
- forAngularInject: isAngular(outputClient)
1700
+ httpClient
1245
1701
  });
1246
- const queryArgumentsForOptions = generateQueryArguments({
1702
+ const queryArgumentsForOptions = adapter.generateQueryArguments({
1247
1703
  operationName,
1248
1704
  definitions: "",
1249
1705
  mutator,
1250
1706
  isRequestOptions,
1251
1707
  type,
1252
- hasSvelteQueryV4,
1253
- hasSvelteQueryV6,
1254
- hasQueryV5,
1255
- hasQueryV5WithInfiniteQueryOptionsError,
1256
1708
  queryParams,
1257
1709
  queryParam,
1258
1710
  httpClient,
1259
- isAngularClient: isAngular(outputClient),
1260
1711
  forQueryOptions: true
1261
1712
  });
1262
1713
  const queryOptions = getQueryOptions({
@@ -1282,43 +1733,42 @@ const generateQueryImplementation = ({ queryOption: { name, queryParam, options,
1282
1733
  mutator,
1283
1734
  definitions: "",
1284
1735
  type,
1285
- hasSvelteQueryV4,
1736
+ prefix: adapter.getQueryOptionsDefinitionPrefix(),
1286
1737
  hasQueryV5,
1287
1738
  hasQueryV5WithInfiniteQueryOptionsError,
1288
1739
  queryParams,
1289
1740
  queryParam,
1290
- isReturnType: true,
1291
- isAngularClient: isAngular(outputClient)
1741
+ isReturnType: true
1292
1742
  });
1293
1743
  const queryOptionsImp = generateQueryOptions({
1294
1744
  params,
1295
1745
  options,
1296
1746
  type,
1297
- outputClient
1747
+ adapter
1298
1748
  });
1299
1749
  const queryOptionsFnName = camel(queryKeyMutator || queryOptionsMutator || mutator?.isHook ? `use-${name}-queryOptions` : `get-${name}-queryOptions`);
1300
1750
  const queryOptionsVarName = isRequestOptions ? "queryOptions" : "options";
1301
1751
  const queryResultVarName = props.some((prop) => prop.name === "query") ? "_query" : "query";
1302
1752
  const infiniteParam = queryParams && queryParam ? `, ${queryParams.schema.name}['${queryParam}']` : "";
1303
1753
  const TData = hasQueryV5 && (type === QueryType.INFINITE || type === QueryType.SUSPENSE_INFINITE) ? `InfiniteData<Awaited<ReturnType<${dataType}>>${infiniteParam}>` : `Awaited<ReturnType<${dataType}>>`;
1304
- const queryOptionsFn = `export const ${queryOptionsFnName} = <TData = ${TData}, TError = ${errorType}>(${isAngularHttp && (!mutator || mutator.hasSecondArg) ? "http: HttpClient, " : ""}${queryProps} ${queryArgumentsForOptions}) => {
1754
+ const queryOptionsFn = `export const ${queryOptionsFnName} = <TData = ${TData}, TError = ${errorType}>(${adapter.getHttpFirstParam(mutator)}${queryProps} ${queryArgumentsForOptions}) => {
1305
1755
 
1306
1756
  ${hookOptions}
1307
1757
 
1308
- const queryKey = ${queryKeyMutator ? `${queryKeyMutator.name}({ ${queryProperties} }${queryKeyMutator.hasSecondArg ? `, { url: \`${route}\`, queryOptions }` : ""});` : `${hasVueQueryV4 ? "" : "queryOptions?.queryKey ?? "}${queryKeyFnName}(${queryKeyProperties});`}
1758
+ const queryKey = ${queryKeyMutator ? `${queryKeyMutator.name}({ ${queryProperties} }${queryKeyMutator.hasSecondArg ? `, { url: \`${route}\`, queryOptions }` : ""});` : `${adapter.getQueryKeyPrefix()}${queryKeyFnName}(${queryKeyProperties});`}
1309
1759
 
1310
1760
  ${mutator?.isHook ? `const ${operationName} = use${pascal(operationName)}Hook();` : ""}
1311
1761
 
1312
1762
  const queryFn: QueryFunction<Awaited<ReturnType<${mutator?.isHook ? `ReturnType<typeof use${pascal(operationName)}Hook>` : `typeof ${operationName}`}>>${hasQueryV5 && hasInfiniteQueryParam ? `, QueryKey, ${queryParams.schema.name}['${queryParam}']` : ""}> = (${queryFnArguments}) => ${operationName}(${httpFunctionProps}${httpFunctionProps ? ", " : ""}${queryOptions});
1313
1763
 
1314
- ${isVue(outputClient) ? vueUnRefParams(props.filter((prop) => prop.type === GetterPropType.NAMED_PATH_PARAMS)) : ""}
1764
+ ${adapter.getUnrefStatements(props)}
1315
1765
 
1316
1766
  ${queryOptionsMutator ? `const customOptions = ${queryOptionsMutator.name}({...queryOptions, queryKey, queryFn}${queryOptionsMutator.hasSecondArg ? `, { ${queryProperties} }` : ""}${queryOptionsMutator.hasThirdArg ? `, { url: \`${route}\` }` : ""});` : ""}
1317
1767
 
1318
- return ${queryOptionsMutator ? "customOptions" : `{ queryKey, queryFn, ${queryOptionsImp}}`} as ${queryOptionFnReturnType} ${isVue(outputClient) || isAngular(outputClient) ? "" : `& { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }`}
1768
+ return ${queryOptionsMutator ? "customOptions" : `{ queryKey, queryFn, ${queryOptionsImp}}`} as ${queryOptionFnReturnType} ${adapter.shouldAnnotateQueryKey() ? `& { queryKey: ${hasQueryV5 ? `DataTag<QueryKey, TData${hasQueryV5WithDataTagError ? ", TError" : ""}>` : "QueryKey"} }` : ""}
1319
1769
  }`;
1320
- const operationPrefix = getFrameworkPrefix(hasSvelteQueryV4, isAngular(outputClient), isSolid(outputClient));
1321
- const optionalQueryClientArgument = hasSvelteQueryV6 ? `, queryClient?: () => QueryClient` : hasQueryV5 && !isAngular(outputClient) ? ", queryClient?: QueryClient" : "";
1770
+ const operationPrefix = adapter.hookPrefix;
1771
+ const optionalQueryClientArgument = adapter.getOptionalQueryClientArgument();
1322
1772
  const queryHookName = camel(`${operationPrefix}-${name}`);
1323
1773
  const overrideTypes = `
1324
1774
  export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${definedInitialDataQueryPropsDefinitions} ${definedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${definedInitialDataReturnType}
@@ -1343,36 +1793,39 @@ export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${q
1343
1793
  });
1344
1794
  const shouldGenerateInvalidate = useInvalidate && (type === QueryType.QUERY || type === QueryType.INFINITE || type === QueryType.SUSPENSE_QUERY && !useQuery || type === QueryType.SUSPENSE_INFINITE && !useInfinite);
1345
1795
  const invalidateFnName = camel(`invalidate-${name}`);
1796
+ const queryInit = adapter.generateQueryInit({
1797
+ queryOptionsFnName,
1798
+ queryProperties,
1799
+ isRequestOptions,
1800
+ mutator
1801
+ });
1802
+ const queryInvocationArgs = adapter.generateQueryInvocationArgs({
1803
+ props,
1804
+ queryOptionsFnName,
1805
+ queryProperties,
1806
+ isRequestOptions,
1807
+ mutator,
1808
+ operationPrefix,
1809
+ type,
1810
+ queryOptionsVarName,
1811
+ optionalQueryClientArgument
1812
+ });
1813
+ const queryInvocationSuffix = adapter.getQueryInvocationSuffix();
1346
1814
  return `
1347
1815
  ${queryOptionsFn}
1348
1816
 
1349
1817
  export type ${pascal(name)}QueryResult = NonNullable<Awaited<ReturnType<${dataType}>>>
1350
1818
  export type ${pascal(name)}QueryError = ${errorType}
1351
1819
 
1352
- ${hasQueryV5 && OutputClient.REACT_QUERY === outputClient ? overrideTypes : ""}
1820
+ ${adapter.shouldGenerateOverrideTypes() ? overrideTypes : ""}
1353
1821
  ${doc}
1354
- export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${hasSvelteQueryV6 ? toObjectString(props.map((p) => ({
1355
- ...p,
1356
- definition: p.definition.replace(":", ": () => ")
1357
- })), "definition") : isAngular(outputClient) ? angularQueryPropsDefinitions : queryProps} ${queryArguments} ${optionalQueryClientArgument} \n ): ${returnType} {
1822
+ export function ${queryHookName}<TData = ${TData}, TError = ${errorType}>(\n ${adapter.getHookPropsDefinitions(props)} ${queryArguments} ${optionalQueryClientArgument} \n ): ${returnType} {
1358
1823
 
1359
- ${hasSvelteQueryV6 ? "" : isAngular(outputClient) && (!mutator || mutator.hasSecondArg) ? `const http = inject(HttpClient);` : isAngular(outputClient) ? "" : `const ${queryOptionsVarName} = ${queryOptionsFnName}(${queryProperties}${queryProperties ? "," : ""}${isRequestOptions ? "options" : "queryOptions"})`}
1824
+ ${queryInit}
1360
1825
 
1361
- const ${queryResultVarName} = ${camel(`${operationPrefix}-${isAngular(outputClient) || hasSvelteQueryV4 ? getQueryTypeForFramework(type) : type}`)}(${isAngular(outputClient) ? `() => {${props.length > 0 ? `
1362
- // Resolve params if getter function (for signal reactivity)
1363
- ${props.map((p) => `const _${p.name} = typeof ${p.name} === 'function' ? ${p.name}() : ${p.name};`).join("\n ")}` : ""}
1364
- // Resolve options if getter function (for signal reactivity)
1365
- const _options = typeof ${isRequestOptions ? "options" : "queryOptions"} === 'function' ? ${isRequestOptions ? "options" : "queryOptions"}() : ${isRequestOptions ? "options" : "queryOptions"};
1366
- return ${queryOptionsFnName}(${!mutator || mutator.hasSecondArg ? "http" : ""}${props.length > 0 ? `${!mutator || mutator.hasSecondArg ? ", " : ""}${props.map((p) => `_${p.name}`).join(", ")}` : ""}, _options);
1367
- }` : hasSvelteQueryV6 ? `() => ${queryOptionsFnName}(${toObjectString(props.map((p) => ({
1368
- ...p,
1369
- name: p.default || !p.required ? `${p.name}?.()` : `${p.name}()`
1370
- })), "name")}${isRequestOptions ? "options?.()" : "queryOptions?.()"})` : `${queryOptionsVarName}${!isAngular(outputClient) && optionalQueryClientArgument ? ", queryClient" : ""}`}${hasSvelteQueryV6 ? `, queryClient` : ""}) as ${returnType};
1826
+ const ${queryResultVarName} = ${camel(`${operationPrefix}-${adapter.getQueryType(type)}`)}(${queryInvocationArgs}${queryInvocationSuffix}) as ${returnType};
1371
1827
 
1372
- ${getQueryReturnStatement({
1373
- outputClient,
1374
- hasSvelteQueryV4,
1375
- hasSvelteQueryV6,
1828
+ ${adapter.getQueryReturnStatement({
1376
1829
  hasQueryV5,
1377
1830
  hasQueryV5WithDataTagError,
1378
1831
  queryResultVarName,
@@ -1388,24 +1841,16 @@ ${shouldGenerateInvalidate ? `${doc}export const ${invalidateFnName} = async (\n
1388
1841
  }\n` : ""}
1389
1842
  `;
1390
1843
  };
1391
- const generateQueryHook = async (verbOptions, options, outputClient) => {
1844
+ const generateQueryHook = async (verbOptions, options, outputClient, adapter) => {
1845
+ if (!adapter) throw new Error("FrameworkAdapter is required for generateQueryHook");
1392
1846
  const { queryParams, operationName, body, props: _props, verb, params, override, mutator, response, operationId, summary, deprecated } = verbOptions;
1393
1847
  const { route, override: { operations }, context, output } = options;
1394
- let props = _props;
1395
- if (isVue(outputClient)) props = vueWrapTypeWithMaybeRef(_props);
1848
+ const props = adapter.transformProps(_props);
1396
1849
  const query = override.query;
1397
1850
  const isRequestOptions = override.requestOptions !== false;
1398
1851
  const operationQueryOptions = operations[operationId]?.query;
1399
1852
  const isExactOptionalPropertyTypes = !!context.output.tsconfig?.compilerOptions?.exactOptionalPropertyTypes;
1400
- const queryVersion = query.version;
1401
- const hasVueQueryV4 = OutputClient.VUE_QUERY === outputClient && (!isVueQueryV3(context.output.packageJson) || queryVersion === 4);
1402
- const hasSvelteQueryV4 = OutputClient.SVELTE_QUERY === outputClient && (!isSvelteQueryV3(context.output.packageJson) || queryVersion === 4);
1403
- const hasSvelteQueryV6 = OutputClient.SVELTE_QUERY === outputClient && isSvelteQueryV6(context.output.packageJson);
1404
- const hasQueryV5 = queryVersion === 5 || isQueryV5(context.output.packageJson, outputClient);
1405
- const hasQueryV5WithDataTagError = queryVersion === 5 || isQueryV5WithDataTagError(context.output.packageJson, outputClient);
1406
- const hasQueryV5WithInfiniteQueryOptionsError = queryVersion === 5 || isQueryV5WithInfiniteQueryOptionsError(context.output.packageJson, outputClient);
1407
1853
  const httpClient = context.output.httpClient;
1408
- const isAngularHttp = isAngular(outputClient) || httpClient === OutputHttpClient.ANGULAR;
1409
1854
  const doc = jsDoc({
1410
1855
  summary,
1411
1856
  deprecated
@@ -1444,12 +1889,10 @@ const generateQueryHook = async (verbOptions, options, outputClient) => {
1444
1889
  tsconfig: context.output.tsconfig
1445
1890
  }) : void 0;
1446
1891
  const queryProperties = props.map((param) => {
1447
- if (param.type === GetterPropType.NAMED_PATH_PARAMS && !isVue(outputClient)) return param.destructured;
1448
- return param.type === GetterPropType.BODY ? body.implementation : param.name;
1892
+ return adapter.getQueryPropertyForProp(param, body);
1449
1893
  }).join(",");
1450
1894
  const queryKeyProperties = props.filter((prop) => prop.type !== GetterPropType.HEADER).map((param) => {
1451
- if (param.type === GetterPropType.NAMED_PATH_PARAMS && !isVue(outputClient)) return param.destructured;
1452
- return param.type === GetterPropType.BODY ? body.implementation : param.name;
1895
+ return adapter.getQueryPropertyForProp(param, body);
1453
1896
  }).join(",");
1454
1897
  const queries = [
1455
1898
  ...query.useInfinite || operationQueryOptions?.useInfinite ? [{
@@ -1480,8 +1923,8 @@ const generateQueryHook = async (verbOptions, options, outputClient) => {
1480
1923
  }] : []
1481
1924
  ];
1482
1925
  const uniqueQueryOptionsByKeys = queries.filter((obj, index, self) => index === self.findIndex((t) => t.queryKeyFnName === obj.queryKeyFnName));
1483
- implementation += `
1484
- ${queryKeyMutator ? "" : uniqueQueryOptionsByKeys.reduce((acc, queryOption) => {
1926
+ let queryKeyFns = "";
1927
+ if (!queryKeyMutator) for (const queryOption of uniqueQueryOptionsByKeys) {
1485
1928
  const makeOptionalParam = (impl) => {
1486
1929
  if (impl.includes("=")) return impl;
1487
1930
  return impl.replace(/^(\w+):\s*/, "$1?: ");
@@ -1490,10 +1933,10 @@ ${queryKeyMutator ? "" : uniqueQueryOptionsByKeys.reduce((acc, queryOption) => {
1490
1933
  ...prop,
1491
1934
  implementation: prop.type === GetterPropType.PARAM || prop.type === GetterPropType.NAMED_PATH_PARAMS ? prop.implementation : makeOptionalParam(prop.implementation)
1492
1935
  })), "implementation");
1493
- const routeString = isVue(outputClient) || override.query.shouldSplitQueryKey ? getRouteAsArray(route) : `\`${route}\``;
1936
+ const routeString = adapter.getQueryKeyRouteString(route, !!override.query.shouldSplitQueryKey);
1494
1937
  const queryKeyIdentifier = override.query.useOperationIdAsQueryKey ? `"${operationName}"` : routeString;
1495
1938
  const queryKeyParams = props.filter((p) => override.query.useOperationIdAsQueryKey ? true : p.type === GetterPropType.QUERY_PARAM).toSorted((a) => a.required ? -1 : 1).map((p) => `...(${p.name} ? [${p.name}] : [])`).join(", ");
1496
- return acc + `
1939
+ queryKeyFns += `
1497
1940
  ${override.query.shouldExportQueryKey ? "export " : ""}const ${queryOption.queryKeyFnName} = (${queryKeyProps}) => {
1498
1941
  return [
1499
1942
  ${[
@@ -1505,43 +1948,40 @@ ${override.query.shouldExportQueryKey ? "export " : ""}const ${queryOption.query
1505
1948
  ] as const;
1506
1949
  }
1507
1950
  `;
1508
- }, "")}`;
1951
+ }
1509
1952
  implementation += `
1510
- ${queries.reduce((acc, queryOption) => {
1511
- return acc + generateQueryImplementation({
1512
- queryOption,
1513
- operationName,
1514
- queryProperties,
1515
- queryKeyProperties,
1516
- params,
1517
- props,
1518
- mutator,
1519
- isRequestOptions,
1520
- queryParams,
1521
- response,
1522
- outputClient,
1523
- httpClient,
1524
- isExactOptionalPropertyTypes,
1525
- hasSignal: getHasSignal({ overrideQuerySignal: override.query.signal }),
1526
- queryOptionsMutator,
1527
- queryKeyMutator,
1528
- route,
1529
- hasVueQueryV4,
1530
- hasSvelteQueryV4,
1531
- hasSvelteQueryV6,
1532
- hasQueryV5,
1533
- hasQueryV5WithDataTagError,
1534
- hasQueryV5WithInfiniteQueryOptionsError,
1535
- doc,
1536
- usePrefetch: query.usePrefetch,
1537
- useQuery: query.useQuery,
1538
- useInfinite: query.useInfinite,
1539
- useInvalidate: query.useInvalidate
1540
- });
1541
- }, "")}
1953
+ ${queryKeyFns}`;
1954
+ let queryImplementations = "";
1955
+ for (const queryOption of queries) queryImplementations += generateQueryImplementation({
1956
+ queryOption,
1957
+ operationName,
1958
+ queryProperties,
1959
+ queryKeyProperties,
1960
+ params,
1961
+ props,
1962
+ mutator,
1963
+ isRequestOptions,
1964
+ queryParams,
1965
+ response,
1966
+ httpClient,
1967
+ isExactOptionalPropertyTypes,
1968
+ hasSignal: getHasSignal({ overrideQuerySignal: override.query.signal }),
1969
+ queryOptionsMutator,
1970
+ queryKeyMutator,
1971
+ route,
1972
+ doc,
1973
+ usePrefetch: query.usePrefetch,
1974
+ useQuery: query.useQuery,
1975
+ useInfinite: query.useInfinite,
1976
+ useInvalidate: query.useInvalidate,
1977
+ adapter
1978
+ });
1979
+ implementation += `
1980
+ ${queryImplementations}
1542
1981
  `;
1543
1982
  mutators = queryOptionsMutator || queryKeyMutator ? [...queryOptionsMutator ? [queryOptionsMutator] : [], ...queryKeyMutator ? [queryKeyMutator] : []] : void 0;
1544
1983
  }
1984
+ let imports = [];
1545
1985
  if (isMutation) {
1546
1986
  const mutationResult = await generateMutationHook({
1547
1987
  verbOptions: {
@@ -1549,22 +1989,19 @@ ${override.query.shouldExportQueryKey ? "export " : ""}const ${queryOption.query
1549
1989
  props
1550
1990
  },
1551
1991
  options,
1552
- outputClient,
1553
- hasQueryV5,
1554
- hasQueryV5WithInfiniteQueryOptionsError,
1555
- hasSvelteQueryV4,
1556
- hasSvelteQueryV6,
1557
1992
  isRequestOptions,
1558
1993
  httpClient,
1559
1994
  doc,
1560
- isAngularHttp
1995
+ adapter
1561
1996
  });
1562
1997
  implementation += mutationResult.implementation;
1563
1998
  mutators = mutationResult.mutators ? [...mutators ?? [], ...mutationResult.mutators] : mutators;
1999
+ imports = mutationResult.imports;
1564
2000
  }
1565
2001
  return {
1566
2002
  implementation,
1567
- mutators
2003
+ mutators,
2004
+ imports
1568
2005
  };
1569
2006
  };
1570
2007
 
@@ -1578,12 +2015,36 @@ ${getQueryHeader(params)}
1578
2015
  `;
1579
2016
  };
1580
2017
  const generateQuery = async (verbOptions, options, outputClient) => {
1581
- const imports = generateVerbImports(verbOptions);
1582
- const functionImplementation = generateQueryRequestFunction(verbOptions, options, isVue(outputClient));
1583
- const { implementation: hookImplementation, mutators } = await generateQueryHook(verbOptions, options, outputClient);
2018
+ const isZodOutput = typeof options.context.output.schemas === "object" && options.context.output.schemas.type === "zod";
2019
+ const responseType = verbOptions.response.definition.success;
2020
+ const isPrimitiveResponse = [
2021
+ "string",
2022
+ "number",
2023
+ "boolean",
2024
+ "void",
2025
+ "unknown"
2026
+ ].includes(responseType);
2027
+ const normalizedVerbOptions = verbOptions.override.query.runtimeValidation && isZodOutput && !isPrimitiveResponse && verbOptions.response.imports.some((imp) => imp.name === responseType) ? {
2028
+ ...verbOptions,
2029
+ response: {
2030
+ ...verbOptions.response,
2031
+ imports: verbOptions.response.imports.map((imp) => imp.name === responseType ? {
2032
+ ...imp,
2033
+ values: true
2034
+ } : imp)
2035
+ }
2036
+ } : verbOptions;
2037
+ const adapter = createFrameworkAdapter({
2038
+ outputClient,
2039
+ packageJson: options.context.output.packageJson,
2040
+ queryVersion: normalizedVerbOptions.override.query.version
2041
+ });
2042
+ const imports = generateVerbImports(normalizedVerbOptions);
2043
+ const functionImplementation = adapter.generateRequestFunction(normalizedVerbOptions, options);
2044
+ const { implementation: hookImplementation, imports: hookImports, mutators } = await generateQueryHook(normalizedVerbOptions, options, outputClient, adapter);
1584
2045
  return {
1585
2046
  implementation: `${functionImplementation}\n\n${hookImplementation}`,
1586
- imports,
2047
+ imports: [...imports, ...hookImports],
1587
2048
  mutators
1588
2049
  };
1589
2050
  };