openapi-hooks
Version:
Magical fetch inference for OpenAPI with React Query support
72 lines (70 loc) • 3.13 kB
TypeScript
type Paths = {
[key: string]: {
[key: string]: any;
};
};
type HTTPMethod = 'get' | 'put' | 'post' | 'delete' | 'options' | 'head' | 'patch' | 'trace';
type PathMethods<paths extends Paths, TPath extends keyof paths> = {
[TMethod in HTTPMethod]: paths[TPath][TMethod] extends undefined ? never : TMethod;
}[HTTPMethod];
type AnyRequestBody = {
content: Record<string, any>;
};
type AnyResponses = Record<number, {
content?: Record<string, any>;
headers?: Record<string, any>;
}>;
type AnyParameters = {
query?: Record<string, any>;
header?: Record<string, any>;
path?: Record<string, any>;
cookie?: Record<string, any>;
};
type AnyRoute = {
responses: AnyResponses;
requestBody?: AnyRequestBody;
parameters: AnyParameters;
};
type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
type ApiResponse<TResponses extends AnyResponses> = {
[TStatus in keyof TResponses]: TStatus extends number ? TResponses[TStatus]['content'] extends undefined ? {
status: TStatus;
contentType: never;
data: never;
headers: TResponses[TStatus]['headers'] extends Record<string, unknown> ? Map<keyof TResponses[TStatus]['headers'], TResponses[TStatus]['headers'][keyof TResponses[TStatus]['headers']]> : TResponses[TStatus]['headers'];
} : {
[K in keyof TResponses[TStatus]['content']]: {
status: TStatus;
contentType: K;
data: TResponses[TStatus]['content'][K];
headers: TResponses[TStatus]['headers'] extends Record<string, unknown> ? Map<keyof TResponses[TStatus]['headers'], TResponses[TStatus]['headers'][keyof TResponses[TStatus]['headers']]> : TResponses[TStatus]['headers'];
};
}[keyof TResponses[TStatus]['content']] : never;
}[keyof TResponses];
type ApiRequestBody<TBody extends AnyRequestBody | undefined> = TBody extends AnyRequestBody ? {
[K in keyof TBody['content']]: {
contentType: K;
data: TBody['content'][K];
};
}[keyof TBody['content']] : {
contentType?: undefined;
data?: undefined;
};
type HeaderObject = Record<string, string>;
type HeaderPredicate = () => PromiseLike<HeaderObject>;
type OpenApiHookOptions = {
baseUrl: URL | string;
headers?: HeaderObject | HeaderPredicate;
onError?: (error: ApiError) => void;
};
declare class ApiError extends Error {
status: number;
constructor(message: string, status: number);
static fromResponse(response: Response): ApiError;
}
declare const createFetch: <paths extends Paths>(options?: OpenApiHookOptions) => <TPath extends keyof paths, TMethod extends PathMethods<paths, TPath>, TOptions extends TRoute["parameters"] & ApiRequestBody<TRoute["requestBody"]> & {
fetchOptions?: RequestInit;
}, TRoute extends AnyRoute = paths[TPath][TMethod] extends AnyRoute ? paths[TPath][TMethod] : never>(path: TPath, method: TMethod, options: TOptions) => Promise<Prettify<ApiResponse<TRoute["responses"]>>>;
export { ApiError, type ApiRequestBody, type ApiResponse, type HeaderObject, type HeaderPredicate, type OpenApiHookOptions, type PathMethods, createFetch };