From bbbb4a5562bed48fe3d1b84f3850bf3df66a5c2c Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 09:05:38 +0300 Subject: [PATCH 01/10] feat(query): add useFlatInput option to merge params into a single object - Add useFlatInput?: boolean config under override - Queries: destructure path params by name, rest spread for query params - Mutations: destructure path + query param fields by name, rest spread for body - Uses TypeScript intersection types (e.g. { userId: number } & GetUserOrdersParams) - Throws error on duplicate field names across path/query params - Throws error if used together with useNamedParameters - Headers stay as a separate parameter - Snapshot tests for petstore, multi-params, and path+query+body cases Closes #3160 --- packages/core/src/getters/query-params.ts | 1 + packages/core/src/types.ts | 3 + packages/query/src/flat-input.ts | 34 + packages/query/src/mutation-generator.ts | 87 +- packages/query/src/query-generator.ts | 88 +- .../flat-input-multi-params/endpoints.ts | 148 ++++ .../model/getUsersUserIdOrdersParams.ts | 24 + .../model/getUsersUserIdOrdersStatus.ts | 15 + .../flat-input-multi-params/model/index.ts | 9 + .../flat-input-path-query-body/endpoints.ts | 120 +++ .../flat-input-path-query-body/model/index.ts | 12 + .../model/searchItems200.ts | 11 + .../model/searchItems200ResultsItem.ts | 11 + .../model/searchItemsBody.ts | 12 + .../model/searchItemsBodyFilters.ts | 11 + .../model/searchItemsParams.ts | 11 + .../flat-input-petstore/endpoints.ts | 752 ++++++++++++++++++ .../flat-input-petstore/model/cat.ts | 12 + .../flat-input-petstore/model/catType.ts | 13 + .../model/createPetsBody.ts | 11 + .../model/createPetsHeaders.ts | 14 + .../model/createPetsParams.ts | 20 + .../model/createPetsSort.ts | 16 + .../model/createPetsXExample.ts | 15 + .../flat-input-petstore/model/dachshund.ts | 12 + .../model/dachshundBreed.ts | 13 + .../flat-input-petstore/model/dog.ts | 17 + .../flat-input-petstore/model/dogType.ts | 13 + .../flat-input-petstore/model/error.ts | 11 + .../flat-input-petstore/model/index.ts | 30 + .../flat-input-petstore/model/labradoodle.ts | 12 + .../model/labradoodleBreed.ts | 13 + .../model/listPetsHeaders.ts | 14 + .../model/listPetsParams.ts | 20 + .../flat-input-petstore/model/listPetsSort.ts | 16 + .../model/listPetsXExample.ts | 15 + .../flat-input-petstore/model/pet.ts | 28 + .../model/petCallingCode.ts | 14 + .../flat-input-petstore/model/petCountry.ts | 14 + .../flat-input-petstore/model/petWithTag.ts | 12 + .../flat-input-petstore/model/pets.ts | 9 + tests/configs/react-query.config.ts | 48 ++ .../flat-input-with-body-query.yaml | 60 ++ 43 files changed, 1798 insertions(+), 23 deletions(-) create mode 100644 packages/query/src/flat-input.ts create mode 100644 tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts create mode 100644 tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts create mode 100644 tests/__snapshots__/react-query/flat-input-multi-params/model/index.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts create mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/cat.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/createPetsBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/dachshund.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/error.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/index.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/labradoodle.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/petWithTag.ts create mode 100644 tests/__snapshots__/react-query/flat-input-petstore/model/pets.ts create mode 100644 tests/specifications/flat-input-with-body-query.yaml diff --git a/packages/core/src/getters/query-params.ts b/packages/core/src/getters/query-params.ts index 2610ba7523..6d162f91d8 100644 --- a/packages/core/src/getters/query-params.ts +++ b/packages/core/src/getters/query-params.ts @@ -222,5 +222,6 @@ export function getQueryParams({ deps: schemas, isOptional: allOptional, requiredNullableKeys, + fieldNames: types.map(({ name }) => name), }; } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index d31ff8db9e..b480bfc200 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -133,6 +133,7 @@ export interface NormalizedOverrideOutput { useDeprecatedOperations?: boolean; useBigInt?: boolean; useNamedParameters?: boolean; + useFlatInput?: boolean; enumGenerationType: EnumGeneration; suppressReadonlyModifier?: boolean; /** @@ -521,6 +522,7 @@ export interface OverrideOutput { useDeprecatedOperations?: boolean; useBigInt?: boolean; useNamedParameters?: boolean; + useFlatInput?: boolean; enumGenerationType?: EnumGeneration; suppressReadonlyModifier?: boolean; /** @@ -1203,6 +1205,7 @@ export interface GetterQueryParam { isOptional: boolean; originalSchema?: OpenApiSchemaObject; requiredNullableKeys?: string[]; + fieldNames?: string[]; } export type GetterPropType = diff --git a/packages/query/src/flat-input.ts b/packages/query/src/flat-input.ts new file mode 100644 index 0000000000..385c21f0f3 --- /dev/null +++ b/packages/query/src/flat-input.ts @@ -0,0 +1,34 @@ +import { + type GetterProps, + GetterPropType, + type GetterQueryParam, +} from '@orval/core'; + +export function checkFlatInputCollisions( + operationName: string, + props: GetterProps, + queryParams?: GetterQueryParam, +): void { + const pathParamNames = props + .filter( + (p) => + p.type === GetterPropType.PARAM || + p.type === GetterPropType.NAMED_PATH_PARAMS, + ) + .map((p) => p.name); + + const queryFieldNames = queryParams?.fieldNames ?? []; + + const allNames = [...pathParamNames, ...queryFieldNames]; + const seen = new Set(); + + for (const name of allNames) { + if (seen.has(name)) { + throw new Error( + `useFlatInput: duplicate parameter name "${name}" found in operation "${operationName}". ` + + `Path params, query params, and body fields must have unique names when using useFlatInput.`, + ); + } + seen.add(name); + } +} diff --git a/packages/query/src/mutation-generator.ts b/packages/query/src/mutation-generator.ts index c78d02174a..e853cf9f18 100644 --- a/packages/query/src/mutation-generator.ts +++ b/packages/query/src/mutation-generator.ts @@ -17,6 +17,7 @@ import { getMutationRequestArgs, getQueryErrorType, } from './client'; +import { checkFlatInputCollisions } from './flat-input'; import type { FrameworkAdapter } from './framework-adapter'; import { getQueryOptionsDefinition } from './query-options'; @@ -102,6 +103,7 @@ export const generateMutationHook = async ({ response, operationId, override, + queryParams, } = verbOptions; const { route, context, output } = options; const query = override.query; @@ -116,19 +118,72 @@ export const generateMutationHook = async ({ }) : undefined; - const definitions = props - .map(({ definition, type }) => - type === GetterPropType.BODY - ? mutator?.bodyTypeName - ? `data: ${mutator.bodyTypeName}<${body.definition}>` - : `data: ${body.definition}` - : definition, - ) - .join(';'); + const useFlatInput = !!override.useFlatInput; - const properties = props - .map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name)) - .join(','); + if (useFlatInput && props.length > 1) { + checkFlatInputCollisions(operationName, props, queryParams); + } + + let definitions: string; + let properties: string; + let flatMutationCallArgs: string | undefined; + + if (useFlatInput && props.length > 1) { + const pathParamProps = props.filter( + (p) => + p.type === GetterPropType.PARAM || + p.type === GetterPropType.NAMED_PATH_PARAMS, + ); + const queryParamProp = props.find( + (p) => p.type === GetterPropType.QUERY_PARAM, + ); + const bodyPropEntry = props.find((p) => p.type === GetterPropType.BODY); + const queryFieldNames = queryParams?.fieldNames ?? []; + + const pathType = + pathParamProps.length > 0 + ? `{ ${pathParamProps.map((p) => p.definition).join('; ')} }` + : ''; + const queryType = queryParamProp ? (queryParams?.schema.name ?? '') : ''; + const bodyType = bodyPropEntry + ? mutator?.bodyTypeName + ? `${mutator.bodyTypeName}<${body.definition}>` + : body.definition + : ''; + const types = [pathType, queryType, bodyType].filter(Boolean); + definitions = types.join(' & '); + + const knownNames = [ + ...pathParamProps.map((p) => p.name), + ...queryFieldNames, + ]; + const hasBody = !!bodyPropEntry; + properties = hasBody + ? [...knownNames, '...data'].join(', ') + : knownNames.join(', '); + + const pathArgs = pathParamProps.map((p) => p.name).join(', '); + const queryArgs = + queryFieldNames.length > 0 ? `{ ${queryFieldNames.join(', ')} }` : ''; + const bodyArg = hasBody ? 'data' : ''; + flatMutationCallArgs = [pathArgs, queryArgs, bodyArg] + .filter(Boolean) + .join(', '); + } else { + definitions = props + .map(({ definition, type }) => + type === GetterPropType.BODY + ? mutator?.bodyTypeName + ? `data: ${mutator.bodyTypeName}<${body.definition}>` + : `data: ${body.definition}` + : definition, + ) + .join(';'); + + properties = props + .map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name)) + .join(','); + } const errorType = getQueryErrorType( operationName, @@ -221,11 +276,15 @@ ${hooksOptionImplementation} const mutationFn: MutationFunction>, ${ - definitions ? `{${definitions}}` : 'void' + definitions + ? flatMutationCallArgs + ? definitions + : `{${definitions}}` + : 'void' }> = (${properties ? 'props' : ''}) => { ${properties ? `const {${properties}} = props ?? {};` : ''} - return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${properties}${ + return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${flatMutationCallArgs ?? properties}${ properties ? ',' : '' }${getMutationRequestArgs(isRequestOptions, httpClient, mutator)}) } diff --git a/packages/query/src/query-generator.ts b/packages/query/src/query-generator.ts index ea776e0a3a..2fd74a49a1 100644 --- a/packages/query/src/query-generator.ts +++ b/packages/query/src/query-generator.ts @@ -21,6 +21,7 @@ import { } from '@orval/core'; import { getHookOptions, getQueryErrorType, getQueryOptions } from './client'; +import { checkFlatInputCollisions } from './flat-input'; import type { FrameworkAdapter } from './framework-adapter'; import { generateMutationHook } from './mutation-generator'; import { @@ -159,6 +160,7 @@ const generateQueryImplementation = ({ useInfinite, useInvalidate, useSetQueryData, + useFlatInput, adapter, }: { queryOption: { @@ -189,6 +191,7 @@ const generateQueryImplementation = ({ useInfinite?: boolean; useInvalidate?: boolean; useSetQueryData?: boolean; + useFlatInput: boolean; adapter: FrameworkAdapter; }) => { const { @@ -373,7 +376,54 @@ const generateQueryImplementation = ({ // This avoids TS1016 "required param cannot follow optional param" const httpFirstParam = adapter.getHttpFirstParam(mutator); - const queryOptionsFn = `export const ${queryOptionsFnName} = (${httpFirstParam}${queryProps} ${queryArgumentsForOptions}) => { + const pathParams = props.filter( + (p) => + p.type === GetterPropType.PARAM || + p.type === GetterPropType.NAMED_PATH_PARAMS, + ); + const queryParamProp = props.find( + (p) => p.type === GetterPropType.QUERY_PARAM, + ); + const bodyProp = props.find((p) => p.type === GetterPropType.BODY); + const hasMultiplePropTypes = + (pathParams.length > 0 ? 1 : 0) + + (queryParamProp ? 1 : 0) + + (bodyProp ? 1 : 0) > + 1; + + let flatInputType = ''; + let flatInputDestructure = ''; + + if (useFlatInput && hasMultiplePropTypes) { + checkFlatInputCollisions(operationName, props, queryParams); + + const pathParamTypes = pathParams.map((p) => p.definition).join(';\n '); + const pathType = pathParams.length > 0 ? `{ ${pathParamTypes} }` : ''; + const queryType = queryParamProp ? queryParams?.schema.name : ''; + const bodyType = bodyProp + ? bodyProp.definition.split(':').slice(1).join(':').trim() + : ''; + + const types = [pathType, queryType, bodyType].filter(Boolean); + flatInputType = types.join(' & '); + + const pathNames = pathParams.map((p) => p.name); + const queryFieldNames = queryParams?.fieldNames ?? []; + + if (queryParamProp && bodyProp) { + const knownNames = [...pathNames, ...queryFieldNames]; + flatInputDestructure = `{ ${[...knownNames, `...${bodyProp.name}`].join(', ')} }: ${flatInputType},`; + } else if (queryParamProp) { + flatInputDestructure = `{ ${[...pathNames, '...params'].join(', ')} }: ${flatInputType},`; + } else if (bodyProp) { + flatInputDestructure = `{ ${[...pathNames, `...${bodyProp.name}`].join(', ')} }: ${flatInputType},`; + } + } + + const flatProps = + useFlatInput && flatInputDestructure ? flatInputDestructure : queryProps; + + const queryOptionsFn = `export const ${queryOptionsFnName} = (${httpFirstParam}${flatProps} ${queryArgumentsForOptions}) => { ${hookOptions} @@ -438,11 +488,6 @@ ${hookOptions} const queryHookName = camel(`${operationPrefix}-${name}`); - const overrideTypes = ` -export function ${queryHookName}(\n ${definedInitialDataQueryPropsDefinitions} ${definedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${definedInitialDataReturnType} -export function ${queryHookName}(\n ${queryPropDefinitions} ${undefinedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${returnType} -export function ${queryHookName}(\n ${queryPropDefinitions} ${queryArguments} ${optionalQueryClientArgument}\n ): ${returnType}`; - const prefetch = generatePrefetch({ usePrefetch, type, @@ -506,6 +551,26 @@ export function ${queryHookName}(\n ${q const queryInvocationSuffix = adapter.getQueryInvocationSuffix(); + const hookProps = + useFlatInput && flatInputDestructure + ? flatInputDestructure + : adapter.getHookPropsDefinitions(props); + + const hookPropsForDefinedInitialData = + useFlatInput && flatInputDestructure + ? flatInputDestructure + : definedInitialDataQueryPropsDefinitions; + + const hookPropsForOverloads = + useFlatInput && flatInputDestructure + ? flatInputDestructure + : queryPropDefinitions; + + const overrideTypes = ` +export function ${queryHookName}(\n ${hookPropsForDefinedInitialData} ${definedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${definedInitialDataReturnType} +export function ${queryHookName}(\n ${hookPropsForOverloads} ${undefinedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${returnType} +export function ${queryHookName}(\n ${hookPropsForOverloads} ${queryArguments} ${optionalQueryClientArgument}\n ): ${returnType}`; + return ` ${queryOptionsFn} @@ -516,9 +581,7 @@ export type ${pascal(name)}QueryError = ${errorType} ${adapter.shouldGenerateOverrideTypes() ? overrideTypes : ''} ${doc} -export function ${queryHookName}(\n ${adapter.getHookPropsDefinitions( - props, - )} ${queryArguments} ${optionalQueryClientArgument} \n ): ${returnType} { +export function ${queryHookName}(\n ${hookProps} ${queryArguments} ${optionalQueryClientArgument} \n ): ${returnType} { ${queryInit} @@ -598,6 +661,12 @@ export const generateQueryHook = async ( const query = override.query; const isRequestOptions = override.requestOptions !== false; const operationQueryOptions = operations[operationId]?.query; + + if (override.useFlatInput && override.useNamedParameters) { + throw new Error( + 'useFlatInput and useNamedParameters cannot be used together. useFlatInput already flattens all parameters into a single object.', + ); + } const isExactOptionalPropertyTypes = !!context.output.tsconfig?.compilerOptions?.exactOptionalPropertyTypes; @@ -827,6 +896,7 @@ ${queryKeyFns}`; useInvalidate: query.useInvalidate, useSetQueryData: operationQueryOptions?.useSetQueryData ?? query.useSetQueryData, + useFlatInput: !!override.useFlatInput, adapter, }); } diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts new file mode 100644 index 0000000000..b8a3f7227d --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts @@ -0,0 +1,148 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Multi query params + * OpenAPI spec version: 1.0.0 + */ +import { + useQuery +} from '@tanstack/react-query'; +import type { + DataTag, + DefinedInitialDataOptions, + DefinedUseQueryResult, + QueryClient, + QueryFunction, + QueryKey, + UndefinedInitialDataOptions, + UseQueryOptions, + UseQueryResult +} from '@tanstack/react-query'; + +import type { + GetUsersUserIdOrdersParams +} from './model'; + +/** + * Retrieves a list of orders for a specific user with optional filtering + * @summary Get user orders + */ +export type getUsersUserIdOrdersResponse200 = { + data: string[] + status: 200 +} + +export type getUsersUserIdOrdersResponseSuccess = (getUsersUserIdOrdersResponse200) & { + headers: Headers; +}; +; + +export type getUsersUserIdOrdersResponse = (getUsersUserIdOrdersResponseSuccess) + +export const getGetUsersUserIdOrdersUrl = (userId: number, + params?: GetUsersUserIdOrdersParams,) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()) + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 ? `/users/${userId}/orders?${stringifiedParams}` : `/users/${userId}/orders` +} + +export const getUsersUserIdOrders = async (userId: number, + params?: GetUsersUserIdOrdersParams, options?: RequestInit): Promise => { + + const res = await fetch(getGetUsersUserIdOrdersUrl(userId,params), + { + ...options, + method: 'GET' + + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: getUsersUserIdOrdersResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as getUsersUserIdOrdersResponse +} + + + + + +export const getGetUsersUserIdOrdersQueryKey = (userId: number, + params?: GetUsersUserIdOrdersParams,) => { + return [ + `/users/${userId}/orders`, ...(params ? [params] : []) + ] as const; + } + + +export const getGetUsersUserIdOrdersQueryOptions = >, TError = unknown>({ userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +) => { + +const {query: queryOptions, fetch: fetchOptions} = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getGetUsersUserIdOrdersQueryKey(userId,params); + + + + const queryFn: QueryFunction>> = ({ signal }) => getUsersUserIdOrders(userId,params, { signal, ...fetchOptions }); + + + + + + return { queryKey, queryFn, enabled: !!(userId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } +} + +export type GetUsersUserIdOrdersQueryResult = NonNullable>> +export type GetUsersUserIdOrdersQueryError = unknown + + +export function useGetUsersUserIdOrders>, TError = unknown>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options: { query:Partial>, TError, TData>> & Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): DefinedUseQueryResult & { queryKey: DataTag } +export function useGetUsersUserIdOrders>, TError = unknown>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>> & Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +export function useGetUsersUserIdOrders>, TError = unknown>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +/** + * @summary Get user orders + */ + +export function useGetUsersUserIdOrders>, TError = unknown>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } { + + const queryOptions = getGetUsersUserIdOrdersQueryOptions(userId,params,options) + + const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts new file mode 100644 index 0000000000..287d0bc6cd --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts @@ -0,0 +1,24 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Multi query params + * OpenAPI spec version: 1.0.0 + */ +import type { GetUsersUserIdOrdersStatus } from './getUsersUserIdOrdersStatus'; + +export type GetUsersUserIdOrdersParams = { +/** + * Filter orders by status + */ +status?: GetUsersUserIdOrdersStatus; +/** + * Filter orders from this date (YYYY-MM-DD) + */ +fromDate?: string; +/** + * Maximum number of orders to return + * @minimum 1 + * @maximum 100 + */ +limit?: number; +}; diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts new file mode 100644 index 0000000000..fb6d986bbc --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts @@ -0,0 +1,15 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Multi query params + * OpenAPI spec version: 1.0.0 + */ + +export type GetUsersUserIdOrdersStatus = typeof GetUsersUserIdOrdersStatus[keyof typeof GetUsersUserIdOrdersStatus]; + + +export const GetUsersUserIdOrdersStatus = { + pending: 'pending', + completed: 'completed', + cancelled: 'cancelled', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/model/index.ts b/tests/__snapshots__/react-query/flat-input-multi-params/model/index.ts new file mode 100644 index 0000000000..97226f8607 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-multi-params/model/index.ts @@ -0,0 +1,9 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Multi query params + * OpenAPI spec version: 1.0.0 + */ + +export * from './getUsersUserIdOrdersParams'; +export * from './getUsersUserIdOrdersStatus'; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts new file mode 100644 index 0000000000..6721e6fee6 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts @@ -0,0 +1,120 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ +import { + useMutation +} from '@tanstack/react-query'; +import type { + MutationFunction, + QueryClient, + UseMutationOptions, + UseMutationResult +} from '@tanstack/react-query'; + +import type { + SearchItems200, + SearchItemsBody, + SearchItemsParams +} from './model'; + +/** + * @summary Search items with path, query, and body + */ +export type searchItemsResponse200 = { + data: SearchItems200 + status: 200 +} + +export type searchItemsResponseSuccess = (searchItemsResponse200) & { + headers: Headers; +}; +; + +export type searchItemsResponse = (searchItemsResponseSuccess) + +export const getSearchItemsUrl = (orgId: string, + params?: SearchItemsParams,) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()) + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 ? `/api/search/${orgId}?${stringifiedParams}` : `/api/search/${orgId}` +} + +export const searchItems = async (orgId: string, + searchItemsBody: SearchItemsBody, + params?: SearchItemsParams, options?: RequestInit): Promise => { + + const res = await fetch(getSearchItemsUrl(orgId,params), + { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json', ...options?.headers }, + body: JSON.stringify( + searchItemsBody,) + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: searchItemsResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as searchItemsResponse +} + + + + +export const getSearchItemsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext>, fetch?: RequestInit} +): UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext> => { + +const mutationKey = ['searchItems']; +const {mutation: mutationOptions, fetch: fetchOptions} = options ? + options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? + options + : {...options, mutation: {...options.mutation, mutationKey}} + : {mutation: { mutationKey, }, fetch: undefined}; + + + + + const mutationFn: MutationFunction>, { orgId: string } & SearchItemsParams & SearchItemsBody> = (props) => { + const {orgId, page, limit, ...data} = props ?? {}; + + return searchItems(orgId, { page, limit }, data,fetchOptions) + } + + + + + + + return { mutationFn, ...mutationOptions }} + + export type SearchItemsMutationResult = NonNullable>> + export type SearchItemsMutationBody = SearchItemsBody + export type SearchItemsMutationError = unknown + + /** + * @summary Search items with path, query, and body + */ +export const useSearchItems = (options?: { mutation?:UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext>, fetch?: RequestInit} + , queryClient?: QueryClient): UseMutationResult< + Awaited>, + TError, + {{ orgId: string } & SearchItemsParams & SearchItemsBody}, + TContext + > => { + return useMutation(getSearchItemsMutationOptions(options), queryClient); + } diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts new file mode 100644 index 0000000000..97f5a546ad --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ + +export * from './searchItems200'; +export * from './searchItems200ResultsItem'; +export * from './searchItemsBody'; +export * from './searchItemsBodyFilters'; +export * from './searchItemsParams'; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts new file mode 100644 index 0000000000..f34e0b8935 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ +import type { SearchItems200ResultsItem } from './searchItems200ResultsItem'; + +export type SearchItems200 = { + results?: SearchItems200ResultsItem[]; +}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts new file mode 100644 index 0000000000..810b5aa141 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItems200ResultsItem = { + id?: string; + name?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts new file mode 100644 index 0000000000..7123d784aa --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ +import type { SearchItemsBodyFilters } from './searchItemsBodyFilters'; + +export type SearchItemsBody = { + query: string; + filters?: SearchItemsBodyFilters; +}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts new file mode 100644 index 0000000000..e48aba12a0 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItemsBodyFilters = { + status?: string; + category?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts new file mode 100644 index 0000000000..335f6c55f9 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Test - Query with Body + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItemsParams = { +page?: number; +limit?: number; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts new file mode 100644 index 0000000000..85539d5f5c --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts @@ -0,0 +1,752 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import { + useMutation, + useQuery +} from '@tanstack/react-query'; +import type { + DataTag, + DefinedInitialDataOptions, + DefinedUseQueryResult, + MutationFunction, + QueryClient, + QueryFunction, + QueryKey, + UndefinedInitialDataOptions, + UseMutationOptions, + UseMutationResult, + UseQueryOptions, + UseQueryResult +} from '@tanstack/react-query'; + +import type { + CreatePetsBody, + CreatePetsHeaders, + CreatePetsParams, + Error, + ListPetsHeaders, + ListPetsParams, + Pet, + PetWithTag, + Pets +} from './model'; + +export type HTTPStatusCode1xx = 100 | 101 | 102 | 103; +export type HTTPStatusCode2xx = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207; +export type HTTPStatusCode3xx = 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308; +export type HTTPStatusCode4xx = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 426 | 428 | 429 | 431 | 451; +export type HTTPStatusCode5xx = 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511; +export type HTTPStatusCodes = HTTPStatusCode1xx | HTTPStatusCode2xx | HTTPStatusCode3xx | HTTPStatusCode4xx | HTTPStatusCode5xx; + + +/** + * @summary List all pets + */ +export type listPetsResponse200 = { + data: Pets + status: 200 +} + +export type listPetsResponseDefault = { + data: Error + status: Exclude +} + +export type listPetsResponseSuccess = (listPetsResponse200) & { + headers: Headers; +}; +export type listPetsResponseError = (listPetsResponseDefault) & { + headers: Headers; +}; + +export type listPetsResponse = (listPetsResponseSuccess | listPetsResponseError) + +export const getListPetsUrl = (params: ListPetsParams,) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()) + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets` +} + +export const listPets = async (params: ListPetsParams, + headers: ListPetsHeaders, options?: RequestInit): Promise => { + + const res = await fetch(getListPetsUrl(params), + { + ...options, + method: 'GET', + headers: { ...headers, ...options?.headers } + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: listPetsResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as listPetsResponse +} + + + + + +export const getListPetsQueryKey = (params?: ListPetsParams,) => { + return [ + `/pets`, ...(params ? [params] : []) + ] as const; + } + + +export const getListPetsQueryOptions = >, TError = Error>(params: ListPetsParams, + headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +) => { + +const {query: queryOptions, fetch: fetchOptions} = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getListPetsQueryKey(params); + + + + const queryFn: QueryFunction>> = ({ signal }) => listPets(params,headers, { signal, ...fetchOptions }); + + + + + + return { queryKey, queryFn, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } +} + +export type ListPetsQueryResult = NonNullable>> +export type ListPetsQueryError = Error + + +export function useListPets>, TError = Error>( + params: ListPetsParams, + headers: ListPetsHeaders, options: { query:Partial>, TError, TData>> & Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): DefinedUseQueryResult & { queryKey: DataTag } +export function useListPets>, TError = Error>( + params: ListPetsParams, + headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>> & Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +export function useListPets>, TError = Error>( + params: ListPetsParams, + headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +/** + * @summary List all pets + */ + +export function useListPets>, TError = Error>( + params: ListPetsParams, + headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } { + + const queryOptions = getListPetsQueryOptions(params,headers,options) + + const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + + + + + + +/** + * @summary Create a pet + */ +export type createPetsResponse200 = { + data: Pet + status: 200 +} + +export type createPetsResponseDefault = { + data: Error + status: Exclude +} + +export type createPetsResponseSuccess = (createPetsResponse200) & { + headers: Headers; +}; +export type createPetsResponseError = (createPetsResponseDefault) & { + headers: Headers; +}; + +export type createPetsResponse = (createPetsResponseSuccess | createPetsResponseError) + +export const getCreatePetsUrl = (params: CreatePetsParams,) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()) + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets` +} + +export const createPets = async (createPetsBody: CreatePetsBody, + params: CreatePetsParams, + headers: CreatePetsHeaders, options?: RequestInit): Promise => { + + const res = await fetch(getCreatePetsUrl(params), + { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json',...headers, ...options?.headers }, + body: JSON.stringify( + createPetsBody,) + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: createPetsResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as createPetsResponse +} + + + + +export const getCreatePetsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext>, fetch?: RequestInit} +): UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext> => { + +const mutationKey = ['createPets']; +const {mutation: mutationOptions, fetch: fetchOptions} = options ? + options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? + options + : {...options, mutation: {...options.mutation, mutationKey}} + : {mutation: { mutationKey, }, fetch: undefined}; + + + + + const mutationFn: MutationFunction>, CreatePetsParams & CreatePetsBody> = (props) => { + const {limit, sort, ...data} = props ?? {}; + + return createPets({ limit, sort }, data,fetchOptions) + } + + + + + + + return { mutationFn, ...mutationOptions }} + + export type CreatePetsMutationResult = NonNullable>> + export type CreatePetsMutationBody = CreatePetsBody + export type CreatePetsMutationError = Error + + /** + * @summary Create a pet + */ +export const useCreatePets = (options?: { mutation?:UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext>, fetch?: RequestInit} + , queryClient?: QueryClient): UseMutationResult< + Awaited>, + TError, + {CreatePetsParams & CreatePetsBody}, + TContext + > => { + return useMutation(getCreatePetsMutationOptions(options), queryClient); + } + +/** + * @summary Info for a specific pet + */ +export type showPetByIdResponse200 = { + data: Pet + status: 200 +} + +export type showPetByIdResponseDefault = { + data: Error + status: Exclude +} + +export type showPetByIdResponseSuccess = (showPetByIdResponse200) & { + headers: Headers; +}; +export type showPetByIdResponseError = (showPetByIdResponseDefault) & { + headers: Headers; +}; + +export type showPetByIdResponse = (showPetByIdResponseSuccess | showPetByIdResponseError) + +export const getShowPetByIdUrl = (petId: string,) => { + + + + + return `/pets/${petId}` +} + +export const showPetById = async (petId: string, options?: RequestInit): Promise => { + + const res = await fetch(getShowPetByIdUrl(petId), + { + ...options, + method: 'GET' + + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: showPetByIdResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as showPetByIdResponse +} + + + + + +export const getShowPetByIdQueryKey = (petId: string,) => { + return [ + `/pets/${petId}` + ] as const; + } + + +export const getShowPetByIdQueryOptions = >, TError = Error>(petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +) => { + +const {query: queryOptions, fetch: fetchOptions} = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getShowPetByIdQueryKey(petId); + + + + const queryFn: QueryFunction>> = ({ signal }) => showPetById(petId, { signal, ...fetchOptions }); + + + + + + return { queryKey, queryFn, enabled: !!(petId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } +} + +export type ShowPetByIdQueryResult = NonNullable>> +export type ShowPetByIdQueryError = Error + + +export function useShowPetById>, TError = Error>( + petId: string, options: { query:Partial>, TError, TData>> & Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): DefinedUseQueryResult & { queryKey: DataTag } +export function useShowPetById>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>> & Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +export function useShowPetById>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +/** + * @summary Info for a specific pet + */ + +export function useShowPetById>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } { + + const queryOptions = getShowPetByIdQueryOptions(petId,options) + + const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + + + + + + +/** + * @summary Deletes a specific pet + */ +export type deletePetByIdResponse204 = { + data: void + status: 204 +} + +export type deletePetByIdResponseDefault = { + data: Error + status: Exclude +} + +export type deletePetByIdResponseSuccess = (deletePetByIdResponse204) & { + headers: Headers; +}; +export type deletePetByIdResponseError = (deletePetByIdResponseDefault) & { + headers: Headers; +}; + +export type deletePetByIdResponse = (deletePetByIdResponseSuccess | deletePetByIdResponseError) + +export const getDeletePetByIdUrl = (petId: string,) => { + + + + + return `/pets/${petId}` +} + +export const deletePetById = async (petId: string, options?: RequestInit): Promise => { + + const res = await fetch(getDeletePetByIdUrl(petId), + { + ...options, + method: 'DELETE' + + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: deletePetByIdResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as deletePetByIdResponse +} + + + + +export const getDeletePetByIdMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{petId: string}, TContext>, fetch?: RequestInit} +): UseMutationOptions>, TError,{petId: string}, TContext> => { + +const mutationKey = ['deletePetById']; +const {mutation: mutationOptions, fetch: fetchOptions} = options ? + options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? + options + : {...options, mutation: {...options.mutation, mutationKey}} + : {mutation: { mutationKey, }, fetch: undefined}; + + + + + const mutationFn: MutationFunction>, {petId: string}> = (props) => { + const {petId} = props ?? {}; + + return deletePetById(petId,fetchOptions) + } + + + + + + + return { mutationFn, ...mutationOptions }} + + export type DeletePetByIdMutationResult = NonNullable>> + + export type DeletePetByIdMutationError = Error + + /** + * @summary Deletes a specific pet + */ +export const useDeletePetById = (options?: { mutation?:UseMutationOptions>, TError,{petId: string}, TContext>, fetch?: RequestInit} + , queryClient?: QueryClient): UseMutationResult< + Awaited>, + TError, + {petId: string}, + TContext + > => { + return useMutation(getDeletePetByIdMutationOptions(options), queryClient); + } + +/** + * @summary health check + */ +export type healthCheckResponse200 = { + data: string + status: 200 +} + +export type healthCheckResponseDefault = { + data: Error + status: Exclude +} + +export type healthCheckResponseSuccess = (healthCheckResponse200) & { + headers: Headers; +}; +export type healthCheckResponseError = (healthCheckResponseDefault) & { + headers: Headers; +}; + +export type healthCheckResponse = (healthCheckResponseSuccess | healthCheckResponseError) + +export const getHealthCheckUrl = () => { + + + + + return `/health` +} + +export const healthCheck = async ( options?: RequestInit): Promise => { + + const res = await fetch(getHealthCheckUrl(), + { + ...options, + method: 'GET' + + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: healthCheckResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as healthCheckResponse +} + + + + + +export const getHealthCheckQueryKey = () => { + return [ + `/health` + ] as const; + } + + +export const getHealthCheckQueryOptions = >, TError = Error>( options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +) => { + +const {query: queryOptions, fetch: fetchOptions} = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey(); + + + + const queryFn: QueryFunction>> = ({ signal }) => healthCheck({ signal, ...fetchOptions }); + + + + + + return { queryKey, queryFn, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } +} + +export type HealthCheckQueryResult = NonNullable>> +export type HealthCheckQueryError = Error + + +export function useHealthCheck>, TError = Error>( + options: { query:Partial>, TError, TData>> & Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): DefinedUseQueryResult & { queryKey: DataTag } +export function useHealthCheck>, TError = Error>( + options?: { query?:Partial>, TError, TData>> & Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +export function useHealthCheck>, TError = Error>( + options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +/** + * @summary health check + */ + +export function useHealthCheck>, TError = Error>( + options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } { + + const queryOptions = getHealthCheckQueryOptions(options) + + const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + + + + + + +/** + * @summary combinate nullable and $ref + */ +export type showPetWithOwnerResponse200 = { + data: PetWithTag + status: 200 +} + +export type showPetWithOwnerResponseDefault = { + data: Error + status: Exclude +} + +export type showPetWithOwnerResponseSuccess = (showPetWithOwnerResponse200) & { + headers: Headers; +}; +export type showPetWithOwnerResponseError = (showPetWithOwnerResponseDefault) & { + headers: Headers; +}; + +export type showPetWithOwnerResponse = (showPetWithOwnerResponseSuccess | showPetWithOwnerResponseError) + +export const getShowPetWithOwnerUrl = (petId: string,) => { + + + + + return `/pets/${petId}/owner` +} + +export const showPetWithOwner = async (petId: string, options?: RequestInit): Promise => { + + const res = await fetch(getShowPetWithOwnerUrl(petId), + { + ...options, + method: 'GET' + + + } +) + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: showPetWithOwnerResponse['data'] = body ? JSON.parse(body) : {} + return { data, status: res.status, headers: res.headers } as showPetWithOwnerResponse +} + + + + + +export const getShowPetWithOwnerQueryKey = (petId: string,) => { + return [ + `/pets/${petId}/owner` + ] as const; + } + + +export const getShowPetWithOwnerQueryOptions = >, TError = Error>(petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +) => { + +const {query: queryOptions, fetch: fetchOptions} = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getShowPetWithOwnerQueryKey(petId); + + + + const queryFn: QueryFunction>> = ({ signal }) => showPetWithOwner(petId, { signal, ...fetchOptions }); + + + + + + return { queryKey, queryFn, enabled: !!(petId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } +} + +export type ShowPetWithOwnerQueryResult = NonNullable>> +export type ShowPetWithOwnerQueryError = Error + + +export function useShowPetWithOwner>, TError = Error>( + petId: string, options: { query:Partial>, TError, TData>> & Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): DefinedUseQueryResult & { queryKey: DataTag } +export function useShowPetWithOwner>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>> & Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + > , 'initialData' + >, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +export function useShowPetWithOwner>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } +/** + * @summary combinate nullable and $ref + */ + +export function useShowPetWithOwner>, TError = Error>( + petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} + , queryClient?: QueryClient + ): UseQueryResult & { queryKey: DataTag } { + + const queryOptions = getShowPetWithOwnerQueryOptions(petId,options) + + const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/cat.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/cat.ts new file mode 100644 index 0000000000..f6224c562e --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/cat.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { CatType } from './catType'; + +export interface Cat { + petsRequested?: number; + type: CatType; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts new file mode 100644 index 0000000000..6079e86b9d --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts @@ -0,0 +1,13 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type CatType = typeof CatType[keyof typeof CatType]; + + +export const CatType = { + cat: 'cat', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsBody.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsBody.ts new file mode 100644 index 0000000000..d30eae9c59 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsBody.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type CreatePetsBody = { + name: string; + tag: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts new file mode 100644 index 0000000000..eeaa710663 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { CreatePetsXExample } from './createPetsXExample'; + +export type CreatePetsHeaders = { +/** + * Header parameters + */ +'X-EXAMPLE': CreatePetsXExample; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts new file mode 100644 index 0000000000..ac466c128a --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts @@ -0,0 +1,20 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { CreatePetsSort } from './createPetsSort'; + +export type CreatePetsParams = { +/** + * How many items to return at one time (max 100) + */ +limit?: string; +/** + * Which property to sort by? +Example: name sorts ASC while -name sorts DESC. + + */ +sort: CreatePetsSort; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts new file mode 100644 index 0000000000..56081f64e7 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts @@ -0,0 +1,16 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type CreatePetsSort = typeof CreatePetsSort[keyof typeof CreatePetsSort]; + + +export const CreatePetsSort = { + name: 'name', + '-name': '-name', + email: 'email', + '-email': '-email', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts new file mode 100644 index 0000000000..06d3066470 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts @@ -0,0 +1,15 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type CreatePetsXExample = typeof CreatePetsXExample[keyof typeof CreatePetsXExample]; + + +export const CreatePetsXExample = { + ONE: 'ONE', + TWO: 'TWO', + THREE: 'THREE', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dachshund.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshund.ts new file mode 100644 index 0000000000..4396f57599 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshund.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { DachshundBreed } from './dachshundBreed'; + +export interface Dachshund { + length: number; + breed: DachshundBreed; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts new file mode 100644 index 0000000000..80d1345e0e --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts @@ -0,0 +1,13 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type DachshundBreed = typeof DachshundBreed[keyof typeof DachshundBreed]; + + +export const DachshundBreed = { + Dachshund: 'Dachshund', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts new file mode 100644 index 0000000000..fcc8db6a0d --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts @@ -0,0 +1,17 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { Dachshund } from './dachshund'; +import type { DogType } from './dogType'; +import type { Labradoodle } from './labradoodle'; + +export type Dog = (Labradoodle & { + barksPerMinute?: number; + type: DogType; +}) | (Dachshund & { + barksPerMinute?: number; + type: DogType; +}); diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts new file mode 100644 index 0000000000..bed6f5950e --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts @@ -0,0 +1,13 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type DogType = typeof DogType[keyof typeof DogType]; + + +export const DogType = { + dog: 'dog', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/error.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/error.ts new file mode 100644 index 0000000000..39c458b5cc --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/error.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export interface Error { + code: number; + message: string; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/index.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/index.ts new file mode 100644 index 0000000000..89ce02c5c0 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/index.ts @@ -0,0 +1,30 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export * from './cat'; +export * from './catType'; +export * from './createPetsBody'; +export * from './createPetsHeaders'; +export * from './createPetsParams'; +export * from './createPetsSort'; +export * from './createPetsXExample'; +export * from './dachshund'; +export * from './dachshundBreed'; +export * from './dog'; +export * from './dogType'; +export * from './error'; +export * from './labradoodle'; +export * from './labradoodleBreed'; +export * from './listPetsHeaders'; +export * from './listPetsParams'; +export * from './listPetsSort'; +export * from './listPetsXExample'; +export * from './pet'; +export * from './petCallingCode'; +export * from './petCountry'; +export * from './pets'; +export * from './petWithTag'; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodle.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodle.ts new file mode 100644 index 0000000000..b93309d6fa --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodle.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { LabradoodleBreed } from './labradoodleBreed'; + +export interface Labradoodle { + cuteness: number; + breed: LabradoodleBreed; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts new file mode 100644 index 0000000000..9c86beefb7 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts @@ -0,0 +1,13 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type LabradoodleBreed = typeof LabradoodleBreed[keyof typeof LabradoodleBreed]; + + +export const LabradoodleBreed = { + Labradoodle: 'Labradoodle', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts new file mode 100644 index 0000000000..26941df301 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { ListPetsXExample } from './listPetsXExample'; + +export type ListPetsHeaders = { +/** + * Header parameters + */ +'X-EXAMPLE': ListPetsXExample; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts new file mode 100644 index 0000000000..2364f54a80 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts @@ -0,0 +1,20 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { ListPetsSort } from './listPetsSort'; + +export type ListPetsParams = { +/** + * How many items to return at one time (max 100) + */ +limit?: string; +/** + * Which property to sort by? +Example: name sorts ASC while -name sorts DESC. + + */ +sort: ListPetsSort; +}; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts new file mode 100644 index 0000000000..390ec115c0 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts @@ -0,0 +1,16 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type ListPetsSort = typeof ListPetsSort[keyof typeof ListPetsSort]; + + +export const ListPetsSort = { + name: 'name', + '-name': '-name', + email: 'email', + '-email': '-email', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts new file mode 100644 index 0000000000..88d19c2244 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts @@ -0,0 +1,15 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type ListPetsXExample = typeof ListPetsXExample[keyof typeof ListPetsXExample]; + + +export const ListPetsXExample = { + ONE: 'ONE', + TWO: 'TWO', + THREE: 'THREE', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts new file mode 100644 index 0000000000..282821cdb7 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts @@ -0,0 +1,28 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { Cat } from './cat'; +import type { Dog } from './dog'; +import type { PetCallingCode } from './petCallingCode'; +import type { PetCountry } from './petCountry'; + +export type Pet = (Dog & { + '@id'?: string; + id: number; + name: string; + tag?: string; + email?: string; + callingCode?: PetCallingCode; + country?: PetCountry; +}) | (Cat & { + '@id'?: string; + id: number; + name: string; + tag?: string; + email?: string; + callingCode?: PetCallingCode; + country?: PetCountry; +}); diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts new file mode 100644 index 0000000000..fd6c0c7413 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type PetCallingCode = typeof PetCallingCode[keyof typeof PetCallingCode]; + + +export const PetCallingCode = { + '+33': '+33', + '+420': '+420', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts new file mode 100644 index 0000000000..b669eee797 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts @@ -0,0 +1,14 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ + +export type PetCountry = typeof PetCountry[keyof typeof PetCountry]; + + +export const PetCountry = { + 'People\'s_Republic_of_China': 'People\'s Republic of China', + Uruguay: 'Uruguay', +} as const; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/petWithTag.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/petWithTag.ts new file mode 100644 index 0000000000..db9a5ebf0a --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/petWithTag.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { Pet } from './pet'; + +export interface PetWithTag { + tag: string; + pet: Pet | null; +} diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/pets.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/pets.ts new file mode 100644 index 0000000000..e6ca25e731 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/pets.ts @@ -0,0 +1,9 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Swagger Petstore + * OpenAPI spec version: 1.0.0 + */ +import type { Pet } from './pet'; + +export type Pets = Pet[]; diff --git a/tests/configs/react-query.config.ts b/tests/configs/react-query.config.ts index d05801a2f6..c802580e4f 100644 --- a/tests/configs/react-query.config.ts +++ b/tests/configs/react-query.config.ts @@ -773,4 +773,52 @@ export default defineConfig({ target: '../specifications/petstore.yaml', }, }, + flatInputPetstore: { + output: { + target: '../generated/react-query/flat-input-petstore/endpoints.ts', + schemas: '../generated/react-query/flat-input-petstore/model', + client: 'react-query', + headers: true, + override: { + useFlatInput: true, + }, + clean: true, + prettier: true, + }, + input: { + target: '../specifications/petstore.yaml', + }, + }, + flatInputMultiParams: { + output: { + target: '../generated/react-query/flat-input-multi-params/endpoints.ts', + schemas: '../generated/react-query/flat-input-multi-params/model', + client: 'react-query', + override: { + useFlatInput: true, + }, + clean: true, + prettier: true, + }, + input: { + target: '../specifications/multi-query-params.yaml', + }, + }, + flatInputPathQueryBody: { + output: { + target: + '../generated/react-query/flat-input-path-query-body/endpoints.ts', + schemas: + '../generated/react-query/flat-input-path-query-body/model', + client: 'react-query', + override: { + useFlatInput: true, + }, + clean: true, + prettier: true, + }, + input: { + target: '../specifications/flat-input-with-body-query.yaml', + }, + }, }); diff --git a/tests/specifications/flat-input-with-body-query.yaml b/tests/specifications/flat-input-with-body-query.yaml new file mode 100644 index 0000000000..383cac4066 --- /dev/null +++ b/tests/specifications/flat-input-with-body-query.yaml @@ -0,0 +1,60 @@ +openapi: '3.0.0' +info: + title: Flat Input Test - Query with Body + version: 1.0.0 +paths: + /api/search/{orgId}: + post: + operationId: searchItems + summary: Search items with path, query, and body + parameters: + - name: orgId + in: path + required: true + schema: + type: string + - name: page + in: query + required: false + schema: + type: integer + - name: limit + in: query + required: false + schema: + type: integer + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - query + properties: + query: + type: string + filters: + type: object + properties: + status: + type: string + category: + type: string + responses: + '200': + description: Search results + content: + application/json: + schema: + type: object + properties: + results: + type: array + items: + type: object + properties: + id: + type: string + name: + type: string From dce0b6780f0e4c4dad085ed5f6ad9dfc40dceb9f Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 09:11:53 +0300 Subject: [PATCH 02/10] chore: fix prettier formatting --- tests/configs/react-query.config.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/configs/react-query.config.ts b/tests/configs/react-query.config.ts index c802580e4f..f0fb6d21ef 100644 --- a/tests/configs/react-query.config.ts +++ b/tests/configs/react-query.config.ts @@ -808,8 +808,7 @@ export default defineConfig({ output: { target: '../generated/react-query/flat-input-path-query-body/endpoints.ts', - schemas: - '../generated/react-query/flat-input-path-query-body/model', + schemas: '../generated/react-query/flat-input-path-query-body/model', client: 'react-query', override: { useFlatInput: true, From 2fcb2301d3f7990537d3e2aa3065b584d30486f1 Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 09:52:16 +0300 Subject: [PATCH 03/10] fix(query): resolve flat input mutation type issues - Fix double-wrapped braces in mutation variable types by threading overrideVariableType through getQueryOptionsDefinition and generateQueryArguments - Keep definitions in original format for downstream compatibility - Use separate flatVariableType for intersection types in mutationFn and options - Fix prettier: true -> formatter: 'prettier' in test configs --- packages/query/src/framework-adapter.ts | 1 + packages/query/src/frameworks/angular.ts | 2 ++ packages/query/src/frameworks/index.ts | 2 ++ packages/query/src/frameworks/svelte.ts | 2 ++ packages/query/src/mutation-generator.ts | 36 +++++++++---------- packages/query/src/query-options.ts | 8 +++-- .../flat-input-path-query-body/endpoints.ts | 8 ++--- .../flat-input-petstore/endpoints.ts | 8 ++--- tests/configs/react-query.config.ts | 6 ++-- 9 files changed, 42 insertions(+), 31 deletions(-) diff --git a/packages/query/src/framework-adapter.ts b/packages/query/src/framework-adapter.ts index 8a296fc73a..ff8c20d64d 100644 --- a/packages/query/src/framework-adapter.ts +++ b/packages/query/src/framework-adapter.ts @@ -207,6 +207,7 @@ export interface FrameworkAdapter { generateQueryArguments(args: { operationName: string; definitions: string; + overrideVariableType?: string; mutator?: GeneratorMutator; isRequestOptions: boolean; type?: (typeof QueryType)[keyof typeof QueryType]; diff --git a/packages/query/src/frameworks/angular.ts b/packages/query/src/frameworks/angular.ts index 829f5ccc26..a42dcbaf21 100644 --- a/packages/query/src/frameworks/angular.ts +++ b/packages/query/src/frameworks/angular.ts @@ -191,6 +191,7 @@ export const createAngularAdapter = ({ generateQueryArguments({ operationName, definitions, + overrideVariableType, mutator, isRequestOptions, type, @@ -205,6 +206,7 @@ export const createAngularAdapter = ({ operationName, mutator, definitions, + overrideVariableType, type, prefix, hasQueryV5, diff --git a/packages/query/src/frameworks/index.ts b/packages/query/src/frameworks/index.ts index 5efc024196..b1843790bc 100644 --- a/packages/query/src/frameworks/index.ts +++ b/packages/query/src/frameworks/index.ts @@ -116,6 +116,7 @@ const withDefaults = (adapter: FrameworkAdapterConfig): FrameworkAdapter => ({ generateQueryArguments({ operationName, definitions, + overrideVariableType, mutator, isRequestOptions, type, @@ -130,6 +131,7 @@ const withDefaults = (adapter: FrameworkAdapterConfig): FrameworkAdapter => ({ operationName, mutator, definitions, + overrideVariableType, type, prefix, hasQueryV5: adapter.hasQueryV5, diff --git a/packages/query/src/frameworks/svelte.ts b/packages/query/src/frameworks/svelte.ts index 68421fece3..71135b0e0d 100644 --- a/packages/query/src/frameworks/svelte.ts +++ b/packages/query/src/frameworks/svelte.ts @@ -166,6 +166,7 @@ export const createSvelteAdapter = ({ generateQueryArguments({ operationName, definitions, + overrideVariableType, mutator, isRequestOptions, type, @@ -180,6 +181,7 @@ export const createSvelteAdapter = ({ operationName, mutator, definitions, + overrideVariableType, type, prefix, hasQueryV5, diff --git a/packages/query/src/mutation-generator.ts b/packages/query/src/mutation-generator.ts index e853cf9f18..c6dda45942 100644 --- a/packages/query/src/mutation-generator.ts +++ b/packages/query/src/mutation-generator.ts @@ -124,9 +124,19 @@ export const generateMutationHook = async ({ checkFlatInputCollisions(operationName, props, queryParams); } - let definitions: string; + const definitions = props + .map(({ definition, type }) => + type === GetterPropType.BODY + ? mutator?.bodyTypeName + ? `data: ${mutator.bodyTypeName}<${body.definition}>` + : `data: ${body.definition}` + : definition, + ) + .join(';'); + let properties: string; let flatMutationCallArgs: string | undefined; + let flatVariableType: string | undefined; if (useFlatInput && props.length > 1) { const pathParamProps = props.filter( @@ -151,7 +161,7 @@ export const generateMutationHook = async ({ : body.definition : ''; const types = [pathType, queryType, bodyType].filter(Boolean); - definitions = types.join(' & '); + flatVariableType = types.join(' & '); const knownNames = [ ...pathParamProps.map((p) => p.name), @@ -170,16 +180,6 @@ export const generateMutationHook = async ({ .filter(Boolean) .join(', '); } else { - definitions = props - .map(({ definition, type }) => - type === GetterPropType.BODY - ? mutator?.bodyTypeName - ? `data: ${mutator.bodyTypeName}<${body.definition}>` - : `data: ${body.definition}` - : definition, - ) - .join(';'); - properties = props .map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name)) .join(','); @@ -200,6 +200,7 @@ export const generateMutationHook = async ({ operationName, mutator, definitions, + overrideVariableType: flatVariableType, prefix: adapter.getQueryOptionsDefinitionPrefix(), hasQueryV5: adapter.hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError: @@ -226,6 +227,7 @@ export const generateMutationHook = async ({ const mutationArguments = adapter.generateQueryArguments({ operationName, definitions, + overrideVariableType: flatVariableType, mutator, isRequestOptions, httpClient, @@ -236,6 +238,7 @@ export const generateMutationHook = async ({ const mutationArgumentsForOptions = adapter.generateQueryArguments({ operationName, definitions, + overrideVariableType: flatVariableType, mutator, isRequestOptions, httpClient, @@ -276,11 +279,7 @@ ${hooksOptionImplementation} const mutationFn: MutationFunction>, ${ - definitions - ? flatMutationCallArgs - ? definitions - : `{${definitions}}` - : 'void' + flatVariableType ?? (definitions ? `{${definitions}}` : 'void') }> = (${properties ? 'props' : ''}) => { ${properties ? `const {${properties}} = props ?? {};` : ''} @@ -341,7 +340,8 @@ ${ const mutationReturnType = adapter.getMutationReturnType({ dataType, - variableType: definitions ? `{${definitions}}` : 'void', + variableType: + flatVariableType ?? (definitions ? `{${definitions}}` : 'void'), }); const mutationHookBody = adapter.generateMutationHookBody({ diff --git a/packages/query/src/query-options.ts b/packages/query/src/query-options.ts index f252d81212..68e303a167 100644 --- a/packages/query/src/query-options.ts +++ b/packages/query/src/query-options.ts @@ -76,6 +76,7 @@ export const getQueryOptionsDefinition = ({ operationName, mutator, definitions, + overrideVariableType, type, prefix, hasQueryV5, @@ -89,6 +90,7 @@ export const getQueryOptionsDefinition = ({ operationName: string; mutator?: GeneratorMutator; definitions: string; + overrideVariableType?: string; type?: QueryType; /** 'Use' or 'Create' — from adapter.getQueryOptionsDefinitionPrefix() */ prefix: string; @@ -101,6 +103,8 @@ export const getQueryOptionsDefinition = ({ adapter?: FrameworkAdapter; }) => { const isMutatorHook = mutator?.isHook; + const varType = + overrideVariableType ?? (definitions ? `{${definitions}}` : 'void'); const partialOptions = !isReturnType && hasQueryV5; if (type) { @@ -177,10 +181,10 @@ export const getQueryOptionsDefinition = ({ isMutatorHook ? `ReturnType` : `typeof ${operationName}` - }>>, TError,${definitions ? `{${definitions}}` : 'void'}, TContext>` + }>>, TError,${varType}, TContext>` : `${prefix}MutationOptions` : `typeof ${operationName}` - }>>, TError,${definitions ? `{${definitions}}` : 'void'}, TContext>`; + }>>, TError,${varType}, TContext>`; }; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts index 6721e6fee6..2e7110e214 100644 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts @@ -75,8 +75,8 @@ export const searchItems = async (orgId: string, export const getSearchItemsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext>, fetch?: RequestInit} -): UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext> => { + TContext = unknown>(options?: { mutation?:UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext>, fetch?: RequestInit} +): UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext> => { const mutationKey = ['searchItems']; const {mutation: mutationOptions, fetch: fetchOptions} = options ? @@ -109,11 +109,11 @@ const {mutation: mutationOptions, fetch: fetchOptions} = options ? * @summary Search items with path, query, and body */ export const useSearchItems = (options?: { mutation?:UseMutationOptions>, TError,{{ orgId: string } & SearchItemsParams & SearchItemsBody}, TContext>, fetch?: RequestInit} + TContext = unknown>(options?: { mutation?:UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext>, fetch?: RequestInit} , queryClient?: QueryClient): UseMutationResult< Awaited>, TError, - {{ orgId: string } & SearchItemsParams & SearchItemsBody}, + { orgId: string } & SearchItemsParams & SearchItemsBody, TContext > => { return useMutation(getSearchItemsMutationOptions(options), queryClient); diff --git a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts index 85539d5f5c..645f0f48f0 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts @@ -242,8 +242,8 @@ export const createPets = async (createPetsBody: CreatePetsBody, export const getCreatePetsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext>, fetch?: RequestInit} -): UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext> => { + TContext = unknown>(options?: { mutation?:UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext>, fetch?: RequestInit} +): UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext> => { const mutationKey = ['createPets']; const {mutation: mutationOptions, fetch: fetchOptions} = options ? @@ -276,11 +276,11 @@ const {mutation: mutationOptions, fetch: fetchOptions} = options ? * @summary Create a pet */ export const useCreatePets = (options?: { mutation?:UseMutationOptions>, TError,{CreatePetsParams & CreatePetsBody}, TContext>, fetch?: RequestInit} + TContext = unknown>(options?: { mutation?:UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext>, fetch?: RequestInit} , queryClient?: QueryClient): UseMutationResult< Awaited>, TError, - {CreatePetsParams & CreatePetsBody}, + CreatePetsParams & CreatePetsBody, TContext > => { return useMutation(getCreatePetsMutationOptions(options), queryClient); diff --git a/tests/configs/react-query.config.ts b/tests/configs/react-query.config.ts index f0fb6d21ef..edd2696117 100644 --- a/tests/configs/react-query.config.ts +++ b/tests/configs/react-query.config.ts @@ -783,7 +783,7 @@ export default defineConfig({ useFlatInput: true, }, clean: true, - prettier: true, + formatter: 'prettier', }, input: { target: '../specifications/petstore.yaml', @@ -798,7 +798,7 @@ export default defineConfig({ useFlatInput: true, }, clean: true, - prettier: true, + formatter: 'prettier', }, input: { target: '../specifications/multi-query-params.yaml', @@ -814,7 +814,7 @@ export default defineConfig({ useFlatInput: true, }, clean: true, - prettier: true, + formatter: 'prettier', }, input: { target: '../specifications/flat-input-with-body-query.yaml', From 3d5fcbec3a46c00714945e675db6d49a6412baf4 Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 10:02:16 +0300 Subject: [PATCH 04/10] chore: regenerate flat input snapshots --- .../flat-input-multi-params/endpoints.ts | 266 ++-- .../model/getUsersUserIdOrdersParams.ts | 28 +- .../model/getUsersUserIdOrdersStatus.ts | 4 +- .../flat-input-path-query-body/endpoints.ts | 169 ++- .../model/searchItemsParams.ts | 4 +- .../flat-input-petstore/endpoints.ts | 1278 ++++++++++------- .../flat-input-petstore/model/catType.ts | 3 +- .../model/createPetsHeaders.ts | 8 +- .../model/createPetsParams.ts | 12 +- .../model/createPetsSort.ts | 4 +- .../model/createPetsXExample.ts | 4 +- .../model/dachshundBreed.ts | 4 +- .../flat-input-petstore/model/dog.ts | 16 +- .../flat-input-petstore/model/dogType.ts | 3 +- .../model/labradoodleBreed.ts | 4 +- .../model/listPetsHeaders.ts | 8 +- .../model/listPetsParams.ts | 12 +- .../flat-input-petstore/model/listPetsSort.ts | 3 +- .../model/listPetsXExample.ts | 4 +- .../flat-input-petstore/model/pet.ts | 36 +- .../model/petCallingCode.ts | 4 +- .../flat-input-petstore/model/petCountry.ts | 5 +- 22 files changed, 1141 insertions(+), 738 deletions(-) diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts index b8a3f7227d..859beed1e1 100644 --- a/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts @@ -4,9 +4,7 @@ * Multi query params * OpenAPI spec version: 1.0.0 */ -import { - useQuery -} from '@tanstack/react-query'; +import { useQuery } from '@tanstack/react-query'; import type { DataTag, DefinedInitialDataOptions, @@ -16,133 +14,223 @@ import type { QueryKey, UndefinedInitialDataOptions, UseQueryOptions, - UseQueryResult + UseQueryResult, } from '@tanstack/react-query'; -import type { - GetUsersUserIdOrdersParams -} from './model'; +import type { GetUsersUserIdOrdersParams } from './model'; /** * Retrieves a list of orders for a specific user with optional filtering * @summary Get user orders */ export type getUsersUserIdOrdersResponse200 = { - data: string[] - status: 200 -} - -export type getUsersUserIdOrdersResponseSuccess = (getUsersUserIdOrdersResponse200) & { - headers: Headers; + data: string[]; + status: 200; }; -; -export type getUsersUserIdOrdersResponse = (getUsersUserIdOrdersResponseSuccess) +export type getUsersUserIdOrdersResponseSuccess = + getUsersUserIdOrdersResponse200 & { + headers: Headers; + }; +export type getUsersUserIdOrdersResponse = getUsersUserIdOrdersResponseSuccess; -export const getGetUsersUserIdOrdersUrl = (userId: number, - params?: GetUsersUserIdOrdersParams,) => { +export const getGetUsersUserIdOrdersUrl = ( + userId: number, + params?: GetUsersUserIdOrdersParams, +) => { const normalizedParams = new URLSearchParams(); Object.entries(params || {}).forEach(([key, value]) => { - if (value !== undefined) { - normalizedParams.append(key, value === null ? 'null' : value.toString()) + normalizedParams.append(key, value === null ? 'null' : value.toString()); } }); const stringifiedParams = normalizedParams.toString(); - return stringifiedParams.length > 0 ? `/users/${userId}/orders?${stringifiedParams}` : `/users/${userId}/orders` -} - -export const getUsersUserIdOrders = async (userId: number, - params?: GetUsersUserIdOrdersParams, options?: RequestInit): Promise => { + return stringifiedParams.length > 0 + ? `/users/${userId}/orders?${stringifiedParams}` + : `/users/${userId}/orders`; +}; - const res = await fetch(getGetUsersUserIdOrdersUrl(userId,params), - { +export const getUsersUserIdOrders = async ( + userId: number, + params?: GetUsersUserIdOrdersParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getGetUsersUserIdOrdersUrl(userId, params), { ...options, - method: 'GET' - - - } -) + method: 'GET', + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: getUsersUserIdOrdersResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as getUsersUserIdOrdersResponse -} - - - - - -export const getGetUsersUserIdOrdersQueryKey = (userId: number, - params?: GetUsersUserIdOrdersParams,) => { - return [ - `/users/${userId}/orders`, ...(params ? [params] : []) - ] as const; - } - + const data: getUsersUserIdOrdersResponse['data'] = body + ? JSON.parse(body) + : {}; + return { + data, + status: res.status, + headers: res.headers, + } as getUsersUserIdOrdersResponse; +}; -export const getGetUsersUserIdOrdersQueryOptions = >, TError = unknown>({ userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +export const getGetUsersUserIdOrdersQueryKey = ( + userId: number, + params?: GetUsersUserIdOrdersParams, ) => { + return [`/users/${userId}/orders`, ...(params ? [params] : [])] as const; +}; -const {query: queryOptions, fetch: fetchOptions} = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getGetUsersUserIdOrdersQueryKey(userId,params); - - - - const queryFn: QueryFunction>> = ({ signal }) => getUsersUserIdOrders(userId,params, { signal, ...fetchOptions }); - - - - - - return { queryKey, queryFn, enabled: !!(userId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } -} - -export type GetUsersUserIdOrdersQueryResult = NonNullable>> -export type GetUsersUserIdOrdersQueryError = unknown - +export const getGetUsersUserIdOrdersQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = + queryOptions?.queryKey ?? getGetUsersUserIdOrdersQueryKey(userId, params); + + const queryFn: QueryFunction< + Awaited> + > = ({ signal }) => + getUsersUserIdOrders(userId, params, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!userId, + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; -export function useGetUsersUserIdOrders>, TError = unknown>( - { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options: { query:Partial>, TError, TData>> & Pick< +export type GetUsersUserIdOrdersQueryResult = NonNullable< + Awaited> +>; +export type GetUsersUserIdOrdersQueryError = unknown; + +export function useGetUsersUserIdOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + options: { + query: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + > & + Pick< DefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): DefinedUseQueryResult & { queryKey: DataTag } -export function useGetUsersUserIdOrders>, TError = unknown>( - { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>> & Pick< + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useGetUsersUserIdOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + > & + Pick< UndefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } -export function useGetUsersUserIdOrders>, TError = unknown>( - { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useGetUsersUserIdOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; /** * @summary Get user orders */ -export function useGetUsersUserIdOrders>, TError = unknown>( - { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } { - - const queryOptions = getGetUsersUserIdOrdersQueryOptions(userId,params,options) - - const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; +export function useGetUsersUserIdOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getGetUsersUserIdOrdersQueryOptions( + userId, + params, + options, + ); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; return { ...query, queryKey: queryOptions.queryKey }; } diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts index 287d0bc6cd..39019a0e05 100644 --- a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts +++ b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersParams.ts @@ -7,18 +7,18 @@ import type { GetUsersUserIdOrdersStatus } from './getUsersUserIdOrdersStatus'; export type GetUsersUserIdOrdersParams = { -/** - * Filter orders by status - */ -status?: GetUsersUserIdOrdersStatus; -/** - * Filter orders from this date (YYYY-MM-DD) - */ -fromDate?: string; -/** - * Maximum number of orders to return - * @minimum 1 - * @maximum 100 - */ -limit?: number; + /** + * Filter orders by status + */ + status?: GetUsersUserIdOrdersStatus; + /** + * Filter orders from this date (YYYY-MM-DD) + */ + fromDate?: string; + /** + * Maximum number of orders to return + * @minimum 1 + * @maximum 100 + */ + limit?: number; }; diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts index fb6d986bbc..0a2d04f5fd 100644 --- a/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts +++ b/tests/__snapshots__/react-query/flat-input-multi-params/model/getUsersUserIdOrdersStatus.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type GetUsersUserIdOrdersStatus = typeof GetUsersUserIdOrdersStatus[keyof typeof GetUsersUserIdOrdersStatus]; - +export type GetUsersUserIdOrdersStatus = + (typeof GetUsersUserIdOrdersStatus)[keyof typeof GetUsersUserIdOrdersStatus]; export const GetUsersUserIdOrdersStatus = { pending: 'pending', diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts index 2e7110e214..86298041c7 100644 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts @@ -4,117 +4,138 @@ * Flat Input Test - Query with Body * OpenAPI spec version: 1.0.0 */ -import { - useMutation -} from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import type { MutationFunction, QueryClient, UseMutationOptions, - UseMutationResult + UseMutationResult, } from '@tanstack/react-query'; import type { SearchItems200, SearchItemsBody, - SearchItemsParams + SearchItemsParams, } from './model'; /** * @summary Search items with path, query, and body */ export type searchItemsResponse200 = { - data: SearchItems200 - status: 200 -} + data: SearchItems200; + status: 200; +}; -export type searchItemsResponseSuccess = (searchItemsResponse200) & { +export type searchItemsResponseSuccess = searchItemsResponse200 & { headers: Headers; }; -; +export type searchItemsResponse = searchItemsResponseSuccess; -export type searchItemsResponse = (searchItemsResponseSuccess) - -export const getSearchItemsUrl = (orgId: string, - params?: SearchItemsParams,) => { +export const getSearchItemsUrl = ( + orgId: string, + params?: SearchItemsParams, +) => { const normalizedParams = new URLSearchParams(); Object.entries(params || {}).forEach(([key, value]) => { - if (value !== undefined) { - normalizedParams.append(key, value === null ? 'null' : value.toString()) + normalizedParams.append(key, value === null ? 'null' : value.toString()); } }); const stringifiedParams = normalizedParams.toString(); - return stringifiedParams.length > 0 ? `/api/search/${orgId}?${stringifiedParams}` : `/api/search/${orgId}` -} - -export const searchItems = async (orgId: string, - searchItemsBody: SearchItemsBody, - params?: SearchItemsParams, options?: RequestInit): Promise => { + return stringifiedParams.length > 0 + ? `/api/search/${orgId}?${stringifiedParams}` + : `/api/search/${orgId}`; +}; - const res = await fetch(getSearchItemsUrl(orgId,params), - { +export const searchItems = async ( + orgId: string, + searchItemsBody: SearchItemsBody, + params?: SearchItemsParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getSearchItemsUrl(orgId, params), { ...options, method: 'POST', headers: { 'Content-Type': 'application/json', ...options?.headers }, - body: JSON.stringify( - searchItemsBody,) - } -) + body: JSON.stringify(searchItemsBody), + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: searchItemsResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as searchItemsResponse -} - - - - -export const getSearchItemsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext>, fetch?: RequestInit} -): UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext> => { - -const mutationKey = ['searchItems']; -const {mutation: mutationOptions, fetch: fetchOptions} = options ? - options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? - options - : {...options, mutation: {...options.mutation, mutationKey}} - : {mutation: { mutationKey, }, fetch: undefined}; - - - - - const mutationFn: MutationFunction>, { orgId: string } & SearchItemsParams & SearchItemsBody> = (props) => { - const {orgId, page, limit, ...data} = props ?? {}; - - return searchItems(orgId, { page, limit }, data,fetchOptions) - } - - - - - + const data: searchItemsResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as searchItemsResponse; +}; - return { mutationFn, ...mutationOptions }} +export const getSearchItemsMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string } & SearchItemsParams & SearchItemsBody, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { orgId: string } & SearchItemsParams & SearchItemsBody, + TContext +> => { + const mutationKey = ['searchItems']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { orgId: string } & SearchItemsParams & SearchItemsBody + > = (props) => { + const { orgId, page, limit, ...data } = props ?? {}; + + return searchItems(orgId, { page, limit }, data, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; - export type SearchItemsMutationResult = NonNullable>> - export type SearchItemsMutationBody = SearchItemsBody - export type SearchItemsMutationError = unknown +export type SearchItemsMutationResult = NonNullable< + Awaited> +>; +export type SearchItemsMutationBody = SearchItemsBody; +export type SearchItemsMutationError = unknown; - /** +/** * @summary Search items with path, query, and body */ -export const useSearchItems = (options?: { mutation?:UseMutationOptions>, TError,{ orgId: string } & SearchItemsParams & SearchItemsBody, TContext>, fetch?: RequestInit} - , queryClient?: QueryClient): UseMutationResult< - Awaited>, - TError, - { orgId: string } & SearchItemsParams & SearchItemsBody, - TContext - > => { - return useMutation(getSearchItemsMutationOptions(options), queryClient); - } +export const useSearchItems = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string } & SearchItemsParams & SearchItemsBody, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { orgId: string } & SearchItemsParams & SearchItemsBody, + TContext +> => { + return useMutation(getSearchItemsMutationOptions(options), queryClient); +}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts index 335f6c55f9..7866d4b198 100644 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts +++ b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts @@ -6,6 +6,6 @@ */ export type SearchItemsParams = { -page?: number; -limit?: number; + page?: number; + limit?: number; }; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts index 645f0f48f0..610c43deef 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts @@ -4,10 +4,7 @@ * Swagger Petstore * OpenAPI spec version: 1.0.0 */ -import { - useMutation, - useQuery -} from '@tanstack/react-query'; +import { useMutation, useQuery } from '@tanstack/react-query'; import type { DataTag, DefinedInitialDataOptions, @@ -20,7 +17,7 @@ import type { UseMutationOptions, UseMutationResult, UseQueryOptions, - UseQueryResult + UseQueryResult, } from '@tanstack/react-query'; import type { @@ -32,721 +29,1018 @@ import type { ListPetsParams, Pet, PetWithTag, - Pets + Pets, } from './model'; export type HTTPStatusCode1xx = 100 | 101 | 102 | 103; export type HTTPStatusCode2xx = 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207; export type HTTPStatusCode3xx = 300 | 301 | 302 | 303 | 304 | 305 | 307 | 308; -export type HTTPStatusCode4xx = 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 426 | 428 | 429 | 431 | 451; +export type HTTPStatusCode4xx = + | 400 + | 401 + | 402 + | 403 + | 404 + | 405 + | 406 + | 407 + | 408 + | 409 + | 410 + | 411 + | 412 + | 413 + | 414 + | 415 + | 416 + | 417 + | 418 + | 419 + | 420 + | 421 + | 422 + | 423 + | 424 + | 426 + | 428 + | 429 + | 431 + | 451; export type HTTPStatusCode5xx = 500 | 501 | 502 | 503 | 504 | 505 | 507 | 511; -export type HTTPStatusCodes = HTTPStatusCode1xx | HTTPStatusCode2xx | HTTPStatusCode3xx | HTTPStatusCode4xx | HTTPStatusCode5xx; - +export type HTTPStatusCodes = + | HTTPStatusCode1xx + | HTTPStatusCode2xx + | HTTPStatusCode3xx + | HTTPStatusCode4xx + | HTTPStatusCode5xx; /** * @summary List all pets */ export type listPetsResponse200 = { - data: Pets - status: 200 -} + data: Pets; + status: 200; +}; export type listPetsResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type listPetsResponseSuccess = (listPetsResponse200) & { +export type listPetsResponseSuccess = listPetsResponse200 & { headers: Headers; }; -export type listPetsResponseError = (listPetsResponseDefault) & { +export type listPetsResponseError = listPetsResponseDefault & { headers: Headers; }; -export type listPetsResponse = (listPetsResponseSuccess | listPetsResponseError) +export type listPetsResponse = listPetsResponseSuccess | listPetsResponseError; -export const getListPetsUrl = (params: ListPetsParams,) => { +export const getListPetsUrl = (params: ListPetsParams) => { const normalizedParams = new URLSearchParams(); Object.entries(params || {}).forEach(([key, value]) => { - if (value !== undefined) { - normalizedParams.append(key, value === null ? 'null' : value.toString()) + normalizedParams.append(key, value === null ? 'null' : value.toString()); } }); const stringifiedParams = normalizedParams.toString(); - return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets` -} - -export const listPets = async (params: ListPetsParams, - headers: ListPetsHeaders, options?: RequestInit): Promise => { + return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets`; +}; - const res = await fetch(getListPetsUrl(params), - { +export const listPets = async ( + params: ListPetsParams, + headers: ListPetsHeaders, + options?: RequestInit, +): Promise => { + const res = await fetch(getListPetsUrl(params), { ...options, method: 'GET', - headers: { ...headers, ...options?.headers } - - } -) + headers: { ...headers, ...options?.headers }, + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: listPetsResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as listPetsResponse -} - - - - - -export const getListPetsQueryKey = (params?: ListPetsParams,) => { - return [ - `/pets`, ...(params ? [params] : []) - ] as const; - } + const data: listPetsResponse['data'] = body ? JSON.parse(body) : {}; + return { data, status: res.status, headers: res.headers } as listPetsResponse; +}; +export const getListPetsQueryKey = (params?: ListPetsParams) => { + return [`/pets`, ...(params ? [params] : [])] as const; +}; -export const getListPetsQueryOptions = >, TError = Error>(params: ListPetsParams, - headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +export const getListPetsQueryOptions = < + TData = Awaited>, + TError = Error, +>( + params: ListPetsParams, + headers: ListPetsHeaders, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, ) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; -const {query: queryOptions, fetch: fetchOptions} = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getListPetsQueryKey(params); - - + const queryKey = queryOptions?.queryKey ?? getListPetsQueryKey(params); - const queryFn: QueryFunction>> = ({ signal }) => listPets(params,headers, { signal, ...fetchOptions }); - - - - - - return { queryKey, queryFn, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } -} - -export type ListPetsQueryResult = NonNullable>> -export type ListPetsQueryError = Error + const queryFn: QueryFunction>> = ({ + signal, + }) => listPets(params, headers, { signal, ...fetchOptions }); + return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; -export function useListPets>, TError = Error>( - params: ListPetsParams, - headers: ListPetsHeaders, options: { query:Partial>, TError, TData>> & Pick< +export type ListPetsQueryResult = NonNullable< + Awaited> +>; +export type ListPetsQueryError = Error; + +export function useListPets< + TData = Awaited>, + TError = Error, +>( + params: ListPetsParams, + headers: ListPetsHeaders, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< DefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): DefinedUseQueryResult & { queryKey: DataTag } -export function useListPets>, TError = Error>( - params: ListPetsParams, - headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>> & Pick< + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useListPets< + TData = Awaited>, + TError = Error, +>( + params: ListPetsParams, + headers: ListPetsHeaders, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< UndefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } -export function useListPets>, TError = Error>( - params: ListPetsParams, - headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useListPets< + TData = Awaited>, + TError = Error, +>( + params: ListPetsParams, + headers: ListPetsHeaders, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; /** * @summary List all pets */ -export function useListPets>, TError = Error>( - params: ListPetsParams, - headers: ListPetsHeaders, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } { - - const queryOptions = getListPetsQueryOptions(params,headers,options) - - const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; +export function useListPets< + TData = Awaited>, + TError = Error, +>( + params: ListPetsParams, + headers: ListPetsHeaders, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getListPetsQueryOptions(params, headers, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; return { ...query, queryKey: queryOptions.queryKey }; } - - - - - /** * @summary Create a pet */ export type createPetsResponse200 = { - data: Pet - status: 200 -} + data: Pet; + status: 200; +}; export type createPetsResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type createPetsResponseSuccess = (createPetsResponse200) & { +export type createPetsResponseSuccess = createPetsResponse200 & { headers: Headers; }; -export type createPetsResponseError = (createPetsResponseDefault) & { +export type createPetsResponseError = createPetsResponseDefault & { headers: Headers; }; -export type createPetsResponse = (createPetsResponseSuccess | createPetsResponseError) +export type createPetsResponse = + | createPetsResponseSuccess + | createPetsResponseError; -export const getCreatePetsUrl = (params: CreatePetsParams,) => { +export const getCreatePetsUrl = (params: CreatePetsParams) => { const normalizedParams = new URLSearchParams(); Object.entries(params || {}).forEach(([key, value]) => { - if (value !== undefined) { - normalizedParams.append(key, value === null ? 'null' : value.toString()) + normalizedParams.append(key, value === null ? 'null' : value.toString()); } }); const stringifiedParams = normalizedParams.toString(); - return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets` -} - -export const createPets = async (createPetsBody: CreatePetsBody, - params: CreatePetsParams, - headers: CreatePetsHeaders, options?: RequestInit): Promise => { + return stringifiedParams.length > 0 ? `/pets?${stringifiedParams}` : `/pets`; +}; - const res = await fetch(getCreatePetsUrl(params), - { +export const createPets = async ( + createPetsBody: CreatePetsBody, + params: CreatePetsParams, + headers: CreatePetsHeaders, + options?: RequestInit, +): Promise => { + const res = await fetch(getCreatePetsUrl(params), { ...options, method: 'POST', - headers: { 'Content-Type': 'application/json',...headers, ...options?.headers }, - body: JSON.stringify( - createPetsBody,) - } -) + headers: { + 'Content-Type': 'application/json', + ...headers, + ...options?.headers, + }, + body: JSON.stringify(createPetsBody), + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: createPetsResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as createPetsResponse -} - - - - -export const getCreatePetsMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext>, fetch?: RequestInit} -): UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext> => { - -const mutationKey = ['createPets']; -const {mutation: mutationOptions, fetch: fetchOptions} = options ? - options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? - options - : {...options, mutation: {...options.mutation, mutationKey}} - : {mutation: { mutationKey, }, fetch: undefined}; - - - - - const mutationFn: MutationFunction>, CreatePetsParams & CreatePetsBody> = (props) => { - const {limit, sort, ...data} = props ?? {}; - - return createPets({ limit, sort }, data,fetchOptions) - } - - - - - + const data: createPetsResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as createPetsResponse; +}; - return { mutationFn, ...mutationOptions }} +export const getCreatePetsMutationOptions = < + TError = Error, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + CreatePetsParams & CreatePetsBody, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + CreatePetsParams & CreatePetsBody, + TContext +> => { + const mutationKey = ['createPets']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + CreatePetsParams & CreatePetsBody + > = (props) => { + const { limit, sort, ...data } = props ?? {}; + + return createPets({ limit, sort }, data, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; - export type CreatePetsMutationResult = NonNullable>> - export type CreatePetsMutationBody = CreatePetsBody - export type CreatePetsMutationError = Error +export type CreatePetsMutationResult = NonNullable< + Awaited> +>; +export type CreatePetsMutationBody = CreatePetsBody; +export type CreatePetsMutationError = Error; - /** +/** * @summary Create a pet */ -export const useCreatePets = (options?: { mutation?:UseMutationOptions>, TError,CreatePetsParams & CreatePetsBody, TContext>, fetch?: RequestInit} - , queryClient?: QueryClient): UseMutationResult< - Awaited>, - TError, - CreatePetsParams & CreatePetsBody, - TContext - > => { - return useMutation(getCreatePetsMutationOptions(options), queryClient); - } +export const useCreatePets = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + CreatePetsParams & CreatePetsBody, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + CreatePetsParams & CreatePetsBody, + TContext +> => { + return useMutation(getCreatePetsMutationOptions(options), queryClient); +}; /** * @summary Info for a specific pet */ export type showPetByIdResponse200 = { - data: Pet - status: 200 -} + data: Pet; + status: 200; +}; export type showPetByIdResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type showPetByIdResponseSuccess = (showPetByIdResponse200) & { +export type showPetByIdResponseSuccess = showPetByIdResponse200 & { headers: Headers; }; -export type showPetByIdResponseError = (showPetByIdResponseDefault) & { +export type showPetByIdResponseError = showPetByIdResponseDefault & { headers: Headers; }; -export type showPetByIdResponse = (showPetByIdResponseSuccess | showPetByIdResponseError) - -export const getShowPetByIdUrl = (petId: string,) => { - - +export type showPetByIdResponse = + | showPetByIdResponseSuccess + | showPetByIdResponseError; +export const getShowPetByIdUrl = (petId: string) => { + return `/pets/${petId}`; +}; - return `/pets/${petId}` -} - -export const showPetById = async (petId: string, options?: RequestInit): Promise => { - - const res = await fetch(getShowPetByIdUrl(petId), - { +export const showPetById = async ( + petId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getShowPetByIdUrl(petId), { ...options, - method: 'GET' - - - } -) + method: 'GET', + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: showPetByIdResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as showPetByIdResponse -} - - - - - -export const getShowPetByIdQueryKey = (petId: string,) => { - return [ - `/pets/${petId}` - ] as const; - } + const data: showPetByIdResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as showPetByIdResponse; +}; +export const getShowPetByIdQueryKey = (petId: string) => { + return [`/pets/${petId}`] as const; +}; -export const getShowPetByIdQueryOptions = >, TError = Error>(petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +export const getShowPetByIdQueryOptions = < + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, ) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getShowPetByIdQueryKey(petId); + + const queryFn: QueryFunction>> = ({ + signal, + }) => showPetById(petId, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!petId, + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; -const {query: queryOptions, fetch: fetchOptions} = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getShowPetByIdQueryKey(petId); - - - - const queryFn: QueryFunction>> = ({ signal }) => showPetById(petId, { signal, ...fetchOptions }); - - - - - - return { queryKey, queryFn, enabled: !!(petId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } -} - -export type ShowPetByIdQueryResult = NonNullable>> -export type ShowPetByIdQueryError = Error - - -export function useShowPetById>, TError = Error>( - petId: string, options: { query:Partial>, TError, TData>> & Pick< +export type ShowPetByIdQueryResult = NonNullable< + Awaited> +>; +export type ShowPetByIdQueryError = Error; + +export function useShowPetById< + TData = Awaited>, + TError = Error, +>( + petId: string, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< DefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): DefinedUseQueryResult & { queryKey: DataTag } -export function useShowPetById>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>> & Pick< + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useShowPetById< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< UndefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } -export function useShowPetById>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useShowPetById< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; /** * @summary Info for a specific pet */ -export function useShowPetById>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } { - - const queryOptions = getShowPetByIdQueryOptions(petId,options) - - const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; +export function useShowPetById< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getShowPetByIdQueryOptions(petId, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; return { ...query, queryKey: queryOptions.queryKey }; } - - - - - /** * @summary Deletes a specific pet */ export type deletePetByIdResponse204 = { - data: void - status: 204 -} + data: void; + status: 204; +}; export type deletePetByIdResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type deletePetByIdResponseSuccess = (deletePetByIdResponse204) & { +export type deletePetByIdResponseSuccess = deletePetByIdResponse204 & { headers: Headers; }; -export type deletePetByIdResponseError = (deletePetByIdResponseDefault) & { +export type deletePetByIdResponseError = deletePetByIdResponseDefault & { headers: Headers; }; -export type deletePetByIdResponse = (deletePetByIdResponseSuccess | deletePetByIdResponseError) - -export const getDeletePetByIdUrl = (petId: string,) => { - +export type deletePetByIdResponse = + | deletePetByIdResponseSuccess + | deletePetByIdResponseError; +export const getDeletePetByIdUrl = (petId: string) => { + return `/pets/${petId}`; +}; - - return `/pets/${petId}` -} - -export const deletePetById = async (petId: string, options?: RequestInit): Promise => { - - const res = await fetch(getDeletePetByIdUrl(petId), - { +export const deletePetById = async ( + petId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getDeletePetByIdUrl(petId), { ...options, - method: 'DELETE' - - - } -) + method: 'DELETE', + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: deletePetByIdResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as deletePetByIdResponse -} - - - - -export const getDeletePetByIdMutationOptions = (options?: { mutation?:UseMutationOptions>, TError,{petId: string}, TContext>, fetch?: RequestInit} -): UseMutationOptions>, TError,{petId: string}, TContext> => { - -const mutationKey = ['deletePetById']; -const {mutation: mutationOptions, fetch: fetchOptions} = options ? - options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ? - options - : {...options, mutation: {...options.mutation, mutationKey}} - : {mutation: { mutationKey, }, fetch: undefined}; - - - - - const mutationFn: MutationFunction>, {petId: string}> = (props) => { - const {petId} = props ?? {}; - - return deletePetById(petId,fetchOptions) - } - - - - - + const data: deletePetByIdResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as deletePetByIdResponse; +}; - return { mutationFn, ...mutationOptions }} +export const getDeletePetByIdMutationOptions = < + TError = Error, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { petId: string }, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { petId: string }, + TContext +> => { + const mutationKey = ['deletePetById']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { petId: string } + > = (props) => { + const { petId } = props ?? {}; + + return deletePetById(petId, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; - export type DeletePetByIdMutationResult = NonNullable>> +export type DeletePetByIdMutationResult = NonNullable< + Awaited> +>; - export type DeletePetByIdMutationError = Error +export type DeletePetByIdMutationError = Error; - /** +/** * @summary Deletes a specific pet */ -export const useDeletePetById = (options?: { mutation?:UseMutationOptions>, TError,{petId: string}, TContext>, fetch?: RequestInit} - , queryClient?: QueryClient): UseMutationResult< - Awaited>, - TError, - {petId: string}, - TContext - > => { - return useMutation(getDeletePetByIdMutationOptions(options), queryClient); - } +export const useDeletePetById = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { petId: string }, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { petId: string }, + TContext +> => { + return useMutation(getDeletePetByIdMutationOptions(options), queryClient); +}; /** * @summary health check */ export type healthCheckResponse200 = { - data: string - status: 200 -} + data: string; + status: 200; +}; export type healthCheckResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type healthCheckResponseSuccess = (healthCheckResponse200) & { +export type healthCheckResponseSuccess = healthCheckResponse200 & { headers: Headers; }; -export type healthCheckResponseError = (healthCheckResponseDefault) & { +export type healthCheckResponseError = healthCheckResponseDefault & { headers: Headers; }; -export type healthCheckResponse = (healthCheckResponseSuccess | healthCheckResponseError) +export type healthCheckResponse = + | healthCheckResponseSuccess + | healthCheckResponseError; export const getHealthCheckUrl = () => { + return `/health`; +}; - - - - return `/health` -} - -export const healthCheck = async ( options?: RequestInit): Promise => { - - const res = await fetch(getHealthCheckUrl(), - { +export const healthCheck = async ( + options?: RequestInit, +): Promise => { + const res = await fetch(getHealthCheckUrl(), { ...options, - method: 'GET' - - - } -) + method: 'GET', + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: healthCheckResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as healthCheckResponse -} - - - - + const data: healthCheckResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as healthCheckResponse; +}; export const getHealthCheckQueryKey = () => { - return [ - `/health` - ] as const; - } - - -export const getHealthCheckQueryOptions = >, TError = Error>( options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} -) => { - -const {query: queryOptions, fetch: fetchOptions} = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey(); - - - - const queryFn: QueryFunction>> = ({ signal }) => healthCheck({ signal, ...fetchOptions }); - - - - - - return { queryKey, queryFn, ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } -} - -export type HealthCheckQueryResult = NonNullable>> -export type HealthCheckQueryError = Error + return [`/health`] as const; +}; +export const getHealthCheckQueryOptions = < + TData = Awaited>, + TError = Error, +>(options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; +}) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey(); + + const queryFn: QueryFunction>> = ({ + signal, + }) => healthCheck({ signal, ...fetchOptions }); + + return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; -export function useHealthCheck>, TError = Error>( - options: { query:Partial>, TError, TData>> & Pick< +export type HealthCheckQueryResult = NonNullable< + Awaited> +>; +export type HealthCheckQueryError = Error; + +export function useHealthCheck< + TData = Awaited>, + TError = Error, +>( + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< DefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): DefinedUseQueryResult & { queryKey: DataTag } -export function useHealthCheck>, TError = Error>( - options?: { query?:Partial>, TError, TData>> & Pick< + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useHealthCheck< + TData = Awaited>, + TError = Error, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< UndefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } -export function useHealthCheck>, TError = Error>( - options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useHealthCheck< + TData = Awaited>, + TError = Error, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; /** * @summary health check */ -export function useHealthCheck>, TError = Error>( - options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } { - - const queryOptions = getHealthCheckQueryOptions(options) - - const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; +export function useHealthCheck< + TData = Awaited>, + TError = Error, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getHealthCheckQueryOptions(options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; return { ...query, queryKey: queryOptions.queryKey }; } - - - - - /** * @summary combinate nullable and $ref */ export type showPetWithOwnerResponse200 = { - data: PetWithTag - status: 200 -} + data: PetWithTag; + status: 200; +}; export type showPetWithOwnerResponseDefault = { - data: Error - status: Exclude -} + data: Error; + status: Exclude; +}; -export type showPetWithOwnerResponseSuccess = (showPetWithOwnerResponse200) & { +export type showPetWithOwnerResponseSuccess = showPetWithOwnerResponse200 & { headers: Headers; }; -export type showPetWithOwnerResponseError = (showPetWithOwnerResponseDefault) & { +export type showPetWithOwnerResponseError = showPetWithOwnerResponseDefault & { headers: Headers; }; -export type showPetWithOwnerResponse = (showPetWithOwnerResponseSuccess | showPetWithOwnerResponseError) - -export const getShowPetWithOwnerUrl = (petId: string,) => { - - - - - return `/pets/${petId}/owner` -} +export type showPetWithOwnerResponse = + | showPetWithOwnerResponseSuccess + | showPetWithOwnerResponseError; -export const showPetWithOwner = async (petId: string, options?: RequestInit): Promise => { +export const getShowPetWithOwnerUrl = (petId: string) => { + return `/pets/${petId}/owner`; +}; - const res = await fetch(getShowPetWithOwnerUrl(petId), - { +export const showPetWithOwner = async ( + petId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getShowPetWithOwnerUrl(petId), { ...options, - method: 'GET' - - - } -) + method: 'GET', + }); const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - const data: showPetWithOwnerResponse['data'] = body ? JSON.parse(body) : {} - return { data, status: res.status, headers: res.headers } as showPetWithOwnerResponse -} - - - - - -export const getShowPetWithOwnerQueryKey = (petId: string,) => { - return [ - `/pets/${petId}/owner` - ] as const; - } + const data: showPetWithOwnerResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as showPetWithOwnerResponse; +}; +export const getShowPetWithOwnerQueryKey = (petId: string) => { + return [`/pets/${petId}/owner`] as const; +}; -export const getShowPetWithOwnerQueryOptions = >, TError = Error>(petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} +export const getShowPetWithOwnerQueryOptions = < + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, ) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getShowPetWithOwnerQueryKey(petId); + + const queryFn: QueryFunction< + Awaited> + > = ({ signal }) => showPetWithOwner(petId, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!petId, + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; -const {query: queryOptions, fetch: fetchOptions} = options ?? {}; - - const queryKey = queryOptions?.queryKey ?? getShowPetWithOwnerQueryKey(petId); - - - - const queryFn: QueryFunction>> = ({ signal }) => showPetWithOwner(petId, { signal, ...fetchOptions }); - - - - - - return { queryKey, queryFn, enabled: !!(petId), ...queryOptions} as UseQueryOptions>, TError, TData> & { queryKey: DataTag } -} - -export type ShowPetWithOwnerQueryResult = NonNullable>> -export type ShowPetWithOwnerQueryError = Error - - -export function useShowPetWithOwner>, TError = Error>( - petId: string, options: { query:Partial>, TError, TData>> & Pick< +export type ShowPetWithOwnerQueryResult = NonNullable< + Awaited> +>; +export type ShowPetWithOwnerQueryError = Error; + +export function useShowPetWithOwner< + TData = Awaited>, + TError = Error, +>( + petId: string, + options: { + query: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + > & + Pick< DefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): DefinedUseQueryResult & { queryKey: DataTag } -export function useShowPetWithOwner>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>> & Pick< + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useShowPetWithOwner< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + > & + Pick< UndefinedInitialDataOptions< Awaited>, TError, Awaited> - > , 'initialData' - >, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } -export function useShowPetWithOwner>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useShowPetWithOwner< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; /** * @summary combinate nullable and $ref */ -export function useShowPetWithOwner>, TError = Error>( - petId: string, options?: { query?:Partial>, TError, TData>>, fetch?: RequestInit} - , queryClient?: QueryClient - ): UseQueryResult & { queryKey: DataTag } { - - const queryOptions = getShowPetWithOwnerQueryOptions(petId,options) - - const query = useQuery(queryOptions, queryClient) as UseQueryResult & { queryKey: DataTag }; +export function useShowPetWithOwner< + TData = Awaited>, + TError = Error, +>( + petId: string, + options?: { + query?: Partial< + UseQueryOptions< + Awaited>, + TError, + TData + > + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getShowPetWithOwnerQueryOptions(petId, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; return { ...query, queryKey: queryOptions.queryKey }; } diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts index 6079e86b9d..e7834ce494 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/catType.ts @@ -5,8 +5,7 @@ * OpenAPI spec version: 1.0.0 */ -export type CatType = typeof CatType[keyof typeof CatType]; - +export type CatType = (typeof CatType)[keyof typeof CatType]; export const CatType = { cat: 'cat', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts index eeaa710663..126c23faf2 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsHeaders.ts @@ -7,8 +7,8 @@ import type { CreatePetsXExample } from './createPetsXExample'; export type CreatePetsHeaders = { -/** - * Header parameters - */ -'X-EXAMPLE': CreatePetsXExample; + /** + * Header parameters + */ + 'X-EXAMPLE': CreatePetsXExample; }; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts index ac466c128a..174db18355 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsParams.ts @@ -7,14 +7,14 @@ import type { CreatePetsSort } from './createPetsSort'; export type CreatePetsParams = { -/** - * How many items to return at one time (max 100) - */ -limit?: string; -/** + /** + * How many items to return at one time (max 100) + */ + limit?: string; + /** * Which property to sort by? Example: name sorts ASC while -name sorts DESC. */ -sort: CreatePetsSort; + sort: CreatePetsSort; }; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts index 56081f64e7..479f1c6862 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsSort.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type CreatePetsSort = typeof CreatePetsSort[keyof typeof CreatePetsSort]; - +export type CreatePetsSort = + (typeof CreatePetsSort)[keyof typeof CreatePetsSort]; export const CreatePetsSort = { name: 'name', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts index 06d3066470..a4ce383179 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/createPetsXExample.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type CreatePetsXExample = typeof CreatePetsXExample[keyof typeof CreatePetsXExample]; - +export type CreatePetsXExample = + (typeof CreatePetsXExample)[keyof typeof CreatePetsXExample]; export const CreatePetsXExample = { ONE: 'ONE', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts index 80d1345e0e..a41d679cd5 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dachshundBreed.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type DachshundBreed = typeof DachshundBreed[keyof typeof DachshundBreed]; - +export type DachshundBreed = + (typeof DachshundBreed)[keyof typeof DachshundBreed]; export const DachshundBreed = { Dachshund: 'Dachshund', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts index fcc8db6a0d..d351c8d28f 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dog.ts @@ -8,10 +8,12 @@ import type { Dachshund } from './dachshund'; import type { DogType } from './dogType'; import type { Labradoodle } from './labradoodle'; -export type Dog = (Labradoodle & { - barksPerMinute?: number; - type: DogType; -}) | (Dachshund & { - barksPerMinute?: number; - type: DogType; -}); +export type Dog = + | (Labradoodle & { + barksPerMinute?: number; + type: DogType; + }) + | (Dachshund & { + barksPerMinute?: number; + type: DogType; + }); diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts index bed6f5950e..b043adf8ff 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/dogType.ts @@ -5,8 +5,7 @@ * OpenAPI spec version: 1.0.0 */ -export type DogType = typeof DogType[keyof typeof DogType]; - +export type DogType = (typeof DogType)[keyof typeof DogType]; export const DogType = { dog: 'dog', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts index 9c86beefb7..1c95b5fd88 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/labradoodleBreed.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type LabradoodleBreed = typeof LabradoodleBreed[keyof typeof LabradoodleBreed]; - +export type LabradoodleBreed = + (typeof LabradoodleBreed)[keyof typeof LabradoodleBreed]; export const LabradoodleBreed = { Labradoodle: 'Labradoodle', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts index 26941df301..66416ab0bd 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsHeaders.ts @@ -7,8 +7,8 @@ import type { ListPetsXExample } from './listPetsXExample'; export type ListPetsHeaders = { -/** - * Header parameters - */ -'X-EXAMPLE': ListPetsXExample; + /** + * Header parameters + */ + 'X-EXAMPLE': ListPetsXExample; }; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts index 2364f54a80..9548c70391 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsParams.ts @@ -7,14 +7,14 @@ import type { ListPetsSort } from './listPetsSort'; export type ListPetsParams = { -/** - * How many items to return at one time (max 100) - */ -limit?: string; -/** + /** + * How many items to return at one time (max 100) + */ + limit?: string; + /** * Which property to sort by? Example: name sorts ASC while -name sorts DESC. */ -sort: ListPetsSort; + sort: ListPetsSort; }; diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts index 390ec115c0..66384fc6ee 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsSort.ts @@ -5,8 +5,7 @@ * OpenAPI spec version: 1.0.0 */ -export type ListPetsSort = typeof ListPetsSort[keyof typeof ListPetsSort]; - +export type ListPetsSort = (typeof ListPetsSort)[keyof typeof ListPetsSort]; export const ListPetsSort = { name: 'name', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts index 88d19c2244..db09ecbaf9 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/listPetsXExample.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type ListPetsXExample = typeof ListPetsXExample[keyof typeof ListPetsXExample]; - +export type ListPetsXExample = + (typeof ListPetsXExample)[keyof typeof ListPetsXExample]; export const ListPetsXExample = { ONE: 'ONE', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts index 282821cdb7..f324116f84 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/pet.ts @@ -9,20 +9,22 @@ import type { Dog } from './dog'; import type { PetCallingCode } from './petCallingCode'; import type { PetCountry } from './petCountry'; -export type Pet = (Dog & { - '@id'?: string; - id: number; - name: string; - tag?: string; - email?: string; - callingCode?: PetCallingCode; - country?: PetCountry; -}) | (Cat & { - '@id'?: string; - id: number; - name: string; - tag?: string; - email?: string; - callingCode?: PetCallingCode; - country?: PetCountry; -}); +export type Pet = + | (Dog & { + '@id'?: string; + id: number; + name: string; + tag?: string; + email?: string; + callingCode?: PetCallingCode; + country?: PetCountry; + }) + | (Cat & { + '@id'?: string; + id: number; + name: string; + tag?: string; + email?: string; + callingCode?: PetCallingCode; + country?: PetCountry; + }); diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts index fd6c0c7413..82e89560c0 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/petCallingCode.ts @@ -5,8 +5,8 @@ * OpenAPI spec version: 1.0.0 */ -export type PetCallingCode = typeof PetCallingCode[keyof typeof PetCallingCode]; - +export type PetCallingCode = + (typeof PetCallingCode)[keyof typeof PetCallingCode]; export const PetCallingCode = { '+33': '+33', diff --git a/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts b/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts index b669eee797..bef64dd0c8 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/model/petCountry.ts @@ -5,10 +5,9 @@ * OpenAPI spec version: 1.0.0 */ -export type PetCountry = typeof PetCountry[keyof typeof PetCountry]; - +export type PetCountry = (typeof PetCountry)[keyof typeof PetCountry]; export const PetCountry = { - 'People\'s_Republic_of_China': 'People\'s Republic of China', + "People's_Republic_of_China": "People's Republic of China", Uruguay: 'Uruguay', } as const; From 47475c0d1039ac17af7b741930351ef78e30cac6 Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 10:05:10 +0300 Subject: [PATCH 05/10] fix: guard empty overrideVariableType with || instead of ?? --- packages/query/src/query-options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/query/src/query-options.ts b/packages/query/src/query-options.ts index 68e303a167..06fb990236 100644 --- a/packages/query/src/query-options.ts +++ b/packages/query/src/query-options.ts @@ -104,7 +104,7 @@ export const getQueryOptionsDefinition = ({ }) => { const isMutatorHook = mutator?.isHook; const varType = - overrideVariableType ?? (definitions ? `{${definitions}}` : 'void'); + overrideVariableType || (definitions ? `{${definitions}}` : 'void'); const partialOptions = !isReturnType && hasQueryV5; if (type) { From 95e913789445b7928a22fec278f8ccfa48285b98 Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Mon, 30 Mar 2026 10:28:20 +0300 Subject: [PATCH 06/10] fix: use ?? for overrideVariableType (empty string cannot occur) --- packages/query/src/query-options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/query/src/query-options.ts b/packages/query/src/query-options.ts index 06fb990236..68e303a167 100644 --- a/packages/query/src/query-options.ts +++ b/packages/query/src/query-options.ts @@ -104,7 +104,7 @@ export const getQueryOptionsDefinition = ({ }) => { const isMutatorHook = mutator?.isHook; const varType = - overrideVariableType || (definitions ? `{${definitions}}` : 'void'); + overrideVariableType ?? (definitions ? `{${definitions}}` : 'void'); const partialOptions = !isReturnType && hasQueryV5; if (type) { From c2bb8d4427a603636f04c153a28f0a9be84d425a Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Tue, 31 Mar 2026 14:59:16 +0300 Subject: [PATCH 07/10] fix(query): refactor flat input with centralized buildFlatInput utility - Consolidate all flat input logic into buildFlatInput() in flat-input.ts - Both query and mutation generators use the same utility - Fix mutation argument order to match client function signatures - Fix double-wrapped braces in mutation variable types via overrideVariableType - Skip flat input for mutations with headers (non-standard field names) - Add comprehensive test spec covering all 12 scenarios: no params, 1/2 path params, 1/2 query params, path+query, 2path+query, body only, path+body, query+body, path+query+body, delete with 2 path params --- packages/query/src/flat-input.ts | 93 + packages/query/src/mutation-generator.ts | 83 +- packages/query/src/query-generator.ts | 77 +- .../flat-input-multi-params/endpoints.ts | 3 +- .../flat-input-petstore/endpoints.ts | 34 +- .../flat-input-scenarios/endpoints.ts | 1765 +++++++++++++++++ .../model/createOrgProject201.ts | 10 + .../model/createOrgProjectBody.ts | 11 + .../model/createOrgProjectParams.ts | 10 + .../model/createPost201.ts | 10 + .../model/createPostBody.ts | 11 + .../model/createUserPost201.ts | 10 + .../model/createUserPostBody.ts | 11 + .../model/getTeamMembers200Item.ts | 10 + .../model/getTeamMembersParams.ts | 10 + .../flat-input-scenarios/model/getUser200.ts | 11 + .../model/getUserOrders200Item.ts | 10 + .../model/getUserOrdersParams.ts | 11 + .../model/getUserPost200.ts | 11 + .../model/healthCheck200.ts | 10 + .../flat-input-scenarios/model/index.ts | 29 + .../model/listItems200Item.ts | 10 + .../model/listItemsParams.ts | 10 + .../model/listProducts200Item.ts | 10 + .../model/listProductsParams.ts | 11 + .../model/searchItems200Item.ts | 10 + .../model/searchItemsBody.ts | 12 + .../model/searchItemsBodyFilters.ts | 10 + .../model/searchItemsParams.ts | 11 + tests/configs/react-query.config.ts | 9 +- .../specifications/flat-input-scenarios.yaml | 339 ++++ 31 files changed, 2529 insertions(+), 133 deletions(-) create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/endpoints.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProject201.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createPost201.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createPostBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPost201.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPostBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembers200Item.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembersParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getUser200.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrders200Item.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrdersParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/getUserPost200.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/healthCheck200.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/index.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/listItems200Item.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/listItemsParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/listProducts200Item.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/listProductsParams.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/searchItems200Item.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBody.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBodyFilters.ts create mode 100644 tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsParams.ts create mode 100644 tests/specifications/flat-input-scenarios.yaml diff --git a/packages/query/src/flat-input.ts b/packages/query/src/flat-input.ts index 385c21f0f3..a85d66dca3 100644 --- a/packages/query/src/flat-input.ts +++ b/packages/query/src/flat-input.ts @@ -4,6 +4,13 @@ import { type GetterQueryParam, } from '@orval/core'; +export interface FlatInputResult { + type: string; + destructure: string; + properties: string; + callArgs: string; +} + export function checkFlatInputCollisions( operationName: string, props: GetterProps, @@ -32,3 +39,89 @@ export function checkFlatInputCollisions( seen.add(name); } } + +export function buildFlatInput( + props: GetterProps, + queryParams?: GetterQueryParam, + bodyDefinition?: string, + bodyTypeName?: string, +): FlatInputResult | undefined { + const pathParams = props.filter( + (p) => + p.type === GetterPropType.PARAM || + p.type === GetterPropType.NAMED_PATH_PARAMS, + ); + const queryParamProp = props.find( + (p) => p.type === GetterPropType.QUERY_PARAM, + ); + const bodyProp = props.find((p) => p.type === GetterPropType.BODY); + const hasHeaders = props.some((p) => p.type === GetterPropType.HEADER); + + if (hasHeaders) { + return undefined; + } + + const propCount = + pathParams.length + (queryParamProp ? 1 : 0) + (bodyProp ? 1 : 0); + + if (propCount < 2 && pathParams.length < 2) { + return undefined; + } + + const pathType = + pathParams.length > 0 + ? `{ ${pathParams.map((p) => p.definition).join('; ')} }` + : ''; + const queryType = queryParamProp ? (queryParams?.schema.name ?? '') : ''; + const bodyType = bodyProp + ? bodyTypeName + ? `${bodyTypeName}<${bodyDefinition}>` + : (bodyDefinition ?? '') + : ''; + + const types = [pathType, queryType, bodyType].filter(Boolean); + const flatType = types.join(' & '); + + if (!flatType) { + return undefined; + } + + const pathNames = pathParams.map((p) => p.name); + const queryFieldNames = queryParams?.fieldNames ?? []; + const knownNames = [...pathNames, ...queryFieldNames]; + + let destructureNames: string[]; + if (bodyProp) { + destructureNames = [...knownNames, '...data']; + } else if (queryParamProp) { + destructureNames = [...pathNames, '...params']; + } else { + destructureNames = [...pathNames]; + } + + const properties = destructureNames.join(', '); + const destructure = `{ ${properties} }: ${flatType},`; + + const callArgs = props + .filter((p) => p.type !== GetterPropType.HEADER) + .map((p) => { + if ( + p.type === GetterPropType.PARAM || + p.type === GetterPropType.NAMED_PATH_PARAMS + ) { + return p.name; + } + if (p.type === GetterPropType.QUERY_PARAM) { + return queryFieldNames.length > 0 + ? `{ ${queryFieldNames.join(', ')} }` + : p.name; + } + if (p.type === GetterPropType.BODY) { + return 'data'; + } + return p.name; + }) + .join(', '); + + return { type: flatType, destructure, properties, callArgs }; +} diff --git a/packages/query/src/mutation-generator.ts b/packages/query/src/mutation-generator.ts index c6dda45942..b5c7d102cc 100644 --- a/packages/query/src/mutation-generator.ts +++ b/packages/query/src/mutation-generator.ts @@ -17,7 +17,7 @@ import { getMutationRequestArgs, getQueryErrorType, } from './client'; -import { checkFlatInputCollisions } from './flat-input'; +import { buildFlatInput, checkFlatInputCollisions } from './flat-input'; import type { FrameworkAdapter } from './framework-adapter'; import { getQueryOptionsDefinition } from './query-options'; @@ -120,9 +120,17 @@ export const generateMutationHook = async ({ const useFlatInput = !!override.useFlatInput; - if (useFlatInput && props.length > 1) { - checkFlatInputCollisions(operationName, props, queryParams); - } + const flatInput = useFlatInput + ? (() => { + checkFlatInputCollisions(operationName, props, queryParams); + return buildFlatInput( + props, + queryParams, + body.definition, + mutator?.bodyTypeName, + ); + })() + : undefined; const definitions = props .map(({ definition, type }) => @@ -134,56 +142,11 @@ export const generateMutationHook = async ({ ) .join(';'); - let properties: string; - let flatMutationCallArgs: string | undefined; - let flatVariableType: string | undefined; - - if (useFlatInput && props.length > 1) { - const pathParamProps = props.filter( - (p) => - p.type === GetterPropType.PARAM || - p.type === GetterPropType.NAMED_PATH_PARAMS, - ); - const queryParamProp = props.find( - (p) => p.type === GetterPropType.QUERY_PARAM, - ); - const bodyPropEntry = props.find((p) => p.type === GetterPropType.BODY); - const queryFieldNames = queryParams?.fieldNames ?? []; - - const pathType = - pathParamProps.length > 0 - ? `{ ${pathParamProps.map((p) => p.definition).join('; ')} }` - : ''; - const queryType = queryParamProp ? (queryParams?.schema.name ?? '') : ''; - const bodyType = bodyPropEntry - ? mutator?.bodyTypeName - ? `${mutator.bodyTypeName}<${body.definition}>` - : body.definition - : ''; - const types = [pathType, queryType, bodyType].filter(Boolean); - flatVariableType = types.join(' & '); - - const knownNames = [ - ...pathParamProps.map((p) => p.name), - ...queryFieldNames, - ]; - const hasBody = !!bodyPropEntry; - properties = hasBody - ? [...knownNames, '...data'].join(', ') - : knownNames.join(', '); - - const pathArgs = pathParamProps.map((p) => p.name).join(', '); - const queryArgs = - queryFieldNames.length > 0 ? `{ ${queryFieldNames.join(', ')} }` : ''; - const bodyArg = hasBody ? 'data' : ''; - flatMutationCallArgs = [pathArgs, queryArgs, bodyArg] - .filter(Boolean) - .join(', '); - } else { - properties = props - .map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name)) - .join(','); - } + const properties = flatInput + ? flatInput.properties + : props + .map(({ name, type }) => (type === GetterPropType.BODY ? 'data' : name)) + .join(','); const errorType = getQueryErrorType( operationName, @@ -200,7 +163,7 @@ export const generateMutationHook = async ({ operationName, mutator, definitions, - overrideVariableType: flatVariableType, + overrideVariableType: flatInput?.type, prefix: adapter.getQueryOptionsDefinitionPrefix(), hasQueryV5: adapter.hasQueryV5, hasQueryV5WithInfiniteQueryOptionsError: @@ -227,7 +190,7 @@ export const generateMutationHook = async ({ const mutationArguments = adapter.generateQueryArguments({ operationName, definitions, - overrideVariableType: flatVariableType, + overrideVariableType: flatInput?.type, mutator, isRequestOptions, httpClient, @@ -238,7 +201,7 @@ export const generateMutationHook = async ({ const mutationArgumentsForOptions = adapter.generateQueryArguments({ operationName, definitions, - overrideVariableType: flatVariableType, + overrideVariableType: flatInput?.type, mutator, isRequestOptions, httpClient, @@ -279,11 +242,11 @@ ${hooksOptionImplementation} const mutationFn: MutationFunction>, ${ - flatVariableType ?? (definitions ? `{${definitions}}` : 'void') + flatInput?.type ?? (definitions ? `{${definitions}}` : 'void') }> = (${properties ? 'props' : ''}) => { ${properties ? `const {${properties}} = props ?? {};` : ''} - return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${flatMutationCallArgs ?? properties}${ + return ${operationName}(${adapter.getMutationHttpPrefix(mutator)}${flatInput?.callArgs ?? properties}${ properties ? ',' : '' }${getMutationRequestArgs(isRequestOptions, httpClient, mutator)}) } @@ -341,7 +304,7 @@ ${ const mutationReturnType = adapter.getMutationReturnType({ dataType, variableType: - flatVariableType ?? (definitions ? `{${definitions}}` : 'void'), + flatInput?.type ?? (definitions ? `{${definitions}}` : 'void'), }); const mutationHookBody = adapter.generateMutationHookBody({ diff --git a/packages/query/src/query-generator.ts b/packages/query/src/query-generator.ts index 2fd74a49a1..651c6abf39 100644 --- a/packages/query/src/query-generator.ts +++ b/packages/query/src/query-generator.ts @@ -21,7 +21,7 @@ import { } from '@orval/core'; import { getHookOptions, getQueryErrorType, getQueryOptions } from './client'; -import { checkFlatInputCollisions } from './flat-input'; +import { buildFlatInput, checkFlatInputCollisions } from './flat-input'; import type { FrameworkAdapter } from './framework-adapter'; import { generateMutationHook } from './mutation-generator'; import { @@ -376,54 +376,14 @@ const generateQueryImplementation = ({ // This avoids TS1016 "required param cannot follow optional param" const httpFirstParam = adapter.getHttpFirstParam(mutator); - const pathParams = props.filter( - (p) => - p.type === GetterPropType.PARAM || - p.type === GetterPropType.NAMED_PATH_PARAMS, - ); - const queryParamProp = props.find( - (p) => p.type === GetterPropType.QUERY_PARAM, - ); - const bodyProp = props.find((p) => p.type === GetterPropType.BODY); - const hasMultiplePropTypes = - (pathParams.length > 0 ? 1 : 0) + - (queryParamProp ? 1 : 0) + - (bodyProp ? 1 : 0) > - 1; - - let flatInputType = ''; - let flatInputDestructure = ''; - - if (useFlatInput && hasMultiplePropTypes) { - checkFlatInputCollisions(operationName, props, queryParams); - - const pathParamTypes = pathParams.map((p) => p.definition).join(';\n '); - const pathType = pathParams.length > 0 ? `{ ${pathParamTypes} }` : ''; - const queryType = queryParamProp ? queryParams?.schema.name : ''; - const bodyType = bodyProp - ? bodyProp.definition.split(':').slice(1).join(':').trim() - : ''; - - const types = [pathType, queryType, bodyType].filter(Boolean); - flatInputType = types.join(' & '); - - const pathNames = pathParams.map((p) => p.name); - const queryFieldNames = queryParams?.fieldNames ?? []; - - if (queryParamProp && bodyProp) { - const knownNames = [...pathNames, ...queryFieldNames]; - flatInputDestructure = `{ ${[...knownNames, `...${bodyProp.name}`].join(', ')} }: ${flatInputType},`; - } else if (queryParamProp) { - flatInputDestructure = `{ ${[...pathNames, '...params'].join(', ')} }: ${flatInputType},`; - } else if (bodyProp) { - flatInputDestructure = `{ ${[...pathNames, `...${bodyProp.name}`].join(', ')} }: ${flatInputType},`; - } - } - - const flatProps = - useFlatInput && flatInputDestructure ? flatInputDestructure : queryProps; + const flatInput = useFlatInput + ? (() => { + checkFlatInputCollisions(operationName, props, queryParams); + return buildFlatInput(props, queryParams); + })() + : undefined; - const queryOptionsFn = `export const ${queryOptionsFnName} = (${httpFirstParam}${flatProps} ${queryArgumentsForOptions}) => { + const queryOptionsFn = `export const ${queryOptionsFnName} = (${httpFirstParam}${queryProps} ${queryArgumentsForOptions}) => { ${hookOptions} @@ -551,20 +511,17 @@ ${hookOptions} const queryInvocationSuffix = adapter.getQueryInvocationSuffix(); - const hookProps = - useFlatInput && flatInputDestructure - ? flatInputDestructure - : adapter.getHookPropsDefinitions(props); + const hookProps = flatInput + ? flatInput.destructure + : adapter.getHookPropsDefinitions(props); - const hookPropsForDefinedInitialData = - useFlatInput && flatInputDestructure - ? flatInputDestructure - : definedInitialDataQueryPropsDefinitions; + const hookPropsForDefinedInitialData = flatInput + ? flatInput.destructure + : definedInitialDataQueryPropsDefinitions; - const hookPropsForOverloads = - useFlatInput && flatInputDestructure - ? flatInputDestructure - : queryPropDefinitions; + const hookPropsForOverloads = flatInput + ? flatInput.destructure + : queryPropDefinitions; const overrideTypes = ` export function ${queryHookName}(\n ${hookPropsForDefinedInitialData} ${definedInitialDataQueryArguments} ${optionalQueryClientArgument}\n ): ${definedInitialDataReturnType} diff --git a/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts index 859beed1e1..d422e5f1fa 100644 --- a/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-multi-params/endpoints.ts @@ -86,7 +86,8 @@ export const getGetUsersUserIdOrdersQueryOptions = < TData = Awaited>, TError = unknown, >( - { userId, ...params }: { userId: number } & GetUsersUserIdOrdersParams, + userId: number, + params?: GetUsersUserIdOrdersParams, options?: { query?: Partial< UseQueryOptions< diff --git a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts index 610c43deef..afa5fb97df 100644 --- a/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts +++ b/tests/__snapshots__/react-query/flat-input-petstore/endpoints.ts @@ -330,14 +330,22 @@ export const getCreatePetsMutationOptions = < mutation?: UseMutationOptions< Awaited>, TError, - CreatePetsParams & CreatePetsBody, + { + data: CreatePetsBody; + params: CreatePetsParams; + headers: CreatePetsHeaders; + }, TContext >; fetch?: RequestInit; }): UseMutationOptions< Awaited>, TError, - CreatePetsParams & CreatePetsBody, + { + data: CreatePetsBody; + params: CreatePetsParams; + headers: CreatePetsHeaders; + }, TContext > => { const mutationKey = ['createPets']; @@ -351,11 +359,15 @@ export const getCreatePetsMutationOptions = < const mutationFn: MutationFunction< Awaited>, - CreatePetsParams & CreatePetsBody + { + data: CreatePetsBody; + params: CreatePetsParams; + headers: CreatePetsHeaders; + } > = (props) => { - const { limit, sort, ...data } = props ?? {}; + const { data, params, headers } = props ?? {}; - return createPets({ limit, sort }, data, fetchOptions); + return createPets(data, params, headers, fetchOptions); }; return { mutationFn, ...mutationOptions }; @@ -375,7 +387,11 @@ export const useCreatePets = ( mutation?: UseMutationOptions< Awaited>, TError, - CreatePetsParams & CreatePetsBody, + { + data: CreatePetsBody; + params: CreatePetsParams; + headers: CreatePetsHeaders; + }, TContext >; fetch?: RequestInit; @@ -384,7 +400,11 @@ export const useCreatePets = ( ): UseMutationResult< Awaited>, TError, - CreatePetsParams & CreatePetsBody, + { + data: CreatePetsBody; + params: CreatePetsParams; + headers: CreatePetsHeaders; + }, TContext > => { return useMutation(getCreatePetsMutationOptions(options), queryClient); diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/endpoints.ts b/tests/__snapshots__/react-query/flat-input-scenarios/endpoints.ts new file mode 100644 index 0000000000..8a583e2aaa --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/endpoints.ts @@ -0,0 +1,1765 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ +import { useMutation, useQuery } from '@tanstack/react-query'; +import type { + DataTag, + DefinedInitialDataOptions, + DefinedUseQueryResult, + MutationFunction, + QueryClient, + QueryFunction, + QueryKey, + UndefinedInitialDataOptions, + UseMutationOptions, + UseMutationResult, + UseQueryOptions, + UseQueryResult, +} from '@tanstack/react-query'; + +import type { + CreateOrgProject201, + CreateOrgProjectBody, + CreateOrgProjectParams, + CreatePost201, + CreatePostBody, + CreateUserPost201, + CreateUserPostBody, + GetTeamMembers200Item, + GetTeamMembersParams, + GetUser200, + GetUserOrders200Item, + GetUserOrdersParams, + GetUserPost200, + HealthCheck200, + ListItems200Item, + ListItemsParams, + ListProducts200Item, + ListProductsParams, + SearchItems200Item, + SearchItemsBody, + SearchItemsParams, +} from './model'; + +export type healthCheckResponse200 = { + data: HealthCheck200; + status: 200; +}; + +export type healthCheckResponseSuccess = healthCheckResponse200 & { + headers: Headers; +}; +export type healthCheckResponse = healthCheckResponseSuccess; + +export const getHealthCheckUrl = () => { + return `/health`; +}; + +export const healthCheck = async ( + options?: RequestInit, +): Promise => { + const res = await fetch(getHealthCheckUrl(), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: healthCheckResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as healthCheckResponse; +}; + +export const getHealthCheckQueryKey = () => { + return [`/health`] as const; +}; + +export const getHealthCheckQueryOptions = < + TData = Awaited>, + TError = unknown, +>(options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; +}) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getHealthCheckQueryKey(); + + const queryFn: QueryFunction>> = ({ + signal, + }) => healthCheck({ signal, ...fetchOptions }); + + return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type HealthCheckQueryResult = NonNullable< + Awaited> +>; +export type HealthCheckQueryError = unknown; + +export function useHealthCheck< + TData = Awaited>, + TError = unknown, +>( + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useHealthCheck< + TData = Awaited>, + TError = unknown, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useHealthCheck< + TData = Awaited>, + TError = unknown, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useHealthCheck< + TData = Awaited>, + TError = unknown, +>( + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getHealthCheckQueryOptions(options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type getUserResponse200 = { + data: GetUser200; + status: 200; +}; + +export type getUserResponseSuccess = getUserResponse200 & { + headers: Headers; +}; +export type getUserResponse = getUserResponseSuccess; + +export const getGetUserUrl = (userId: string) => { + return `/users/${userId}`; +}; + +export const getUser = async ( + userId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getGetUserUrl(userId), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: getUserResponse['data'] = body ? JSON.parse(body) : {}; + return { data, status: res.status, headers: res.headers } as getUserResponse; +}; + +export const getGetUserQueryKey = (userId: string) => { + return [`/users/${userId}`] as const; +}; + +export const getGetUserQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + userId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getGetUserQueryKey(userId); + + const queryFn: QueryFunction>> = ({ + signal, + }) => getUser(userId, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!userId, + ...queryOptions, + } as UseQueryOptions>, TError, TData> & { + queryKey: DataTag; + }; +}; + +export type GetUserQueryResult = NonNullable< + Awaited> +>; +export type GetUserQueryError = unknown; + +export function useGetUser< + TData = Awaited>, + TError = unknown, +>( + userId: string, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useGetUser< + TData = Awaited>, + TError = unknown, +>( + userId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useGetUser< + TData = Awaited>, + TError = unknown, +>( + userId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useGetUser< + TData = Awaited>, + TError = unknown, +>( + userId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getGetUserQueryOptions(userId, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type getUserPostResponse200 = { + data: GetUserPost200; + status: 200; +}; + +export type getUserPostResponseSuccess = getUserPostResponse200 & { + headers: Headers; +}; +export type getUserPostResponse = getUserPostResponseSuccess; + +export const getGetUserPostUrl = (userId: string, postId: string) => { + return `/users/${userId}/posts/${postId}`; +}; + +export const getUserPost = async ( + userId: string, + postId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getGetUserPostUrl(userId, postId), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: getUserPostResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as getUserPostResponse; +}; + +export const getGetUserPostQueryKey = (userId: string, postId: string) => { + return [`/users/${userId}/posts/${postId}`] as const; +}; + +export const getGetUserPostQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + userId: string, + postId: string, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = + queryOptions?.queryKey ?? getGetUserPostQueryKey(userId, postId); + + const queryFn: QueryFunction>> = ({ + signal, + }) => getUserPost(userId, postId, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!(userId && postId), + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type GetUserPostQueryResult = NonNullable< + Awaited> +>; +export type GetUserPostQueryError = unknown; + +export function useGetUserPost< + TData = Awaited>, + TError = unknown, +>( + { userId, postId }: { userId: string; postId: string }, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useGetUserPost< + TData = Awaited>, + TError = unknown, +>( + { userId, postId }: { userId: string; postId: string }, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useGetUserPost< + TData = Awaited>, + TError = unknown, +>( + { userId, postId }: { userId: string; postId: string }, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useGetUserPost< + TData = Awaited>, + TError = unknown, +>( + { userId, postId }: { userId: string; postId: string }, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getGetUserPostQueryOptions(userId, postId, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type listItemsResponse200 = { + data: ListItems200Item[]; + status: 200; +}; + +export type listItemsResponseSuccess = listItemsResponse200 & { + headers: Headers; +}; +export type listItemsResponse = listItemsResponseSuccess; + +export const getListItemsUrl = (params?: ListItemsParams) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/items?${stringifiedParams}` + : `/items`; +}; + +export const listItems = async ( + params?: ListItemsParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getListItemsUrl(params), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: listItemsResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as listItemsResponse; +}; + +export const getListItemsQueryKey = (params?: ListItemsParams) => { + return [`/items`, ...(params ? [params] : [])] as const; +}; + +export const getListItemsQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + params?: ListItemsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getListItemsQueryKey(params); + + const queryFn: QueryFunction>> = ({ + signal, + }) => listItems(params, { signal, ...fetchOptions }); + + return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type ListItemsQueryResult = NonNullable< + Awaited> +>; +export type ListItemsQueryError = unknown; + +export function useListItems< + TData = Awaited>, + TError = unknown, +>( + params: undefined | ListItemsParams, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useListItems< + TData = Awaited>, + TError = unknown, +>( + params?: ListItemsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useListItems< + TData = Awaited>, + TError = unknown, +>( + params?: ListItemsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useListItems< + TData = Awaited>, + TError = unknown, +>( + params?: ListItemsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getListItemsQueryOptions(params, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type listProductsResponse200 = { + data: ListProducts200Item[]; + status: 200; +}; + +export type listProductsResponseSuccess = listProductsResponse200 & { + headers: Headers; +}; +export type listProductsResponse = listProductsResponseSuccess; + +export const getListProductsUrl = (params?: ListProductsParams) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/products?${stringifiedParams}` + : `/products`; +}; + +export const listProducts = async ( + params?: ListProductsParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getListProductsUrl(params), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: listProductsResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as listProductsResponse; +}; + +export const getListProductsQueryKey = (params?: ListProductsParams) => { + return [`/products`, ...(params ? [params] : [])] as const; +}; + +export const getListProductsQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + params?: ListProductsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = queryOptions?.queryKey ?? getListProductsQueryKey(params); + + const queryFn: QueryFunction>> = ({ + signal, + }) => listProducts(params, { signal, ...fetchOptions }); + + return { queryKey, queryFn, ...queryOptions } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type ListProductsQueryResult = NonNullable< + Awaited> +>; +export type ListProductsQueryError = unknown; + +export function useListProducts< + TData = Awaited>, + TError = unknown, +>( + params: undefined | ListProductsParams, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useListProducts< + TData = Awaited>, + TError = unknown, +>( + params?: ListProductsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useListProducts< + TData = Awaited>, + TError = unknown, +>( + params?: ListProductsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useListProducts< + TData = Awaited>, + TError = unknown, +>( + params?: ListProductsParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getListProductsQueryOptions(params, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type getUserOrdersResponse200 = { + data: GetUserOrders200Item[]; + status: 200; +}; + +export type getUserOrdersResponseSuccess = getUserOrdersResponse200 & { + headers: Headers; +}; +export type getUserOrdersResponse = getUserOrdersResponseSuccess; + +export const getGetUserOrdersUrl = ( + userId: string, + params?: GetUserOrdersParams, +) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/users/${userId}/orders?${stringifiedParams}` + : `/users/${userId}/orders`; +}; + +export const getUserOrders = async ( + userId: string, + params?: GetUserOrdersParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getGetUserOrdersUrl(userId, params), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: getUserOrdersResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as getUserOrdersResponse; +}; + +export const getGetUserOrdersQueryKey = ( + userId: string, + params?: GetUserOrdersParams, +) => { + return [`/users/${userId}/orders`, ...(params ? [params] : [])] as const; +}; + +export const getGetUserOrdersQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + userId: string, + params?: GetUserOrdersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = + queryOptions?.queryKey ?? getGetUserOrdersQueryKey(userId, params); + + const queryFn: QueryFunction>> = ({ + signal, + }) => getUserOrders(userId, params, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!userId, + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type GetUserOrdersQueryResult = NonNullable< + Awaited> +>; +export type GetUserOrdersQueryError = unknown; + +export function useGetUserOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: string } & GetUserOrdersParams, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useGetUserOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: string } & GetUserOrdersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useGetUserOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: string } & GetUserOrdersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useGetUserOrders< + TData = Awaited>, + TError = unknown, +>( + { userId, ...params }: { userId: string } & GetUserOrdersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getGetUserOrdersQueryOptions(userId, params, options); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type getTeamMembersResponse200 = { + data: GetTeamMembers200Item[]; + status: 200; +}; + +export type getTeamMembersResponseSuccess = getTeamMembersResponse200 & { + headers: Headers; +}; +export type getTeamMembersResponse = getTeamMembersResponseSuccess; + +export const getGetTeamMembersUrl = ( + orgId: string, + teamId: string, + params?: GetTeamMembersParams, +) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/orgs/${orgId}/teams/${teamId}/members?${stringifiedParams}` + : `/orgs/${orgId}/teams/${teamId}/members`; +}; + +export const getTeamMembers = async ( + orgId: string, + teamId: string, + params?: GetTeamMembersParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getGetTeamMembersUrl(orgId, teamId, params), { + ...options, + method: 'GET', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: getTeamMembersResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as getTeamMembersResponse; +}; + +export const getGetTeamMembersQueryKey = ( + orgId: string, + teamId: string, + params?: GetTeamMembersParams, +) => { + return [ + `/orgs/${orgId}/teams/${teamId}/members`, + ...(params ? [params] : []), + ] as const; +}; + +export const getGetTeamMembersQueryOptions = < + TData = Awaited>, + TError = unknown, +>( + orgId: string, + teamId: string, + params?: GetTeamMembersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, +) => { + const { query: queryOptions, fetch: fetchOptions } = options ?? {}; + + const queryKey = + queryOptions?.queryKey ?? getGetTeamMembersQueryKey(orgId, teamId, params); + + const queryFn: QueryFunction>> = ({ + signal, + }) => getTeamMembers(orgId, teamId, params, { signal, ...fetchOptions }); + + return { + queryKey, + queryFn, + enabled: !!(orgId && teamId), + ...queryOptions, + } as UseQueryOptions< + Awaited>, + TError, + TData + > & { queryKey: DataTag }; +}; + +export type GetTeamMembersQueryResult = NonNullable< + Awaited> +>; +export type GetTeamMembersQueryError = unknown; + +export function useGetTeamMembers< + TData = Awaited>, + TError = unknown, +>( + { + orgId, + teamId, + ...params + }: { orgId: string; teamId: string } & GetTeamMembersParams, + options: { + query: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + DefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): DefinedUseQueryResult & { + queryKey: DataTag; +}; +export function useGetTeamMembers< + TData = Awaited>, + TError = unknown, +>( + { + orgId, + teamId, + ...params + }: { orgId: string; teamId: string } & GetTeamMembersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + > & + Pick< + UndefinedInitialDataOptions< + Awaited>, + TError, + Awaited> + >, + 'initialData' + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; +export function useGetTeamMembers< + TData = Awaited>, + TError = unknown, +>( + { + orgId, + teamId, + ...params + }: { orgId: string; teamId: string } & GetTeamMembersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +}; + +export function useGetTeamMembers< + TData = Awaited>, + TError = unknown, +>( + { + orgId, + teamId, + ...params + }: { orgId: string; teamId: string } & GetTeamMembersParams, + options?: { + query?: Partial< + UseQueryOptions>, TError, TData> + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseQueryResult & { + queryKey: DataTag; +} { + const queryOptions = getGetTeamMembersQueryOptions( + orgId, + teamId, + params, + options, + ); + + const query = useQuery(queryOptions, queryClient) as UseQueryResult< + TData, + TError + > & { queryKey: DataTag }; + + return { ...query, queryKey: queryOptions.queryKey }; +} + +export type createPostResponse201 = { + data: CreatePost201; + status: 201; +}; + +export type createPostResponseSuccess = createPostResponse201 & { + headers: Headers; +}; +export type createPostResponse = createPostResponseSuccess; + +export const getCreatePostUrl = () => { + return `/posts`; +}; + +export const createPost = async ( + createPostBody: CreatePostBody, + options?: RequestInit, +): Promise => { + const res = await fetch(getCreatePostUrl(), { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json', ...options?.headers }, + body: JSON.stringify(createPostBody), + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: createPostResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as createPostResponse; +}; + +export const getCreatePostMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { data: CreatePostBody }, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { data: CreatePostBody }, + TContext +> => { + const mutationKey = ['createPost']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { data: CreatePostBody } + > = (props) => { + const { data } = props ?? {}; + + return createPost(data, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type CreatePostMutationResult = NonNullable< + Awaited> +>; +export type CreatePostMutationBody = CreatePostBody; +export type CreatePostMutationError = unknown; + +export const useCreatePost = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { data: CreatePostBody }, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { data: CreatePostBody }, + TContext +> => { + return useMutation(getCreatePostMutationOptions(options), queryClient); +}; + +export type createUserPostResponse201 = { + data: CreateUserPost201; + status: 201; +}; + +export type createUserPostResponseSuccess = createUserPostResponse201 & { + headers: Headers; +}; +export type createUserPostResponse = createUserPostResponseSuccess; + +export const getCreateUserPostUrl = (userId: string) => { + return `/users/${userId}/posts`; +}; + +export const createUserPost = async ( + userId: string, + createUserPostBody: CreateUserPostBody, + options?: RequestInit, +): Promise => { + const res = await fetch(getCreateUserPostUrl(userId), { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json', ...options?.headers }, + body: JSON.stringify(createUserPostBody), + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: createUserPostResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as createUserPostResponse; +}; + +export const getCreateUserPostMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { userId: string } & CreateUserPostBody, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { userId: string } & CreateUserPostBody, + TContext +> => { + const mutationKey = ['createUserPost']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { userId: string } & CreateUserPostBody + > = (props) => { + const { userId, ...data } = props ?? {}; + + return createUserPost(userId, data, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type CreateUserPostMutationResult = NonNullable< + Awaited> +>; +export type CreateUserPostMutationBody = CreateUserPostBody; +export type CreateUserPostMutationError = unknown; + +export const useCreateUserPost = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { userId: string } & CreateUserPostBody, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { userId: string } & CreateUserPostBody, + TContext +> => { + return useMutation(getCreateUserPostMutationOptions(options), queryClient); +}; + +export type searchItemsResponse200 = { + data: SearchItems200Item[]; + status: 200; +}; + +export type searchItemsResponseSuccess = searchItemsResponse200 & { + headers: Headers; +}; +export type searchItemsResponse = searchItemsResponseSuccess; + +export const getSearchItemsUrl = (params?: SearchItemsParams) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/search?${stringifiedParams}` + : `/search`; +}; + +export const searchItems = async ( + searchItemsBody: SearchItemsBody, + params?: SearchItemsParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getSearchItemsUrl(params), { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json', ...options?.headers }, + body: JSON.stringify(searchItemsBody), + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: searchItemsResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as searchItemsResponse; +}; + +export const getSearchItemsMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + SearchItemsParams & SearchItemsBody, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + SearchItemsParams & SearchItemsBody, + TContext +> => { + const mutationKey = ['searchItems']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + SearchItemsParams & SearchItemsBody + > = (props) => { + const { page, limit, ...data } = props ?? {}; + + return searchItems(data, { page, limit }, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type SearchItemsMutationResult = NonNullable< + Awaited> +>; +export type SearchItemsMutationBody = SearchItemsBody; +export type SearchItemsMutationError = unknown; + +export const useSearchItems = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + SearchItemsParams & SearchItemsBody, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + SearchItemsParams & SearchItemsBody, + TContext +> => { + return useMutation(getSearchItemsMutationOptions(options), queryClient); +}; + +export type createOrgProjectResponse201 = { + data: CreateOrgProject201; + status: 201; +}; + +export type createOrgProjectResponseSuccess = createOrgProjectResponse201 & { + headers: Headers; +}; +export type createOrgProjectResponse = createOrgProjectResponseSuccess; + +export const getCreateOrgProjectUrl = ( + orgId: string, + params?: CreateOrgProjectParams, +) => { + const normalizedParams = new URLSearchParams(); + + Object.entries(params || {}).forEach(([key, value]) => { + if (value !== undefined) { + normalizedParams.append(key, value === null ? 'null' : value.toString()); + } + }); + + const stringifiedParams = normalizedParams.toString(); + + return stringifiedParams.length > 0 + ? `/orgs/${orgId}/projects?${stringifiedParams}` + : `/orgs/${orgId}/projects`; +}; + +export const createOrgProject = async ( + orgId: string, + createOrgProjectBody: CreateOrgProjectBody, + params?: CreateOrgProjectParams, + options?: RequestInit, +): Promise => { + const res = await fetch(getCreateOrgProjectUrl(orgId, params), { + ...options, + method: 'POST', + headers: { 'Content-Type': 'application/json', ...options?.headers }, + body: JSON.stringify(createOrgProjectBody), + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: createOrgProjectResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as createOrgProjectResponse; +}; + +export const getCreateOrgProjectMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string } & CreateOrgProjectParams & CreateOrgProjectBody, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { orgId: string } & CreateOrgProjectParams & CreateOrgProjectBody, + TContext +> => { + const mutationKey = ['createOrgProject']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { orgId: string } & CreateOrgProjectParams & CreateOrgProjectBody + > = (props) => { + const { orgId, templateId, ...data } = props ?? {}; + + return createOrgProject(orgId, data, { templateId }, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type CreateOrgProjectMutationResult = NonNullable< + Awaited> +>; +export type CreateOrgProjectMutationBody = CreateOrgProjectBody; +export type CreateOrgProjectMutationError = unknown; + +export const useCreateOrgProject = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string } & CreateOrgProjectParams & CreateOrgProjectBody, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { orgId: string } & CreateOrgProjectParams & CreateOrgProjectBody, + TContext +> => { + return useMutation(getCreateOrgProjectMutationOptions(options), queryClient); +}; + +export type removeOrgMemberResponse204 = { + data: void; + status: 204; +}; + +export type removeOrgMemberResponseSuccess = removeOrgMemberResponse204 & { + headers: Headers; +}; +export type removeOrgMemberResponse = removeOrgMemberResponseSuccess; + +export const getRemoveOrgMemberUrl = (orgId: string, memberId: string) => { + return `/orgs/${orgId}/members/${memberId}`; +}; + +export const removeOrgMember = async ( + orgId: string, + memberId: string, + options?: RequestInit, +): Promise => { + const res = await fetch(getRemoveOrgMemberUrl(orgId, memberId), { + ...options, + method: 'DELETE', + }); + + const body = [204, 205, 304].includes(res.status) ? null : await res.text(); + + const data: removeOrgMemberResponse['data'] = body ? JSON.parse(body) : {}; + return { + data, + status: res.status, + headers: res.headers, + } as removeOrgMemberResponse; +}; + +export const getRemoveOrgMemberMutationOptions = < + TError = unknown, + TContext = unknown, +>(options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string; memberId: string }, + TContext + >; + fetch?: RequestInit; +}): UseMutationOptions< + Awaited>, + TError, + { orgId: string; memberId: string }, + TContext +> => { + const mutationKey = ['removeOrgMember']; + const { mutation: mutationOptions, fetch: fetchOptions } = options + ? options.mutation && + 'mutationKey' in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey }, fetch: undefined }; + + const mutationFn: MutationFunction< + Awaited>, + { orgId: string; memberId: string } + > = (props) => { + const { orgId, memberId } = props ?? {}; + + return removeOrgMember(orgId, memberId, fetchOptions); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type RemoveOrgMemberMutationResult = NonNullable< + Awaited> +>; + +export type RemoveOrgMemberMutationError = unknown; + +export const useRemoveOrgMember = ( + options?: { + mutation?: UseMutationOptions< + Awaited>, + TError, + { orgId: string; memberId: string }, + TContext + >; + fetch?: RequestInit; + }, + queryClient?: QueryClient, +): UseMutationResult< + Awaited>, + TError, + { orgId: string; memberId: string }, + TContext +> => { + return useMutation(getRemoveOrgMemberMutationOptions(options), queryClient); +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProject201.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProject201.ts new file mode 100644 index 0000000000..d52c1cfaaa --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProject201.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreateOrgProject201 = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectBody.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectBody.ts new file mode 100644 index 0000000000..a955a542a9 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectBody.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreateOrgProjectBody = { + name: string; + description?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectParams.ts new file mode 100644 index 0000000000..d82e332ee0 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createOrgProjectParams.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreateOrgProjectParams = { + templateId?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createPost201.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createPost201.ts new file mode 100644 index 0000000000..ce790acaf0 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createPost201.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreatePost201 = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createPostBody.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createPostBody.ts new file mode 100644 index 0000000000..2a18481a9c --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createPostBody.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreatePostBody = { + title: string; + content?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPost201.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPost201.ts new file mode 100644 index 0000000000..c418a23c00 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPost201.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreateUserPost201 = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPostBody.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPostBody.ts new file mode 100644 index 0000000000..450e2b84a9 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/createUserPostBody.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type CreateUserPostBody = { + title: string; + content?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembers200Item.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembers200Item.ts new file mode 100644 index 0000000000..e7b2a6d162 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembers200Item.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetTeamMembers200Item = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembersParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembersParams.ts new file mode 100644 index 0000000000..79fe08b661 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getTeamMembersParams.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetTeamMembersParams = { + role?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getUser200.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUser200.ts new file mode 100644 index 0000000000..bd7bdad854 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUser200.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetUser200 = { + id?: string; + name?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrders200Item.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrders200Item.ts new file mode 100644 index 0000000000..26562de121 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrders200Item.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetUserOrders200Item = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrdersParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrdersParams.ts new file mode 100644 index 0000000000..136cc56e8c --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserOrdersParams.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetUserOrdersParams = { + status?: string; + page?: number; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserPost200.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserPost200.ts new file mode 100644 index 0000000000..4bfd64c733 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/getUserPost200.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type GetUserPost200 = { + id?: string; + title?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/healthCheck200.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/healthCheck200.ts new file mode 100644 index 0000000000..47117cbd79 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/healthCheck200.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type HealthCheck200 = { + status?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/index.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/index.ts new file mode 100644 index 0000000000..b4bcbace83 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/index.ts @@ -0,0 +1,29 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export * from './createOrgProject201'; +export * from './createOrgProjectBody'; +export * from './createOrgProjectParams'; +export * from './createPost201'; +export * from './createPostBody'; +export * from './createUserPost201'; +export * from './createUserPostBody'; +export * from './getTeamMembers200Item'; +export * from './getTeamMembersParams'; +export * from './getUser200'; +export * from './getUserOrders200Item'; +export * from './getUserOrdersParams'; +export * from './getUserPost200'; +export * from './healthCheck200'; +export * from './listItems200Item'; +export * from './listItemsParams'; +export * from './listProducts200Item'; +export * from './listProductsParams'; +export * from './searchItems200Item'; +export * from './searchItemsBody'; +export * from './searchItemsBodyFilters'; +export * from './searchItemsParams'; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/listItems200Item.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/listItems200Item.ts new file mode 100644 index 0000000000..574fe75066 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/listItems200Item.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type ListItems200Item = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/listItemsParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/listItemsParams.ts new file mode 100644 index 0000000000..44d52b751d --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/listItemsParams.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type ListItemsParams = { + page?: number; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/listProducts200Item.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/listProducts200Item.ts new file mode 100644 index 0000000000..8d7549bf96 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/listProducts200Item.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type ListProducts200Item = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/listProductsParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/listProductsParams.ts new file mode 100644 index 0000000000..32224c8dba --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/listProductsParams.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type ListProductsParams = { + page?: number; + category?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItems200Item.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItems200Item.ts new file mode 100644 index 0000000000..db30675c5a --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItems200Item.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItems200Item = { + id?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBody.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBody.ts new file mode 100644 index 0000000000..96ab935adf --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBody.ts @@ -0,0 +1,12 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ +import type { SearchItemsBodyFilters } from './searchItemsBodyFilters'; + +export type SearchItemsBody = { + query: string; + filters?: SearchItemsBodyFilters; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBodyFilters.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBodyFilters.ts new file mode 100644 index 0000000000..89ea065dac --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsBodyFilters.ts @@ -0,0 +1,10 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItemsBodyFilters = { + category?: string; +}; diff --git a/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsParams.ts b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsParams.ts new file mode 100644 index 0000000000..4592538bc8 --- /dev/null +++ b/tests/__snapshots__/react-query/flat-input-scenarios/model/searchItemsParams.ts @@ -0,0 +1,11 @@ +/** + * Generated by orval v8.6.2 🍺 + * Do not edit manually. + * Flat Input Scenarios + * OpenAPI spec version: 1.0.0 + */ + +export type SearchItemsParams = { + page?: number; + limit?: number; +}; diff --git a/tests/configs/react-query.config.ts b/tests/configs/react-query.config.ts index edd2696117..8170b83b00 100644 --- a/tests/configs/react-query.config.ts +++ b/tests/configs/react-query.config.ts @@ -804,11 +804,10 @@ export default defineConfig({ target: '../specifications/multi-query-params.yaml', }, }, - flatInputPathQueryBody: { + flatInputScenarios: { output: { - target: - '../generated/react-query/flat-input-path-query-body/endpoints.ts', - schemas: '../generated/react-query/flat-input-path-query-body/model', + target: '../generated/react-query/flat-input-scenarios/endpoints.ts', + schemas: '../generated/react-query/flat-input-scenarios/model', client: 'react-query', override: { useFlatInput: true, @@ -817,7 +816,7 @@ export default defineConfig({ formatter: 'prettier', }, input: { - target: '../specifications/flat-input-with-body-query.yaml', + target: '../specifications/flat-input-scenarios.yaml', }, }, }); diff --git a/tests/specifications/flat-input-scenarios.yaml b/tests/specifications/flat-input-scenarios.yaml new file mode 100644 index 0000000000..6aa4e3f6d0 --- /dev/null +++ b/tests/specifications/flat-input-scenarios.yaml @@ -0,0 +1,339 @@ +openapi: '3.0.0' +info: + title: Flat Input Scenarios + version: 1.0.0 +paths: + /health: + get: + operationId: healthCheck + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + status: + type: string + + /users/{userId}: + get: + operationId: getUser + parameters: + - name: userId + in: path + required: true + schema: + type: string + responses: + '200': + description: User + content: + application/json: + schema: + type: object + properties: + id: + type: string + name: + type: string + + /users/{userId}/posts/{postId}: + get: + operationId: getUserPost + parameters: + - name: userId + in: path + required: true + schema: + type: string + - name: postId + in: path + required: true + schema: + type: string + responses: + '200': + description: Post + content: + application/json: + schema: + type: object + properties: + id: + type: string + title: + type: string + + /items: + get: + operationId: listItems + parameters: + - name: page + in: query + required: false + schema: + type: integer + responses: + '200': + description: Items + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + + /products: + get: + operationId: listProducts + parameters: + - name: page + in: query + required: false + schema: + type: integer + - name: category + in: query + required: false + schema: + type: string + responses: + '200': + description: Products + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + + /users/{userId}/orders: + get: + operationId: getUserOrders + parameters: + - name: userId + in: path + required: true + schema: + type: string + - name: status + in: query + required: false + schema: + type: string + - name: page + in: query + required: false + schema: + type: integer + responses: + '200': + description: Orders + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + + /orgs/{orgId}/teams/{teamId}/members: + get: + operationId: getTeamMembers + parameters: + - name: orgId + in: path + required: true + schema: + type: string + - name: teamId + in: path + required: true + schema: + type: string + - name: role + in: query + required: false + schema: + type: string + responses: + '200': + description: Members + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + + /posts: + post: + operationId: createPost + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - title + properties: + title: + type: string + content: + type: string + responses: + '201': + description: Created + content: + application/json: + schema: + type: object + properties: + id: + type: string + + /users/{userId}/posts: + post: + operationId: createUserPost + parameters: + - name: userId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - title + properties: + title: + type: string + content: + type: string + responses: + '201': + description: Created + content: + application/json: + schema: + type: object + properties: + id: + type: string + + /search: + post: + operationId: searchItems + parameters: + - name: page + in: query + required: false + schema: + type: integer + - name: limit + in: query + required: false + schema: + type: integer + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - query + properties: + query: + type: string + filters: + type: object + properties: + category: + type: string + responses: + '200': + description: Results + content: + application/json: + schema: + type: array + items: + type: object + properties: + id: + type: string + + /orgs/{orgId}/projects: + post: + operationId: createOrgProject + parameters: + - name: orgId + in: path + required: true + schema: + type: string + - name: templateId + in: query + required: false + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - name + properties: + name: + type: string + description: + type: string + responses: + '201': + description: Created + content: + application/json: + schema: + type: object + properties: + id: + type: string + + /orgs/{orgId}/members/{memberId}: + delete: + operationId: removeOrgMember + parameters: + - name: orgId + in: path + required: true + schema: + type: string + - name: memberId + in: path + required: true + schema: + type: string + responses: + '204': + description: Deleted From 781a7d764a7d75eab1928c2e63ac95ba3c056e8d Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Tue, 31 Mar 2026 16:00:54 +0300 Subject: [PATCH 08/10] chore: remove orphaned flat-input-path-query-body snapshots and old spec --- .../flat-input-path-query-body/endpoints.ts | 141 ------------------ .../flat-input-path-query-body/model/index.ts | 12 -- .../model/searchItems200.ts | 11 -- .../model/searchItems200ResultsItem.ts | 11 -- .../model/searchItemsBody.ts | 12 -- .../model/searchItemsBodyFilters.ts | 11 -- .../model/searchItemsParams.ts | 11 -- .../flat-input-with-body-query.yaml | 60 -------- 8 files changed, 269 deletions(-) delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts delete mode 100644 tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts delete mode 100644 tests/specifications/flat-input-with-body-query.yaml diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts deleted file mode 100644 index 86298041c7..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/endpoints.ts +++ /dev/null @@ -1,141 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ -import { useMutation } from '@tanstack/react-query'; -import type { - MutationFunction, - QueryClient, - UseMutationOptions, - UseMutationResult, -} from '@tanstack/react-query'; - -import type { - SearchItems200, - SearchItemsBody, - SearchItemsParams, -} from './model'; - -/** - * @summary Search items with path, query, and body - */ -export type searchItemsResponse200 = { - data: SearchItems200; - status: 200; -}; - -export type searchItemsResponseSuccess = searchItemsResponse200 & { - headers: Headers; -}; -export type searchItemsResponse = searchItemsResponseSuccess; - -export const getSearchItemsUrl = ( - orgId: string, - params?: SearchItemsParams, -) => { - const normalizedParams = new URLSearchParams(); - - Object.entries(params || {}).forEach(([key, value]) => { - if (value !== undefined) { - normalizedParams.append(key, value === null ? 'null' : value.toString()); - } - }); - - const stringifiedParams = normalizedParams.toString(); - - return stringifiedParams.length > 0 - ? `/api/search/${orgId}?${stringifiedParams}` - : `/api/search/${orgId}`; -}; - -export const searchItems = async ( - orgId: string, - searchItemsBody: SearchItemsBody, - params?: SearchItemsParams, - options?: RequestInit, -): Promise => { - const res = await fetch(getSearchItemsUrl(orgId, params), { - ...options, - method: 'POST', - headers: { 'Content-Type': 'application/json', ...options?.headers }, - body: JSON.stringify(searchItemsBody), - }); - - const body = [204, 205, 304].includes(res.status) ? null : await res.text(); - - const data: searchItemsResponse['data'] = body ? JSON.parse(body) : {}; - return { - data, - status: res.status, - headers: res.headers, - } as searchItemsResponse; -}; - -export const getSearchItemsMutationOptions = < - TError = unknown, - TContext = unknown, ->(options?: { - mutation?: UseMutationOptions< - Awaited>, - TError, - { orgId: string } & SearchItemsParams & SearchItemsBody, - TContext - >; - fetch?: RequestInit; -}): UseMutationOptions< - Awaited>, - TError, - { orgId: string } & SearchItemsParams & SearchItemsBody, - TContext -> => { - const mutationKey = ['searchItems']; - const { mutation: mutationOptions, fetch: fetchOptions } = options - ? options.mutation && - 'mutationKey' in options.mutation && - options.mutation.mutationKey - ? options - : { ...options, mutation: { ...options.mutation, mutationKey } } - : { mutation: { mutationKey }, fetch: undefined }; - - const mutationFn: MutationFunction< - Awaited>, - { orgId: string } & SearchItemsParams & SearchItemsBody - > = (props) => { - const { orgId, page, limit, ...data } = props ?? {}; - - return searchItems(orgId, { page, limit }, data, fetchOptions); - }; - - return { mutationFn, ...mutationOptions }; -}; - -export type SearchItemsMutationResult = NonNullable< - Awaited> ->; -export type SearchItemsMutationBody = SearchItemsBody; -export type SearchItemsMutationError = unknown; - -/** - * @summary Search items with path, query, and body - */ -export const useSearchItems = ( - options?: { - mutation?: UseMutationOptions< - Awaited>, - TError, - { orgId: string } & SearchItemsParams & SearchItemsBody, - TContext - >; - fetch?: RequestInit; - }, - queryClient?: QueryClient, -): UseMutationResult< - Awaited>, - TError, - { orgId: string } & SearchItemsParams & SearchItemsBody, - TContext -> => { - return useMutation(getSearchItemsMutationOptions(options), queryClient); -}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts deleted file mode 100644 index 97f5a546ad..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ - -export * from './searchItems200'; -export * from './searchItems200ResultsItem'; -export * from './searchItemsBody'; -export * from './searchItemsBodyFilters'; -export * from './searchItemsParams'; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts deleted file mode 100644 index f34e0b8935..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ -import type { SearchItems200ResultsItem } from './searchItems200ResultsItem'; - -export type SearchItems200 = { - results?: SearchItems200ResultsItem[]; -}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts deleted file mode 100644 index 810b5aa141..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItems200ResultsItem.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ - -export type SearchItems200ResultsItem = { - id?: string; - name?: string; -}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts deleted file mode 100644 index 7123d784aa..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBody.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ -import type { SearchItemsBodyFilters } from './searchItemsBodyFilters'; - -export type SearchItemsBody = { - query: string; - filters?: SearchItemsBodyFilters; -}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts deleted file mode 100644 index e48aba12a0..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsBodyFilters.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ - -export type SearchItemsBodyFilters = { - status?: string; - category?: string; -}; diff --git a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts b/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts deleted file mode 100644 index 7866d4b198..0000000000 --- a/tests/__snapshots__/react-query/flat-input-path-query-body/model/searchItemsParams.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Generated by orval v8.6.2 🍺 - * Do not edit manually. - * Flat Input Test - Query with Body - * OpenAPI spec version: 1.0.0 - */ - -export type SearchItemsParams = { - page?: number; - limit?: number; -}; diff --git a/tests/specifications/flat-input-with-body-query.yaml b/tests/specifications/flat-input-with-body-query.yaml deleted file mode 100644 index 383cac4066..0000000000 --- a/tests/specifications/flat-input-with-body-query.yaml +++ /dev/null @@ -1,60 +0,0 @@ -openapi: '3.0.0' -info: - title: Flat Input Test - Query with Body - version: 1.0.0 -paths: - /api/search/{orgId}: - post: - operationId: searchItems - summary: Search items with path, query, and body - parameters: - - name: orgId - in: path - required: true - schema: - type: string - - name: page - in: query - required: false - schema: - type: integer - - name: limit - in: query - required: false - schema: - type: integer - requestBody: - required: true - content: - application/json: - schema: - type: object - required: - - query - properties: - query: - type: string - filters: - type: object - properties: - status: - type: string - category: - type: string - responses: - '200': - description: Search results - content: - application/json: - schema: - type: object - properties: - results: - type: array - items: - type: object - properties: - id: - type: string - name: - type: string From 6acdc3dc88d46b0eb34d9c1415c6a7d67589f27a Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Tue, 31 Mar 2026 19:27:29 +0300 Subject: [PATCH 09/10] refactor: remove IIFEs for flatInput computation --- packages/query/src/mutation-generator.ts | 13 ++++--------- packages/query/src/query-generator.ts | 8 ++++---- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/packages/query/src/mutation-generator.ts b/packages/query/src/mutation-generator.ts index b5c7d102cc..7f9ee8f838 100644 --- a/packages/query/src/mutation-generator.ts +++ b/packages/query/src/mutation-generator.ts @@ -120,16 +120,11 @@ export const generateMutationHook = async ({ const useFlatInput = !!override.useFlatInput; + if (useFlatInput) { + checkFlatInputCollisions(operationName, props, queryParams); + } const flatInput = useFlatInput - ? (() => { - checkFlatInputCollisions(operationName, props, queryParams); - return buildFlatInput( - props, - queryParams, - body.definition, - mutator?.bodyTypeName, - ); - })() + ? buildFlatInput(props, queryParams, body.definition, mutator?.bodyTypeName) : undefined; const definitions = props diff --git a/packages/query/src/query-generator.ts b/packages/query/src/query-generator.ts index 651c6abf39..66b111e4ce 100644 --- a/packages/query/src/query-generator.ts +++ b/packages/query/src/query-generator.ts @@ -376,11 +376,11 @@ const generateQueryImplementation = ({ // This avoids TS1016 "required param cannot follow optional param" const httpFirstParam = adapter.getHttpFirstParam(mutator); + if (useFlatInput) { + checkFlatInputCollisions(operationName, props, queryParams); + } const flatInput = useFlatInput - ? (() => { - checkFlatInputCollisions(operationName, props, queryParams); - return buildFlatInput(props, queryParams); - })() + ? buildFlatInput(props, queryParams) : undefined; const queryOptionsFn = `export const ${queryOptionsFnName} = (${httpFirstParam}${queryProps} ${queryArgumentsForOptions}) => { From 3ce50618c46835c818b45adcf1b252f6e3b5d991 Mon Sep 17 00:00:00 2001 From: inas sarhan Date: Wed, 1 Apr 2026 02:49:36 +0300 Subject: [PATCH 10/10] docs: add useFlatInput documentation to all framework guides and config reference --- docs/content/docs/guides/angular-query.mdx | 4 ++++ docs/content/docs/guides/react-query.mdx | 12 ++++++++++++ docs/content/docs/guides/solid-query.mdx | 4 ++++ docs/content/docs/guides/svelte-query.mdx | 4 ++++ docs/content/docs/guides/vue-query.mdx | 4 ++++ docs/content/docs/reference/configuration/output.mdx | 9 +++++++++ 6 files changed, 37 insertions(+) diff --git a/docs/content/docs/guides/angular-query.mdx b/docs/content/docs/guides/angular-query.mdx index 45bcf0233e..68ed15c5de 100644 --- a/docs/content/docs/guides/angular-query.mdx +++ b/docs/content/docs/guides/angular-query.mdx @@ -355,6 +355,10 @@ const request$ = http.get(url, { params: httpParams }) Validation is automatically skipped for primitive response types (`string`, `void`, etc.) and for operations using a custom mutator. +## Flat Input + +When `useFlatInput: true` is set, Orval flattens path params, query params, and body into a single object argument. + ## Full Example See the [Angular Query sample](https://github.com/orval-labs/orval/tree/master/samples/angular-query) on GitHub. diff --git a/docs/content/docs/guides/react-query.mdx b/docs/content/docs/guides/react-query.mdx index f7403e9d95..7fe4b41d77 100644 --- a/docs/content/docs/guides/react-query.mdx +++ b/docs/content/docs/guides/react-query.mdx @@ -149,6 +149,18 @@ export const useSetListPetsQueryData = () => { }; ``` +## Flat Input + +When `useFlatInput: true` is set, Orval flattens path params, query params, and body into a single object argument: + +```ts +// Before +useGetUserOrders(userId, params, options); + +// After +useGetUserOrders({ userId, status, page }, options); +``` + ## Full Example See the [complete React Query example](https://github.com/orval-labs/orval/blob/master/samples/react-query/basic) on GitHub. diff --git a/docs/content/docs/guides/solid-query.mdx b/docs/content/docs/guides/solid-query.mdx index d1f5d7ae0b..f1f030cc2f 100644 --- a/docs/content/docs/guides/solid-query.mdx +++ b/docs/content/docs/guides/solid-query.mdx @@ -139,6 +139,10 @@ export const setListPetsQueryData = ( }; ``` +## Flat Input + +When `useFlatInput: true` is set, Orval flattens path params, query params, and body into a single object argument. + ## Full Example See the [complete Solid Query example](https://github.com/orval-labs/orval/tree/master/samples/solid-query) on GitHub. diff --git a/docs/content/docs/guides/svelte-query.mdx b/docs/content/docs/guides/svelte-query.mdx index 9dbc29bae0..60365d04e0 100644 --- a/docs/content/docs/guides/svelte-query.mdx +++ b/docs/content/docs/guides/svelte-query.mdx @@ -118,6 +118,10 @@ export const setListPetsQueryData = ( }; ``` +## Flat Input + +When `useFlatInput: true` is set, Orval flattens path params, query params, and body into a single object argument. + ## Full Example See the [complete Svelte Query example](https://github.com/orval-labs/orval/tree/master/samples/svelte-query) on GitHub. diff --git a/docs/content/docs/guides/vue-query.mdx b/docs/content/docs/guides/vue-query.mdx index 350b67161d..03d9a802ab 100644 --- a/docs/content/docs/guides/vue-query.mdx +++ b/docs/content/docs/guides/vue-query.mdx @@ -146,6 +146,10 @@ export const setListPetsQueryData = ( }; ``` +## Flat Input + +When `useFlatInput: true` is set, Orval flattens path params, query params, and body into a single object argument. + ## Full Example See the [complete Vue Query example](https://github.com/orval-labs/orval/tree/master/samples/vue-query) on GitHub. diff --git a/docs/content/docs/reference/configuration/output.mdx b/docs/content/docs/reference/configuration/output.mdx index a3871734ad..fc54882ef4 100644 --- a/docs/content/docs/reference/configuration/output.mdx +++ b/docs/content/docs/reference/configuration/output.mdx @@ -1286,6 +1286,15 @@ Use TypeScript `type` instead of `interface`. Use named parameters object instead of positional arguments. +### useFlatInput + +**Type:** `Boolean` +**Default:** `false` + +Flatten path params, query params, and body into a single object argument for query hooks and mutations. Uses TypeScript intersection types. + +Cannot be used together with `useNamedParameters`. + ### useDeprecatedOperations **Type:** `Boolean`