apiful
Version:
Extensible, typed API tooling
46 lines (28 loc) • 2.3 kB
text/typescript
import type { FetchError, FetchOptions } from 'ofetch';
import type { ErrorResponse, IsOperationRequestBodyOptional, MediaType, OperationRequestBodyContent, ResponseObjectMap, SuccessResponse } from 'openapi-typescript-helpers';
type FetchResponseData<T extends Record<PropertyKey, any>> = SuccessResponse<ResponseObjectMap<T>, MediaType>;
type FetchResponseError<T extends Record<PropertyKey, any>> = FetchError<ErrorResponse<ResponseObjectMap<T>, MediaType>>;
type MethodOption<M, P> = 'get' extends keyof P ? {
method?: M;
} : {
method: M;
};
type ParamsOption<T> = T extends {
parameters?: any;
query?: any;
} ? Omit<T['parameters'], 'cookie' | 'header'> & {
headers?: T['parameters']['header'] | HeadersInit;
} : Record<string, unknown>;
type RequestBodyOption<T> = OperationRequestBodyContent<T> extends never ? {
body?: never;
} : IsOperationRequestBodyOptional<T> extends true ? {
body?: OperationRequestBodyContent<T>;
} : {
body: OperationRequestBodyContent<T>;
};
type FilterMethods<T> = {
[K in keyof Omit<T, 'parameters'> as T[K] extends never | undefined ? never : K]: T[K];
};
type OpenAPIFetchOptions<Method, LowercasedMethod, Params, Operation = 'get' extends LowercasedMethod ? ('get' extends keyof Params ? Params['get'] : never) : LowercasedMethod extends keyof Params ? Params[LowercasedMethod] : never> = MethodOption<Method, Params> & ParamsOption<Operation> & RequestBodyOption<Operation> & Omit<FetchOptions, 'query' | 'body' | 'method'>;
type OpenAPIClient<Paths> = <ReqT extends Extract<keyof Paths, string>, Methods extends FilterMethods<Paths[ReqT]>, Method extends Extract<keyof Methods, string> | Uppercase<Extract<keyof Methods, string>>, LowercasedMethod extends Lowercase<Method> extends keyof Methods ? Lowercase<Method> : never, DefaultMethod extends 'get' extends LowercasedMethod ? 'get' : LowercasedMethod, ResT = Methods[DefaultMethod] extends Record<PropertyKey, any> ? FetchResponseData<Methods[DefaultMethod]> : never>(url: ReqT, options?: OpenAPIFetchOptions<Method, LowercasedMethod, Methods>) => Promise<ResT>;
export type { FetchResponseData as F, MethodOption as M, OpenAPIClient as O, ParamsOption as P, RequestBodyOption as R, FetchResponseError as a, FilterMethods as b, OpenAPIFetchOptions as c };