import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse, HttpContextToken, HttpHeaders, HttpContext } from '@angular/common/http';
import { Observable } from 'rxjs';
import * as i0 from '@angular/core';
import { Type, InjectionToken, OnDestroy, ModuleWithProviders } from '@angular/core';

declare class NgHttpCachingInterceptorService implements HttpInterceptor {
    private readonly cacheService;
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
    /**
     * Send http request (next handler)
     */
    sendRequest(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
    static ɵfac: i0.ɵɵFactoryDeclaration<NgHttpCachingInterceptorService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<NgHttpCachingInterceptorService>;
}

interface NgHttpCachingStorageInterface {
    /**
     * The number of cached entries.
     */
    readonly size: number;
    /**
     * Clear the cache.
     */
    clear(): void;
    /**
     * Delete the cache entry for the provided key.
     */
    delete(key: string): boolean;
    /**
     * The forEach() method executes a provided function once for each cache entry.
     */
    forEach<K = any, T = any>(callbackfn: (value: NgHttpCachingEntry<K, T>, key: string) => void): void;
    /**
     * Return the cache entry for the provided key.
     */
    get<K = any, T = any>(key: string): Readonly<NgHttpCachingEntry<K, T>> | undefined;
    /**
     * Return true if the cache entry exists the provided key.
     */
    has(key: string): boolean;
    /**
     * Set the cache entry for the provided key.
     */
    set<K = any, T = any>(key: string, value: NgHttpCachingEntry<K, T>): void;
}

/**
 * State shape expected by the adapter.
 */
interface NgHttpCachingNgSimpleState<K = unknown, T = unknown> {
    entries: Record<string, NgHttpCachingEntry<K, T>>;
}
/**
 * User-facing configuration for the ng-simple-state adapter.
 */
interface NgHttpCachingNgSimpleStateAdapterConfig {
    storeName?: string;
    [key: string]: any;
}
/**
 * InjectionToken used to pass the user-provided adapter configuration.
 */
declare const NG_HTTP_CACHING_NG_SIMPLE_STATE_CONFIG: InjectionToken<NgHttpCachingNgSimpleStateAdapterConfig>;
/**
 * Lightweight sentinel / marker class.
 */
declare class NgHttpCachingNgSimpleStateSentinel {
    readonly adapterClass: Type<NgHttpCachingStorageInterface>;
    readonly adapterConfig?: NgHttpCachingNgSimpleStateAdapterConfig | undefined;
    constructor(adapterClass: Type<NgHttpCachingStorageInterface>, adapterConfig?: NgHttpCachingNgSimpleStateAdapterConfig | undefined);
}

type NgHttpCachingContext = Pick<NgHttpCachingConfig, 'getKey' | 'isCacheable' | 'isExpired' | 'isValid' | 'clearCacheOnMutation'>;
declare const NG_HTTP_CACHING_CONTEXT: HttpContextToken<NgHttpCachingContext>;
declare const withNgHttpCachingContext: (value: NgHttpCachingContext, context?: HttpContext) => HttpContext;
declare const checkCacheHeaders: (headers: HttpHeaders) => boolean | number;
interface NgHttpCachingEntry<K = any, T = any> {
    /**
     * URL
     */
    url: string;
    /**
     * HttpResponse
     */
    response: HttpResponse<T>;
    /**
     * HttpRequest
     */
    request: HttpRequest<K>;
    /**
     * Timestamp of add to cache time
     */
    addedTime: number;
    /**
     * Cache version
     */
    version: string;
}
declare const NG_HTTP_CACHING_CONFIG: InjectionToken<NgHttpCachingConfig>;
declare const NgHttpCachingStrategy: {
    /**
     * All request are cacheable if HTTP method is into `allowedMethod`
     */
    ALLOW_ALL: string;
    /**
     * Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`
     */
    DISALLOW_ALL: string;
};
type NgHttpCachingStrategy = typeof NgHttpCachingStrategy[keyof typeof NgHttpCachingStrategy];
declare const NgHttpCachingMutationStrategy: {
    /**
     * No invalidation on mutation
     */
    NONE: string;
    /**
     * Clear all cache on mutation
     */
    ALL: string;
    /**
     * Clear only the cache entries with the same URL as the mutation request
     */
    IDENTICAL: string;
    /**
     * Clear the cache entries with the same URL or the parent URL as the mutation request
     */
    COLLECTION: string;
};
type NgHttpCachingMutationStrategy = typeof NgHttpCachingMutationStrategy[keyof typeof NgHttpCachingMutationStrategy];
declare const NgHttpCachingHeaders: {
    /**
     * Request is cacheable if HTTP method is into `allowedMethod`
     */
    ALLOW_CACHE: string;
    /**
     * Request isn't cacheable
     */
    DISALLOW_CACHE: string;
    /**
     * Specific cache lifetime for the request
     */
    LIFETIME: string;
    /**
     * You can tag multiple request by adding this header with the same tag and
     * using `NgHttpCachingService.clearCacheByTag(tag: string)` for delete all the tagged request
     */
    TAG: string;
};
type NgHttpCachingHeaders = typeof NgHttpCachingHeaders[keyof typeof NgHttpCachingHeaders];
declare const NgHttpCachingHeadersList: string[];
declare const NG_HTTP_CACHING_SECOND_IN_MS = 1000;
declare const NG_HTTP_CACHING_MINUTE_IN_MS: number;
declare const NG_HTTP_CACHING_HOUR_IN_MS: number;
declare const NG_HTTP_CACHING_DAY_IN_MS: number;
declare const NG_HTTP_CACHING_WEEK_IN_MS: number;
declare const NG_HTTP_CACHING_MONTH_IN_MS: number;
declare const NG_HTTP_CACHING_YEAR_IN_MS: number;
interface NgHttpCachingConfig {
    /**
     * Set the cache store. You can implement your custom store by implement the `NgHttpCachingStorageInterface` interface, eg.:
     */
    store?: NgHttpCachingStorageInterface | NgHttpCachingNgSimpleStateSentinel;
    /**
     * Number of millisecond that a response is stored in the cache.
     * You can set specific "lifetime" for each request by add the header `X-NG-HTTP-CACHING-LIFETIME` (see example below).
     */
    lifetime?: number;
    /**
     * Array of allowed HTTP methods to cache.
     * You can allow multiple methods, eg.: `['GET', 'POST', 'PUT', 'DELETE', 'HEAD']` or
     * allow all methods by: `['ALL']`. If `allowedMethod` is an empty array (`[]`), no response are cached.
     * *Warning!* `NgHttpCaching` use the full url (url with query parameters) as unique key for the cached response,
     * this is correct for the `GET` request but is _potentially_ wrong for other type of request (eg. `POST`, `PUT`).
     * You can set a different "key" by customizing the `getKey` config method (see `getKey` section).
     */
    allowedMethod?: string[];
    /**
     * Set the cache strategy, possible strategies are:
     * - `NgHttpCachingStrategy.ALLOW_ALL`: All request are cacheable if HTTP method is into `allowedMethod`;
     * - `NgHttpCachingStrategy.DISALLOW_ALL`: Only the request with `X-NG-HTTP-CACHING-ALLOW-CACHE` header are cacheable if HTTP method is into `allowedMethod`;
     */
    cacheStrategy?: NgHttpCachingStrategy;
    /**
     * Cache version. When you have a breaking change, change the version, and it'll delete the current cache automatically.
     * The default value is Angular major version (eg. 13), in this way, the cache is invalidated on every Angular upgrade.
     */
    version?: string;
    /**
     * If true response headers cache-control and expires are respected.
     */
    checkResponseHeaders?: boolean;
    /**
     * If this function return `true` the request is expired and a new request is send to backend, if return `false` isn't expired.
     * If the result is `undefined`, the normal behaviour is provided.
     */
    isExpired?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;
    /**
     * If this function return `true` the request is cacheable, if return `false` isn't cacheable.
     * If the result is `undefined`, the normal behaviour is provided.
     */
    isCacheable?: <K>(req: HttpRequest<K>) => boolean | undefined | void;
    /**
     * This function return the unique key (`string`) for store the response into the cache.
     * If the result is `undefined`, the normal behaviour is provided.
     */
    getKey?: <K>(req: HttpRequest<K>) => string | undefined | void;
    /**
     * If this function return `true` the cache entry is valid and can be stored, if return `false` isn't valid.
     * If the result is `undefined`, the normal behaviour is provided.
     */
    isValid?: <K, T>(entry: NgHttpCachingEntry<K, T>) => boolean | undefined | void;
    /**
     * Set the mutation strategy.
     * If `true`, it behaves like `NgHttpCachingMutationStrategy.ALL`.
     * If `false`, it behaves like `NgHttpCachingMutationStrategy.NONE`.
     * If a custom function is provided, returning `true` will clear the **entire** cache store.
     * Returning `false` (or `undefined`) will skip invalidation for that request.
     */
    clearCacheOnMutation?: NgHttpCachingMutationStrategy | boolean | (<K>(req: HttpRequest<K>) => boolean | undefined | void);
}
interface NgHttpCachingDefaultConfig extends NgHttpCachingConfig {
    store: NgHttpCachingStorageInterface;
    lifetime: number;
    allowedMethod: string[];
    cacheStrategy: NgHttpCachingStrategy;
    version: string;
    checkResponseHeaders: boolean;
}
declare const NgHttpCachingConfigDefault: Readonly<NgHttpCachingDefaultConfig>;
declare class NgHttpCachingService implements OnDestroy {
    private readonly queue;
    private readonly config;
    private gcLock;
    private gcLastRun;
    private devMode;
    constructor();
    /**
     * Return the config
     */
    getConfig(): Readonly<NgHttpCachingConfig>;
    /**
     * Return the queue map
     */
    getQueue(): Readonly<Map<string, Observable<HttpEvent<any>>>>;
    /**
     * Return the cache store
     */
    getStore(): Readonly<NgHttpCachingStorageInterface>;
    /**
     * Return response from cache
     */
    getFromCache<K, T>(req: HttpRequest<K>): Readonly<HttpResponse<T>> | undefined;
    /**
     * Add response to cache
     */
    addToCache<K, T>(req: HttpRequest<K>, res: HttpResponse<T>): boolean;
    /**
     * Delete response from cache
     */
    deleteFromCache<K>(req: HttpRequest<K>): boolean;
    /**
     * Clear the cache
     */
    clearCache(): void;
    /**
     * Clear the cache by key
     */
    clearCacheByKey(key: string): boolean;
    /**
     * Clear the cache by keys
     */
    clearCacheByKeys(keys: Array<string>): number;
    /**
     * Clear the cache by regex
     */
    clearCacheByRegex<K, T>(regex: RegExp): number;
    /**
     * Clear the cache by TAG
     */
    clearCacheByTag<K, T>(tag: string): number;
    /**
     * Run garbage collector (delete expired cache entry)
     */
    runGc<K, T>(): boolean;
    /**
     * Clear the cache by mutation
     */
    clearCacheByMutation<K>(req: HttpRequest<K>): boolean;
    /**
     * Escape regex special characters
     */
    private escapeRegExp;
    /**
     * Return true if cache entry is expired
     */
    isExpired<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
    /**
     * Return true if cache entry is valid for store in the cache
     * Default behaviour is whether the status code falls in the 2xx range and response headers cache-control and expires allow cache.
     */
    isValid<K, T>(entry: NgHttpCachingEntry<K, T>): boolean;
    /**
     * Return true if the request is cacheable
     */
    isCacheable<K>(req: HttpRequest<K>): boolean;
    /**
     * Return the cache key.
     * Default key is http method plus url with query parameters, eg.:
     * `GET@https://github.com/nigrosimone/ng-http-caching`
     */
    getKey<K>(req: HttpRequest<K>): string;
    /**
     * Return observable from cache
     */
    getFromQueue<K, T>(req: HttpRequest<K>): Observable<HttpEvent<T>> | undefined;
    /**
     * Add observable to cache
     */
    addToQueue<K, T>(req: HttpRequest<K>, obs: Observable<HttpEvent<T>>): void;
    /**
     * Delete observable from cache
     */
    deleteFromQueue<K>(req: HttpRequest<K>): boolean;
    /**
     * Recursively Object.freeze simple Javascript structures consisting of plain objects, arrays, and primitives.
     * Make the data immutable.
     * @returns immutable object
     */
    private deepFreeze;
    ngOnDestroy(): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<NgHttpCachingService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<NgHttpCachingService>;
}

/** @deprecated use provideNgHttpCaching */
declare class NgHttpCachingModule {
    static forRoot(ngHttpCachingConfig?: NgHttpCachingConfig): ModuleWithProviders<NgHttpCachingModule>;
    static ɵfac: i0.ɵɵFactoryDeclaration<NgHttpCachingModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<NgHttpCachingModule, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<NgHttpCachingModule>;
}

declare function provideNgHttpCaching(ngHttpCachingConfig?: NgHttpCachingConfig): i0.EnvironmentProviders;

declare class NgHttpCachingMemoryStorage extends Map<string, NgHttpCachingEntry<any, any>> implements NgHttpCachingStorageInterface {
}
declare const withNgHttpCachingMemoryStorage: () => NgHttpCachingMemoryStorage;

interface NgHttpCachingStorageEntry {
    url: string;
    response: string;
    request: string;
    addedTime: number;
    version: string;
}
declare const serializeRequest: (req: HttpRequest<any>) => string;
declare const serializeResponse: (res: HttpResponse<any>) => string;
declare const deserializeRequest: <T = unknown>(req: string) => HttpRequest<T>;
declare const deserializeResponse: <T = unknown>(res: string) => HttpResponse<T>;
declare class NgHttpCachingBrowserStorage implements NgHttpCachingStorageInterface {
    private storage;
    constructor(storage: Storage);
    get size(): number;
    clear(): void;
    delete(key: string): boolean;
    forEach(callbackfn: (value: NgHttpCachingEntry, key: string) => void): void;
    get(key: string): Readonly<NgHttpCachingEntry> | undefined;
    has(key: string): boolean;
    set(key: string, value: NgHttpCachingEntry): void;
    protected serialize(value: NgHttpCachingEntry): NgHttpCachingStorageEntry;
    protected deserialize(value: NgHttpCachingStorageEntry): NgHttpCachingEntry;
}

declare class NgHttpCachingLocalStorage extends NgHttpCachingBrowserStorage {
    constructor();
}
declare const withNgHttpCachingLocalStorage: () => NgHttpCachingLocalStorage;

declare class NgHttpCachingSessionStorage extends NgHttpCachingBrowserStorage {
    constructor();
}
declare const withNgHttpCachingSessionStorage: () => NgHttpCachingSessionStorage;

export { NG_HTTP_CACHING_CONFIG, NG_HTTP_CACHING_CONTEXT, NG_HTTP_CACHING_DAY_IN_MS, NG_HTTP_CACHING_HOUR_IN_MS, NG_HTTP_CACHING_MINUTE_IN_MS, NG_HTTP_CACHING_MONTH_IN_MS, NG_HTTP_CACHING_NG_SIMPLE_STATE_CONFIG, NG_HTTP_CACHING_SECOND_IN_MS, NG_HTTP_CACHING_WEEK_IN_MS, NG_HTTP_CACHING_YEAR_IN_MS, NgHttpCachingBrowserStorage, NgHttpCachingConfigDefault, NgHttpCachingHeaders, NgHttpCachingHeadersList, NgHttpCachingInterceptorService, NgHttpCachingLocalStorage, NgHttpCachingMemoryStorage, NgHttpCachingModule, NgHttpCachingMutationStrategy, NgHttpCachingNgSimpleStateSentinel, NgHttpCachingService, NgHttpCachingSessionStorage, NgHttpCachingStrategy, checkCacheHeaders, deserializeRequest, deserializeResponse, provideNgHttpCaching, serializeRequest, serializeResponse, withNgHttpCachingContext, withNgHttpCachingLocalStorage, withNgHttpCachingMemoryStorage, withNgHttpCachingSessionStorage };
export type { NgHttpCachingConfig, NgHttpCachingContext, NgHttpCachingDefaultConfig, NgHttpCachingEntry, NgHttpCachingNgSimpleState, NgHttpCachingNgSimpleStateAdapterConfig, NgHttpCachingStorageEntry, NgHttpCachingStorageInterface };
