UNPKG

openapi-react-query

Version:

Fast, type-safe @tanstack/react-query client to work with your OpenAPI schema.

1 lines 13.1 kB
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n type UseMutationOptions,\n type UseMutationResult,\n type UseQueryOptions,\n type UseQueryResult,\n type InfiniteData,\n type UseInfiniteQueryOptions,\n type UseInfiniteQueryResult,\n type UseSuspenseQueryOptions,\n type UseSuspenseQueryResult,\n type QueryClient,\n type QueryFunctionContext,\n type SkipToken,\n useMutation,\n useQuery,\n useSuspenseQuery,\n useInfiniteQuery,\n} from \"@tanstack/react-query\";\nimport type {\n ClientMethod,\n FetchResponse,\n MaybeOptionalInit,\n Client as FetchClient,\n DefaultParamsOption,\n} from \"openapi-fetch\";\nimport type { HttpMethod, MediaType, PathsWithMethod, RequiredKeysOf } from \"openapi-typescript-helpers\";\n\n// Helper type to dynamically infer the type from the `select` property\ntype InferSelectReturnType<TData, TSelect> = TSelect extends (data: TData) => infer R ? R : TData;\n\ntype InitWithUnknowns<Init> = Init & { [key: string]: unknown };\n\nexport type QueryKey<\n Paths extends Record<string, Record<HttpMethod, {}>>,\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init = MaybeOptionalInit<Paths[Path], Method>,\n> = Init extends undefined ? readonly [Method, Path] : readonly [Method, Path, Init];\n\nexport type QueryOptionsFunction<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init extends MaybeOptionalInit<Paths[Path], Method>,\n Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types\n Options extends Omit<\n UseQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<Response[\"data\"], Options[\"select\"]>,\n QueryKey<Paths, Method, Path>\n >,\n \"queryKey\" | \"queryFn\"\n >,\n>(\n method: Method,\n path: Path,\n ...[init, options]: RequiredKeysOf<Init> extends never\n ? [InitWithUnknowns<Init>?, Options?]\n : [InitWithUnknowns<Init>, Options?]\n) => NoInfer<\n Omit<\n UseQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<Response[\"data\"], Options[\"select\"]>,\n QueryKey<Paths, Method, Path>\n >,\n \"queryFn\"\n > & {\n queryFn: Exclude<\n UseQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<Response[\"data\"], Options[\"select\"]>,\n QueryKey<Paths, Method, Path>\n >[\"queryFn\"],\n SkipToken | undefined\n >;\n }\n>;\n\nexport type UseQueryMethod<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init extends MaybeOptionalInit<Paths[Path], Method>,\n Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types\n Options extends Omit<\n UseQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<Response[\"data\"], Options[\"select\"]>,\n QueryKey<Paths, Method, Path>\n >,\n \"queryKey\" | \"queryFn\"\n >,\n>(\n method: Method,\n url: Path,\n ...[init, options, queryClient]: RequiredKeysOf<Init> extends never\n ? [InitWithUnknowns<Init>?, Options?, QueryClient?]\n : [InitWithUnknowns<Init>, Options?, QueryClient?]\n) => UseQueryResult<InferSelectReturnType<Response[\"data\"], Options[\"select\"]>, Response[\"error\"]>;\n\nexport type UseInfiniteQueryMethod<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init extends MaybeOptionalInit<Paths[Path], Method>,\n Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>,\n Options extends Omit<\n UseInfiniteQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<InfiniteData<Response[\"data\"]>, Options[\"select\"]>,\n Response[\"data\"],\n QueryKey<Paths, Method, Path>,\n unknown\n >,\n \"queryKey\" | \"queryFn\"\n > & {\n pageParamName?: string;\n },\n>(\n method: Method,\n url: Path,\n init: InitWithUnknowns<Init>,\n options: Options,\n queryClient?: QueryClient,\n) => UseInfiniteQueryResult<\n InferSelectReturnType<InfiniteData<Response[\"data\"]>, Options[\"select\"]>,\n Response[\"error\"]\n>;\n\nexport type UseSuspenseQueryMethod<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init extends MaybeOptionalInit<Paths[Path], Method>,\n Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types\n Options extends Omit<\n UseSuspenseQueryOptions<\n Response[\"data\"],\n Response[\"error\"],\n InferSelectReturnType<Response[\"data\"], Options[\"select\"]>,\n QueryKey<Paths, Method, Path>\n >,\n \"queryKey\" | \"queryFn\"\n >,\n>(\n method: Method,\n url: Path,\n ...[init, options, queryClient]: RequiredKeysOf<Init> extends never\n ? [InitWithUnknowns<Init>?, Options?, QueryClient?]\n : [InitWithUnknowns<Init>, Options?, QueryClient?]\n) => UseSuspenseQueryResult<InferSelectReturnType<Response[\"data\"], Options[\"select\"]>, Response[\"error\"]>;\n\nexport type UseMutationMethod<Paths extends Record<string, Record<HttpMethod, {}>>, Media extends MediaType> = <\n Method extends HttpMethod,\n Path extends PathsWithMethod<Paths, Method>,\n Init extends MaybeOptionalInit<Paths[Path], Method>,\n Response extends Required<FetchResponse<Paths[Path][Method], Init, Media>>, // note: Required is used to avoid repeating NonNullable in UseQuery types\n Options extends Omit<UseMutationOptions<Response[\"data\"], Response[\"error\"], Init>, \"mutationKey\" | \"mutationFn\">,\n>(\n method: Method,\n url: Path,\n options?: Options,\n queryClient?: QueryClient,\n) => UseMutationResult<Response[\"data\"], Response[\"error\"], Init>;\n\nexport interface OpenapiQueryClient<Paths extends {}, Media extends MediaType = MediaType> {\n queryOptions: QueryOptionsFunction<Paths, Media>;\n useQuery: UseQueryMethod<Paths, Media>;\n useSuspenseQuery: UseSuspenseQueryMethod<Paths, Media>;\n useInfiniteQuery: UseInfiniteQueryMethod<Paths, Media>;\n useMutation: UseMutationMethod<Paths, Media>;\n}\n\nexport type MethodResponse<\n CreatedClient extends OpenapiQueryClient<any, any>,\n Method extends HttpMethod,\n Path extends CreatedClient extends OpenapiQueryClient<infer Paths, infer _Media>\n ? PathsWithMethod<Paths, Method>\n : never,\n Options = object,\n> = CreatedClient extends OpenapiQueryClient<infer Paths extends { [key: string]: any }, infer Media extends MediaType>\n ? NonNullable<FetchResponse<Paths[Path][Method], Options, Media>[\"data\"]>\n : never;\n\n// TODO: Add the ability to bring queryClient as argument\nexport default function createClient<Paths extends {}, Media extends MediaType = MediaType>(\n client: FetchClient<Paths, Media>,\n): OpenapiQueryClient<Paths, Media> {\n const queryFn = async <Method extends HttpMethod, Path extends PathsWithMethod<Paths, Method>>({\n queryKey: [method, path, init],\n signal,\n }: QueryFunctionContext<QueryKey<Paths, Method, Path>>) => {\n const mth = method.toUpperCase() as Uppercase<typeof method>;\n const fn = client[mth] as ClientMethod<Paths, typeof method, Media>;\n const { data, error, response } = await fn(path, { signal, ...(init as any) }); // TODO: find a way to avoid as any\n if (error) {\n throw error;\n }\n if (response.status === 204 || response.headers.get(\"Content-Length\") === \"0\") {\n return data ?? null;\n }\n\n return data;\n };\n\n const queryOptions: QueryOptionsFunction<Paths, Media> = (method, path, ...[init, options]) => ({\n queryKey: (init === undefined ? ([method, path] as const) : ([method, path, init] as const)) as QueryKey<\n Paths,\n typeof method,\n typeof path\n >,\n queryFn,\n ...options,\n });\n\n return {\n queryOptions,\n useQuery: (method, path, ...[init, options, queryClient]) =>\n useQuery(queryOptions(method, path, init as InitWithUnknowns<typeof init>, options), queryClient),\n useSuspenseQuery: (method, path, ...[init, options, queryClient]) =>\n useSuspenseQuery(queryOptions(method, path, init as InitWithUnknowns<typeof init>, options), queryClient),\n useInfiniteQuery: (method, path, init, options, queryClient) => {\n const { pageParamName = \"cursor\", ...restOptions } = options;\n const { queryKey } = queryOptions(method, path, init);\n return useInfiniteQuery(\n {\n queryKey,\n queryFn: async ({ queryKey: [method, path, init], pageParam = 0, signal }) => {\n const mth = method.toUpperCase() as Uppercase<typeof method>;\n const fn = client[mth] as ClientMethod<Paths, typeof method, Media>;\n const mergedInit = {\n ...init,\n signal,\n params: {\n ...(init?.params || {}),\n query: {\n ...(init?.params as { query?: DefaultParamsOption })?.query,\n [pageParamName]: pageParam,\n },\n },\n };\n\n const { data, error } = await fn(path, mergedInit as any);\n if (error) {\n throw error;\n }\n return data;\n },\n ...restOptions,\n },\n queryClient,\n );\n },\n useMutation: (method, path, options, queryClient) =>\n useMutation(\n {\n mutationKey: [method, path],\n mutationFn: async (init) => {\n const mth = method.toUpperCase() as Uppercase<typeof method>;\n const fn = client[mth] as ClientMethod<Paths, typeof method, Media>;\n const { data, error } = await fn(path, init as InitWithUnknowns<typeof init>);\n if (error) {\n throw error;\n }\n\n return data as Exclude<typeof data, undefined>;\n },\n ...options,\n },\n queryClient,\n ),\n };\n}\n"],"names":["method","path","init"],"mappings":"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"}