UNPKG

@7nohe/openapi-react-query-codegen

Version:
73 lines (72 loc) 4.21 kB
import { StructureKind, VariableDeclarationKind, } from "ts-morph"; import { buildClientOptionsParam, buildGetNextPageParamExpr, buildInfiniteClientOptionsParam, buildPagedQueryFn, formatInitialPageParam, getPageType, QUERY_SDK_CALL_ARGS, } from "./buildQueryHooks.mjs"; /** * Build a queryOptions factory for a GET operation. * The factory centralizes queryKey and queryFn so they can be reused with * every TanStack Query utility (useQuery, useQueries, prefetchQuery, * ensureQueryData, setQueryData, ...) with full type safety. * Example: * export const findPetsOptions = (clientOptions: Options<FindPetsData, true> = {}, queryKey?: Array<unknown>) => * queryOptions({ * queryKey: Common.UseFindPetsKeyFn(clientOptions, queryKey), * queryFn: () => findPets({ ...clientOptions, throwOnError: true }).then(response => response.data), * }); */ export function buildQueryOptionsFn(op) { const fnName = `${op.methodName}Options`; const clientOptionsParam = buildClientOptionsParam(op); 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 { kind: StructureKind.VariableStatement, // Copy the operation's JSDoc (description and @deprecated) from the SDK function leadingTrivia: op.jsDoc ? `${op.jsDoc}\n` : undefined, isExported: true, declarationKind: VariableDeclarationKind.Const, declarations: [ { name: fnName, initializer: `(${clientOptionsParam}, queryKey?: Array<unknown>) => ${body}`, }, ], }; } /** * Build an infiniteQueryOptions factory for a paginatable GET operation. * Uses the dedicated infinite query key and page-less options type. * Example: * export const findPaginatedPetsInfiniteOptions = (clientOptions: Common.FindPaginatedPetsInfiniteClientOptions = {}, queryKey?: Array<unknown>, options?: Partial<Pick<UseInfiniteQueryOptions<NonNullable<Common.FindPaginatedPetsDefaultResponse>>, "initialPageParam" | "getNextPageParam">>) => * infiniteQueryOptions({ * queryKey: Common.UseFindPaginatedPetsInfiniteKeyFn(clientOptions, queryKey), * queryFn: ({ pageParam }) => findPaginatedPets({ ...clientOptions, query: { ...clientOptions.query, page: pageParam as number }, throwOnError: true } as Options<FindPaginatedPetsData, true>).then(response => response.data as NonNullable<Common.FindPaginatedPetsDefaultResponse>), * initialPageParam: 1, * getNextPageParam: (response: unknown) => (response as { nextPage: number }).nextPage, * ...options, * }); */ export function buildInfiniteQueryOptionsFn(op, ctx) { if (!op.isPaginatable) { return null; } const fnName = `${op.methodName}InfiniteOptions`; const queryFn = buildPagedQueryFn(op, ctx); const infiniteOptions = `initialPageParam: ${formatInitialPageParam(ctx, op)}, getNextPageParam: ${buildGetNextPageParamExpr(ctx, op)}`; // Only the pagination fields are overridable here: the factory's return type // is what every downstream consumer infers from, and a wider options type // (select, placeholderData, ...) would make that inference ambiguous (#203). const optionsParam = `options?: Partial<Pick<UseInfiniteQueryOptions<${getPageType(op)}>, "initialPageParam" | "getNextPageParam">>`; const body = `infiniteQueryOptions({ queryKey: Common.Use${op.capitalizedMethodName}InfiniteKeyFn(clientOptions, queryKey), queryFn: ${queryFn}, ${infiniteOptions}, ...options })`; return { kind: StructureKind.VariableStatement, // Copy the operation's JSDoc (description and @deprecated) from the SDK function leadingTrivia: op.jsDoc ? `${op.jsDoc}\n` : undefined, isExported: true, declarationKind: VariableDeclarationKind.Const, declarations: [ { name: fnName, initializer: `(${buildInfiniteClientOptionsParam(op)}, queryKey?: Array<unknown>, ${optionsParam}) => ${body}`, }, ], }; }