import { RecursiveRecord, CacheStore } from '@dvcol/common-utils';
import { BaseSettings } from '../models/base-client.model.cjs';
import { BaseTemplateOptions, BaseBody, BaseTemplate } from '../models/base-template.model.cjs';
import { ClientEndpointCall, CacheKeyFunction, ClientEndpointCache } from '../models/client-endpoint.model.cjs';

/**
 * Creates a cached function that will wrap the inner client function and store the response in a provided cache store
 * @param clientFn - the inner client function to cache
 * @param key - the key to use for the cache
 * @param evictionKey - the key to use for eviction of the method (all cache entries matching this key will be evicted)
 * @param cache - the cache store to use
 * @param retention - the default retention time for the cache
 */
declare const getCachedFunction: <Parameter extends RecursiveRecord = RecursiveRecord, ResponseBody = unknown, ResponseType extends Response = Response>(clientFn: ClientEndpointCall<Parameter, ResponseBody>, { key, evictionKey, cache, retention, }: {
    key: string | CacheKeyFunction<Parameter>;
    evictionKey?: string | CacheKeyFunction<Parameter>;
    cache: CacheStore<ResponseType>;
    retention?: BaseTemplateOptions['cache'];
}) => ClientEndpointCache<Parameter, ResponseBody>;
/**
 * Parses body from a template and generate a json BodyInit.
 *
 * @template T - The type of the parameters.
 *
 * @param template - The expected body structure.
 * @param {T} params - The actual parameters.
 *
 * @returns {RecursiveRecord} The parsed request body as a Json Object.
 */
declare const parseBodyJson: <T extends RecursiveRecord = RecursiveRecord>(template: BaseBody<string | keyof T>, params: T) => RecursiveRecord;
/**
 * Parses body from a template and constructs a FormData BodyInit.
 *
 * @template T - The type of the parameters.
 *
 * @param template - The expected body structure.
 * @param {T} params - The actual parameters.
 *
 * @returns {FormData} The parsed request body as a FormData Object.
 */
declare const parseBodyFormData: <T extends RecursiveRecord = RecursiveRecord>(template: BaseBody<string | keyof T>, params: T) => FormData;
/**
 * Parses body from a template and constructs a URLSearchParams BodyInit.
 *
 * @template T - The type of the parameters.
 *
 * @param template - The expected body structure.
 * @param {T} params - The actual parameters.
 *
 * @returns {URLSearchParams} The parsed request body as a URLSearchParams Object.
 */
declare const parseBodyUrlEncoded: <T extends RecursiveRecord = RecursiveRecord>(template: BaseBody<string | keyof T>, params: T) => URLSearchParams;
/**
 * Parses body from a template and stringifies a {@link BodyInit}
 *
 * @private
 *
 * @template T - The type of the parameters.
 *
 * @param template - The expected body structure.
 * @param {T} params - The actual parameters.
 *
 * @returns {BodyInit} The parsed request body.
 */
declare const parseBody: <T extends RecursiveRecord = RecursiveRecord>(template: BaseBody<string | keyof T>, params: T) => BodyInit;
/**
 * Patches the response object to include a json method that parses the response data.
 * @param response - The response to patch
 * @param parseResponse - Optional function to parse the response data
 */
declare const patchResponse: <T extends Response, D = unknown, R = unknown>(response: T, parseResponse?: (data: D) => R) => T;
/**
 * Parses the parameters and constructs the URL for a  API request.
 *
 * @private
 *
 * @template P - The type of the parameters.
 *
 * @param {BaseTemplate<P>} template - The template for the API endpoint.
 * @param {P} params - The parameters for the API call.
 * @param {string} base - The API base url.
 *
 * @returns {URL} The URL for the  API request.
 *
 * @throws {Error} Throws an error if mandatory parameters are missing or if a filter is not supported.
 */
declare const parseUrl: <P extends RecursiveRecord = RecursiveRecord, O extends BaseTemplateOptions = BaseTemplateOptions>(template: BaseTemplate<P, O>, params: P, base: string, encode?: boolean) => URL;
/**
 * Injects a url prefix to the template URL if it is not already present.
 *
 * @param prefix - The prefix to inject.
 * @param template - The template for the API endpoint.
 * @param mutate - Whether to mutate the template or return a new one.
 */
declare const injectUrlPrefix: <P extends string, T extends {
    url: string;
}>(prefix: P, template: T, mutate?: boolean) => T;
/**
 * Injects the cors proxy prefix to the URL if it is not already present.
 *
 * @param template - The template for the API endpoint.
 * @param settings - The client settings.
 * @param mutate - Whether to mutate the template or return a new one.
 */
declare const injectCorsProxyPrefix: <T extends {
    url: string;
}, S extends BaseSettings>(template: T, settings: S, mutate?: boolean) => T;

export { getCachedFunction, injectCorsProxyPrefix, injectUrlPrefix, parseBody, parseBodyFormData, parseBodyJson, parseBodyUrlEncoded, parseUrl, patchResponse };
