@gaddario98/react-queries
Version:
90 lines (89 loc) • 3.68 kB
TypeScript
import { AxiosRequestConfig } from 'axios';
import { Endpoint } from './endpoint';
import { MutateOptions, UseMutationResult } from '@tanstack/react-query';
import { NotificationConfig } from '@gaddario98/react-notifications';
import { TOptions } from 'i18next';
type HttpMethod = 'POST' | 'PUT' | 'DELETE';
export interface QueriesProps<TProps, TResponse, TConverter = null> {
endpoint: [keyof Endpoint, string] | [keyof Endpoint];
queryKeyToInvalidate?: string[];
headers?: AxiosRequestConfig['headers'];
method: HttpMethod;
converter?: (props: TProps) => TConverter;
customRequest?: (url: string, method: string, data: TProps) => Promise<TResponse>;
mutateOptions?: MutateOptions<TResponse, Error, TProps, unknown>;
isTest?: boolean;
notification?: {
success?: NotificationConfig | ((res: TResponse) => NotificationConfig);
error?: NotificationConfig | ((error: string) => NotificationConfig);
translationOption?: TOptions;
};
}
export interface QueryProps<Key extends string, TResponse> {
endpoint: [keyof Endpoint, string] | [keyof Endpoint];
queryKey: string[];
enabled: boolean;
keyToMap: Key;
disableLoading?: boolean;
customQueryFn?: () => Promise<TResponse>;
headers?: AxiosRequestConfig["headers"];
disableAuthControl?: boolean;
onDataChanged?: (data: TResponse) => void;
}
export type MultipleQueryResponse<Q extends QueriesArray> = {
[K in ExtractQuery<Q>['key']]: {
data: ExtractQueryResponse<Q, K>['response'];
isLoading: boolean;
isLoadingMapped: boolean;
isFetching: boolean;
isPending: boolean;
};
};
export type QueryDefinition<K extends string, T extends 'query' | 'mutation', P, R, C = any> = {
key: K;
props: P;
response: R;
converter: C;
type: T;
};
export type QueriesArray = Array<QueryDefinition<string, any, any, any, any>>;
export type ExtractQuery<Q extends QueriesArray> = Extract<Q[number], {
type: 'query';
}>;
export type ExtractQueryResponse<Q extends QueriesArray, K extends Q[number]['key']> = Extract<Q[number], {
key: K;
}>;
export type ExtractMutation<Q extends QueriesArray> = Extract<Q[number], {
type: 'mutation';
}>;
export type AllMutation<Q extends QueriesArray = QueriesArray> = {
[K in ExtractMutation<Q>['key']]: UseMutationResult<ExtractQueryResponse<Q, K>['response'], Error, ExtractQueryResponse<Q, K>['props'], unknown>;
};
interface MutationConfig<TProps = unknown, TResponse = unknown, TConverter = any> extends QueriesProps<TProps, TResponse, TConverter> {
method: 'POST' | 'PUT' | 'DELETE';
}
type SingleQueryConfig<Q extends QueryDefinition<any, any, any, any>> = Q extends QueryDefinition<infer K, infer T, infer P, infer R, infer C> ? T extends 'mutation' ? {
type: 'mutation';
mutationConfig: MutationConfig<P, R, C>;
key: K;
} : {
type: 'query';
queryConfig?: Omit<QueryProps<K, R>, 'keyToMap'>;
key: K;
} : never;
type QueryAtIndex<Q extends QueriesArray, I extends keyof Q> = Q[I] extends QueryDefinition<infer K, infer T, infer P, infer R, infer C> ? QueryDefinition<K, T, P, R, C> : never;
export type QueryConfigArray<Q extends QueriesArray> = {
[I in keyof Q]: SingleQueryConfig<QueryAtIndex<Q, I>>;
};
export interface ContextValue<Q extends QueriesArray> {
allMutation: AllMutation<Q>;
allQuery: MultipleQueryResponse<Q>;
}
export type MutationItem<Q extends QueriesArray> = Extract<QueryConfigArray<Q>[number], {
type: 'mutation';
mutationConfig: any;
}>;
export type QueryItem<Q extends QueriesArray> = Extract<QueryConfigArray<Q>[number], {
type: 'query';
}>;
export {};