import { AxiosRequestHeaders, RawAxiosRequestHeaders, Method } from 'axios';

interface CreateTypes {
    data?: any;
    params?: any;
    cancelToken?: any;
    query?: any;
}
interface UpdateTypes {
    id?: any;
    data?: any;
    params?: any;
}
interface DestroyTypes {
    id?: any;
    params?: any;
}
interface GetByIdTypes {
    id?: any;
    params?: any;
    query?: any;
    cancelToken?: any;
}
interface ListTypes {
    query?: any;
    params?: any;
    cancelToken?: any;
}
type RestEntityAPIReturnTypes = {
    create: (data?: CreateTypes['data'], params?: CreateTypes['params'], cancelToken?: CreateTypes['cancelToken'], query?: CreateTypes['query']) => Promise<any>;
    update: (id?: UpdateTypes['id'], data?: UpdateTypes['data'], params?: UpdateTypes['params']) => Promise<any>;
    destroy: (id?: DestroyTypes['id'], params?: DestroyTypes['params']) => Promise<any>;
    getById: (id?: GetByIdTypes['id'], params?: GetByIdTypes['params'], query?: GetByIdTypes['query'], cancelToken?: GetByIdTypes['cancelToken']) => Promise<any>;
    list: (query?: ListTypes['query'], params?: ListTypes['params'], cancelToken?: ListTypes['cancelToken']) => Promise<any>;
    buildEndpoint: Function;
    toQueryString: Function;
} & {};

declare const METHOD_TYPES: {
    POST: string;
    PUT: string;
    DELETE: string;
    GET: string;
    LIST: string;
};
/**
 *
 * @param {Object} options
 * @param {String} options.name
 * @param {Function}options.endpoint
 * @param {Object} options.endpoints
 * @param {Object} options.entities
 */
interface ApiBuilderOptions {
    name?: string;
    endpoint?: () => string;
    endpoints?: {
        [x: string]: {
            endpoint: () => string;
            type: 'list' | 'create' | 'update' | 'destroy' | 'getById' | string;
        };
    };
    entities?: {
        [key: string]: {
            name: string;
            endpoint: () => string;
        };
    };
    headers?: AxiosRequestHeaders | RawAxiosRequestHeaders;
}
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
interface DefaultEntityAPIReturnTypes extends RestEntityAPIReturnTypes {
}
interface EndpointsAPIReturnTypes {
    [key: string]: UnionToIntersection<RestEntityAPIReturnTypes[keyof RestEntityAPIReturnTypes]>;
}
interface EntityAPIReturnTypes {
    [key: string]: RestEntityAPIReturnTypes;
}
declare const ApiBuilder: (options: ApiBuilderOptions) => DefaultEntityAPIReturnTypes & EndpointsAPIReturnTypes & EntityAPIReturnTypes;

/**
 * Convert api params to query string
 *
 * @param {Object}  params  Params to convert
 * @return {String}
 */
declare const toQueryString: (params: any) => string;
/**
 * Make a request and throw an error if response code is not in successful range.
 *
 * @param {String} url              The url of the request.
 * @param {Object} options
 * @param {String} options.method   The method for the request.
 * @param {Object} options.headers  The headers to send with the request.
 * @param {Object} options.body     The body to send with the request.
 */
type RequestOptionTypes = {
    method?: Method;
    headers?: AxiosRequestHeaders | RawAxiosRequestHeaders;
    body?: any;
    cancelToken?: any;
    formData?: boolean;
};
/**
 * Make a request with the ability to refresh tokens in the event of a 401.
 *
 * @param {String} url              The url of the request.
 * @param {Object} options
 * @param {Number} retry            Retry count
 * @param {String} options.method   The method for the request.
 * @param {Object} options.headers  The headers to send with the request.
 * @param {Object} options.body     The body to send with the request.
 */
declare function apiRequest(url: string, options: RequestOptionTypes): Promise<any>;

export { type DefaultEntityAPIReturnTypes, type EndpointsAPIReturnTypes, type EntityAPIReturnTypes, METHOD_TYPES, ApiBuilder as default, apiRequest as request, toQueryString };
