diff --git a/docs/src/content/docs/guides/cli-options.mdx b/docs/src/content/docs/guides/cli-options.mdx index 60f9443..42380d4 100644 --- a/docs/src/content/docs/guides/cli-options.mdx +++ b/docs/src/content/docs/guides/cli-options.mdx @@ -77,9 +77,9 @@ The available options are: ### --useDateType -> **Deprecated:** This option is currently accepted but has no effect. It will be removed in a future version. - -Use Date type instead of string for date. The default value is `false`. +Use `Date` instead of `string` for `date` and `date-time` model properties. +Generated SDK transformers also convert matching response values into `Date` +objects at runtime. The default value is `false`. ### --debug diff --git a/docs/src/content/docs/guides/usage.mdx b/docs/src/content/docs/guides/usage.mdx index f043bb3..b296c91 100644 --- a/docs/src/content/docs/guides/usage.mdx +++ b/docs/src/content/docs/guides/usage.mdx @@ -103,8 +103,42 @@ function App() { export default App; ``` +Generated query functions forward TanStack Query's `AbortSignal` to the HTTP +client. Requests are therefore cancelled when a query becomes stale or when +you call `queryClient.cancelQueries`. + +Mutations can be cancelled explicitly by passing a signal in the generated +client options: + +```tsx +const controller = new AbortController(); +const { mutate } = useAddPet(); + +mutate({ + body: { name: "Fluffy" }, + signal: controller.signal, +}); + +controller.abort(); +``` + Invalidating queries after a mutation is important to ensure the cache is updated with the new data. This is done by calling the `queryClient.invalidateQueries` function with the query key used by the query hook. +Mutation results contain the complete SDK response, not only the response +body. This makes response headers available in `onSuccess` or from +`mutateAsync`: + +```tsx +const { mutateAsync } = useDownloadReport(); +const result = await mutateAsync({ body: { reportId } }); + +// @hey-api/client-fetch +const disposition = result.response.headers.get("content-disposition"); + +// @hey-api/client-axios +const axiosDisposition = result.headers["content-disposition"]; +``` + Learn more about invalidating queries [here](https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation). To ensure the query key is created the same way as the query hook, you can use the query key function exported by the generated query hooks. diff --git a/examples/react-app/src/App.tsx b/examples/react-app/src/App.tsx index 464d39d..7c9e1e5 100644 --- a/examples/react-app/src/App.tsx +++ b/examples/react-app/src/App.tsx @@ -1,5 +1,5 @@ import "./App.css"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { UseFindPetsKeyFn, @@ -26,7 +26,15 @@ function App() { const { data: notDefined } = useGetNotDefined(); const { mutate: mutateNotDefined } = usePostNotDefined(); - const { mutate: addPet, isError } = useAddPet(); + const { mutate: addPet, isError, isPending: isAddingPet } = useAddPet(); + const addPetAbortController = useRef(null); + + useEffect( + () => () => { + addPetAbortController.current?.abort(); + }, + [], + ); const [text, setText] = useState(""); const [errorText, setErrorText] = useState(); @@ -53,9 +61,14 @@ function App() { + {isError && (

[number] = - formattedOptions.noOperationId + const sdkPlugin: NonNullable[number] = { + name: "@hey-api/sdk" as const, + ...(formattedOptions.noOperationId ? { - name: "@hey-api/sdk" as const, // `operationId: false` was deprecated in favor of `operations.nesting` operations: { nesting: "id" as const, }, } - : "@hey-api/sdk"; + : {}), + ...(formattedOptions.useDateType + ? { transformer: "@hey-api/transformers" as const } + : {}), + }; const plugins: NonNullable[number][] = [ clientPlugin, @@ -46,6 +50,13 @@ export async function generate(options: LimitedUserConfig, version: string) { sdkPlugin, ]; + if (formattedOptions.useDateType) { + plugins.push({ + name: "@hey-api/transformers", + dates: "date", + }); + } + // Conditionally add schemas plugin if (!formattedOptions.noSchemas) { plugins.push( diff --git a/src/parseOperations.mts b/src/parseOperations.mts index f5bed99..e5d8971 100644 --- a/src/parseOperations.mts +++ b/src/parseOperations.mts @@ -13,8 +13,36 @@ import type { GenerationContext, OperationInfo, OperationParameter, + PageParamTypeKind, } from "./types.mjs"; +type PageParamInfo = { + type: string; + typeKind: PageParamTypeKind; +}; + +function getPageParamTypeKind(type: ts.Type): PageParamTypeKind { + const types = type.isUnion() + ? type.types.filter( + (item) => !(item.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)), + ) + : [type]; + + if ( + types.length > 0 && + types.every((item) => item.flags & ts.TypeFlags.StringLike) + ) { + return "string"; + } + if ( + types.length > 0 && + types.every((item) => item.flags & ts.TypeFlags.NumberLike) + ) { + return "number"; + } + return "other"; +} + /** * Extract parameter information from a method's variable declaration. */ @@ -43,14 +71,18 @@ function extractParameters( * Get paginatable methods by checking if their Data type has the pageParam in query property. * Uses TypeScript compiler API for accurate AST traversal. */ -function getPaginatableMethods(project: Project, pageParam: string): string[] { +function getPaginatableMethods( + project: Project, + pageParam: string, +): Map { const modelsFile = project .getSourceFiles() .find((sf) => sf.getFilePath().includes(modelsFileName)); - if (!modelsFile) return []; + if (!modelsFile) return new Map(); - const paginatableMethods: string[] = []; + const paginatableMethods = new Map(); + const typeChecker = project.getTypeChecker().compilerObject; const modelDeclarations = modelsFile.getExportedDeclarations(); const entries = modelDeclarations.entries(); @@ -77,17 +109,27 @@ function getPaginatableMethods(project: Project, pageParam: string): string[] { const queryType = (query as ts.PropertySignature).type; if (!queryType || queryType.kind !== ts.SyntaxKind.TypeLiteral) continue; - const hasPageParam = (queryType as ts.TypeLiteralNode).members.some( - (m) => m.name?.getText() === pageParam, + const pageParamNode = (queryType as ts.TypeLiteralNode).members.find( + (m): m is ts.PropertySignature => + ts.isPropertySignature(m) && m.name?.getText() === pageParam, ); - if (hasPageParam) { + if (pageParamNode) { // Extract method name from Data type name (e.g., "FindPetsData" -> "findPets") const methodName = key.slice(0, -4); // Remove "Data" suffix // Convert first letter to lowercase const methodNameLower = methodName.charAt(0).toLowerCase() + methodName.slice(1); - paginatableMethods.push(methodNameLower); + const pageParamType = pageParamNode.type?.getText( + modelsFile.compilerNode, + ); + const resolvedType = typeChecker.getTypeAtLocation( + pageParamNode.type ?? pageParamNode, + ); + paginatableMethods.set(methodNameLower, { + type: pageParamType ?? "unknown", + typeKind: getPageParamTypeKind(resolvedType), + }); } } @@ -115,8 +157,8 @@ export async function parseOperations( const sdkParams = getVariableArrowFunctionParameters(desc.method); const allParamsOptional = sdkParams.length === 0 || sdkParams[0].isOptional(); - const isPaginatable = - httpMethod === "GET" && paginatableMethods.includes(methodName); + const pageParamInfo = paginatableMethods.get(methodName); + const isPaginatable = httpMethod === "GET" && pageParamInfo !== undefined; return { methodName, @@ -127,6 +169,8 @@ export async function parseOperations( parameters, allParamsOptional, isPaginatable, + pageParamType: isPaginatable ? pageParamInfo.type : undefined, + pageParamTypeKind: isPaginatable ? pageParamInfo.typeKind : undefined, }; }); } diff --git a/src/tsmorph/buildQueryHooks.mts b/src/tsmorph/buildQueryHooks.mts index 738e179..7095a53 100644 --- a/src/tsmorph/buildQueryHooks.mts +++ b/src/tsmorph/buildQueryHooks.mts @@ -41,6 +41,15 @@ export function getDataTypeName( */ export const SDK_CALL_ARGS = "{ ...clientOptions, throwOnError: true }"; +/** SDK call arguments for TanStack query functions with cancellation. */ +export const QUERY_SDK_CALL_ARGS = + "{ ...clientOptions, signal, throwOnError: true }"; + +/** Resolve the OpenAPI page parameter type, preserving older numeric output. */ +export function getPageParamType(op: OperationInfo): string { + return op.pageParamType ?? "number"; +} + /** * Build the client options parameter string. */ @@ -81,12 +90,13 @@ export function buildPagedQueryFn( const thenClause = castTData ? ".then(response => response.data as TData) as TData" : ".then(response => response.data)"; + const pageParamType = getPageParamType(op); // When the initial page param is omitted, the first request must send no // page param at all, so spread it in only once TanStack Query provides one. const pageQuery = ctx.omitInitialPageParam - ? `...(pageParam === undefined ? {} : { ${ctx.pageParam}: pageParam as number })` - : `${ctx.pageParam}: pageParam as number`; - return `({ pageParam }) => ${op.methodName}({ ...clientOptions, query: { ...clientOptions.query, ${pageQuery} }, throwOnError: true } as Options<${dataTypeName}, true>)${thenClause}`; + ? `...(pageParam === undefined ? {} : { ${ctx.pageParam}: pageParam as ${pageParamType} })` + : `${ctx.pageParam}: pageParam as ${pageParamType}`; + return `({ pageParam, signal }) => ${op.methodName}({ ...clientOptions, query: { ...clientOptions.query, ${pageQuery} }, signal, throwOnError: true } as Options<${dataTypeName}, true>)${thenClause}`; } /** @@ -94,10 +104,21 @@ export function buildPagedQueryFn( * to omit it (#177); otherwise a numeric literal when possible so the inferred * pageParam type matches what getNextPageParam returns. */ -export function formatInitialPageParam(ctx: GenerationContext): string { +export function formatInitialPageParam( + ctx: GenerationContext, + op?: OperationInfo, +): string { if (ctx.omitInitialPageParam) { return "undefined"; } + const isStringPageParam = op + ? op.pageParamTypeKind === "string" || + (op.pageParamTypeKind === undefined && + /\bstring\b/.test(getPageParamType(op))) + : false; + if (isStringPageParam) { + return JSON.stringify(ctx.initialPageParam); + } return /^-?\d+$/.test(ctx.initialPageParam) ? ctx.initialPageParam : JSON.stringify(ctx.initialPageParam); @@ -107,11 +128,14 @@ export function formatInitialPageParam(ctx: GenerationContext): string { * Build the nested type for getNextPageParam. * E.g., "meta.next" becomes "{ meta: { next: number } }" */ -export function buildNestedNextPageType(nextPageParam: string): string { +export function buildNestedNextPageType( + nextPageParam: string, + pageParamType = "number", +): string { const segments = nextPageParam.split("."); return segments.reduceRight((acc, segment) => { return `{ ${segment}: ${acc} }`; - }, "number"); + }, pageParamType); } /** @@ -119,8 +143,14 @@ export function buildNestedNextPageType(nextPageParam: string): string { * not every TanStack entry point contextually types it (prefetchInfiniteQuery * does not, which would fail noImplicitAny). */ -export function buildGetNextPageParamExpr(ctx: GenerationContext): string { - const nestedType = buildNestedNextPageType(ctx.nextPageParam); +export function buildGetNextPageParamExpr( + ctx: GenerationContext, + op?: OperationInfo, +): string { + const nestedType = buildNestedNextPageType( + ctx.nextPageParam, + op ? getPageParamType(op) : "number", + ); return `(response: unknown) => (response as ${nestedType}).${ctx.nextPageParam}`; } @@ -158,7 +188,7 @@ export function buildUseQueryHook( const dataTypeDefault = `Common.${op.capitalizedMethodName}DefaultResponse`; const clientOptionsParam = buildClientOptionsParam(op, ctx); - const queryFn = `() => ${op.methodName}(${SDK_CALL_ARGS}).then(response => response.data as TData) as TData`; + const queryFn = `({ signal }) => ${op.methodName}(${QUERY_SDK_CALL_ARGS}).then(response => response.data as TData) as TData`; const body = `useQuery({ queryKey: Common.Use${op.capitalizedMethodName}KeyFn(clientOptions, queryKey), queryFn: ${queryFn}, ...options })`; @@ -189,7 +219,7 @@ export function buildUseSuspenseQueryHook( const dataTypeDefault = `NonNullable`; const clientOptionsParam = buildClientOptionsParam(op, ctx); - const queryFn = `() => ${op.methodName}(${SDK_CALL_ARGS}).then(response => response.data as TData) as TData`; + const queryFn = `({ signal }) => ${op.methodName}(${QUERY_SDK_CALL_ARGS}).then(response => response.data as TData) as TData`; const body = `useSuspenseQuery({ queryKey: Common.Use${op.capitalizedMethodName}KeyFn(clientOptions, queryKey), queryFn: ${queryFn}, ...options })`; @@ -238,7 +268,7 @@ function buildInfiniteHook( : `InfiniteData<${baseDataType}>`; const queryFn = buildPagedQueryFn(op, ctx, true); - const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx)}`; + const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx, op)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx, op)}`; const body = `${hookCall}({ queryKey: Common.Use${op.capitalizedMethodName}InfiniteKeyFn(clientOptions, queryKey), queryFn: ${queryFn}, ${infiniteOptions}, ...options })`; @@ -293,7 +323,7 @@ export function buildPrefetchFn( ): VariableStatementStructure { const fnName = `prefetchUse${op.capitalizedMethodName}`; - const queryFn = `() => ${op.methodName}(${SDK_CALL_ARGS}).then(response => response.data)`; + const queryFn = `({ signal }) => ${op.methodName}(${QUERY_SDK_CALL_ARGS}).then(response => response.data)`; const optionsParam = `options?: Omit, "queryKey" | "queryFn">`; const body = `queryClient.prefetchQuery({ queryKey: Common.Use${op.capitalizedMethodName}KeyFn(clientOptions), queryFn: ${queryFn}, ...options })`; @@ -336,7 +366,7 @@ export function buildPrefetchInfiniteQueryFn( const fnName = `prefetchUse${op.capitalizedMethodName}Infinite`; const queryFn = buildPagedQueryFn(op, ctx, false); - const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx)}`; + const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx, op)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx, op)}`; const optionsParam = `options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">`; const body = `queryClient.prefetchInfiniteQuery({ queryKey: Common.Use${op.capitalizedMethodName}InfiniteKeyFn(clientOptions), queryFn: ${queryFn}, ${infiniteOptions}, ...options })`; @@ -372,7 +402,7 @@ export function buildEnsureQueryDataFn( ): VariableStatementStructure { const fnName = `ensureUse${op.capitalizedMethodName}Data`; - const queryFn = `() => ${op.methodName}(${SDK_CALL_ARGS}).then(response => response.data)`; + const queryFn = `({ signal }) => ${op.methodName}(${QUERY_SDK_CALL_ARGS}).then(response => response.data)`; const optionsParam = `options?: Omit, "queryKey" | "queryFn">`; const body = `queryClient.ensureQueryData({ queryKey: Common.Use${op.capitalizedMethodName}KeyFn(clientOptions), queryFn: ${queryFn}, ...options })`; diff --git a/src/tsmorph/buildQueryOptions.mts b/src/tsmorph/buildQueryOptions.mts index 4e4b400..da82de4 100644 --- a/src/tsmorph/buildQueryOptions.mts +++ b/src/tsmorph/buildQueryOptions.mts @@ -10,7 +10,7 @@ import { buildInfiniteClientOptionsParam, buildPagedQueryFn, formatInitialPageParam, - SDK_CALL_ARGS, + QUERY_SDK_CALL_ARGS, } from "./buildQueryHooks.mjs"; /** @@ -32,7 +32,7 @@ export function buildQueryOptionsFn( const fnName = `${op.methodName}Options`; const clientOptionsParam = buildClientOptionsParam(op, ctx); - const queryFn = `() => ${op.methodName}(${SDK_CALL_ARGS}).then(response => response.data)`; + const queryFn = `({ signal }) => ${op.methodName}(${QUERY_SDK_CALL_ARGS}).then(response => response.data)`; const body = `queryOptions({ queryKey: Common.Use${op.capitalizedMethodName}KeyFn(clientOptions, queryKey), queryFn: ${queryFn} })`; return { @@ -73,7 +73,7 @@ export function buildInfiniteQueryOptionsFn( const fnName = `${op.methodName}InfiniteOptions`; const queryFn = buildPagedQueryFn(op, ctx, false); - const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx)}`; + const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx, op)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx, op)}`; const body = `infiniteQueryOptions({ queryKey: Common.Use${op.capitalizedMethodName}InfiniteKeyFn(clientOptions, queryKey), queryFn: ${queryFn}, ${infiniteOptions} })`; diff --git a/src/types.mts b/src/types.mts index 0af5dc0..f10457a 100644 --- a/src/types.mts +++ b/src/types.mts @@ -19,8 +19,14 @@ export interface OperationInfo { allParamsOptional: boolean; /** Whether this operation supports pagination (for infinite queries) */ isPaginatable: boolean; + /** Type of the configured page query parameter */ + pageParamType?: string; + /** Resolved primitive kind of the configured page query parameter */ + pageParamTypeKind?: PageParamTypeKind; } +export type PageParamTypeKind = "string" | "number" | "other"; + export interface OperationParameter { /** Parameter name */ name: string; diff --git a/tests/__snapshots__/createSource.test.ts.snap b/tests/__snapshots__/createSource.test.ts.snap index 1d0c9ee..92d216c 100644 --- a/tests/__snapshots__/createSource.test.ts.snap +++ b/tests/__snapshots__/createSource.test.ts.snap @@ -81,22 +81,22 @@ import { AxiosError } from "axios"; * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useFindPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefined = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefined = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useFindPetById = , TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetById = , TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPaginatedPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Creates a new pet in the store. Duplicates are allowed */ @@ -131,27 +131,27 @@ import { AxiosError } from "axios"; * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useFindPetsSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetsSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefinedSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefinedSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useFindPetByIdSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetByIdSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPetsSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPaginatedPetsSuspense = , TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPetsSuspenseInfinite = >, TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"> & Partial, "initialPageParam" | "getNextPageParam">>) => useSuspenseInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), queryFn: ({ pageParam }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options).then(response => response.data as TData) as TData, initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); +export const useFindPaginatedPetsSuspenseInfinite = >, TError = AxiosError, TQueryKey extends Array = unknown[]>(clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"> & Partial, "initialPageParam" | "getNextPageParam">>) => useSuspenseInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, signal, throwOnError: true } as Options).then(response => response.data as TData) as TData, initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); " `; @@ -172,27 +172,27 @@ import { AxiosError } from "axios"; * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const prefetchUseFindPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * This path is not fully defined. * * @deprecated */ -export const prefetchUseGetNotDefined = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseGetNotDefined = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const prefetchUseFindPetById = (queryClient: QueryClient, clientOptions: Options, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPetById = (queryClient: QueryClient, clientOptions: Options, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const prefetchUseFindPaginatedPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPaginatedPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const prefetchUseFindPaginatedPetsInfinite = (queryClient: QueryClient, clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">) => queryClient.prefetchInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions), queryFn: ({ pageParam }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options).then(response => response.data), initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); +export const prefetchUseFindPaginatedPetsInfinite = (queryClient: QueryClient, clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">) => queryClient.prefetchInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions), queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, signal, throwOnError: true } as Options).then(response => response.data), initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); " `; @@ -275,22 +275,22 @@ import { ClientOptions, Pet, NewPet, Error, FindPetsData, FindPetsErrors, FindPe * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useFindPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefined = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefined = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useFindPetById = = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetById = = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPaginatedPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Creates a new pet in the store. Duplicates are allowed */ @@ -324,27 +324,27 @@ import { ClientOptions, Pet, NewPet, Error, FindPetsData, FindPetsErrors, FindPe * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useFindPetsSuspense = , TError = FindPetsError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetsSuspense = , TError = FindPetsError, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefinedSuspense = , TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefinedSuspense = , TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useFindPetByIdSuspense = , TError = FindPetByIdError, TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetByIdSuspense = , TError = FindPetByIdError, TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPetsSuspense = , TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPaginatedPetsSuspense = , TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useSuspenseQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPetsSuspenseInfinite = >, TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"> & Partial, "initialPageParam" | "getNextPageParam">>) => useSuspenseInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), queryFn: ({ pageParam }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options).then(response => response.data as TData) as TData, initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); +export const useFindPaginatedPetsSuspenseInfinite = >, TError = unknown, TQueryKey extends Array = unknown[]>(clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"> & Partial, "initialPageParam" | "getNextPageParam">>) => useSuspenseInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, signal, throwOnError: true } as Options).then(response => response.data as TData) as TData, initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); " `; @@ -364,26 +364,26 @@ import { ClientOptions, Pet, NewPet, Error, FindPetsData, FindPetsErrors, FindPe * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const prefetchUseFindPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * This path is not fully defined. * * @deprecated */ -export const prefetchUseGetNotDefined = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseGetNotDefined = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const prefetchUseFindPetById = (queryClient: QueryClient, clientOptions: Options, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPetById = (queryClient: QueryClient, clientOptions: Options, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const prefetchUseFindPaginatedPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data), ...options }); +export const prefetchUseFindPaginatedPets = (queryClient: QueryClient, clientOptions: Options = {}, options?: Omit, "queryKey" | "queryFn">) => queryClient.prefetchQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data), ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const prefetchUseFindPaginatedPetsInfinite = (queryClient: QueryClient, clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">) => queryClient.prefetchInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions), queryFn: ({ pageParam }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options).then(response => response.data), initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); +export const prefetchUseFindPaginatedPetsInfinite = (queryClient: QueryClient, clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, options?: Omit, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">) => queryClient.prefetchInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions), queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, signal, throwOnError: true } as Options).then(response => response.data), initialPageParam: 1, getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, ...options }); " `; diff --git a/tests/__snapshots__/generate.test.ts.snap b/tests/__snapshots__/generate.test.ts.snap index b60f6a6..bab3ae7 100644 --- a/tests/__snapshots__/generate.test.ts.snap +++ b/tests/__snapshots__/generate.test.ts.snap @@ -158,8 +158,8 @@ export const ensureUseFindPetsData = ( ) => queryClient.ensureQueryData({ queryKey: Common.UseFindPetsKeyFn(clientOptions), - queryFn: () => - findPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -179,8 +179,8 @@ export const ensureUseGetNotDefinedData = ( ) => queryClient.ensureQueryData({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), - queryFn: () => - getNotDefined({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + getNotDefined({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -198,8 +198,8 @@ export const ensureUseFindPetByIdData = ( ) => queryClient.ensureQueryData({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), - queryFn: () => - findPetById({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPetById({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -218,8 +218,8 @@ export const ensureUseFindPaginatedPetsData = ( ) => queryClient.ensureQueryData({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), - queryFn: () => - findPaginatedPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -272,10 +272,11 @@ export const useFindPaginatedPetsInfinite = < ) => useInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), - queryFn: ({ pageParam }) => + queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, + signal, throwOnError: true, } as Options).then( (response) => response.data as TData, @@ -328,8 +329,8 @@ export const prefetchUseFindPets = ( ) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions), - queryFn: () => - findPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -349,8 +350,8 @@ export const prefetchUseGetNotDefined = ( ) => queryClient.prefetchQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions), - queryFn: () => - getNotDefined({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + getNotDefined({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -368,8 +369,8 @@ export const prefetchUseFindPetById = ( ) => queryClient.prefetchQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions), - queryFn: () => - findPetById({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPetById({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -388,8 +389,8 @@ export const prefetchUseFindPaginatedPets = ( ) => queryClient.prefetchQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions), - queryFn: () => - findPaginatedPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data, ), ...options, @@ -408,10 +409,11 @@ export const prefetchUseFindPaginatedPetsInfinite = ( ) => queryClient.prefetchInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions), - queryFn: ({ pageParam }) => + queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, + signal, throwOnError: true, } as Options).then( (response) => response.data, @@ -476,8 +478,8 @@ export const useFindPets = < ) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), - queryFn: () => - findPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -498,8 +500,8 @@ export const useGetNotDefined = < ) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), - queryFn: () => - getNotDefined({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + getNotDefined({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -518,8 +520,8 @@ export const useFindPetById = < ) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), - queryFn: () => - findPetById({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPetById({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -539,8 +541,8 @@ export const useFindPaginatedPets = < ) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), - queryFn: () => - findPaginatedPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -627,6 +629,114 @@ export const useDeletePet = < " `; +exports[`generate > queryOptions.ts 1`] = ` +"// generated with @7nohe/openapi-react-query-codegen@1.0.0 + +import { infiniteQueryOptions, queryOptions } from "@tanstack/react-query"; +import { + findPaginatedPets, + findPetById, + findPets, + getNotDefined, + type Options, +} from "../requests/sdk.gen"; +import type { + FindPaginatedPetsData, + FindPetByIdData, + FindPetsData, + GetNotDefinedData, +} from "../requests/types.gen"; +import * as Common from "./common"; + +/** + * Returns all pets from the system that the user has access to + * Nam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia. + * + * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. + * + */ +export const findPetsOptions = ( + clientOptions: Options = {}, + queryKey?: Array, +) => + queryOptions({ + queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), + queryFn: ({ signal }) => + findPets({ ...clientOptions, signal, throwOnError: true }).then( + (response) => response.data, + ), + }); +/** + * This path is not fully defined. + * + * @deprecated + */ +export const getNotDefinedOptions = ( + clientOptions: Options = {}, + queryKey?: Array, +) => + queryOptions({ + queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), + queryFn: ({ signal }) => + getNotDefined({ ...clientOptions, signal, throwOnError: true }).then( + (response) => response.data, + ), + }); +/** + * Returns a user based on a single ID, if the user does not have access to the pet + */ +export const findPetByIdOptions = ( + clientOptions: Options, + queryKey?: Array, +) => + queryOptions({ + queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), + queryFn: ({ signal }) => + findPetById({ ...clientOptions, signal, throwOnError: true }).then( + (response) => response.data, + ), + }); +/** + * Returns paginated pets from the system that the user has access to + * + */ +export const findPaginatedPetsOptions = ( + clientOptions: Options = {}, + queryKey?: Array, +) => + queryOptions({ + queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), + queryFn: ({ signal }) => + findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then( + (response) => response.data, + ), + }); +/** + * Returns paginated pets from the system that the user has access to + * + */ +export const findPaginatedPetsInfiniteOptions = ( + clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, + queryKey?: Array, +) => + infiniteQueryOptions({ + queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), + queryFn: ({ pageParam, signal }) => + findPaginatedPets({ + ...clientOptions, + query: { ...clientOptions.query, page: pageParam as number }, + signal, + throwOnError: true, + } as Options).then( + (response) => response.data, + ), + initialPageParam: "initial", + getNextPageParam: (response: unknown) => + (response as { meta: { next: number } }).meta.next, + }); +" +`; + exports[`generate > suspense.ts 1`] = ` "// generated with @7nohe/openapi-react-query-codegen@1.0.0 @@ -675,8 +785,8 @@ export const useFindPetsSuspense = < ) => useSuspenseQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), - queryFn: () => - findPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -700,8 +810,8 @@ export const useGetNotDefinedSuspense = < ) => useSuspenseQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), - queryFn: () => - getNotDefined({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + getNotDefined({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -723,8 +833,8 @@ export const useFindPetByIdSuspense = < ) => useSuspenseQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), - queryFn: () => - findPetById({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPetById({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -747,8 +857,8 @@ export const useFindPaginatedPetsSuspense = < ) => useSuspenseQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), - queryFn: () => - findPaginatedPets({ ...clientOptions, throwOnError: true }).then( + queryFn: ({ signal }) => + findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then( (response) => response.data as TData, ) as TData, ...options, @@ -777,10 +887,11 @@ export const useFindPaginatedPetsSuspenseInfinite = < ) => useSuspenseInfiniteQuery({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), - queryFn: ({ pageParam }) => + queryFn: ({ pageParam, signal }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, + signal, throwOnError: true, } as Options).then( (response) => response.data as TData, @@ -809,22 +920,22 @@ import * as Common from "./common"; * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useGetPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPetsKeyFn(clientOptions, queryKey), queryFn: () => getPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefined = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefined = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useGetPetsById = , TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPetsByIdKeyFn(clientOptions, queryKey), queryFn: () => getPetsById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetPetsById = , TQueryKey extends Array = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPetsByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getPetsById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useGetPaginatedPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => getPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetPaginatedPets = , TQueryKey extends Array = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Creates a new pet in the store. Duplicates are allowed */ @@ -857,22 +968,22 @@ import * as Common from "./common"; * Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien. * */ -export const useFindPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * This path is not fully defined. * * @deprecated */ -export const useGetNotDefined = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: () => getNotDefined({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useGetNotDefined = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseGetNotDefinedKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => getNotDefined({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns a user based on a single ID, if the user does not have access to the pet */ -export const useFindPetById = = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: () => findPetById({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPetById = = unknown[]>(clientOptions: Options, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPetByIdKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPetById({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Returns paginated pets from the system that the user has access to * */ -export const useFindPaginatedPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: () => findPaginatedPets({ ...clientOptions, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); +export const useFindPaginatedPets = = unknown[]>(clientOptions: Options = {}, queryKey?: TQueryKey, options?: Omit, "queryKey" | "queryFn">) => useQuery({ queryKey: Common.UseFindPaginatedPetsKeyFn(clientOptions, queryKey), queryFn: ({ signal }) => findPaginatedPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data as TData) as TData, ...options }); /** * Creates a new pet in the store. Duplicates are allowed */ diff --git a/tests/generate.test.ts b/tests/generate.test.ts index a7b4acb..024c7fe 100644 --- a/tests/generate.test.ts +++ b/tests/generate.test.ts @@ -1,6 +1,7 @@ import { existsSync, readFileSync } from "node:fs"; import { rm } from "node:fs/promises"; import path from "node:path"; +import { pathToFileURL } from "node:url"; import { afterAll, beforeAll, describe, expect, test } from "vitest"; import type { LimitedUserConfig } from "../src/cli.mts"; import { generate } from "../src/generate.mjs"; @@ -44,6 +45,10 @@ describe("generate", () => { expect(readOutput("queries.ts")).toMatchSnapshot(); }); + test("queryOptions.ts", () => { + expect(readOutput("queryOptions.ts")).toMatchSnapshot(); + }); + test("infiniteQueries.ts", () => { expect(readOutput("infiniteQueries.ts")).toMatchSnapshot(); }); @@ -132,3 +137,55 @@ describe("generate - noSchemas option", () => { expect(readNoSchemasOutput("queries.ts")).toMatchSnapshot(); }); }); + +describe("generate - useDateType", () => { + const outputDir = "outputs-generate-dates"; + const readDateOutput = (fileName: string) => + readFileSync( + path.join(__dirname, outputDir, "requests", fileName), + "utf-8", + ); + + beforeAll(async () => { + const options: LimitedUserConfig = { + input: path.join(__dirname, "inputs", "dates.yaml"), + output: path.join("tests", outputDir), + client: "@hey-api/client-fetch", + useDateType: true, + pageParam: "page", + nextPageParam: "nextPage", + initialPageParam: "1", + }; + await generate(options, "1.0.0"); + }); + + afterAll(async () => { + if (existsSync(path.join(__dirname, outputDir))) { + await rm(path.join(__dirname, outputDir), { recursive: true }); + } + }); + + test("uses Date in generated model types", () => { + expect(readDateOutput("types.gen.ts")).toContain("createdAt: Date"); + }); + + test("wires the runtime date transformer into the SDK", async () => { + const transformer = readDateOutput("transformers.gen.ts"); + expect(transformer).toContain("new Date"); + expect(transformer).toContain("createdAt"); + + const sdk = readDateOutput("sdk.gen.ts"); + expect(sdk).toContain("listEventsResponseTransformer"); + expect(sdk).toContain("responseTransformer: listEventsResponseTransformer"); + + const transformerModule = await import( + pathToFileURL( + path.join(__dirname, outputDir, "requests", "transformers.gen.ts"), + ).href + ); + const transformed = await transformerModule.listEventsResponseTransformer([ + { createdAt: "2026-07-20T00:00:00.000Z" }, + ]); + expect(transformed[0].createdAt).toBeInstanceOf(Date); + }); +}); diff --git a/tests/inputs/dates.yaml b/tests/inputs/dates.yaml new file mode 100644 index 0000000..b5c843f --- /dev/null +++ b/tests/inputs/dates.yaml @@ -0,0 +1,27 @@ +openapi: 3.0.3 +info: + title: Dates API + version: 1.0.0 +paths: + /events: + get: + operationId: listEvents + responses: + "200": + description: Events + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Event" +components: + schemas: + Event: + type: object + required: + - createdAt + properties: + createdAt: + type: string + format: date-time diff --git a/tests/inputs/string-pagination.yaml b/tests/inputs/string-pagination.yaml new file mode 100644 index 0000000..63e655a --- /dev/null +++ b/tests/inputs/string-pagination.yaml @@ -0,0 +1,32 @@ +openapi: 3.0.3 +info: + title: Cursor API + version: 1.0.0 +paths: + /items: + get: + operationId: listItems + parameters: + - name: cursor + in: query + required: false + schema: + $ref: "#/components/schemas/Cursor" + responses: + "200": + description: Items + content: + application/json: + schema: + type: object + properties: + nextCursor: + $ref: "#/components/schemas/Cursor" + items: + type: array + items: + type: string +components: + schemas: + Cursor: + type: string diff --git a/tests/parseOperations.test.ts b/tests/parseOperations.test.ts index 2d4518e..30364fc 100644 --- a/tests/parseOperations.test.ts +++ b/tests/parseOperations.test.ts @@ -65,8 +65,9 @@ describe("parseOperations", () => { ); expect(findPaginatedPets).toBeDefined(); expect(findPaginatedPets?.httpMethod).toBe("GET"); - // Note: isPaginatable detection uses simplified regex which may not detect all cases - // The actual pagination support is validated via createSourceV2 integration tests + expect(findPaginatedPets?.isPaginatable).toBe(true); + expect(findPaginatedPets?.pageParamType).toBe("number"); + expect(findPaginatedPets?.pageParamTypeKind).toBe("number"); }); it("should extract parameters correctly", async () => { @@ -182,3 +183,25 @@ describe("parseOperations", () => { }); }); }); + +describe("parseOperations - string pagination", () => { + const stringFileName = "parseOperations-string-pagination"; + + beforeAll( + async () => + await generateTSClients(stringFileName, "string-pagination.yaml"), + ); + afterAll(async () => await cleanOutputs(stringFileName)); + + it("should preserve a string page parameter type", async () => { + const project = new Project({ skipAddingFilesFromTsConfig: true }); + project.addSourceFilesAtPaths(`${outputPath(stringFileName)}/**/*`); + + const operations = await parseOperations(project, "cursor"); + const listItems = operations.find((op) => op.methodName === "listItems"); + + expect(listItems?.isPaginatable).toBe(true); + expect(listItems?.pageParamType).toBe("Cursor"); + expect(listItems?.pageParamTypeKind).toBe("string"); + }); +}); diff --git a/tests/tsmorph/buildMutationHooks.test.ts b/tests/tsmorph/buildMutationHooks.test.ts index 16019c2..1566a8b 100644 --- a/tests/tsmorph/buildMutationHooks.test.ts +++ b/tests/tsmorph/buildMutationHooks.test.ts @@ -95,6 +95,23 @@ describe("buildMutationHooks", () => { ); }); + it("should default to the complete SDK response so headers stay available", () => { + const result = buildUseMutationHook(mockPostOperation, mockFetchContext); + const initializer = result.declarations[0].initializer as string; + + expect(initializer).toContain("TData = Common.AddPetMutationResult"); + expect(initializer).not.toContain('AddPetMutationResult["data"]'); + expect(initializer).not.toContain("response.data"); + }); + + it("should accept an AbortSignal through mutation client options", () => { + const result = buildUseMutationHook(mockPostOperation, mockFetchContext); + const initializer = result.declarations[0].initializer as string; + + expect(initializer).toContain("Options"); + expect(initializer).toContain("...clientOptions"); + }); + it("should build useMutation hook for DELETE operation", () => { const result = buildUseMutationHook( mockDeleteOperation, diff --git a/tests/tsmorph/buildQueryHooks.test.ts b/tests/tsmorph/buildQueryHooks.test.ts index 21cfcb4..f2161f5 100644 --- a/tests/tsmorph/buildQueryHooks.test.ts +++ b/tests/tsmorph/buildQueryHooks.test.ts @@ -29,6 +29,14 @@ const mockPaginatableOperation: OperationInfo = { parameters: [{ name: "page", typeName: "number", optional: true }], allParamsOptional: true, isPaginatable: true, + pageParamType: "number", + pageParamTypeKind: "number", +}; + +const mockStringPaginatableOperation: OperationInfo = { + ...mockPaginatableOperation, + pageParamType: "Cursor", + pageParamTypeKind: "string", }; const mockRequiredParamsOperation: OperationInfo = { @@ -107,8 +115,9 @@ describe("buildQueryHooks", () => { "Common.UseFindPetsKeyFn(clientOptions, queryKey)", ); expect(initializer).toContain( - "findPets({ ...clientOptions, throwOnError: true })", + "findPets({ ...clientOptions, signal, throwOnError: true })", ); + expect(initializer).toContain("queryFn: ({ signal }) =>"); expect(initializer).toContain("response.data as TData"); }); @@ -152,7 +161,7 @@ describe("buildQueryHooks", () => { "clientOptions: Options = {}", ); expect(initializer).toContain( - "getStatus({ ...clientOptions, throwOnError: true })", + "getStatus({ ...clientOptions, signal, throwOnError: true })", ); }); }); @@ -191,7 +200,7 @@ describe("buildQueryHooks", () => { "clientOptions: Options = {}", ); expect(initializer).toContain( - "getStatus({ ...clientOptions, throwOnError: true })", + "getStatus({ ...clientOptions, signal, throwOnError: true })", ); }); }); @@ -249,6 +258,22 @@ describe("buildQueryHooks", () => { const initializer = result?.declarations[0].initializer as string; expect(initializer).toContain("page: pageParam as number"); + expect(initializer).toContain("({ pageParam, signal }) =>"); + expect(initializer).toContain("signal, throwOnError: true"); + }); + + it("should preserve string cursor types and quote the initial value", () => { + const result = buildUseInfiniteQueryHook( + mockStringPaginatableOperation, + mockFetchContext, + ); + const initializer = result?.declarations[0].initializer as string; + + expect(initializer).toContain("page: pageParam as Cursor"); + expect(initializer).toContain('initialPageParam: "1"'); + expect(initializer).toContain( + "(response as { nextPage: Cursor }).nextPage", + ); }); it("should use unknown data type when not present in modelNames", () => { @@ -278,8 +303,9 @@ describe("buildQueryHooks", () => { expect(initializer).toContain("queryClient.prefetchQuery"); expect(initializer).toContain("Common.UseFindPetsKeyFn(clientOptions)"); expect(initializer).toContain( - "findPets({ ...clientOptions, throwOnError: true })", + "findPets({ ...clientOptions, signal, throwOnError: true })", ); + expect(initializer).toContain("queryFn: ({ signal }) =>"); expect(initializer).toContain("response.data"); }); @@ -326,7 +352,7 @@ describe("buildQueryHooks", () => { "clientOptions: Options = {}", ); expect(initializer).toContain( - "getStatus({ ...clientOptions, throwOnError: true })", + "getStatus({ ...clientOptions, signal, throwOnError: true })", ); }); }); @@ -369,7 +395,7 @@ describe("buildQueryHooks", () => { "clientOptions: Options = {}", ); expect(initializer).toContain( - "getStatus({ ...clientOptions, throwOnError: true })", + "getStatus({ ...clientOptions, signal, throwOnError: true })", ); }); @@ -416,6 +442,7 @@ describe("buildQueryHooks", () => { expect(initializer).toContain("initialPageParam: 1"); expect(initializer).toContain("getNextPageParam"); expect(initializer).toContain("throwOnError: true"); + expect(initializer).toContain("({ pageParam, signal }) =>"); }); }); @@ -453,6 +480,7 @@ describe("buildQueryHooks", () => { expect(initializer).toContain( 'Partial, "initialPageParam" | "getNextPageParam">>', ); + expect(initializer).toContain("({ pageParam, signal }) =>"); }); }); }); diff --git a/tests/tsmorph/buildQueryOptions.test.ts b/tests/tsmorph/buildQueryOptions.test.ts index 3adb0c6..42ffc13 100644 --- a/tests/tsmorph/buildQueryOptions.test.ts +++ b/tests/tsmorph/buildQueryOptions.test.ts @@ -24,6 +24,14 @@ const mockPaginatableOperation: OperationInfo = { parameters: [{ name: "page", typeName: "number", optional: true }], allParamsOptional: true, isPaginatable: true, + pageParamType: "number", + pageParamTypeKind: "number", +}; + +const mockStringPaginatableOperation: OperationInfo = { + ...mockPaginatableOperation, + pageParamType: "Cursor", + pageParamTypeKind: "string", }; const mockRequiredParamsOperation: OperationInfo = { @@ -69,7 +77,7 @@ describe("buildQueryOptions", () => { "queryOptions({ queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey)", ); expect(initializer).toContain( - "queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data)", + "queryFn: ({ signal }) => findPets({ ...clientOptions, signal, throwOnError: true }).then(response => response.data)", ); }); @@ -124,7 +132,7 @@ describe("buildQueryOptions", () => { "infiniteQueryOptions({ queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey)", ); expect(initializer).toContain( - "query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options", + "query: { ...clientOptions.query, page: pageParam as number }, signal, throwOnError: true } as Options", ); expect(initializer).toContain( "getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage", @@ -153,6 +161,20 @@ describe("buildQueryOptions", () => { expect(initializer).toContain('initialPageParam: "cursor-start",'); }); + it("should preserve a string cursor type even for numeric-looking values", () => { + const result = buildInfiniteQueryOptionsFn( + mockStringPaginatableOperation, + mockContext, + ); + const initializer = result?.declarations[0].initializer as string; + + expect(initializer).toContain("page: pageParam as Cursor"); + expect(initializer).toContain('initialPageParam: "1"'); + expect(initializer).toContain( + "(response as { nextPage: Cursor }).nextPage", + ); + }); + it("should respect a custom pageParam and nested nextPageParam", () => { const ctx: GenerationContext = { ...mockContext,