axios-cache-interceptor
Advanced tools
Comparing version 0.7.9 to 0.8.0-beta1
@@ -8,3 +8,3 @@ import type { AxiosDefaults, AxiosInstance, AxiosInterceptorManager, AxiosRequestConfig, AxiosResponse } from 'axios'; | ||
export declare type CacheAxiosResponse<R = any, D = any> = AxiosResponse<R, D> & { | ||
config: CacheRequestConfig<D>; | ||
config: CacheRequestConfig<R, D>; | ||
/** The id used for this request. if config specified an id, the id will be returned */ | ||
@@ -18,5 +18,6 @@ id: string; | ||
* | ||
* @template R The type returned by this response | ||
* @template D The type for the request body | ||
*/ | ||
export declare type CacheRequestConfig<D = any> = AxiosRequestConfig<D> & { | ||
export declare type CacheRequestConfig<R = any, D = any> = AxiosRequestConfig<D> & { | ||
/** | ||
@@ -34,3 +35,3 @@ * An id for this request, if this request is used in cache, only the last request made | ||
*/ | ||
cache?: false | Partial<CacheProperties>; | ||
cache?: false | Partial<CacheProperties<R, D>>; | ||
}; | ||
@@ -51,3 +52,3 @@ /** | ||
*/ | ||
<T = any, D = any, R = CacheAxiosResponse<T, D>>(config: CacheRequestConfig<D>): Promise<R>; | ||
<T = any, D = any, R = CacheAxiosResponse<T, D>>(config: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -58,3 +59,3 @@ * @template T The type returned by this response | ||
*/ | ||
<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<D>): Promise<R>; | ||
<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
defaults: AxiosDefaults<any> & { | ||
@@ -64,7 +65,7 @@ cache: CacheProperties; | ||
interceptors: { | ||
request: AxiosInterceptorManager<CacheRequestConfig<any>>; | ||
response: AxiosInterceptorManager<CacheAxiosResponse<never, any>>; | ||
request: AxiosInterceptorManager<CacheRequestConfig<any, any>>; | ||
response: AxiosInterceptorManager<CacheAxiosResponse<any, any>>; | ||
}; | ||
/** @template D The type that the request body use */ | ||
getUri<D>(config?: CacheRequestConfig<D>): string; | ||
getUri<D>(config?: CacheRequestConfig<any, D>): string; | ||
/** | ||
@@ -75,3 +76,3 @@ * @template T The type returned by this response | ||
*/ | ||
request<T = any, D = any, R = CacheAxiosResponse<T, D>>(config?: CacheRequestConfig<D>): Promise<R>; | ||
request<T = any, D = any, R = CacheAxiosResponse<T, D>>(config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -82,3 +83,3 @@ * @template T The type returned by this response | ||
*/ | ||
get<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<D>): Promise<R>; | ||
get<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -89,3 +90,3 @@ * @template T The type returned by this response | ||
*/ | ||
delete<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<D>): Promise<R>; | ||
delete<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -96,3 +97,3 @@ * @template T The type returned by this response | ||
*/ | ||
head<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<D>): Promise<R>; | ||
head<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -103,3 +104,3 @@ * @template T The type returned by this response | ||
*/ | ||
options<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<D>): Promise<R>; | ||
options<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -110,3 +111,3 @@ * @template T The type returned by this response | ||
*/ | ||
post<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<D>): Promise<R>; | ||
post<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -117,3 +118,3 @@ * @template T The type returned by this response | ||
*/ | ||
put<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<D>): Promise<R>; | ||
put<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
/** | ||
@@ -124,4 +125,4 @@ * @template T The type returned by this response | ||
*/ | ||
patch<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<D>): Promise<R>; | ||
patch<T = any, D = any, R = CacheAxiosResponse<T, D>>(url: string, data?: D, config?: CacheRequestConfig<T, D>): Promise<R>; | ||
} | ||
//# sourceMappingURL=axios.d.ts.map |
@@ -5,19 +5,21 @@ import type { Method } from 'axios'; | ||
import type { AxiosInterceptor } from '../interceptors/types'; | ||
import type { AxiosStorage } from '../storage/storage'; | ||
import type { CachedResponse } from '../storage/types'; | ||
import type { CachePredicate, KeyGenerator } from '../util/types'; | ||
import type { CacheUpdater } from '../util/update-cache'; | ||
import type { AxiosStorage, CachedResponse } from '../storage/types'; | ||
import type { CachePredicate, CacheUpdater, KeyGenerator } from '../util/types'; | ||
import type { CacheAxiosResponse, CacheRequestConfig } from './axios'; | ||
export declare type CacheProperties = { | ||
/** | ||
* @template R The type returned by this response | ||
* @template D The type for the request body | ||
*/ | ||
export declare type CacheProperties<R = any, D = any> = { | ||
/** | ||
* The time until the cached value is expired in milliseconds. | ||
* | ||
* If a function is used, it will receive the complete response and waits to return a TTL value | ||
* | ||
* When using `interpretHeader: true`, this value will only be used if the interpreter | ||
* can't determine their TTL value to override this | ||
* | ||
* **Note**: a custom storage implementation may not respect this. | ||
* | ||
* @default 1000 * 60 * 5 // 5 Minutes | ||
*/ | ||
ttl: number; | ||
ttl: number | ((response: CacheAxiosResponse<R, D>) => number | Promise<number>); | ||
/** | ||
@@ -41,3 +43,3 @@ * If this interceptor should configure the cache from the request cache header When | ||
*/ | ||
cachePredicate: CachePredicate; | ||
cachePredicate: CachePredicate<R, D>; | ||
/** | ||
@@ -47,6 +49,6 @@ * Once the request is resolved, this specifies what requests should we change the | ||
* | ||
* If the function returns nothing, the entry is deleted | ||
* | ||
* This is independent if the request made was cached or not. | ||
* | ||
* If an provided id represents and loading cache, he will be ignored. | ||
* | ||
* The id used is the same as the id on `CacheRequestConfig['id']`, auto-generated or not. | ||
@@ -56,3 +58,3 @@ * | ||
*/ | ||
update: Record<string, CacheUpdater>; | ||
update: Record<string, CacheUpdater<R, D>>; | ||
/** | ||
@@ -77,5 +79,5 @@ * If the request should handle ETag and If-None-Match support. Use a string to force a | ||
/** | ||
* The storage to save the cache data. | ||
* The storage to save the cache data. Defaults to an in-memory storage. | ||
* | ||
* @default new MemoryAxiosStorage() | ||
* @default buildMemoryStorage() | ||
*/ | ||
@@ -101,6 +103,6 @@ storage: AxiosStorage; | ||
/** The request interceptor that will be used to handle the cache. */ | ||
requestInterceptor: AxiosInterceptor<CacheRequestConfig<any>>; | ||
requestInterceptor: AxiosInterceptor<CacheRequestConfig<unknown, unknown>>; | ||
/** The response interceptor that will be used to handle the cache. */ | ||
responseInterceptor: AxiosInterceptor<CacheAxiosResponse<any, any>>; | ||
responseInterceptor: AxiosInterceptor<CacheAxiosResponse<unknown, unknown>>; | ||
} | ||
//# sourceMappingURL=cache.d.ts.map |
@@ -46,2 +46,10 @@ import type { AxiosInstance } from 'axios'; | ||
export declare const createCache: "use setupCache instead"; | ||
/** | ||
* Detects if the given parameter has caching enabled. The only way to this return true is | ||
* by using the {@link setupCache} function. | ||
* | ||
* @param axios The axios instance to use | ||
* @returns True if the axios instance is using the caching interceptor | ||
*/ | ||
export declare const isAxiosCacheInterceptor: (axios: any) => axios is AxiosCacheInstance; | ||
//# sourceMappingURL=create.d.ts.map |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
declare type MaybeTtl = false | undefined | number; | ||
declare type MaybeTtl = 'dont cache' | 'not enough headers' | number; | ||
/** | ||
@@ -11,0 +11,0 @@ * Interpret all http headers to determina a time to live. |
export * from './cache/axios'; | ||
export * from './cache/cache'; | ||
export * from './cache/create'; | ||
export * from './header/interpreter'; | ||
export * from './header/types'; | ||
export * from './interceptors/request'; | ||
export * from './interceptors/response'; | ||
export * from './interceptors/types'; | ||
export * from './storage/storage'; | ||
export * as InterceptorUtil from './interceptors/util'; | ||
export * from './storage/build'; | ||
export * from './storage/memory'; | ||
export * from './storage/types'; | ||
export * from './storage/web-api'; | ||
export * from './util/cache-predicate'; | ||
export * from './util/headers'; | ||
export * from './util/key-generator'; | ||
export * from './util/types'; | ||
export * from './util/update-cache'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -93,10 +93,31 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
__webpack_require__.d(__webpack_exports__, { | ||
"AxiosStorage": () => (/* reexport */ AxiosStorage), | ||
"BrowserAxiosStorage": () => (/* reexport */ BrowserAxiosStorage), | ||
"MemoryAxiosStorage": () => (/* reexport */ MemoryAxiosStorage), | ||
"CacheRequestInterceptor": () => (/* reexport */ CacheRequestInterceptor), | ||
"CacheResponseInterceptor": () => (/* reexport */ CacheResponseInterceptor), | ||
"Header": () => (/* reexport */ Header), | ||
"InterceptorUtil": () => (/* reexport */ util_namespaceObject), | ||
"buildMemoryStorage": () => (/* reexport */ buildMemoryStorage), | ||
"buildStorage": () => (/* reexport */ buildStorage), | ||
"buildWebStorage": () => (/* reexport */ buildWebStorage), | ||
"createCache": () => (/* reexport */ createCache), | ||
"defaultHeaderInterpreter": () => (/* reexport */ defaultHeaderInterpreter), | ||
"defaultKeyGenerator": () => (/* reexport */ defaultKeyGenerator), | ||
"isAxiosCacheInterceptor": () => (/* reexport */ isAxiosCacheInterceptor), | ||
"isCachePredicateValid": () => (/* reexport */ isCachePredicateValid), | ||
"isStorage": () => (/* reexport */ isStorage), | ||
"setupCache": () => (/* reexport */ setupCache), | ||
"shouldCacheResponse": () => (/* reexport */ shouldCacheResponse), | ||
"updateCache": () => (/* reexport */ updateCache), | ||
"useCache": () => (/* reexport */ useCache) | ||
}); | ||
// NAMESPACE OBJECT: ./src/interceptors/util.ts | ||
var util_namespaceObject = {}; | ||
__webpack_require__.r(util_namespaceObject); | ||
__webpack_require__.d(util_namespaceObject, { | ||
"createValidateStatus": () => (createValidateStatus), | ||
"isMethodIn": () => (isMethodIn), | ||
"setRevalidationHeaders": () => (setRevalidationHeaders), | ||
"setupCacheData": () => (setupCacheData) | ||
}); | ||
// EXTERNAL MODULE: ./node_modules/cache-parser/index.min.js | ||
@@ -197,44 +218,106 @@ var index_min = __webpack_require__(86); | ||
const defaultHeaderInterpreter = (headers = {}) => { | ||
if (Header.CacheControl in headers) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return interpretCacheControl(headers[Header.CacheControl], headers); | ||
const defaultHeaderInterpreter = (headers) => { | ||
if (!headers) | ||
return 'not enough headers'; | ||
const cacheControl = headers[Header.CacheControl]; | ||
if (cacheControl) { | ||
const { noCache, noStore, mustRevalidate, maxAge, immutable } = (0,index_min.parse)(cacheControl); | ||
// Header told that this response should not be cached. | ||
if (noCache || noStore) { | ||
return 'dont cache'; | ||
} | ||
if (immutable) { | ||
// 1 year is sufficient, as Infinity may cause more problems. | ||
// It might not be the best way, but a year is better than none. | ||
return 1000 * 60 * 60 * 24 * 365; | ||
} | ||
// Already out of date, for cache can be saved, but must be requested again | ||
if (mustRevalidate) { | ||
return 0; | ||
} | ||
if (maxAge) { | ||
const age = headers[Header.Age]; | ||
if (!age) { | ||
return maxAge * 1000; | ||
} | ||
return (maxAge - Number(age)) * 1000; | ||
} | ||
} | ||
if (Header.Expires in headers) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return interpretExpires(headers[Header.Expires], headers); | ||
const expires = headers[Header.Expires]; | ||
if (expires) { | ||
const milliseconds = Date.parse(expires) - Date.now(); | ||
return milliseconds >= 0 ? milliseconds : 'dont cache'; | ||
} | ||
return undefined; | ||
return 'not enough headers'; | ||
}; | ||
const interpretExpires = (expires) => { | ||
const milliseconds = Date.parse(expires) - Date.now(); | ||
return milliseconds >= 0 ? milliseconds : false; | ||
}; | ||
const interpretCacheControl = (cacheControl, headers) => { | ||
const { noCache, noStore, mustRevalidate, maxAge, immutable } = (0,index_min.parse)(cacheControl); | ||
// Header told that this response should not be cached. | ||
if (noCache || noStore) { | ||
return false; | ||
// EXTERNAL MODULE: ./node_modules/fast-defer/index.min.js | ||
var fast_defer_index_min = __webpack_require__(549); | ||
;// CONCATENATED MODULE: ./src/interceptors/util.ts | ||
/** | ||
* Creates a new validateStatus function that will use the one already used and also | ||
* accept status code 304. | ||
*/ | ||
function createValidateStatus(oldValidate) { | ||
return oldValidate | ||
? (status) => oldValidate(status) || status === 304 | ||
: (status) => (status >= 200 && status < 300) || status === 304; | ||
} | ||
/** Checks if the given method is in the methods array */ | ||
function isMethodIn(requestMethod, methodList = []) { | ||
requestMethod = requestMethod.toLowerCase(); | ||
for (const method of methodList) { | ||
if (method.toLowerCase() === requestMethod) { | ||
return true; | ||
} | ||
} | ||
if (immutable) { | ||
// 1 year is sufficient, as Infinity may cause more problems. | ||
// It might not be the best way, but a year is better than none. | ||
return 1000 * 60 * 60 * 24 * 365; | ||
return false; | ||
} | ||
function setRevalidationHeaders(cache, config) { | ||
config.headers || (config.headers = {}); | ||
const { etag, modifiedSince } = config.cache; | ||
if (etag) { | ||
const etagValue = etag === true ? cache.data?.headers[Header.ETag] : etag; | ||
if (etagValue) { | ||
config.headers[Header.IfNoneMatch] = etagValue; | ||
} | ||
} | ||
// Already out of date, for cache can be saved, but must be requested again | ||
if (mustRevalidate) { | ||
return 0; | ||
if (modifiedSince) { | ||
config.headers[Header.IfModifiedSince] = | ||
modifiedSince === true | ||
? // If last-modified is not present, use the createdAt timestamp | ||
cache.data.headers[Header.LastModified] || | ||
new Date(cache.createdAt).toUTCString() | ||
: modifiedSince.toUTCString(); | ||
} | ||
if (maxAge) { | ||
const age = headers[Header.Age]; | ||
if (!age) { | ||
return maxAge * 1000; | ||
} | ||
return (maxAge - Number(age)) * 1000; | ||
} | ||
/** | ||
* Creates the new date to the cache by the provided response. Also handles possible 304 | ||
* Not Modified by updating response properties. | ||
*/ | ||
function setupCacheData(response, cache) { | ||
if (response.status === 304 && cache) { | ||
// Set the cache information into the response object | ||
response.cached = true; | ||
response.data = cache.data; | ||
response.status = cache.status; | ||
response.statusText = cache.statusText; | ||
// Update possible new headers | ||
response.headers = { | ||
...cache.headers, | ||
...response.headers | ||
}; | ||
// return the old cache | ||
return cache; | ||
} | ||
return undefined; | ||
}; | ||
// New Response | ||
return { | ||
data: response.data, | ||
status: response.status, | ||
statusText: response.statusText, | ||
headers: response.headers | ||
}; | ||
} | ||
// EXTERNAL MODULE: ./node_modules/fast-defer/index.min.js | ||
var fast_defer_index_min = __webpack_require__(549); | ||
;// CONCATENATED MODULE: ./src/interceptors/request.ts | ||
@@ -257,3 +340,3 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
!CacheRequestInterceptor.isMethodAllowed(config.method, config.cache)) { | ||
!isMethodIn(config.method, config.cache.methods)) { | ||
return config; | ||
@@ -287,6 +370,5 @@ } | ||
if (cache.state === 'stale') { | ||
//@ts-expect-error type infer couldn't resolve this | ||
CacheRequestInterceptor.setRevalidationHeaders(cache, config); | ||
setRevalidationHeaders(cache, config); | ||
} | ||
config.validateStatus = CacheRequestInterceptor.createValidateStatus(config.validateStatus); | ||
config.validateStatus = createValidateStatus(config.validateStatus); | ||
return config; | ||
@@ -320,3 +402,3 @@ } | ||
Promise.resolve({ | ||
config: config, | ||
config, | ||
data: cachedResponse.data, | ||
@@ -333,40 +415,2 @@ headers: cachedResponse.headers, | ||
} | ||
CacheRequestInterceptor.isMethodAllowed = (method, properties) => { | ||
const requestMethod = method.toLowerCase(); | ||
for (const method of properties.methods || []) { | ||
if (method.toLowerCase() === requestMethod) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
CacheRequestInterceptor.setRevalidationHeaders = (cache, config) => { | ||
config.headers || (config.headers = {}); | ||
const { etag, modifiedSince } = config.cache; | ||
if (etag) { | ||
const etagValue = etag === true ? cache.data?.headers[Header.ETag] : etag; | ||
if (etagValue) { | ||
config.headers[Header.IfNoneMatch] = etagValue; | ||
} | ||
} | ||
if (modifiedSince) { | ||
config.headers[Header.IfModifiedSince] = | ||
modifiedSince === true | ||
? // If last-modified is not present, use the createdAt timestamp | ||
cache.data.headers[Header.LastModified] || | ||
new Date(cache.createdAt).toUTCString() | ||
: modifiedSince.toUTCString(); | ||
} | ||
}; | ||
/** | ||
* Creates a new validateStatus function that will use the one already used and also | ||
* accept status code 304. | ||
*/ | ||
CacheRequestInterceptor.createValidateStatus = (oldValidate) => { | ||
return (status) => { | ||
return oldValidate | ||
? oldValidate(status) || status === 304 | ||
: (status >= 200 && status < 300) || status === 304; | ||
}; | ||
}; | ||
@@ -419,3 +463,3 @@ ;// CONCATENATED MODULE: ./src/util/cache-predicate.ts | ||
} | ||
if (responseMatch && !responseMatch(response.data)) { | ||
if (responseMatch && !responseMatch(response)) { | ||
return false; | ||
@@ -438,10 +482,12 @@ } | ||
if (oldValue.state === 'loading') { | ||
throw new Error('cannot update the cache while loading'); | ||
continue; | ||
} | ||
const newValue = value(oldValue, data); | ||
if (newValue === undefined) { | ||
const newValue = await value(oldValue, data); | ||
if (newValue === 'delete') { | ||
await storage.remove(cacheKey); | ||
continue; | ||
} | ||
await storage.set(cacheKey, newValue); | ||
if (newValue !== 'ignore') { | ||
await storage.set(cacheKey, newValue); | ||
} | ||
} | ||
@@ -454,2 +500,3 @@ } | ||
class CacheResponseInterceptor { | ||
@@ -506,9 +553,12 @@ constructor(axios) { | ||
// Cache should not be used | ||
if (expirationTime === false) { | ||
if (expirationTime === 'dont cache') { | ||
await this.rejectResponse(response.id); | ||
return response; | ||
} | ||
ttl = expirationTime || expirationTime === 0 ? expirationTime : ttl; | ||
ttl = expirationTime === 'not enough headers' ? ttl : expirationTime; | ||
} | ||
const data = CacheResponseInterceptor.setupCacheData(response, cache.data); | ||
const data = setupCacheData(response, cache.data); | ||
if (typeof ttl === 'function') { | ||
ttl = await ttl(response); | ||
} | ||
const newCache = { | ||
@@ -522,3 +572,3 @@ state: 'cached', | ||
if (cacheConfig?.update) { | ||
updateCache(this.axios.storage, response.data, cacheConfig.update); | ||
updateCache(this.axios.storage, response, cacheConfig.update); | ||
} | ||
@@ -552,43 +602,47 @@ const deferred = this.axios.waiting[response.id]; | ||
} | ||
;// CONCATENATED MODULE: ./src/storage/build.ts | ||
const storage = Symbol(); | ||
/** Returns true if the provided object was created from {@link buildStorage} function. */ | ||
const isStorage = (obj) => !!obj && !!obj[storage]; | ||
/** | ||
* Creates the new date to the cache by the provided response. Also handles possible 304 | ||
* Not Modified by updating response properties. | ||
* Builds a custom storage. | ||
* | ||
* **Note**: You can only create an custom storage with this function. | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const myStorage = buildStorage({ | ||
* find: () => {...}, | ||
* set: () => {...}, | ||
* remove: () => {...} | ||
* }); | ||
* | ||
* const axios = setupCache(axios, { storage: myStorage }); | ||
* ``` | ||
*/ | ||
CacheResponseInterceptor.setupCacheData = (response, cache) => { | ||
if (response.status === 304 && cache) { | ||
// Set the cache information into the response object | ||
response.cached = true; | ||
response.data = cache.data; | ||
response.status = cache.status; | ||
response.statusText = cache.statusText; | ||
// Update possible new headers | ||
response.headers = { | ||
...cache.headers, | ||
...response.headers | ||
}; | ||
// return the old cache | ||
return cache; | ||
} | ||
// New Response | ||
function buildStorage({ set, find, remove }) { | ||
return { | ||
data: response.data, | ||
status: response.status, | ||
statusText: response.statusText, | ||
headers: response.headers | ||
}; | ||
}; | ||
;// CONCATENATED MODULE: ./src/storage/storage.ts | ||
class AxiosStorage { | ||
constructor() { | ||
this.get = async (key) => { | ||
const value = await this.find(key); | ||
if (value.state !== 'cached' || | ||
// Cached and fresh value | ||
//@ts-expect-error - we don't want to expose this | ||
[storage]: 1, | ||
set, | ||
remove, | ||
get: async (key) => { | ||
const value = await find(key); | ||
if (!value) { | ||
return { state: 'empty' }; | ||
} | ||
if ( | ||
// Not cached or fresh value | ||
value.state !== 'cached' || | ||
value.createdAt + value.ttl > Date.now()) { | ||
return value; | ||
} | ||
// Check if his can stale value. | ||
if (AxiosStorage.keepIfStale(value)) { | ||
if (value.data.headers && | ||
(Header.ETag in value.data.headers || | ||
Header.LastModified in value.data.headers || | ||
Header.XAxiosCacheEtag in value.data.headers || | ||
Header.XAxiosCacheLastModified in value.data.headers)) { | ||
const stale = { | ||
@@ -599,37 +653,43 @@ data: value.data, | ||
}; | ||
await this.set(key, stale); | ||
await set(key, stale); | ||
return stale; | ||
} | ||
await this.remove(key); | ||
await remove(key); | ||
return { state: 'empty' }; | ||
}; | ||
} | ||
} | ||
}; | ||
} | ||
/** Returns true if a invalid cache should still be kept */ | ||
AxiosStorage.keepIfStale = ({ data }) => { | ||
if (data?.headers) { | ||
return (Header.ETag in data.headers || | ||
Header.LastModified in data.headers || | ||
Header.XAxiosCacheEtag in data.headers || | ||
Header.XAxiosCacheLastModified in data.headers); | ||
} | ||
return false; | ||
}; | ||
;// CONCATENATED MODULE: ./src/storage/memory.ts | ||
class MemoryAxiosStorage extends AxiosStorage { | ||
constructor(storage = {}) { | ||
super(); | ||
this.storage = storage; | ||
this.find = async (key) => { | ||
return this.storage[key] || { state: 'empty' }; | ||
}; | ||
this.set = async (key, value) => { | ||
this.storage[key] = value; | ||
}; | ||
this.remove = async (key) => { | ||
delete this.storage[key]; | ||
}; | ||
} | ||
/** | ||
* Creates a simple in-memory storage. This means that if you need to persist data between | ||
* page or server reloads, this will not help. | ||
* | ||
* This is the storage used by default. | ||
* | ||
* If you need to modify it's data, you can do by the `data` property. | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const memoryStorage = buildMemoryStorage(); | ||
* | ||
* setupCache(axios, { storage: memoryStorage }); | ||
* | ||
* // Simple example to force delete the request cache | ||
* | ||
* const { id } = axios.get('url'); | ||
* | ||
* delete memoryStorage.data[id]; | ||
* ``` | ||
*/ | ||
function buildMemoryStorage() { | ||
const data = {}; | ||
const storage = buildStorage({ | ||
find: (key) => data[key], | ||
set: (key, value) => void (data[key] = value), | ||
remove: (key) => void delete data[key] | ||
}); | ||
return { ...storage, data }; | ||
} | ||
@@ -641,11 +701,16 @@ | ||
const SLASHES_REGEX = /^\/|\/+$/g; | ||
const defaultKeyGenerator = ({ baseURL = '', url = '', method: nullableMethod, params, id }) => { | ||
if (id) | ||
return String(id); | ||
const defaultKeyGenerator = ({ baseURL = '', url = '', method, params, id }) => { | ||
if (id) { | ||
return id; | ||
} | ||
// Remove trailing slashes | ||
baseURL = baseURL.replace(SLASHES_REGEX, ''); | ||
url = url.replace(SLASHES_REGEX, ''); | ||
const method = nullableMethod?.toLowerCase() || 'get'; | ||
const jsonParams = params ? JSON.stringify(params, Object.keys(params).sort()) : '{}'; | ||
return `${method}::${baseURL + (url && baseURL ? '/' : '') + url}::${jsonParams}`; | ||
return `${ | ||
// method | ||
method?.toLowerCase() || 'get'}::${ | ||
// complete url | ||
baseURL + (baseURL && url ? '/' : '') + url}::${ | ||
//params | ||
params ? JSON.stringify(params, Object.keys(params).sort()) : '{}'}`; | ||
}; | ||
@@ -659,2 +724,4 @@ | ||
const symbolKey = Symbol(); | ||
/** | ||
@@ -698,3 +765,6 @@ * Apply the caching interceptors for a already created axios instance. | ||
const axiosCache = axios; | ||
axiosCache.storage = storage || new MemoryAxiosStorage(); | ||
axiosCache.storage = storage || buildMemoryStorage(); | ||
if (!isStorage(axiosCache.storage)) { | ||
throw new Error('Use buildStorage()'); | ||
} | ||
axiosCache.generateKey = generateKey || defaultKeyGenerator; | ||
@@ -724,2 +794,4 @@ axiosCache.waiting = waiting || {}; | ||
axiosCache.responseInterceptor.use(); | ||
// @ts-expect-error - internal only | ||
axiosCache[symbolKey] = 1; | ||
return axiosCache; | ||
@@ -731,30 +803,41 @@ } | ||
const createCache = setupCache; | ||
/** | ||
* Detects if the given parameter has caching enabled. The only way to this return true is | ||
* by using the {@link setupCache} function. | ||
* | ||
* @param axios The axios instance to use | ||
* @returns True if the axios instance is using the caching interceptor | ||
*/ | ||
const isAxiosCacheInterceptor = (axios) => !!axios && !!axios[symbolKey]; | ||
;// CONCATENATED MODULE: ./src/storage/browser.ts | ||
;// CONCATENATED MODULE: ./src/storage/web-api.ts | ||
class BrowserAxiosStorage extends AxiosStorage { | ||
/** | ||
* @param storage Any browser storage, like sessionStorage or localStorage | ||
* @param prefix The key prefix to use on all keys. | ||
*/ | ||
constructor(storage, prefix = BrowserAxiosStorage.DEFAULT_KEY_PREFIX) { | ||
super(); | ||
this.storage = storage; | ||
this.prefix = prefix; | ||
this.find = async (key) => { | ||
const json = this.storage.getItem(`${this.prefix}:${key}`); | ||
return json ? JSON.parse(json) : { state: 'empty' }; | ||
}; | ||
this.set = async (key, value) => { | ||
return this.storage.setItem(`${this.prefix}:${key}`, JSON.stringify(value)); | ||
}; | ||
this.remove = async (key) => { | ||
return this.storage.removeItem(`${this.prefix}:${key}`); | ||
}; | ||
} | ||
/** | ||
* Creates a simple storage. You can persist his data by using `sessionStorage` or | ||
* `localStorage` with it. | ||
* | ||
* **ImplNote**: Without polyfill, this storage only works on browser environments. | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const fromLocalStorage = buildWebStorage(localStorage); | ||
* const fromSessionStorage = buildWebStorage(sessionStorage); | ||
* | ||
* const myStorage = new Storage(); | ||
* const fromMyStorage = buildWebStorage(myStorage); | ||
* ``` | ||
*/ | ||
function buildWebStorage(storage, prefix = '') { | ||
return buildStorage({ | ||
find: (key) => { | ||
const json = storage.getItem(prefix + key); | ||
return json ? JSON.parse(json) : undefined; | ||
}, | ||
set: (key, value) => void storage.setItem(prefix + key, JSON.stringify(value)), | ||
remove: (key) => void storage.removeItem(prefix + key) | ||
}); | ||
} | ||
BrowserAxiosStorage.DEFAULT_KEY_PREFIX = 'a-c-i'; | ||
;// CONCATENATED MODULE: ./src/index.development.ts | ||
/** Index file for webpack and cdn usage */ | ||
;// CONCATENATED MODULE: ./src/index.ts | ||
@@ -764,4 +847,21 @@ | ||
console.warn('You are using a development build. Make sure to use the correct build in production\nhttps://github.com/arthurfiorette/axios-cache-interceptor#installing'); | ||
;// CONCATENATED MODULE: ./src/index.development.ts | ||
console.warn('You are using a development build. Make sure to use the correct build in production\nhttps://axios-cache-interceptor.js.org/#/pages/installing'); | ||
})(); | ||
@@ -768,0 +868,0 @@ |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return(()=>{var e={86:(e,t)=>{!function(e){var t=Symbol("cache-parser"),a=Number;function s(e){return("string"==typeof e||"number"==typeof e)&&(e=a(e))>=0&&e<1/0}function r(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:s,toBoolean:r},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return r(e.immutable)&&t.push("immutable"),s(e.maxAge)&&t.push("max-age="+a(e.maxAge)),s(e.maxStale)&&t.push("max-stale="+a(e.maxStale)),s(e.minFresh)&&t.push("min-fresh="+a(e.minFresh)),r(e.mustRevalidate)&&t.push("must-revalidate"),r(e.mustUnderstand)&&t.push("must-understand"),r(e.noCache)&&t.push("no-cache"),r(e.noStore)&&t.push("no-store"),r(e.noTransform)&&t.push("no-transform"),r(e.onlyIfCached)&&t.push("only-if-cached"),r(e.private)&&t.push("private"),r(e.proxyRevalidate)&&t.push("proxy-revalidate"),r(e.public)&&t.push("public"),s(e.sMaxAge)&&t.push("s-maxage="+a(e.sMaxAge)),s(e.staleIfError)&&t.push("stale-if-error="+a(e.staleIfError)),s(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+a(e.staleWhileRevalidate)),t},e.parse=function(e){var i=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return i;var o={},n=e.toLowerCase().replace(/\s+/g,"").split(",");for(var c in n){var d=n[c].split("=",2);o[d[0]]=1===d.length||d[1]}return r(o.immutable)&&(i.immutable=!0),s(o["max-age"])&&(i.maxAge=a(o["max-age"])),s(o["max-stale"])&&(i.maxStale=a(o["max-stale"])),s(o["min-fresh"])&&(i.minFresh=a(o["min-fresh"])),r(o["must-revalidate"])&&(i.mustRevalidate=!0),r(o["must-understand"])&&(i.mustUnderstand=!0),r(o["no-cache"])&&(i.noCache=!0),r(o["no-store"])&&(i.noStore=!0),r(o["no-transform"])&&(i.noTransform=!0),r(o["only-if-cached"])&&(i.onlyIfCached=!0),r(o.private)&&(i.private=!0),r(o["proxy-revalidate"])&&(i.proxyRevalidate=!0),r(o.public)&&(i.public=!0),s(o["s-maxage"])&&(i.sMaxAge=a(o["s-maxage"])),s(o["stale-if-error"])&&(i.staleIfError=a(o["stale-if-error"])),s(o["stale-while-revalidate"])&&(i.staleWhileRevalidate=a(o["stale-while-revalidate"])),i}}(t)},549:(e,t)=>{var a,s;a=t,s=Symbol("fast-defer"),a.deferred=function(){var e,t,a=new Promise((function(a,s){e=a,t=s}));return a.resolve=e,a.reject=t,a[s]=1,a},a.isDeferred=function(e){return!!e&&!!e[s]}}},t={};function a(s){var r=t[s];if(void 0!==r)return r.exports;var i=t[s]={exports:{}};return e[s](i,i.exports,a),i.exports}a.d=(e,t)=>{for(var s in t)a.o(t,s)&&!a.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var s={};return(()=>{"use strict";a.r(s),a.d(s,{AxiosStorage:()=>h,BrowserAxiosStorage:()=>x,MemoryAxiosStorage:()=>u,createCache:()=>m,setupCache:()=>p,useCache:()=>g});var e,t=a(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(e||(e={}));const r=(t={})=>e.CacheControl in t?o(t[e.CacheControl],t):e.Expires in t?i(t[e.Expires],t):void 0,i=e=>{const t=Date.parse(e)-Date.now();return t>=0&&t},o=(a,s)=>{const{noCache:r,noStore:i,mustRevalidate:o,maxAge:n,immutable:c}=(0,t.parse)(a);if(r||i)return!1;if(c)return 31536e6;if(o)return 0;if(n){const t=s[e.Age];return t?1e3*(n-Number(t)):1e3*n}};var n=a(549);class c{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.request.use(this.onFulfilled)},this.onFulfilled=async e=>{if(!1===e.cache)return e;if(e.cache={...this.axios.defaults.cache,...e.cache},!c.isMethodAllowed(e.method,e.cache))return e;const t=this.axios.generateKey(e);let a,s=await this.axios.storage.get(t);e:if("empty"==s.state||"stale"===s.state){if(this.axios.waiting[t]){s=await this.axios.storage.get(t);break e}return this.axios.waiting[t]=(0,n.deferred)(),this.axios.waiting[t]?.catch((()=>{})),await this.axios.storage.set(t,{state:"loading",data:s.data}),"stale"===s.state&&c.setRevalidationHeaders(s,e),e.validateStatus=c.createValidateStatus(e.validateStatus),e}if("loading"===s.state){const s=this.axios.waiting[t];if(!s)return await this.axios.storage.remove(t),e;try{a=await s}catch{return e}}else a=s.data;return e.adapter=()=>Promise.resolve({config:e,data:a.data,headers:a.headers,status:a.status,statusText:a.statusText,cached:!0,id:t}),e}}}c.isMethodAllowed=(e,t)=>{const a=e.toLowerCase();for(const e of t.methods||[])if(e.toLowerCase()===a)return!0;return!1},c.setRevalidationHeaders=(t,a)=>{a.headers||(a.headers={});const{etag:s,modifiedSince:r}=a.cache;if(s){const r=!0===s?t.data?.headers[e.ETag]:s;r&&(a.headers[e.IfNoneMatch]=r)}r&&(a.headers[e.IfModifiedSince]=!0===r?t.data.headers[e.LastModified]||new Date(t.createdAt).toUTCString():r.toUTCString())},c.createValidateStatus=e=>t=>e?e(t)||304===t:t>=200&&t<300||304===t;class d{constructor(t){this.axios=t,this.use=()=>{this.axios.interceptors.response.use(this.onFulfilled)},this.onFulfilled=async t=>{const a=this.cachedResponse(t);if(a.cached)return a;if(!a.config.cache)return{...a,cached:!1};const s=a.config.cache,r=await this.axios.storage.get(a.id);if("stale"===r.state||"empty"===r.state||"cached"===r.state)return a;if(!r.data&&!function(e,{cachePredicate:t}){return"function"==typeof t?t(e):function(e,{statusCheck:t,containsHeaders:a,responseMatch:s}){if(t)if("function"==typeof t){if(!t(e.status))return!1}else{const[a,s]=t;if(e.status<a||e.status>s)return!1}if(a)for(const t in a){const s=a[t],r=e.headers[t];if(!r)return!1;switch(typeof s){case"string":if(r!=s)return!1;break;case"function":if(!s(r))return!1}}return!(s&&!s(e.data))}(e,t)}(a,s))return await this.rejectResponse(a.id),a;delete a.headers[e.XAxiosCacheEtag],delete a.headers[e.XAxiosCacheLastModified],s.etag&&!0!==s.etag&&(a.headers[e.XAxiosCacheEtag]=s.etag),s.modifiedSince&&(a.headers[e.XAxiosCacheLastModified]=!0===s.modifiedSince?"use-cache-timestamp":s.modifiedSince.toUTCString());let i=s.ttl||-1;if(s?.interpretHeader){const e=this.axios.headerInterpreter(a.headers);if(!1===e)return await this.rejectResponse(a.id),a;i=e||0===e?e:i}const o=d.setupCacheData(a,r.data),n={state:"cached",ttl:i,createdAt:Date.now(),data:o};s?.update&&async function(e,t,a){for(const s in a){const r=a[s];if("delete"===r){await e.remove(s);continue}const i=await e.get(s);if("loading"===i.state)throw new Error("cannot update the cache while loading");const o=r(i,t);void 0!==o?await e.set(s,o):await e.remove(s)}}(this.axios.storage,a.data,s.update);const c=this.axios.waiting[a.id];return await(c?.resolve(n.data)),delete this.axios.waiting[a.id],await this.axios.storage.set(a.id,n),a},this.rejectResponse=async e=>{await this.axios.storage.remove(e),this.axios.waiting[e]?.reject(null),delete this.axios.waiting[e]},this.cachedResponse=e=>({id:this.axios.generateKey(e.config),cached:e.cached||!1,...e})}}d.setupCacheData=(e,t)=>304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers={...t.headers,...e.headers},t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers};class h{constructor(){this.get=async e=>{const t=await this.find(e);if("cached"!==t.state||t.createdAt+t.ttl>Date.now())return t;if(h.keepIfStale(t)){const a={data:t.data,state:"stale",createdAt:t.createdAt};return await this.set(e,a),a}return await this.remove(e),{state:"empty"}}}}h.keepIfStale=({data:t})=>!!t?.headers&&(e.ETag in t.headers||e.LastModified in t.headers||e.XAxiosCacheEtag in t.headers||e.XAxiosCacheLastModified in t.headers);class u extends h{constructor(e={}){super(),this.storage=e,this.find=async e=>this.storage[e]||{state:"empty"},this.set=async(e,t)=>{this.storage[e]=t},this.remove=async e=>{delete this.storage[e]}}}const f=/^\/|\/+$/g,l=({baseURL:e="",url:t="",method:a,params:s,id:r})=>{if(r)return String(r);e=e.replace(f,""),t=t.replace(f,"");return`${a?.toLowerCase()||"get"}::${e+(t&&e?"/":"")+t}::${s?JSON.stringify(s,Object.keys(s).sort()):"{}"}`};function p(e,{storage:t,generateKey:a,waiting:s,headerInterpreter:i,requestInterceptor:o,responseInterceptor:n,...h}={}){const f=e;return f.storage=t||new u,f.generateKey=a||l,f.waiting=s||{},f.headerInterpreter=i||r,f.requestInterceptor=o||new c(f),f.responseInterceptor=n||new d(f),f.defaults={...e.defaults,cache:{ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{},...h}},f.requestInterceptor.use(),f.responseInterceptor.use(),f}const g=p,m=p;class x extends h{constructor(e,t=x.DEFAULT_KEY_PREFIX){super(),this.storage=e,this.prefix=t,this.find=async e=>{const t=this.storage.getItem(`${this.prefix}:${e}`);return t?JSON.parse(t):{state:"empty"}},this.set=async(e,t)=>this.storage.setItem(`${this.prefix}:${e}`,JSON.stringify(t)),this.remove=async e=>this.storage.removeItem(`${this.prefix}:${e}`)}}x.DEFAULT_KEY_PREFIX="a-c-i"})(),s})()})); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return(()=>{var e={86:(e,t)=>{!function(e){var t=Symbol("cache-parser"),a=Number;function r(e){return("string"==typeof e||"number"==typeof e)&&(e=a(e))>=0&&e<1/0}function s(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:r,toBoolean:s},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return s(e.immutable)&&t.push("immutable"),r(e.maxAge)&&t.push("max-age="+a(e.maxAge)),r(e.maxStale)&&t.push("max-stale="+a(e.maxStale)),r(e.minFresh)&&t.push("min-fresh="+a(e.minFresh)),s(e.mustRevalidate)&&t.push("must-revalidate"),s(e.mustUnderstand)&&t.push("must-understand"),s(e.noCache)&&t.push("no-cache"),s(e.noStore)&&t.push("no-store"),s(e.noTransform)&&t.push("no-transform"),s(e.onlyIfCached)&&t.push("only-if-cached"),s(e.private)&&t.push("private"),s(e.proxyRevalidate)&&t.push("proxy-revalidate"),s(e.public)&&t.push("public"),r(e.sMaxAge)&&t.push("s-maxage="+a(e.sMaxAge)),r(e.staleIfError)&&t.push("stale-if-error="+a(e.staleIfError)),r(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+a(e.staleWhileRevalidate)),t},e.parse=function(e){var i=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return i;var o={},n=e.toLowerCase().replace(/\s+/g,"").split(",");for(var c in n){var d=n[c].split("=",2);o[d[0]]=1===d.length||d[1]}return s(o.immutable)&&(i.immutable=!0),r(o["max-age"])&&(i.maxAge=a(o["max-age"])),r(o["max-stale"])&&(i.maxStale=a(o["max-stale"])),r(o["min-fresh"])&&(i.minFresh=a(o["min-fresh"])),s(o["must-revalidate"])&&(i.mustRevalidate=!0),s(o["must-understand"])&&(i.mustUnderstand=!0),s(o["no-cache"])&&(i.noCache=!0),s(o["no-store"])&&(i.noStore=!0),s(o["no-transform"])&&(i.noTransform=!0),s(o["only-if-cached"])&&(i.onlyIfCached=!0),s(o.private)&&(i.private=!0),s(o["proxy-revalidate"])&&(i.proxyRevalidate=!0),s(o.public)&&(i.public=!0),r(o["s-maxage"])&&(i.sMaxAge=a(o["s-maxage"])),r(o["stale-if-error"])&&(i.staleIfError=a(o["stale-if-error"])),r(o["stale-while-revalidate"])&&(i.staleWhileRevalidate=a(o["stale-while-revalidate"])),i}}(t)},549:(e,t)=>{var a,r;a=t,r=Symbol("fast-defer"),a.deferred=function(){var e,t,a=new Promise((function(a,r){e=a,t=r}));return a.resolve=e,a.reject=t,a[r]=1,a},a.isDeferred=function(e){return!!e&&!!e[r]}}},t={};function a(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,a),i.exports}a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";a.r(r),a.d(r,{CacheRequestInterceptor:()=>h,CacheResponseInterceptor:()=>g,Header:()=>t,InterceptorUtil:()=>e,buildMemoryStorage:()=>v,buildStorage:()=>y,buildWebStorage:()=>R,createCache:()=>A,defaultHeaderInterpreter:()=>i,defaultKeyGenerator:()=>C,isAxiosCacheInterceptor:()=>M,isCachePredicateValid:()=>l,isStorage:()=>x,setupCache:()=>S,shouldCacheResponse:()=>f,updateCache:()=>p,useCache:()=>I});var e={};a.r(e),a.d(e,{createValidateStatus:()=>n,isMethodIn:()=>c,setRevalidationHeaders:()=>d,setupCacheData:()=>u});var t,s=a(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(t||(t={}));const i=e=>{if(!e)return"not enough headers";const a=e[t.CacheControl];if(a){const{noCache:r,noStore:i,mustRevalidate:o,maxAge:n,immutable:c}=(0,s.parse)(a);if(r||i)return"dont cache";if(c)return 31536e6;if(o)return 0;if(n){const a=e[t.Age];return a?1e3*(n-Number(a)):1e3*n}}const r=e[t.Expires];if(r){const e=Date.parse(r)-Date.now();return e>=0?e:"dont cache"}return"not enough headers"};var o=a(549);function n(e){return e?t=>e(t)||304===t:e=>e>=200&&e<300||304===e}function c(e,t=[]){e=e.toLowerCase();for(const a of t)if(a.toLowerCase()===e)return!0;return!1}function d(e,a){a.headers||(a.headers={});const{etag:r,modifiedSince:s}=a.cache;if(r){const s=!0===r?e.data?.headers[t.ETag]:r;s&&(a.headers[t.IfNoneMatch]=s)}s&&(a.headers[t.IfModifiedSince]=!0===s?e.data.headers[t.LastModified]||new Date(e.createdAt).toUTCString():s.toUTCString())}function u(e,t){return 304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers={...t.headers,...e.headers},t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers}}class h{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.request.use(this.onFulfilled)},this.onFulfilled=async e=>{if(!1===e.cache)return e;if(e.cache={...this.axios.defaults.cache,...e.cache},!c(e.method,e.cache.methods))return e;const t=this.axios.generateKey(e);let a,r=await this.axios.storage.get(t);e:if("empty"==r.state||"stale"===r.state){if(this.axios.waiting[t]){r=await this.axios.storage.get(t);break e}return this.axios.waiting[t]=(0,o.deferred)(),this.axios.waiting[t]?.catch((()=>{})),await this.axios.storage.set(t,{state:"loading",data:r.data}),"stale"===r.state&&d(r,e),e.validateStatus=n(e.validateStatus),e}if("loading"===r.state){const r=this.axios.waiting[t];if(!r)return await this.axios.storage.remove(t),e;try{a=await r}catch{return e}}else a=r.data;return e.adapter=()=>Promise.resolve({config:e,data:a.data,headers:a.headers,status:a.status,statusText:a.statusText,cached:!0,id:t}),e}}}function f(e,{cachePredicate:t}){return"function"==typeof t?t(e):l(e,t)}function l(e,{statusCheck:t,containsHeaders:a,responseMatch:r}){if(t)if("function"==typeof t){if(!t(e.status))return!1}else{const[a,r]=t;if(e.status<a||e.status>r)return!1}if(a)for(const t in a){const r=a[t],s=e.headers[t];if(!s)return!1;switch(typeof r){case"string":if(s!=r)return!1;break;case"function":if(!r(s))return!1}}return!(r&&!r(e))}async function p(e,t,a){for(const r in a){const s=a[r];if("delete"===s){await e.remove(r);continue}const i=await e.get(r);if("loading"===i.state)continue;const o=await s(i,t);"delete"!==o?"ignore"!==o&&await e.set(r,o):await e.remove(r)}}class g{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.response.use(this.onFulfilled)},this.onFulfilled=async e=>{const a=this.cachedResponse(e);if(a.cached)return a;if(!a.config.cache)return{...a,cached:!1};const r=a.config.cache,s=await this.axios.storage.get(a.id);if("stale"===s.state||"empty"===s.state||"cached"===s.state)return a;if(!s.data&&!f(a,r))return await this.rejectResponse(a.id),a;delete a.headers[t.XAxiosCacheEtag],delete a.headers[t.XAxiosCacheLastModified],r.etag&&!0!==r.etag&&(a.headers[t.XAxiosCacheEtag]=r.etag),r.modifiedSince&&(a.headers[t.XAxiosCacheLastModified]=!0===r.modifiedSince?"use-cache-timestamp":r.modifiedSince.toUTCString());let i=r.ttl||-1;if(r?.interpretHeader){const e=this.axios.headerInterpreter(a.headers);if("dont cache"===e)return await this.rejectResponse(a.id),a;i="not enough headers"===e?i:e}const o=u(a,s.data);"function"==typeof i&&(i=await i(a));const n={state:"cached",ttl:i,createdAt:Date.now(),data:o};r?.update&&p(this.axios.storage,a,r.update);const c=this.axios.waiting[a.id];return await(c?.resolve(n.data)),delete this.axios.waiting[a.id],await this.axios.storage.set(a.id,n),a},this.rejectResponse=async e=>{await this.axios.storage.remove(e),this.axios.waiting[e]?.reject(null),delete this.axios.waiting[e]},this.cachedResponse=e=>({id:this.axios.generateKey(e.config),cached:e.cached||!1,...e})}}const m=Symbol(),x=e=>!!e&&!!e[m];function y({set:e,find:a,remove:r}){return{[m]:1,set:e,remove:r,get:async s=>{const i=await a(s);if(!i)return{state:"empty"};if("cached"!==i.state||i.createdAt+i.ttl>Date.now())return i;if(i.data.headers&&(t.ETag in i.data.headers||t.LastModified in i.data.headers||t.XAxiosCacheEtag in i.data.headers||t.XAxiosCacheLastModified in i.data.headers)){const t={data:i.data,state:"stale",createdAt:i.createdAt};return await e(s,t),t}return await r(s),{state:"empty"}}}}function v(){const e={};return{...y({find:t=>e[t],set:(t,a)=>{e[t]=a},remove:t=>{delete e[t]}}),data:e}}const w=/^\/|\/+$/g,C=({baseURL:e="",url:t="",method:a,params:r,id:s})=>s||(e=e.replace(w,""),t=t.replace(w,""),`${a?.toLowerCase()||"get"}::${e+(e&&t?"/":"")+t}::${r?JSON.stringify(r,Object.keys(r).sort()):"{}"}`),b=Symbol();function S(e,{storage:t,generateKey:a,waiting:r,headerInterpreter:s,requestInterceptor:o,responseInterceptor:n,...c}={}){const d=e;if(d.storage=t||v(),!x(d.storage))throw new Error("Use buildStorage()");return d.generateKey=a||C,d.waiting=r||{},d.headerInterpreter=s||i,d.requestInterceptor=o||new h(d),d.responseInterceptor=n||new g(d),d.defaults={...e.defaults,cache:{ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{},...c}},d.requestInterceptor.use(),d.responseInterceptor.use(),d[b]=1,d}const I=S,A=S,M=e=>!!e&&!!e[b];function R(e,t=""){return y({find:a=>{const r=e.getItem(t+a);return r?JSON.parse(r):void 0},set:(a,r)=>{e.setItem(t+a,JSON.stringify(r))},remove:a=>{e.removeItem(t+a)}})}})(),r})()})); | ||
//# sourceMappingURL=index.es2020.min.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return function(){var e={86:function(e,t){!function(e){var t=Symbol("cache-parser"),n=Number;function r(e){return("string"==typeof e||"number"==typeof e)&&(e=n(e))>=0&&e<1/0}function a(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:r,toBoolean:a},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return a(e.immutable)&&t.push("immutable"),r(e.maxAge)&&t.push("max-age="+n(e.maxAge)),r(e.maxStale)&&t.push("max-stale="+n(e.maxStale)),r(e.minFresh)&&t.push("min-fresh="+n(e.minFresh)),a(e.mustRevalidate)&&t.push("must-revalidate"),a(e.mustUnderstand)&&t.push("must-understand"),a(e.noCache)&&t.push("no-cache"),a(e.noStore)&&t.push("no-store"),a(e.noTransform)&&t.push("no-transform"),a(e.onlyIfCached)&&t.push("only-if-cached"),a(e.private)&&t.push("private"),a(e.proxyRevalidate)&&t.push("proxy-revalidate"),a(e.public)&&t.push("public"),r(e.sMaxAge)&&t.push("s-maxage="+n(e.sMaxAge)),r(e.staleIfError)&&t.push("stale-if-error="+n(e.staleIfError)),r(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+n(e.staleWhileRevalidate)),t},e.parse=function(e){var o=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return o;var i={},s=e.toLowerCase().replace(/\s+/g,"").split(",");for(var u in s){var c=s[u].split("=",2);i[c[0]]=1===c.length||c[1]}return a(i.immutable)&&(o.immutable=!0),r(i["max-age"])&&(o.maxAge=n(i["max-age"])),r(i["max-stale"])&&(o.maxStale=n(i["max-stale"])),r(i["min-fresh"])&&(o.minFresh=n(i["min-fresh"])),a(i["must-revalidate"])&&(o.mustRevalidate=!0),a(i["must-understand"])&&(o.mustUnderstand=!0),a(i["no-cache"])&&(o.noCache=!0),a(i["no-store"])&&(o.noStore=!0),a(i["no-transform"])&&(o.noTransform=!0),a(i["only-if-cached"])&&(o.onlyIfCached=!0),a(i.private)&&(o.private=!0),a(i["proxy-revalidate"])&&(o.proxyRevalidate=!0),a(i.public)&&(o.public=!0),r(i["s-maxage"])&&(o.sMaxAge=n(i["s-maxage"])),r(i["stale-if-error"])&&(o.staleIfError=n(i["stale-if-error"])),r(i["stale-while-revalidate"])&&(o.staleWhileRevalidate=n(i["stale-while-revalidate"])),o}}(t)},549:function(e,t){var n,r;n=t,r=Symbol("fast-defer"),n.deferred=function(){var e,t,n=new Promise((function(n,r){e=n,t=r}));return n.resolve=e,n.reject=t,n[r]=1,n},n.isDeferred=function(e){return!!e&&!!e[r]}}},t={};function n(r){var a=t[r];if(void 0!==a)return a.exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return function(){"use strict";n.r(r),n.d(r,{AxiosStorage:function(){return O},BrowserAxiosStorage:function(){return U},MemoryAxiosStorage:function(){return I},createCache:function(){return L},setupCache:function(){return M},useCache:function(){return R}});var e,t=n(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(e||(e={}));var a=function(t){return void 0===t&&(t={}),e.CacheControl in t?i(t[e.CacheControl],t):e.Expires in t?o(t[e.Expires],t):void 0},o=function(e){var t=Date.parse(e)-Date.now();return t>=0&&t},i=function(n,r){var a=(0,t.parse)(n),o=a.noCache,i=a.noStore,s=a.mustRevalidate,u=a.maxAge,c=a.immutable;if(o||i)return!1;if(c)return 31536e6;if(s)return 0;if(u){var l=r[e.Age];return l?1e3*(u-Number(l)):1e3*u}},s=n(549),u=function(){return u=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},u.apply(this,arguments)},c=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},l=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},f=function(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")},h=function(){function t(e){var n=this;this.axios=e,this.use=function(){n.axios.interceptors.request.use(n.onFulfilled)},this.onFulfilled=function(e){return c(n,void 0,void 0,(function(){var n,r,a,o,i;return l(this,(function(c){switch(c.label){case 0:return!1===e.cache?[2,e]:(e.cache=u(u({},this.axios.defaults.cache),e.cache),t.isMethodAllowed(e.method,e.cache)?(n=this.axios.generateKey(e),[4,this.axios.storage.get(n)]):[2,e]);case 1:return"empty"!=(r=c.sent()).state&&"stale"!==r.state?[3,5]:this.axios.waiting[n]?[4,this.axios.storage.get(n)]:[3,3];case 2:return r=c.sent(),[3,5];case 3:return this.axios.waiting[n]=(0,s.deferred)(),null===(i=this.axios.waiting[n])||void 0===i||i.catch((function(){})),[4,this.axios.storage.set(n,{state:"loading",data:r.data})];case 4:return c.sent(),"stale"===r.state&&t.setRevalidationHeaders(r,e),e.validateStatus=t.createValidateStatus(e.validateStatus),[2,e];case 5:return"loading"!==r.state?[3,11]:(o=this.axios.waiting[n])?[3,7]:[4,this.axios.storage.remove(n)];case 6:return c.sent(),[2,e];case 7:return c.trys.push([7,9,,10]),[4,o];case 8:return a=c.sent(),[3,10];case 9:return c.sent(),[2,e];case 10:return[3,12];case 11:a=r.data,c.label=12;case 12:return e.adapter=function(){return Promise.resolve({config:e,data:a.data,headers:a.headers,status:a.status,statusText:a.statusText,cached:!0,id:n})},[2,e]}}))}))}}return t.isMethodAllowed=function(e,t){var n,r,a=e.toLowerCase();try{for(var o=f(t.methods||[]),i=o.next();!i.done;i=o.next()){if(i.value.toLowerCase()===a)return!0}}catch(e){n={error:e}}finally{try{i&&!i.done&&(r=o.return)&&r.call(o)}finally{if(n)throw n.error}}return!1},t.setRevalidationHeaders=function(t,n){var r;n.headers||(n.headers={});var a=n.cache,o=a.etag,i=a.modifiedSince;if(o){var s=!0===o?null===(r=t.data)||void 0===r?void 0:r.headers[e.ETag]:o;s&&(n.headers[e.IfNoneMatch]=s)}i&&(n.headers[e.IfModifiedSince]=!0===i?t.data.headers[e.LastModified]||new Date(t.createdAt).toUTCString():i.toUTCString())},t.createValidateStatus=function(e){return function(t){return e?e(t)||304===t:t>=200&&t<300||304===t}},t}(),d=function(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,a,o=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=o.next()).done;)i.push(r.value)}catch(e){a={error:e}}finally{try{r&&!r.done&&(n=o.return)&&n.call(o)}finally{if(a)throw a.error}}return i};function p(e,t){var n=t.cachePredicate;return"function"==typeof n?n(e):function(e,t){var n=t.statusCheck,r=t.containsHeaders,a=t.responseMatch;if(n)if("function"==typeof n){if(!n(e.status))return!1}else{var o=d(n,2),i=o[0],s=o[1];if(e.status<i||e.status>s)return!1}if(r)for(var u in r){var c=r[u],l=e.headers[u];if(!l)return!1;switch(typeof c){case"string":if(l!=c)return!1;break;case"function":if(!c(l))return!1}}if(a&&!a(e.data))return!1;return!0}(e,n)}var v=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},y=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}};var b,g=function(){return g=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},g.apply(this,arguments)},x=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},m=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},w=function(){function t(n){var r=this;this.axios=n,this.use=function(){r.axios.interceptors.response.use(r.onFulfilled)},this.onFulfilled=function(n){return x(r,void 0,void 0,(function(){var r,a,o,i,s,u,c,l;return m(this,(function(f){switch(f.label){case 0:return(r=this.cachedResponse(n)).cached?[2,r]:r.config.cache?(a=r.config.cache,[4,this.axios.storage.get(r.id)]):[2,g(g({},r),{cached:!1})];case 1:return"stale"===(o=f.sent()).state||"empty"===o.state||"cached"===o.state?[2,r]:o.data||p(r,a)?[3,3]:[4,this.rejectResponse(r.id)];case 2:return f.sent(),[2,r];case 3:return delete r.headers[e.XAxiosCacheEtag],delete r.headers[e.XAxiosCacheLastModified],a.etag&&!0!==a.etag&&(r.headers[e.XAxiosCacheEtag]=a.etag),a.modifiedSince&&(r.headers[e.XAxiosCacheLastModified]=!0===a.modifiedSince?"use-cache-timestamp":a.modifiedSince.toUTCString()),i=a.ttl||-1,(null==a?void 0:a.interpretHeader)?!1!==(s=this.axios.headerInterpreter(r.headers))?[3,5]:[4,this.rejectResponse(r.id)]:[3,6];case 4:return f.sent(),[2,r];case 5:i=s||0===s?s:i,f.label=6;case 6:return u=t.setupCacheData(r,o.data),c={state:"cached",ttl:i,createdAt:Date.now(),data:u},(null==a?void 0:a.update)&&function(e,t,n){v(this,void 0,void 0,(function(){var r,a,o,i,s,u,c;return y(this,(function(l){switch(l.label){case 0:for(a in r=[],n)r.push(a);o=0,l.label=1;case 1:return o<r.length?(i=r[o],"delete"!==(s=n[i])?[3,3]:[4,e.remove(i)]):[3,9];case 2:return l.sent(),[3,8];case 3:return[4,e.get(i)];case 4:if("loading"===(u=l.sent()).state)throw new Error("cannot update the cache while loading");return void 0!==(c=s(u,t))?[3,6]:[4,e.remove(i)];case 5:return l.sent(),[3,8];case 6:return[4,e.set(i,c)];case 7:l.sent(),l.label=8;case 8:return o++,[3,1];case 9:return[2]}}))}))}(this.axios.storage,r.data,a.update),[4,null==(l=this.axios.waiting[r.id])?void 0:l.resolve(c.data)];case 7:return f.sent(),delete this.axios.waiting[r.id],[4,this.axios.storage.set(r.id,c)];case 8:return f.sent(),[2,r]}}))}))},this.rejectResponse=function(e){return x(r,void 0,void 0,(function(){var t;return m(this,(function(n){switch(n.label){case 0:return[4,this.axios.storage.remove(e)];case 1:return n.sent(),null===(t=this.axios.waiting[e])||void 0===t||t.reject(null),delete this.axios.waiting[e],[2]}}))}))},this.cachedResponse=function(e){return g({id:r.axios.generateKey(e.config),cached:e.cached||!1},e)}}return t.setupCacheData=function(e,t){return 304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers=g(g({},t.headers),e.headers),t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers}},t}(),S=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},C=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},O=function(){function t(){var e=this;this.get=function(n){return S(e,void 0,void 0,(function(){var e,r;return C(this,(function(a){switch(a.label){case 0:return[4,this.find(n)];case 1:return"cached"!==(e=a.sent()).state||e.createdAt+e.ttl>Date.now()?[2,e]:t.keepIfStale(e)?(r={data:e.data,state:"stale",createdAt:e.createdAt},[4,this.set(n,r)]):[3,3];case 2:return a.sent(),[2,r];case 3:return[4,this.remove(n)];case 4:return a.sent(),[2,{state:"empty"}]}}))}))}}return t.keepIfStale=function(t){var n=t.data;return!!(null==n?void 0:n.headers)&&(e.ETag in n.headers||e.LastModified in n.headers||e.XAxiosCacheEtag in n.headers||e.XAxiosCacheLastModified in n.headers)},t}(),A=(b=function(e,t){return b=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},b(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}b(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),j=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},k=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},I=function(e){function t(t){void 0===t&&(t={});var n=e.call(this)||this;return n.storage=t,n.find=function(e){return j(n,void 0,void 0,(function(){return k(this,(function(t){return[2,this.storage[e]||{state:"empty"}]}))}))},n.set=function(e,t){return j(n,void 0,void 0,(function(){return k(this,(function(n){return this.storage[e]=t,[2]}))}))},n.remove=function(e){return j(n,void 0,void 0,(function(){return k(this,(function(t){return delete this.storage[e],[2]}))}))},n}return A(t,e),t}(O),E=/^\/|\/+$/g,T=function(e){var t=e.baseURL,n=void 0===t?"":t,r=e.url,a=void 0===r?"":r,o=e.method,i=e.params,s=e.id;if(s)return String(s);n=n.replace(E,""),a=a.replace(E,"");var u=(null==o?void 0:o.toLowerCase())||"get",c=i?JSON.stringify(i,Object.keys(i).sort()):"{}";return"".concat(u,"::").concat(n+(a&&n?"/":"")+a,"::").concat(c)},P=function(){return P=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var a in t=arguments[n])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},P.apply(this,arguments)},_=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(r=Object.getOwnPropertySymbols(e);a<r.length;a++)t.indexOf(r[a])<0&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]])}return n};function M(e,t){void 0===t&&(t={});var n=t.storage,r=t.generateKey,o=t.waiting,i=t.headerInterpreter,s=t.requestInterceptor,u=t.responseInterceptor,c=_(t,["storage","generateKey","waiting","headerInterpreter","requestInterceptor","responseInterceptor"]),l=e;return l.storage=n||new I,l.generateKey=r||T,l.waiting=o||{},l.headerInterpreter=i||a,l.requestInterceptor=s||new h(l),l.responseInterceptor=u||new w(l),l.defaults=P(P({},e.defaults),{cache:P({ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{}},c)}),l.requestInterceptor.use(),l.responseInterceptor.use(),l}var R=M,L=M,D=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function r(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}(),F=function(e,t,n,r){return new(n||(n=Promise))((function(a,o){function i(e){try{u(r.next(e))}catch(e){o(e)}}function s(e){try{u(r.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}u((r=r.apply(e,t||[])).next())}))},X=function(e,t){var n,r,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(a=2&o[0]?r.return:o[0]?r.throw||((a=r.return)&&a.call(r),0):r.next)&&!(a=a.call(r,o[1])).done)return a;switch(r=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,r=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],r=0}finally{n=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},U=function(e){function t(n,r){void 0===r&&(r=t.DEFAULT_KEY_PREFIX);var a=e.call(this)||this;return a.storage=n,a.prefix=r,a.find=function(e){return F(a,void 0,void 0,(function(){var t;return X(this,(function(n){return[2,(t=this.storage.getItem("".concat(this.prefix,":").concat(e)))?JSON.parse(t):{state:"empty"}]}))}))},a.set=function(e,t){return F(a,void 0,void 0,(function(){return X(this,(function(n){return[2,this.storage.setItem("".concat(this.prefix,":").concat(e),JSON.stringify(t))]}))}))},a.remove=function(e){return F(a,void 0,void 0,(function(){return X(this,(function(t){return[2,this.storage.removeItem("".concat(this.prefix,":").concat(e))]}))}))},a}return D(t,e),t.DEFAULT_KEY_PREFIX="a-c-i",t}(O)}(),r}()})); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return function(){var e={86:function(e,t){!function(e){var t=Symbol("cache-parser"),r=Number;function n(e){return("string"==typeof e||"number"==typeof e)&&(e=r(e))>=0&&e<1/0}function a(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:n,toBoolean:a},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return a(e.immutable)&&t.push("immutable"),n(e.maxAge)&&t.push("max-age="+r(e.maxAge)),n(e.maxStale)&&t.push("max-stale="+r(e.maxStale)),n(e.minFresh)&&t.push("min-fresh="+r(e.minFresh)),a(e.mustRevalidate)&&t.push("must-revalidate"),a(e.mustUnderstand)&&t.push("must-understand"),a(e.noCache)&&t.push("no-cache"),a(e.noStore)&&t.push("no-store"),a(e.noTransform)&&t.push("no-transform"),a(e.onlyIfCached)&&t.push("only-if-cached"),a(e.private)&&t.push("private"),a(e.proxyRevalidate)&&t.push("proxy-revalidate"),a(e.public)&&t.push("public"),n(e.sMaxAge)&&t.push("s-maxage="+r(e.sMaxAge)),n(e.staleIfError)&&t.push("stale-if-error="+r(e.staleIfError)),n(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+r(e.staleWhileRevalidate)),t},e.parse=function(e){var o=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return o;var i={},s=e.toLowerCase().replace(/\s+/g,"").split(",");for(var u in s){var c=s[u].split("=",2);i[c[0]]=1===c.length||c[1]}return a(i.immutable)&&(o.immutable=!0),n(i["max-age"])&&(o.maxAge=r(i["max-age"])),n(i["max-stale"])&&(o.maxStale=r(i["max-stale"])),n(i["min-fresh"])&&(o.minFresh=r(i["min-fresh"])),a(i["must-revalidate"])&&(o.mustRevalidate=!0),a(i["must-understand"])&&(o.mustUnderstand=!0),a(i["no-cache"])&&(o.noCache=!0),a(i["no-store"])&&(o.noStore=!0),a(i["no-transform"])&&(o.noTransform=!0),a(i["only-if-cached"])&&(o.onlyIfCached=!0),a(i.private)&&(o.private=!0),a(i["proxy-revalidate"])&&(o.proxyRevalidate=!0),a(i.public)&&(o.public=!0),n(i["s-maxage"])&&(o.sMaxAge=r(i["s-maxage"])),n(i["stale-if-error"])&&(o.staleIfError=r(i["stale-if-error"])),n(i["stale-while-revalidate"])&&(o.staleWhileRevalidate=r(i["stale-while-revalidate"])),o}}(t)},549:function(e,t){var r,n;r=t,n=Symbol("fast-defer"),r.deferred=function(){var e,t,r=new Promise((function(r,n){e=r,t=n}));return r.resolve=e,r.reject=t,r[n]=1,r},r.isDeferred=function(e){return!!e&&!!e[n]}}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var o=t[n]={exports:{}};return e[n](o,o.exports,r),o.exports}r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var n={};return function(){"use strict";r.r(n),r.d(n,{CacheRequestInterceptor:function(){return y},CacheResponseInterceptor:function(){return j},Header:function(){return t},InterceptorUtil:function(){return e},buildMemoryStorage:function(){return R},buildStorage:function(){return E},buildWebStorage:function(){return G},createCache:function(){return H},defaultHeaderInterpreter:function(){return o},defaultKeyGenerator:function(){return D},isAxiosCacheInterceptor:function(){return K},isCachePredicateValid:function(){return m},isStorage:function(){return k},setupCache:function(){return N},shouldCacheResponse:function(){return g},updateCache:function(){return S},useCache:function(){return q}});var e={};r.r(e),r.d(e,{createValidateStatus:function(){return c},isMethodIn:function(){return l},setRevalidationHeaders:function(){return f},setupCacheData:function(){return d}});var t,a=r(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(t||(t={}));var o=function(e){if(!e)return"not enough headers";var r=e[t.CacheControl];if(r){var n=(0,a.parse)(r),o=n.noCache,i=n.noStore,s=n.mustRevalidate,u=n.maxAge,c=n.immutable;if(o||i)return"dont cache";if(c)return 31536e6;if(s)return 0;if(u){var l=e[t.Age];return l?1e3*(u-Number(l)):1e3*u}}var f=e[t.Expires];if(f){var d=Date.parse(f)-Date.now();return d>=0?d:"dont cache"}return"not enough headers"},i=r(549),s=function(){return s=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},s.apply(this,arguments)},u=function(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],n=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")};function c(e){return e?function(t){return e(t)||304===t}:function(e){return e>=200&&e<300||304===e}}function l(e,t){var r,n;void 0===t&&(t=[]),e=e.toLowerCase();try{for(var a=u(t),o=a.next();!o.done;o=a.next()){if(o.value.toLowerCase()===e)return!0}}catch(e){r={error:e}}finally{try{o&&!o.done&&(n=a.return)&&n.call(a)}finally{if(r)throw r.error}}return!1}function f(e,r){var n;r.headers||(r.headers={});var a=r.cache,o=a.etag,i=a.modifiedSince;if(o){var s=!0===o?null===(n=e.data)||void 0===n?void 0:n.headers[t.ETag]:o;s&&(r.headers[t.IfNoneMatch]=s)}i&&(r.headers[t.IfModifiedSince]=!0===i?e.data.headers[t.LastModified]||new Date(e.createdAt).toUTCString():i.toUTCString())}function d(e,t){return 304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers=s(s({},t.headers),e.headers),t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers}}var h=function(){return h=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},h.apply(this,arguments)},p=function(e,t,r,n){return new(r||(r=Promise))((function(a,o){function i(e){try{u(n.next(e))}catch(e){o(e)}}function s(e){try{u(n.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,s)}u((n=n.apply(e,t||[])).next())}))},v=function(e,t){var r,n,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(r)throw new TypeError("Generator is already executing.");for(;i;)try{if(r=1,n&&(a=2&o[0]?n.return:o[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,o[1])).done)return a;switch(n=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,n=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],n=0}finally{r=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},y=function(e){var t=this;this.axios=e,this.use=function(){t.axios.interceptors.request.use(t.onFulfilled)},this.onFulfilled=function(e){return p(t,void 0,void 0,(function(){var t,r,n,a,o;return v(this,(function(s){switch(s.label){case 0:return!1===e.cache?[2,e]:(e.cache=h(h({},this.axios.defaults.cache),e.cache),l(e.method,e.cache.methods)?(t=this.axios.generateKey(e),[4,this.axios.storage.get(t)]):[2,e]);case 1:return"empty"!=(r=s.sent()).state&&"stale"!==r.state?[3,5]:this.axios.waiting[t]?[4,this.axios.storage.get(t)]:[3,3];case 2:return r=s.sent(),[3,5];case 3:return this.axios.waiting[t]=(0,i.deferred)(),null===(o=this.axios.waiting[t])||void 0===o||o.catch((function(){})),[4,this.axios.storage.set(t,{state:"loading",data:r.data})];case 4:return s.sent(),"stale"===r.state&&f(r,e),e.validateStatus=c(e.validateStatus),[2,e];case 5:return"loading"!==r.state?[3,11]:(a=this.axios.waiting[t])?[3,7]:[4,this.axios.storage.remove(t)];case 6:return s.sent(),[2,e];case 7:return s.trys.push([7,9,,10]),[4,a];case 8:return n=s.sent(),[3,10];case 9:return s.sent(),[2,e];case 10:return[3,12];case 11:n=r.data,s.label=12;case 12:return e.adapter=function(){return Promise.resolve({config:e,data:n.data,headers:n.headers,status:n.status,statusText:n.statusText,cached:!0,id:t})},[2,e]}}))}))}},b=function(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,a,o=r.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(e){a={error:e}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(a)throw a.error}}return i};function g(e,t){var r=t.cachePredicate;return"function"==typeof r?r(e):m(e,r)}function m(e,t){var r=t.statusCheck,n=t.containsHeaders,a=t.responseMatch;if(r)if("function"==typeof r){if(!r(e.status))return!1}else{var o=b(r,2),i=o[0],s=o[1];if(e.status<i||e.status>s)return!1}if(n)for(var u in n){var c=n[u],l=e.headers[u];if(!l)return!1;switch(typeof c){case"string":if(l!=c)return!1;break;case"function":if(!c(l))return!1}}return!(a&&!a(e))}var x=function(e,t,r,n){return new(r||(r=Promise))((function(a,o){function i(e){try{u(n.next(e))}catch(e){o(e)}}function s(e){try{u(n.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,s)}u((n=n.apply(e,t||[])).next())}))},w=function(e,t){var r,n,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(r)throw new TypeError("Generator is already executing.");for(;i;)try{if(r=1,n&&(a=2&o[0]?n.return:o[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,o[1])).done)return a;switch(n=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,n=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],n=0}finally{r=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}};function S(e,t,r){return x(this,void 0,void 0,(function(){var n,a,o,i,s,u,c;return w(this,(function(l){switch(l.label){case 0:for(a in n=[],r)n.push(a);o=0,l.label=1;case 1:return o<n.length?(i=n[o],"delete"!==(s=r[i])?[3,3]:[4,e.remove(i)]):[3,10];case 2:return l.sent(),[3,9];case 3:return[4,e.get(i)];case 4:return"loading"===(u=l.sent()).state?[3,9]:[4,s(u,t)];case 5:return"delete"!==(c=l.sent())?[3,7]:[4,e.remove(i)];case 6:return l.sent(),[3,9];case 7:return"ignore"===c?[3,9]:[4,e.set(i,c)];case 8:l.sent(),l.label=9;case 9:return o++,[3,1];case 10:return[2]}}))}))}var C=function(){return C=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},C.apply(this,arguments)},O=function(e,t,r,n){return new(r||(r=Promise))((function(a,o){function i(e){try{u(n.next(e))}catch(e){o(e)}}function s(e){try{u(n.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,s)}u((n=n.apply(e,t||[])).next())}))},I=function(e,t){var r,n,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(r)throw new TypeError("Generator is already executing.");for(;i;)try{if(r=1,n&&(a=2&o[0]?n.return:o[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,o[1])).done)return a;switch(n=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,n=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],n=0}finally{r=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},j=function(e){var r=this;this.axios=e,this.use=function(){r.axios.interceptors.response.use(r.onFulfilled)},this.onFulfilled=function(e){return O(r,void 0,void 0,(function(){var r,n,a,o,i,s,u,c;return I(this,(function(l){switch(l.label){case 0:return(r=this.cachedResponse(e)).cached?[2,r]:r.config.cache?(n=r.config.cache,[4,this.axios.storage.get(r.id)]):[2,C(C({},r),{cached:!1})];case 1:return"stale"===(a=l.sent()).state||"empty"===a.state||"cached"===a.state?[2,r]:a.data||g(r,n)?[3,3]:[4,this.rejectResponse(r.id)];case 2:return l.sent(),[2,r];case 3:return delete r.headers[t.XAxiosCacheEtag],delete r.headers[t.XAxiosCacheLastModified],n.etag&&!0!==n.etag&&(r.headers[t.XAxiosCacheEtag]=n.etag),n.modifiedSince&&(r.headers[t.XAxiosCacheLastModified]=!0===n.modifiedSince?"use-cache-timestamp":n.modifiedSince.toUTCString()),o=n.ttl||-1,(null==n?void 0:n.interpretHeader)?"dont cache"!==(i=this.axios.headerInterpreter(r.headers))?[3,5]:[4,this.rejectResponse(r.id)]:[3,6];case 4:return l.sent(),[2,r];case 5:o="not enough headers"===i?o:i,l.label=6;case 6:return s=d(r,a.data),"function"!=typeof o?[3,8]:[4,o(r)];case 7:o=l.sent(),l.label=8;case 8:return u={state:"cached",ttl:o,createdAt:Date.now(),data:s},(null==n?void 0:n.update)&&S(this.axios.storage,r,n.update),[4,null==(c=this.axios.waiting[r.id])?void 0:c.resolve(u.data)];case 9:return l.sent(),delete this.axios.waiting[r.id],[4,this.axios.storage.set(r.id,u)];case 10:return l.sent(),[2,r]}}))}))},this.rejectResponse=function(e){return O(r,void 0,void 0,(function(){var t;return I(this,(function(r){switch(r.label){case 0:return[4,this.axios.storage.remove(e)];case 1:return r.sent(),null===(t=this.axios.waiting[e])||void 0===t||t.reject(null),delete this.axios.waiting[e],[2]}}))}))},this.cachedResponse=function(e){return C({id:r.axios.generateKey(e.config),cached:e.cached||!1},e)}},A=function(e,t,r,n){return new(r||(r=Promise))((function(a,o){function i(e){try{u(n.next(e))}catch(e){o(e)}}function s(e){try{u(n.throw(e))}catch(e){o(e)}}function u(e){var t;e.done?a(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,s)}u((n=n.apply(e,t||[])).next())}))},P=function(e,t){var r,n,a,o,i={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return o={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function s(o){return function(s){return function(o){if(r)throw new TypeError("Generator is already executing.");for(;i;)try{if(r=1,n&&(a=2&o[0]?n.return:o[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,o[1])).done)return a;switch(n=0,a&&(o=[2&o[0],a.value]),o[0]){case 0:case 1:a=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,n=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(a=i.trys,(a=a.length>0&&a[a.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!a||o[1]>a[0]&&o[1]<a[3])){i.label=o[1];break}if(6===o[0]&&i.label<a[1]){i.label=a[1],a=o;break}if(a&&i.label<a[2]){i.label=a[2],i.ops.push(o);break}a[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],n=0}finally{r=a=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,s])}}},T=Symbol(),k=function(e){return!!e&&!!e[T]};function E(e){var r,n=this,a=e.set,o=e.find,i=e.remove;return(r={})[T]=1,r.set=a,r.remove=i,r.get=function(e){return A(n,void 0,void 0,(function(){var r,n;return P(this,(function(s){switch(s.label){case 0:return[4,o(e)];case 1:return(r=s.sent())?"cached"!==r.state||r.createdAt+r.ttl>Date.now()?[2,r]:r.data.headers&&(t.ETag in r.data.headers||t.LastModified in r.data.headers||t.XAxiosCacheEtag in r.data.headers||t.XAxiosCacheLastModified in r.data.headers)?(n={data:r.data,state:"stale",createdAt:r.createdAt},[4,a(e,n)]):[3,3]:[2,{state:"empty"}];case 2:return s.sent(),[2,n];case 3:return[4,i(e)];case 4:return s.sent(),[2,{state:"empty"}]}}))}))},r}var M=function(){return M=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},M.apply(this,arguments)};function R(){var e={},t=E({find:function(t){return e[t]},set:function(t,r){e[t]=r},remove:function(t){delete e[t]}});return M(M({},t),{data:e})}var L=/^\/|\/+$/g,D=function(e){var t=e.baseURL,r=void 0===t?"":t,n=e.url,a=void 0===n?"":n,o=e.method,i=e.params,s=e.id;return s||(r=r.replace(L,""),a=a.replace(L,""),"".concat((null==o?void 0:o.toLowerCase())||"get","::").concat(r+(r&&a?"/":"")+a,"::").concat(i?JSON.stringify(i,Object.keys(i).sort()):"{}"))},U=function(){return U=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var a in t=arguments[r])Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e},U.apply(this,arguments)},X=function(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(n=Object.getOwnPropertySymbols(e);a<n.length;a++)t.indexOf(n[a])<0&&Object.prototype.propertyIsEnumerable.call(e,n[a])&&(r[n[a]]=e[n[a]])}return r},F=Symbol();function N(e,t){void 0===t&&(t={});var r=t.storage,n=t.generateKey,a=t.waiting,i=t.headerInterpreter,s=t.requestInterceptor,u=t.responseInterceptor,c=X(t,["storage","generateKey","waiting","headerInterpreter","requestInterceptor","responseInterceptor"]),l=e;if(l.storage=r||R(),!k(l.storage))throw new Error("Use buildStorage()");return l.generateKey=n||D,l.waiting=a||{},l.headerInterpreter=i||o,l.requestInterceptor=s||new y(l),l.responseInterceptor=u||new j(l),l.defaults=U(U({},e.defaults),{cache:U({ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{}},c)}),l.requestInterceptor.use(),l.responseInterceptor.use(),l[F]=1,l}var q=N,H=N,K=function(e){return!!e&&!!e[F]};function G(e,t){return void 0===t&&(t=""),E({find:function(r){var n=e.getItem(t+r);return n?JSON.parse(n):void 0},set:function(r,n){e.setItem(t+r,JSON.stringify(n))},remove:function(r){e.removeItem(t+r)}})}}(),n}()})); | ||
//# sourceMappingURL=index.es5.min.js.map |
@@ -1,20 +0,2 @@ | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./cache/axios"), exports); | ||
__exportStar(require("./cache/cache"), exports); | ||
__exportStar(require("./cache/create"), exports); | ||
__exportStar(require("./header/types"), exports); | ||
__exportStar(require("./interceptors/types"), exports); | ||
__exportStar(require("./storage/storage"), exports); | ||
__exportStar(require("./storage/types"), exports); | ||
__exportStar(require("./util/types"), exports); | ||
(()=>{var e={86:(e,t)=>{!function(e){var t=Symbol("cache-parser"),a=Number;function r(e){return("string"==typeof e||"number"==typeof e)&&(e=a(e))>=0&&e<1/0}function s(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:r,toBoolean:s},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return s(e.immutable)&&t.push("immutable"),r(e.maxAge)&&t.push("max-age="+a(e.maxAge)),r(e.maxStale)&&t.push("max-stale="+a(e.maxStale)),r(e.minFresh)&&t.push("min-fresh="+a(e.minFresh)),s(e.mustRevalidate)&&t.push("must-revalidate"),s(e.mustUnderstand)&&t.push("must-understand"),s(e.noCache)&&t.push("no-cache"),s(e.noStore)&&t.push("no-store"),s(e.noTransform)&&t.push("no-transform"),s(e.onlyIfCached)&&t.push("only-if-cached"),s(e.private)&&t.push("private"),s(e.proxyRevalidate)&&t.push("proxy-revalidate"),s(e.public)&&t.push("public"),r(e.sMaxAge)&&t.push("s-maxage="+a(e.sMaxAge)),r(e.staleIfError)&&t.push("stale-if-error="+a(e.staleIfError)),r(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+a(e.staleWhileRevalidate)),t},e.parse=function(e){var i=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return i;var n={},o=e.toLowerCase().replace(/\s+/g,"").split(",");for(var c in o){var d=o[c].split("=",2);n[d[0]]=1===d.length||d[1]}return s(n.immutable)&&(i.immutable=!0),r(n["max-age"])&&(i.maxAge=a(n["max-age"])),r(n["max-stale"])&&(i.maxStale=a(n["max-stale"])),r(n["min-fresh"])&&(i.minFresh=a(n["min-fresh"])),s(n["must-revalidate"])&&(i.mustRevalidate=!0),s(n["must-understand"])&&(i.mustUnderstand=!0),s(n["no-cache"])&&(i.noCache=!0),s(n["no-store"])&&(i.noStore=!0),s(n["no-transform"])&&(i.noTransform=!0),s(n["only-if-cached"])&&(i.onlyIfCached=!0),s(n.private)&&(i.private=!0),s(n["proxy-revalidate"])&&(i.proxyRevalidate=!0),s(n.public)&&(i.public=!0),r(n["s-maxage"])&&(i.sMaxAge=a(n["s-maxage"])),r(n["stale-if-error"])&&(i.staleIfError=a(n["stale-if-error"])),r(n["stale-while-revalidate"])&&(i.staleWhileRevalidate=a(n["stale-while-revalidate"])),i}}(t)},549:(e,t)=>{var a,r;a=t,r=Symbol("fast-defer"),a.deferred=function(){var e,t,a=new Promise((function(a,r){e=a,t=r}));return a.resolve=e,a.reject=t,a[r]=1,a},a.isDeferred=function(e){return!!e&&!!e[r]}}},t={};function a(r){var s=t[r];if(void 0!==s)return s.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,a),i.exports}a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{"use strict";a.r(r),a.d(r,{CacheRequestInterceptor:()=>h,CacheResponseInterceptor:()=>g,Header:()=>t,InterceptorUtil:()=>e,buildMemoryStorage:()=>y,buildStorage:()=>v,buildWebStorage:()=>M,createCache:()=>j,defaultHeaderInterpreter:()=>i,defaultKeyGenerator:()=>w,isAxiosCacheInterceptor:()=>A,isCachePredicateValid:()=>f,isStorage:()=>x,setupCache:()=>O,shouldCacheResponse:()=>l,updateCache:()=>p,useCache:()=>I});var e={};a.r(e),a.d(e,{createValidateStatus:()=>o,isMethodIn:()=>c,setRevalidationHeaders:()=>d,setupCacheData:()=>u});var t,s=a(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(t||(t={}));const i=e=>{if(!e)return"not enough headers";const a=e[t.CacheControl];if(a){const{noCache:r,noStore:i,mustRevalidate:n,maxAge:o,immutable:c}=(0,s.parse)(a);if(r||i)return"dont cache";if(c)return 31536e6;if(n)return 0;if(o){const a=e[t.Age];return a?1e3*(o-Number(a)):1e3*o}}const r=e[t.Expires];if(r){const e=Date.parse(r)-Date.now();return e>=0?e:"dont cache"}return"not enough headers"};var n=a(549);function o(e){return e?t=>e(t)||304===t:e=>e>=200&&e<300||304===e}function c(e,t=[]){e=e.toLowerCase();for(const a of t)if(a.toLowerCase()===e)return!0;return!1}function d(e,a){var r;a.headers||(a.headers={});const{etag:s,modifiedSince:i}=a.cache;if(s){const i=!0===s?null===(r=e.data)||void 0===r?void 0:r.headers[t.ETag]:s;i&&(a.headers[t.IfNoneMatch]=i)}i&&(a.headers[t.IfModifiedSince]=!0===i?e.data.headers[t.LastModified]||new Date(e.createdAt).toUTCString():i.toUTCString())}function u(e,t){return 304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers=Object.assign(Object.assign({},t.headers),e.headers),t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers}}class h{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.request.use(this.onFulfilled)},this.onFulfilled=async e=>{var t;if(!1===e.cache)return e;if(e.cache=Object.assign(Object.assign({},this.axios.defaults.cache),e.cache),!c(e.method,e.cache.methods))return e;const a=this.axios.generateKey(e);let r,s=await this.axios.storage.get(a);e:if("empty"==s.state||"stale"===s.state){if(this.axios.waiting[a]){s=await this.axios.storage.get(a);break e}return this.axios.waiting[a]=(0,n.deferred)(),null===(t=this.axios.waiting[a])||void 0===t||t.catch((()=>{})),await this.axios.storage.set(a,{state:"loading",data:s.data}),"stale"===s.state&&d(s,e),e.validateStatus=o(e.validateStatus),e}if("loading"===s.state){const t=this.axios.waiting[a];if(!t)return await this.axios.storage.remove(a),e;try{r=await t}catch(t){return e}}else r=s.data;return e.adapter=()=>Promise.resolve({config:e,data:r.data,headers:r.headers,status:r.status,statusText:r.statusText,cached:!0,id:a}),e}}}function l(e,{cachePredicate:t}){return"function"==typeof t?t(e):f(e,t)}function f(e,{statusCheck:t,containsHeaders:a,responseMatch:r}){if(t)if("function"==typeof t){if(!t(e.status))return!1}else{const[a,r]=t;if(e.status<a||e.status>r)return!1}if(a)for(const t in a){const r=a[t],s=e.headers[t];if(!s)return!1;switch(typeof r){case"string":if(s!=r)return!1;break;case"function":if(!r(s))return!1}}return!(r&&!r(e))}async function p(e,t,a){for(const r in a){const s=a[r];if("delete"===s){await e.remove(r);continue}const i=await e.get(r);if("loading"===i.state)continue;const n=await s(i,t);"delete"!==n?"ignore"!==n&&await e.set(r,n):await e.remove(r)}}class g{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.response.use(this.onFulfilled)},this.onFulfilled=async e=>{const a=this.cachedResponse(e);if(a.cached)return a;if(!a.config.cache)return Object.assign(Object.assign({},a),{cached:!1});const r=a.config.cache,s=await this.axios.storage.get(a.id);if("stale"===s.state||"empty"===s.state||"cached"===s.state)return a;if(!s.data&&!l(a,r))return await this.rejectResponse(a.id),a;delete a.headers[t.XAxiosCacheEtag],delete a.headers[t.XAxiosCacheLastModified],r.etag&&!0!==r.etag&&(a.headers[t.XAxiosCacheEtag]=r.etag),r.modifiedSince&&(a.headers[t.XAxiosCacheLastModified]=!0===r.modifiedSince?"use-cache-timestamp":r.modifiedSince.toUTCString());let i=r.ttl||-1;if(null==r?void 0:r.interpretHeader){const e=this.axios.headerInterpreter(a.headers);if("dont cache"===e)return await this.rejectResponse(a.id),a;i="not enough headers"===e?i:e}const n=u(a,s.data);"function"==typeof i&&(i=await i(a));const o={state:"cached",ttl:i,createdAt:Date.now(),data:n};(null==r?void 0:r.update)&&p(this.axios.storage,a,r.update);const c=this.axios.waiting[a.id];return await(null==c?void 0:c.resolve(o.data)),delete this.axios.waiting[a.id],await this.axios.storage.set(a.id,o),a},this.rejectResponse=async e=>{var t;await this.axios.storage.remove(e),null===(t=this.axios.waiting[e])||void 0===t||t.reject(null),delete this.axios.waiting[e]},this.cachedResponse=e=>Object.assign({id:this.axios.generateKey(e.config),cached:e.cached||!1},e)}}const m=Symbol(),x=e=>!!e&&!!e[m];function v({set:e,find:a,remove:r}){return{[m]:1,set:e,remove:r,get:async s=>{const i=await a(s);if(!i)return{state:"empty"};if("cached"!==i.state||i.createdAt+i.ttl>Date.now())return i;if(i.data.headers&&(t.ETag in i.data.headers||t.LastModified in i.data.headers||t.XAxiosCacheEtag in i.data.headers||t.XAxiosCacheLastModified in i.data.headers)){const t={data:i.data,state:"stale",createdAt:i.createdAt};return await e(s,t),t}return await r(s),{state:"empty"}}}}function y(){const e={},t=v({find:t=>e[t],set:(t,a)=>{e[t]=a},remove:t=>{delete e[t]}});return Object.assign(Object.assign({},t),{data:e})}const b=/^\/|\/+$/g,w=({baseURL:e="",url:t="",method:a,params:r,id:s})=>s||(e=e.replace(b,""),t=t.replace(b,""),`${(null==a?void 0:a.toLowerCase())||"get"}::${e+(e&&t?"/":"")+t}::${r?JSON.stringify(r,Object.keys(r).sort()):"{}"}`);var C=function(e,t){var a={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(a[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var s=0;for(r=Object.getOwnPropertySymbols(e);s<r.length;s++)t.indexOf(r[s])<0&&Object.prototype.propertyIsEnumerable.call(e,r[s])&&(a[r[s]]=e[r[s]])}return a};const S=Symbol();function O(e,t={}){var{storage:a,generateKey:r,waiting:s,headerInterpreter:n,requestInterceptor:o,responseInterceptor:c}=t,d=C(t,["storage","generateKey","waiting","headerInterpreter","requestInterceptor","responseInterceptor"]);const u=e;if(u.storage=a||y(),!x(u.storage))throw new Error("Use buildStorage()");return u.generateKey=r||w,u.waiting=s||{},u.headerInterpreter=n||i,u.requestInterceptor=o||new h(u),u.responseInterceptor=c||new g(u),u.defaults=Object.assign(Object.assign({},e.defaults),{cache:Object.assign({ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{}},d)}),u.requestInterceptor.use(),u.responseInterceptor.use(),u[S]=1,u}const I=O,j=O,A=e=>!!e&&!!e[S];function M(e,t=""){return v({find:a=>{const r=e.getItem(t+a);return r?JSON.parse(r):void 0},set:(a,r)=>{e.setItem(t+a,JSON.stringify(r))},remove:a=>{e.removeItem(t+a)}})}})();var s=exports;for(var i in r)s[i]=r[i];r.__esModule&&Object.defineProperty(s,"__esModule",{value:!0})})(); | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return(()=>{var e={86:(e,t)=>{!function(e){var t=Symbol("cache-parser"),a=Number;function i(e){return("string"==typeof e||"number"==typeof e)&&(e=a(e))>=0&&e<1/0}function n(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:i,toBoolean:n},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return n(e.immutable)&&t.push("immutable"),i(e.maxAge)&&t.push("max-age="+a(e.maxAge)),i(e.maxStale)&&t.push("max-stale="+a(e.maxStale)),i(e.minFresh)&&t.push("min-fresh="+a(e.minFresh)),n(e.mustRevalidate)&&t.push("must-revalidate"),n(e.mustUnderstand)&&t.push("must-understand"),n(e.noCache)&&t.push("no-cache"),n(e.noStore)&&t.push("no-store"),n(e.noTransform)&&t.push("no-transform"),n(e.onlyIfCached)&&t.push("only-if-cached"),n(e.private)&&t.push("private"),n(e.proxyRevalidate)&&t.push("proxy-revalidate"),n(e.public)&&t.push("public"),i(e.sMaxAge)&&t.push("s-maxage="+a(e.sMaxAge)),i(e.staleIfError)&&t.push("stale-if-error="+a(e.staleIfError)),i(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+a(e.staleWhileRevalidate)),t},e.parse=function(e){var r=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return r;var s={},o=e.toLowerCase().replace(/\s+/g,"").split(",");for(var c in o){var d=o[c].split("=",2);s[d[0]]=1===d.length||d[1]}return n(s.immutable)&&(r.immutable=!0),i(s["max-age"])&&(r.maxAge=a(s["max-age"])),i(s["max-stale"])&&(r.maxStale=a(s["max-stale"])),i(s["min-fresh"])&&(r.minFresh=a(s["min-fresh"])),n(s["must-revalidate"])&&(r.mustRevalidate=!0),n(s["must-understand"])&&(r.mustUnderstand=!0),n(s["no-cache"])&&(r.noCache=!0),n(s["no-store"])&&(r.noStore=!0),n(s["no-transform"])&&(r.noTransform=!0),n(s["only-if-cached"])&&(r.onlyIfCached=!0),n(s.private)&&(r.private=!0),n(s["proxy-revalidate"])&&(r.proxyRevalidate=!0),n(s.public)&&(r.public=!0),i(s["s-maxage"])&&(r.sMaxAge=a(s["s-maxage"])),i(s["stale-if-error"])&&(r.staleIfError=a(s["stale-if-error"])),i(s["stale-while-revalidate"])&&(r.staleWhileRevalidate=a(s["stale-while-revalidate"])),r}}(t)},549:(e,t)=>{var a,i;a=t,i=Symbol("fast-defer"),a.deferred=function(){var e,t,a=new Promise((function(a,i){e=a,t=i}));return a.resolve=e,a.reject=t,a[i]=1,a},a.isDeferred=function(e){return!!e&&!!e[i]}}},t={};function a(i){var n=t[i];if(void 0!==n)return n.exports;var r=t[i]={exports:{}};return e[i](r,r.exports,a),r.exports}a.d=(e,t)=>{for(var i in t)a.o(t,i)&&!a.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};return(()=>{"use strict";a.r(i),a.d(i,{AxiosStorage:()=>p,BrowserAxiosStorage:()=>A,MemoryAxiosStorage:()=>g,createCache:()=>C,setupCache:()=>w,useCache:()=>b});var e,t=a(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(e||(e={}));const n=(t={})=>e.CacheControl in t?s(t[e.CacheControl],t):e.Expires in t?r(t[e.Expires],t):void 0,r=e=>{const t=Date.parse(e)-Date.now();return t>=0&&t},s=(a,i)=>{const{noCache:n,noStore:r,mustRevalidate:s,maxAge:o,immutable:c}=(0,t.parse)(a);if(n||r)return!1;if(c)return 31536e6;if(s)return 0;if(o){const t=i[e.Age];return t?1e3*(o-Number(t)):1e3*o}};var o=a(549),c=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};class d{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.request.use(this.onFulfilled)},this.onFulfilled=e=>c(this,void 0,void 0,(function*(){var t;if(!1===e.cache)return e;if(e.cache=Object.assign(Object.assign({},this.axios.defaults.cache),e.cache),!d.isMethodAllowed(e.method,e.cache))return e;const a=this.axios.generateKey(e);let i,n=yield this.axios.storage.get(a);e:if("empty"==n.state||"stale"===n.state){if(this.axios.waiting[a]){n=yield this.axios.storage.get(a);break e}return this.axios.waiting[a]=(0,o.deferred)(),null===(t=this.axios.waiting[a])||void 0===t||t.catch((()=>{})),yield this.axios.storage.set(a,{state:"loading",data:n.data}),"stale"===n.state&&d.setRevalidationHeaders(n,e),e.validateStatus=d.createValidateStatus(e.validateStatus),e}if("loading"===n.state){const t=this.axios.waiting[a];if(!t)return yield this.axios.storage.remove(a),e;try{i=yield t}catch(t){return e}}else i=n.data;return e.adapter=()=>Promise.resolve({config:e,data:i.data,headers:i.headers,status:i.status,statusText:i.statusText,cached:!0,id:a}),e}))}}d.isMethodAllowed=(e,t)=>{const a=e.toLowerCase();for(const e of t.methods||[])if(e.toLowerCase()===a)return!0;return!1},d.setRevalidationHeaders=(t,a)=>{var i;a.headers||(a.headers={});const{etag:n,modifiedSince:r}=a.cache;if(n){const r=!0===n?null===(i=t.data)||void 0===i?void 0:i.headers[e.ETag]:n;r&&(a.headers[e.IfNoneMatch]=r)}r&&(a.headers[e.IfModifiedSince]=!0===r?t.data.headers[e.LastModified]||new Date(t.createdAt).toUTCString():r.toUTCString())},d.createValidateStatus=e=>t=>e?e(t)||304===t:t>=200&&t<300||304===t;var u=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};var h=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};class f{constructor(t){this.axios=t,this.use=()=>{this.axios.interceptors.response.use(this.onFulfilled)},this.onFulfilled=t=>h(this,void 0,void 0,(function*(){const a=this.cachedResponse(t);if(a.cached)return a;if(!a.config.cache)return Object.assign(Object.assign({},a),{cached:!1});const i=a.config.cache,n=yield this.axios.storage.get(a.id);if("stale"===n.state||"empty"===n.state||"cached"===n.state)return a;if(!n.data&&!function(e,{cachePredicate:t}){return"function"==typeof t?t(e):function(e,{statusCheck:t,containsHeaders:a,responseMatch:i}){if(t)if("function"==typeof t){if(!t(e.status))return!1}else{const[a,i]=t;if(e.status<a||e.status>i)return!1}if(a)for(const t in a){const i=a[t],n=e.headers[t];if(!n)return!1;switch(typeof i){case"string":if(n!=i)return!1;break;case"function":if(!i(n))return!1}}return!(i&&!i(e.data))}(e,t)}(a,i))return yield this.rejectResponse(a.id),a;delete a.headers[e.XAxiosCacheEtag],delete a.headers[e.XAxiosCacheLastModified],i.etag&&!0!==i.etag&&(a.headers[e.XAxiosCacheEtag]=i.etag),i.modifiedSince&&(a.headers[e.XAxiosCacheLastModified]=!0===i.modifiedSince?"use-cache-timestamp":i.modifiedSince.toUTCString());let r=i.ttl||-1;if(null==i?void 0:i.interpretHeader){const e=this.axios.headerInterpreter(a.headers);if(!1===e)return yield this.rejectResponse(a.id),a;r=e||0===e?e:r}const s=f.setupCacheData(a,n.data),o={state:"cached",ttl:r,createdAt:Date.now(),data:s};(null==i?void 0:i.update)&&function(e,t,a){u(this,void 0,void 0,(function*(){for(const i in a){const n=a[i];if("delete"===n){yield e.remove(i);continue}const r=yield e.get(i);if("loading"===r.state)throw new Error("cannot update the cache while loading");const s=n(r,t);void 0!==s?yield e.set(i,s):yield e.remove(i)}}))}(this.axios.storage,a.data,i.update);const c=this.axios.waiting[a.id];return yield null==c?void 0:c.resolve(o.data),delete this.axios.waiting[a.id],yield this.axios.storage.set(a.id,o),a})),this.rejectResponse=e=>h(this,void 0,void 0,(function*(){var t;yield this.axios.storage.remove(e),null===(t=this.axios.waiting[e])||void 0===t||t.reject(null),delete this.axios.waiting[e]})),this.cachedResponse=e=>Object.assign({id:this.axios.generateKey(e.config),cached:e.cached||!1},e)}}f.setupCacheData=(e,t)=>304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers=Object.assign(Object.assign({},t.headers),e.headers),t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers};var l=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};class p{constructor(){this.get=e=>l(this,void 0,void 0,(function*(){const t=yield this.find(e);if("cached"!==t.state||t.createdAt+t.ttl>Date.now())return t;if(p.keepIfStale(t)){const a={data:t.data,state:"stale",createdAt:t.createdAt};return yield this.set(e,a),a}return yield this.remove(e),{state:"empty"}}))}}p.keepIfStale=({data:t})=>!!(null==t?void 0:t.headers)&&(e.ETag in t.headers||e.LastModified in t.headers||e.XAxiosCacheEtag in t.headers||e.XAxiosCacheLastModified in t.headers);var v=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};class g extends p{constructor(e={}){super(),this.storage=e,this.find=e=>v(this,void 0,void 0,(function*(){return this.storage[e]||{state:"empty"}})),this.set=(e,t)=>v(this,void 0,void 0,(function*(){this.storage[e]=t})),this.remove=e=>v(this,void 0,void 0,(function*(){delete this.storage[e]}))}}const m=/^\/|\/+$/g,x=({baseURL:e="",url:t="",method:a,params:i,id:n})=>{if(n)return String(n);e=e.replace(m,""),t=t.replace(m,"");return`${(null==a?void 0:a.toLowerCase())||"get"}::${e+(t&&e?"/":"")+t}::${i?JSON.stringify(i,Object.keys(i).sort()):"{}"}`};var y=function(e,t){var a={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.indexOf(i)<0&&(a[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(e);n<i.length;n++)t.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(e,i[n])&&(a[i[n]]=e[i[n]])}return a};function w(e,t={}){var{storage:a,generateKey:i,waiting:r,headerInterpreter:s,requestInterceptor:o,responseInterceptor:c}=t,u=y(t,["storage","generateKey","waiting","headerInterpreter","requestInterceptor","responseInterceptor"]);const h=e;return h.storage=a||new g,h.generateKey=i||x,h.waiting=r||{},h.headerInterpreter=s||n,h.requestInterceptor=o||new d(h),h.responseInterceptor=c||new f(h),h.defaults=Object.assign(Object.assign({},e.defaults),{cache:Object.assign({ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{}},u)}),h.requestInterceptor.use(),h.responseInterceptor.use(),h}const b=w,C=w;var S=function(e,t,a,i){return new(a||(a=Promise))((function(n,r){function s(e){try{c(i.next(e))}catch(e){r(e)}}function o(e){try{c(i.throw(e))}catch(e){r(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((i=i.apply(e,t||[])).next())}))};class A extends p{constructor(e,t=A.DEFAULT_KEY_PREFIX){super(),this.storage=e,this.prefix=t,this.find=e=>S(this,void 0,void 0,(function*(){const t=this.storage.getItem(`${this.prefix}:${e}`);return t?JSON.parse(t):{state:"empty"}})),this.set=(e,t)=>S(this,void 0,void 0,(function*(){return this.storage.setItem(`${this.prefix}:${e}`,JSON.stringify(t))})),this.remove=e=>S(this,void 0,void 0,(function*(){return this.storage.removeItem(`${this.prefix}:${e}`)}))}}A.DEFAULT_KEY_PREFIX="a-c-i"})(),i})()})); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AxiosCacheInterceptor=t():e.AxiosCacheInterceptor=t()}("undefined"==typeof self?this:self,(function(){return(()=>{var e={86:(e,t)=>{!function(e){var t=Symbol("cache-parser"),a=Number;function r(e){return("string"==typeof e||"number"==typeof e)&&(e=a(e))>=0&&e<1/0}function n(e){return"number"==typeof e||!0===e||"string"==typeof e&&"false"!==e}e.__internal={isDuration:r,toBoolean:n},e.isCacheControl=function(e){return!!e&&!!e[t]},e.tokenize=function(e){if(!e||"object"!=typeof e)return[];var t=[];return n(e.immutable)&&t.push("immutable"),r(e.maxAge)&&t.push("max-age="+a(e.maxAge)),r(e.maxStale)&&t.push("max-stale="+a(e.maxStale)),r(e.minFresh)&&t.push("min-fresh="+a(e.minFresh)),n(e.mustRevalidate)&&t.push("must-revalidate"),n(e.mustUnderstand)&&t.push("must-understand"),n(e.noCache)&&t.push("no-cache"),n(e.noStore)&&t.push("no-store"),n(e.noTransform)&&t.push("no-transform"),n(e.onlyIfCached)&&t.push("only-if-cached"),n(e.private)&&t.push("private"),n(e.proxyRevalidate)&&t.push("proxy-revalidate"),n(e.public)&&t.push("public"),r(e.sMaxAge)&&t.push("s-maxage="+a(e.sMaxAge)),r(e.staleIfError)&&t.push("stale-if-error="+a(e.staleIfError)),r(e.staleWhileRevalidate)&&t.push("stale-while-revalidate="+a(e.staleWhileRevalidate)),t},e.parse=function(e){var i=Object.defineProperty({},t,{enumerable:!1,value:1});if(!e||"string"!=typeof e)return i;var s={},o=e.toLowerCase().replace(/\s+/g,"").split(",");for(var c in o){var d=o[c].split("=",2);s[d[0]]=1===d.length||d[1]}return n(s.immutable)&&(i.immutable=!0),r(s["max-age"])&&(i.maxAge=a(s["max-age"])),r(s["max-stale"])&&(i.maxStale=a(s["max-stale"])),r(s["min-fresh"])&&(i.minFresh=a(s["min-fresh"])),n(s["must-revalidate"])&&(i.mustRevalidate=!0),n(s["must-understand"])&&(i.mustUnderstand=!0),n(s["no-cache"])&&(i.noCache=!0),n(s["no-store"])&&(i.noStore=!0),n(s["no-transform"])&&(i.noTransform=!0),n(s["only-if-cached"])&&(i.onlyIfCached=!0),n(s.private)&&(i.private=!0),n(s["proxy-revalidate"])&&(i.proxyRevalidate=!0),n(s.public)&&(i.public=!0),r(s["s-maxage"])&&(i.sMaxAge=a(s["s-maxage"])),r(s["stale-if-error"])&&(i.staleIfError=a(s["stale-if-error"])),r(s["stale-while-revalidate"])&&(i.staleWhileRevalidate=a(s["stale-while-revalidate"])),i}}(t)},549:(e,t)=>{var a,r;a=t,r=Symbol("fast-defer"),a.deferred=function(){var e,t,a=new Promise((function(a,r){e=a,t=r}));return a.resolve=e,a.reject=t,a[r]=1,a},a.isDeferred=function(e){return!!e&&!!e[r]}}},t={};function a(r){var n=t[r];if(void 0!==n)return n.exports;var i=t[r]={exports:{}};return e[r](i,i.exports,a),i.exports}a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";a.r(r),a.d(r,{CacheRequestInterceptor:()=>h,CacheResponseInterceptor:()=>y,Header:()=>t,InterceptorUtil:()=>e,buildMemoryStorage:()=>S,buildStorage:()=>C,buildWebStorage:()=>E,createCache:()=>P,defaultHeaderInterpreter:()=>i,defaultKeyGenerator:()=>j,isAxiosCacheInterceptor:()=>T,isCachePredicateValid:()=>p,isStorage:()=>w,setupCache:()=>M,shouldCacheResponse:()=>l,updateCache:()=>m,useCache:()=>R});var e={};a.r(e),a.d(e,{createValidateStatus:()=>o,isMethodIn:()=>c,setRevalidationHeaders:()=>d,setupCacheData:()=>u});var t,n=a(86);!function(e){e.IfModifiedSince="if-modified-since",e.LastModified="last-modified",e.IfNoneMatch="if-none-match",e.CacheControl="cache-control",e.ETag="etag",e.Expires="expires",e.Age="age",e.ContentType="content-type",e.XAxiosCacheEtag="x-axios-cache-etag",e.XAxiosCacheLastModified="x-axios-cache-last-modified"}(t||(t={}));const i=e=>{if(!e)return"not enough headers";const a=e[t.CacheControl];if(a){const{noCache:r,noStore:i,mustRevalidate:s,maxAge:o,immutable:c}=(0,n.parse)(a);if(r||i)return"dont cache";if(c)return 31536e6;if(s)return 0;if(o){const a=e[t.Age];return a?1e3*(o-Number(a)):1e3*o}}const r=e[t.Expires];if(r){const e=Date.parse(r)-Date.now();return e>=0?e:"dont cache"}return"not enough headers"};var s=a(549);function o(e){return e?t=>e(t)||304===t:e=>e>=200&&e<300||304===e}function c(e,t=[]){e=e.toLowerCase();for(const a of t)if(a.toLowerCase()===e)return!0;return!1}function d(e,a){var r;a.headers||(a.headers={});const{etag:n,modifiedSince:i}=a.cache;if(n){const i=!0===n?null===(r=e.data)||void 0===r?void 0:r.headers[t.ETag]:n;i&&(a.headers[t.IfNoneMatch]=i)}i&&(a.headers[t.IfModifiedSince]=!0===i?e.data.headers[t.LastModified]||new Date(e.createdAt).toUTCString():i.toUTCString())}function u(e,t){return 304===e.status&&t?(e.cached=!0,e.data=t.data,e.status=t.status,e.statusText=t.statusText,e.headers=Object.assign(Object.assign({},t.headers),e.headers),t):{data:e.data,status:e.status,statusText:e.statusText,headers:e.headers}}var f=function(e,t,a,r){return new(a||(a=Promise))((function(n,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function o(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};class h{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.request.use(this.onFulfilled)},this.onFulfilled=e=>f(this,void 0,void 0,(function*(){var t;if(!1===e.cache)return e;if(e.cache=Object.assign(Object.assign({},this.axios.defaults.cache),e.cache),!c(e.method,e.cache.methods))return e;const a=this.axios.generateKey(e);let r,n=yield this.axios.storage.get(a);e:if("empty"==n.state||"stale"===n.state){if(this.axios.waiting[a]){n=yield this.axios.storage.get(a);break e}return this.axios.waiting[a]=(0,s.deferred)(),null===(t=this.axios.waiting[a])||void 0===t||t.catch((()=>{})),yield this.axios.storage.set(a,{state:"loading",data:n.data}),"stale"===n.state&&d(n,e),e.validateStatus=o(e.validateStatus),e}if("loading"===n.state){const t=this.axios.waiting[a];if(!t)return yield this.axios.storage.remove(a),e;try{r=yield t}catch(t){return e}}else r=n.data;return e.adapter=()=>Promise.resolve({config:e,data:r.data,headers:r.headers,status:r.status,statusText:r.statusText,cached:!0,id:a}),e}))}}function l(e,{cachePredicate:t}){return"function"==typeof t?t(e):p(e,t)}function p(e,{statusCheck:t,containsHeaders:a,responseMatch:r}){if(t)if("function"==typeof t){if(!t(e.status))return!1}else{const[a,r]=t;if(e.status<a||e.status>r)return!1}if(a)for(const t in a){const r=a[t],n=e.headers[t];if(!n)return!1;switch(typeof r){case"string":if(n!=r)return!1;break;case"function":if(!r(n))return!1}}return!(r&&!r(e))}var g=function(e,t,a,r){return new(a||(a=Promise))((function(n,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function o(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};function m(e,t,a){return g(this,void 0,void 0,(function*(){for(const r in a){const n=a[r];if("delete"===n){yield e.remove(r);continue}const i=yield e.get(r);if("loading"===i.state)continue;const s=yield n(i,t);"delete"!==s?"ignore"!==s&&(yield e.set(r,s)):yield e.remove(r)}}))}var v=function(e,t,a,r){return new(a||(a=Promise))((function(n,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function o(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};class y{constructor(e){this.axios=e,this.use=()=>{this.axios.interceptors.response.use(this.onFulfilled)},this.onFulfilled=e=>v(this,void 0,void 0,(function*(){const a=this.cachedResponse(e);if(a.cached)return a;if(!a.config.cache)return Object.assign(Object.assign({},a),{cached:!1});const r=a.config.cache,n=yield this.axios.storage.get(a.id);if("stale"===n.state||"empty"===n.state||"cached"===n.state)return a;if(!n.data&&!l(a,r))return yield this.rejectResponse(a.id),a;delete a.headers[t.XAxiosCacheEtag],delete a.headers[t.XAxiosCacheLastModified],r.etag&&!0!==r.etag&&(a.headers[t.XAxiosCacheEtag]=r.etag),r.modifiedSince&&(a.headers[t.XAxiosCacheLastModified]=!0===r.modifiedSince?"use-cache-timestamp":r.modifiedSince.toUTCString());let i=r.ttl||-1;if(null==r?void 0:r.interpretHeader){const e=this.axios.headerInterpreter(a.headers);if("dont cache"===e)return yield this.rejectResponse(a.id),a;i="not enough headers"===e?i:e}const s=u(a,n.data);"function"==typeof i&&(i=yield i(a));const o={state:"cached",ttl:i,createdAt:Date.now(),data:s};(null==r?void 0:r.update)&&m(this.axios.storage,a,r.update);const c=this.axios.waiting[a.id];return yield null==c?void 0:c.resolve(o.data),delete this.axios.waiting[a.id],yield this.axios.storage.set(a.id,o),a})),this.rejectResponse=e=>v(this,void 0,void 0,(function*(){var t;yield this.axios.storage.remove(e),null===(t=this.axios.waiting[e])||void 0===t||t.reject(null),delete this.axios.waiting[e]})),this.cachedResponse=e=>Object.assign({id:this.axios.generateKey(e.config),cached:e.cached||!1},e)}}var x=function(e,t,a,r){return new(a||(a=Promise))((function(n,i){function s(e){try{c(r.next(e))}catch(e){i(e)}}function o(e){try{c(r.throw(e))}catch(e){i(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};const b=Symbol(),w=e=>!!e&&!!e[b];function C({set:e,find:a,remove:r}){return{[b]:1,set:e,remove:r,get:n=>x(this,void 0,void 0,(function*(){const i=yield a(n);if(!i)return{state:"empty"};if("cached"!==i.state||i.createdAt+i.ttl>Date.now())return i;if(i.data.headers&&(t.ETag in i.data.headers||t.LastModified in i.data.headers||t.XAxiosCacheEtag in i.data.headers||t.XAxiosCacheLastModified in i.data.headers)){const t={data:i.data,state:"stale",createdAt:i.createdAt};return yield e(n,t),t}return yield r(n),{state:"empty"}}))}}function S(){const e={},t=C({find:t=>e[t],set:(t,a)=>{e[t]=a},remove:t=>{delete e[t]}});return Object.assign(Object.assign({},t),{data:e})}const I=/^\/|\/+$/g,j=({baseURL:e="",url:t="",method:a,params:r,id:n})=>n||(e=e.replace(I,""),t=t.replace(I,""),`${(null==a?void 0:a.toLowerCase())||"get"}::${e+(e&&t?"/":"")+t}::${r?JSON.stringify(r,Object.keys(r).sort()):"{}"}`);var O=function(e,t){var a={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(a[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(r=Object.getOwnPropertySymbols(e);n<r.length;n++)t.indexOf(r[n])<0&&Object.prototype.propertyIsEnumerable.call(e,r[n])&&(a[r[n]]=e[r[n]])}return a};const A=Symbol();function M(e,t={}){var{storage:a,generateKey:r,waiting:n,headerInterpreter:s,requestInterceptor:o,responseInterceptor:c}=t,d=O(t,["storage","generateKey","waiting","headerInterpreter","requestInterceptor","responseInterceptor"]);const u=e;if(u.storage=a||S(),!w(u.storage))throw new Error("Use buildStorage()");return u.generateKey=r||j,u.waiting=n||{},u.headerInterpreter=s||i,u.requestInterceptor=o||new h(u),u.responseInterceptor=c||new y(u),u.defaults=Object.assign(Object.assign({},e.defaults),{cache:Object.assign({ttl:3e5,interpretHeader:!1,methods:["get"],cachePredicate:{statusCheck:[200,399]},etag:!1,modifiedSince:!1,update:{}},d)}),u.requestInterceptor.use(),u.responseInterceptor.use(),u[A]=1,u}const R=M,P=M,T=e=>!!e&&!!e[A];function E(e,t=""){return C({find:a=>{const r=e.getItem(t+a);return r?JSON.parse(r):void 0},set:(a,r)=>{e.setItem(t+a,JSON.stringify(r))},remove:a=>{e.removeItem(t+a)}})}})(),r})()})); | ||
//# sourceMappingURL=index.min.js.map |
@@ -1,24 +0,9 @@ | ||
import type { AxiosRequestConfig, Method } from 'axios'; | ||
import type { CacheProperties } from '..'; | ||
import type { AxiosCacheInstance, CacheRequestConfig } from '../cache/axios'; | ||
import type { StaleStorageValue } from '../storage/types'; | ||
import type { AxiosInterceptor } from './types'; | ||
export declare class CacheRequestInterceptor<D> implements AxiosInterceptor<CacheRequestConfig<D>> { | ||
export declare class CacheRequestInterceptor implements AxiosInterceptor<CacheRequestConfig<unknown, unknown>> { | ||
readonly axios: AxiosCacheInstance; | ||
constructor(axios: AxiosCacheInstance); | ||
readonly use: () => void; | ||
readonly onFulfilled: (config: CacheRequestConfig<D>) => Promise<CacheRequestConfig<D>>; | ||
static readonly isMethodAllowed: (method: Method, properties: Partial<CacheProperties>) => boolean; | ||
static readonly setRevalidationHeaders: <D_1>(cache: StaleStorageValue, config: AxiosRequestConfig<D_1> & { | ||
id?: string | undefined; | ||
cache?: false | Partial<CacheProperties> | undefined; | ||
} & { | ||
cache: Partial<CacheProperties>; | ||
}) => void; | ||
/** | ||
* Creates a new validateStatus function that will use the one already used and also | ||
* accept status code 304. | ||
*/ | ||
static readonly createValidateStatus: (oldValidate?: AxiosRequestConfig['validateStatus']) => (status: number) => boolean; | ||
readonly onFulfilled: (config: CacheRequestConfig<unknown>) => Promise<CacheRequestConfig<unknown>>; | ||
} | ||
//# sourceMappingURL=request.d.ts.map |
import type { AxiosResponse } from 'axios'; | ||
import type { AxiosCacheInstance, CacheAxiosResponse } from '../cache/axios'; | ||
import type { CachedResponse } from '../storage/types'; | ||
import type { AxiosInterceptor } from './types'; | ||
export declare class CacheResponseInterceptor<R, D> implements AxiosInterceptor<CacheAxiosResponse<R, D>> { | ||
export declare class CacheResponseInterceptor implements AxiosInterceptor<CacheAxiosResponse<unknown, unknown>> { | ||
readonly axios: AxiosCacheInstance; | ||
constructor(axios: AxiosCacheInstance); | ||
readonly use: () => void; | ||
readonly onFulfilled: (axiosResponse: AxiosResponse<R, D>) => Promise<CacheAxiosResponse<R, D>>; | ||
readonly onFulfilled: (axiosResponse: AxiosResponse<unknown, unknown>) => Promise<CacheAxiosResponse<unknown, unknown>>; | ||
/** Rejects cache for this response. Also update the waiting list for this key by rejecting it. */ | ||
readonly rejectResponse: (key: string) => Promise<void>; | ||
readonly cachedResponse: (response: AxiosResponse<R, D>) => CacheAxiosResponse<R, D>; | ||
/** | ||
* Creates the new date to the cache by the provided response. Also handles possible 304 | ||
* Not Modified by updating response properties. | ||
*/ | ||
static readonly setupCacheData: <R_1, D_1>(response: CacheAxiosResponse<R_1, D_1>, cache?: CachedResponse | undefined) => CachedResponse; | ||
readonly cachedResponse: (response: AxiosResponse<unknown, unknown>) => CacheAxiosResponse<unknown, unknown>; | ||
} | ||
//# sourceMappingURL=response.d.ts.map |
@@ -1,10 +0,30 @@ | ||
import { AxiosStorage } from './storage'; | ||
import type { NotEmptyStorageValue, StorageValue } from './types'; | ||
export declare class MemoryAxiosStorage extends AxiosStorage { | ||
readonly storage: Record<string, StorageValue>; | ||
constructor(storage?: Record<string, StorageValue>); | ||
readonly find: (key: string) => Promise<StorageValue>; | ||
readonly set: (key: string, value: NotEmptyStorageValue) => Promise<void>; | ||
readonly remove: (key: string) => Promise<void>; | ||
} | ||
import type { StorageValue } from './types'; | ||
/** | ||
* Creates a simple in-memory storage. This means that if you need to persist data between | ||
* page or server reloads, this will not help. | ||
* | ||
* This is the storage used by default. | ||
* | ||
* If you need to modify it's data, you can do by the `data` property. | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const memoryStorage = buildMemoryStorage(); | ||
* | ||
* setupCache(axios, { storage: memoryStorage }); | ||
* | ||
* // Simple example to force delete the request cache | ||
* | ||
* const { id } = axios.get('url'); | ||
* | ||
* delete memoryStorage.data[id]; | ||
* ``` | ||
*/ | ||
export declare function buildMemoryStorage(): { | ||
data: Record<string, StorageValue>; | ||
set: (key: string, value: import("./types").NotEmptyStorageValue) => import("..").MaybePromise<void>; | ||
remove: (key: string) => import("..").MaybePromise<void>; | ||
get: (key: string) => import("..").MaybePromise<StorageValue>; | ||
}; | ||
//# sourceMappingURL=memory.d.ts.map |
@@ -0,3 +1,4 @@ | ||
import type { MaybePromise } from '../util/types'; | ||
export declare type CachedResponse = { | ||
data?: any; | ||
data?: unknown; | ||
headers: Record<string, string>; | ||
@@ -41,2 +42,31 @@ status: number; | ||
}; | ||
/** | ||
* A storage implementation that stores data in memory. | ||
* | ||
* **You can create yours with {@link buildStorage} function** | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const myStorage = buildStorage({ | ||
* find: () => {...}, | ||
* set: () => {...}, | ||
* remove: () => {...} | ||
* }); | ||
* | ||
* const axios = setupCache(axios, { storage: myStorage }); | ||
* ``` | ||
*/ | ||
export declare type AxiosStorage = { | ||
/** | ||
* Sets a new value for the given key | ||
* | ||
* Use CacheStorage.remove(key) to define a key to 'empty' state. | ||
*/ | ||
set: (key: string, value: NotEmptyStorageValue) => MaybePromise<void>; | ||
/** Removes the value for the given key */ | ||
remove: (key: string) => MaybePromise<void>; | ||
/** Returns the value for the given key. This method make checks for cache invalidation or etc. */ | ||
get: (key: string) => MaybePromise<StorageValue>; | ||
}; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -1,7 +0,7 @@ | ||
import type { AxiosResponse } from 'axios'; | ||
import type { CacheProperties } from '..'; | ||
import type { CacheAxiosResponse } from '../cache/axios'; | ||
import type { CacheProperties } from '../cache/cache'; | ||
import type { CachePredicateObject } from './types'; | ||
/** Returns true if the response should be cached */ | ||
export declare function shouldCacheResponse<R>(response: AxiosResponse<R>, { cachePredicate }: CacheProperties): boolean; | ||
export declare function isCachePredicateValid<R>(response: AxiosResponse<R>, { statusCheck, containsHeaders, responseMatch }: CachePredicateObject): boolean; | ||
export declare function shouldCacheResponse<R, D>(response: CacheAxiosResponse<R, D>, { cachePredicate }: CacheProperties): boolean; | ||
export declare function isCachePredicateValid<R, D>(response: CacheAxiosResponse<R, D>, { statusCheck, containsHeaders, responseMatch }: CachePredicateObject<R, D>): boolean; | ||
//# sourceMappingURL=cache-predicate.d.ts.map |
@@ -1,5 +0,5 @@ | ||
import type { AxiosResponse } from 'axios'; | ||
import type { CacheRequestConfig } from '../cache/axios'; | ||
export declare type CachePredicate = CachePredicateObject | (<R>(response: AxiosResponse<R>) => boolean); | ||
export declare type CachePredicateObject = { | ||
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; | ||
import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types'; | ||
export declare type CachePredicate<R = any, D = any> = CachePredicateObject<R, D> | (<R, D>(response: CacheAxiosResponse<R, D>) => boolean); | ||
export declare type CachePredicateObject<R = any, D = any> = { | ||
/** | ||
@@ -16,6 +16,8 @@ * The status predicate, if a tuple is returned, the first and seconds value means the | ||
/** Check if the desired response matches this predicate. */ | ||
responseMatch?: <T = any>(res: T | undefined) => boolean; | ||
responseMatch?: (res: CacheAxiosResponse<R, D>) => boolean; | ||
}; | ||
/** A simple function that receives a cache request config and should return a string id for it. */ | ||
export declare type KeyGenerator = <R>(options: CacheRequestConfig<R>) => string; | ||
export declare type KeyGenerator = <R = any, D = any>(options: CacheRequestConfig<R, D>) => string; | ||
export declare type MaybePromise<T> = T | Promise<T> | PromiseLike<T>; | ||
export declare type CacheUpdater<R, D> = 'delete' | ((cached: Exclude<StorageValue, LoadingStorageValue>, response: CacheAxiosResponse<R, D>) => MaybePromise<CachedStorageValue | 'delete' | 'ignore'>); | ||
//# sourceMappingURL=types.d.ts.map |
@@ -1,6 +0,6 @@ | ||
import type { AxiosStorage } from '../storage/storage'; | ||
import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types'; | ||
export declare type CacheUpdater = 'delete' | ((cached: Exclude<StorageValue, LoadingStorageValue>, newData: any) => CachedStorageValue | void); | ||
import type { CacheAxiosResponse } from '../cache/axios'; | ||
import type { AxiosStorage } from '../storage/types'; | ||
import type { CacheUpdater } from './types'; | ||
/** Function to update all caches, from CacheProperties.update, with the new data. */ | ||
export declare function updateCache<T = any>(storage: AxiosStorage, data: T, entries: Record<string, CacheUpdater>): Promise<void>; | ||
export declare function updateCache<T, D>(storage: AxiosStorage, data: CacheAxiosResponse<T, D>, entries: Record<string, CacheUpdater<T, D>>): Promise<void>; | ||
//# sourceMappingURL=update-cache.d.ts.map |
@@ -0,52 +1,55 @@ | ||
//@ts-check | ||
/* eslint-disable @typescript-eslint/no-var-requires */ | ||
const { create: createAxios } = require('axios').default; | ||
const { setupCache } = require('../dist'); | ||
const { setupCache } = require('axios-cache-interceptor'); | ||
const { log } = console; | ||
async function main() { | ||
// | ||
// Complete documentation at: | ||
// https://axios-cache-interceptor.js.org/ | ||
// | ||
(async () => { | ||
const axios = setupCache( | ||
// creating axios instance | ||
createAxios({ | ||
baseUrl: 'https://registry.npmjs.org/' | ||
}), | ||
createAxios({ baseURL: 'https://registry.npmjs.org/' }), | ||
// configuring the cache | ||
{ | ||
ttl: 99999, | ||
// Parse the Cache-Control header to determine the cache strategy | ||
interpretHeader: true | ||
} | ||
{ ttl: 99999, interpretHeader: true } | ||
); | ||
const fetchedResponse = await axios.get('/axios-cache-interceptor'); | ||
// fetchedResponse.cached == false | ||
// This won't made a network request, because the response is already cached | ||
// | ||
// The next request won't do a network request, because the response is already cached | ||
// | ||
const cachedResponse = await axios.get('/axios-cache-interceptor'); | ||
// cachedResponse.cached == true | ||
console.log('First request was cached?'); | ||
console.log(fetchedResponse.cached, '\n'); | ||
log(`First request was ${fetchedResponse.cached ? 'cached' : 'fetched'}`); | ||
log(`Second request was ${cachedResponse.cached ? 'cached' : 'fetched'}`); | ||
console.log('Second request was cached?'); | ||
console.log(cachedResponse.cached, '\n'); | ||
// | ||
// The interpretHeader option used a different strategy, see the received Cache-Control header | ||
// (server may return undefined if this is the first request in a while :)) | ||
// | ||
console.log('The interpretHeader option used a different strategy', '\n'); | ||
console.log('See the received Cache-Control header'); | ||
console.log(fetchedResponse.headers['cache-control'], '\n'); | ||
console.log('And also the received Age header'); | ||
console.log(fetchedResponse.headers['age'], '\n'); | ||
log(`Fetched response Cache-Control: ${fetchedResponse.headers['cache-control']}`); | ||
log(`Fetched response Age: ${fetchedResponse.headers['age']}`); | ||
const cacheInformation = await axios.storage.get(fetchedResponse.id); | ||
console.log( | ||
'As you can see, the TTL used was the maxAge cache directive minus the Age header', | ||
'\n' | ||
); | ||
console.log('See the time to live in the cache: '); | ||
console.log(cacheInformation.ttl, '\n'); | ||
// | ||
// As you can see, the TTL used was the maxAge cache directive minus the Age header | ||
// | ||
console.log( | ||
"If you disable the interpretHeader option you'll see that the TTL will be the default (99999)\n" | ||
); | ||
log(`Cache TTL info: ${cacheInformation.ttl}`); | ||
// | ||
// If you disable the interpretHeader option you'll see that the TTL will be the default (99999)\n | ||
// | ||
// Remove the old cache by brute force | ||
@@ -64,6 +67,3 @@ await axios.storage.remove(fetchedResponse.id); | ||
console.log('Third request TTL:'); | ||
console.log(refetchedInformation.ttl); | ||
} | ||
main(); | ||
log(`Third request TTL: ${refetchedInformation.ttl}`); | ||
})().catch(console.error); |
{ | ||
"name": "axios-cache-interceptor", | ||
"version": "0.7.9", | ||
"version": "0.8.0-beta1", | ||
"description": "Cache interceptor for axios", | ||
"types": "./dist/index.ts", | ||
"main": "./dist/index.js", | ||
@@ -11,12 +12,7 @@ "browser": "./dist/index.min.js", | ||
"scripts": { | ||
"build": "concurrently 'npm:build:*'", | ||
"build:browser": "webpack", | ||
"build:node": "tsc -p tsconfig.build.json", | ||
"test": "jest", | ||
"test:watch": "jest --watch", | ||
"test:coverage": "jest --coverage", | ||
"escheck": "es-check es5 ./dist/index.es5.min.js && es-check es6 ./dist/index.min.js", | ||
"build": "webpack", | ||
"test": "jest --coverage", | ||
"escheck": "npx es-check es5 ./dist/index.es5.min.js && npx es-check es6 ./dist/index.min.js", | ||
"format": "prettier --write .", | ||
"lint": "tsc --noEmit && eslint . --ext .ts", | ||
"lint:fix": "eslint . --ext .ts --fix", | ||
"version": "auto-changelog -p && git add CHANGELOG.md" | ||
@@ -46,3 +42,3 @@ }, | ||
}, | ||
"homepage": "https://github.com/ArthurFiorette/axios-cache-interceptor#readme", | ||
"homepage": "https://axios-cache-interceptor.js.org/", | ||
"dependencies": { | ||
@@ -61,4 +57,2 @@ "cache-parser": "^1.1.2", | ||
"axios": "~0.24.0", | ||
"concurrently": "^6.4.0", | ||
"es-check": "^6.1.1", | ||
"eslint": "^8.3.0", | ||
@@ -65,0 +59,0 @@ "eslint-config-prettier": "^8.3.0", |
509
README.md
@@ -31,2 +31,9 @@ <br /> | ||
></code> | ||
<code | ||
><a href="https://twitter.com/acdlite/status/974390255393505280" | ||
><img | ||
src="https://img.shields.io/badge/speed-Blazing%20%F0%9F%94%A5-brightgreen.svg" | ||
target="_blank" | ||
alt="Blazing Fast" /></a | ||
></code> | ||
<br /> | ||
@@ -65,6 +72,4 @@ <code | ||
<pre> | ||
<br /> | ||
<h1>🗄️🔥💨 | ||
<h1>📬 | ||
Axios Cache Interceptor</h1> | ||
<br /> | ||
</pre> | ||
@@ -74,500 +79,34 @@ <br /> | ||
<h1></h1> | ||
<br /> | ||
<br /> | ||
<h3 align="center"> | ||
<code>axios-cache-interceptor</code> is a small and efficient cache interceptor for axios. | ||
<br /> | ||
<br /> | ||
</h3> | ||
### `axios-cache-interceptor` is a axios wrapper for caching and preventing unneeded requests | ||
<br /> | ||
```ts | ||
import axios from 'axios'; | ||
import { setupCache, SessionCacheStorage } from 'axios-cache-interceptor'; | ||
// An axios instance with modified types | ||
const api = setupCache(axios.create(), { | ||
/* options */ | ||
}); | ||
// Make a simple request, with caching support, to the api | ||
const resp1 = await api.get('https://api.example.com/'); | ||
// resp1.cached = false | ||
const resp2 = await api.get('https://api.example.com/'); | ||
// resp2.cached = true | ||
``` | ||
<br /> | ||
<br /> | ||
## Table of contents | ||
- [Table of contents](#table-of-contents) | ||
- [Features](#features) | ||
- [Installing](#installing) | ||
- [Via NPM](#via-npm) | ||
- [Via CDN](#via-cdn) | ||
- [Support list](#support-list) | ||
- [Getting Started](#getting-started) | ||
- [Compiled code](#compiled-code) | ||
- [NodeJS](#nodejs) | ||
- [Browsers](#browsers) | ||
- [Typescript users](#typescript-users) | ||
- [Basic Knowledge](#basic-knowledge) | ||
- [Request id](#request-id) | ||
- [Response object](#response-object) | ||
- [response.cached](#responsecached) | ||
- [response.id](#responseid) | ||
- [Global configuration](#global-configuration) | ||
- [config.storage](#configstorage) | ||
- [config.generateKey](#configgeneratekey) | ||
- [config.waiting](#configwaiting) | ||
- [config.headerInterpreter](#configheaderinterpreter) | ||
- [config.requestInterceptor and config.responseInterceptor](#configrequestinterceptor-and-configresponseinterceptor) | ||
- [Per-request configuration](#per-request-configuration) | ||
- [request.id](#requestid) | ||
- [request.cache.ttl](#requestcachettl) | ||
- [request.cache.interpretHeader](#requestcacheinterpretheader) | ||
- [request.cache.methods](#requestcachemethods) | ||
- [request.cache.cachePredicate](#requestcachecachepredicate) | ||
- [request.cache.update](#requestcacheupdate) | ||
- [request.cache.etag](#requestcacheetag) | ||
- [request.cache.modifiedSince](#requestcachemodifiedsince) | ||
- [License](#license) | ||
- [Contact](#contact) | ||
<br /> | ||
## Features | ||
- [x] Concurrent requests | ||
- [x] Typescript support | ||
- [x] Unit tests | ||
- [x] Header interpretation | ||
- [x] ETag and If-Modified-Since cache support | ||
- [x] Infinity storage options | ||
- [x] Cache revalidation from responses | ||
- [x] Support for external storages | ||
<br /> | ||
## Installing | ||
> Axios must be installed separately. | ||
### Via NPM | ||
```sh | ||
npm install --save axios axios-cache-interceptor | ||
# or | ||
yarn add axios axios-cache-interceptor | ||
``` | ||
```js | ||
const { setupCache } = require('axios-cache-interceptor'); | ||
// or | ||
import Axios from 'axios'; | ||
import { setupCache } from 'axios-cache-interceptor'; | ||
``` | ||
### Via CDN | ||
// same object, but with updated typings. | ||
const axios = setupCache(Axios); | ||
![Version](https://img.shields.io/npm/v/axios-cache-interceptor?style=flat) | ||
const req1 = axios.get('https://api.example.com/'); | ||
const req2 = axios.get('https://api.example.com/'); | ||
```html | ||
<!-- Replace latest with the desired version --> | ||
const [res1, res2] = await Promise.all([req1, req2]); | ||
<!-- Development (ES2020) (~30KB) --> | ||
<script | ||
crossorigin | ||
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@latest/dist/index.development.js" | ||
></script> | ||
<!-- Production for ES6+ (~12KB) --> | ||
<script | ||
crossorigin | ||
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@latest/dist/index.min.js" | ||
></script> | ||
<!-- Production for ES5+ (~22KB) --> | ||
<script | ||
crossorigin | ||
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@latest/dist/index.es5.min.js" | ||
></script> | ||
<!-- Production for ES2020+ (~9KB) --> | ||
<script | ||
crossorigin | ||
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@latest/dist/index.es2020.min.js" | ||
></script> | ||
res1.cached; // false | ||
res2.cached; // true | ||
``` | ||
```js | ||
const { setupCache } = window.AxiosCacheInterceptor; | ||
``` | ||
<br /> | ||
## Support list | ||
<h3 align=center> | ||
<a href="https://axios-cache-interceptor.js.org/" target="_blank">Documentation at <code>axios-cache-interceptor.js.org</code> 🎉🎉</a> | ||
</h3> | ||
Below you can check what version of this package is supported by your version of axios. | ||
But that does not mean that won't work with any version. **Most of "breaking changes" made | ||
by axios was it's types.** | ||
> **NOTE**: Below v0.3, axios was not configured as a peer dependency | ||
| [Version](https://github.com/ArthurFiorette/axios-cache-interceptor/releases) | [Axios](https://github.com/axios/axios/releases) | | ||
| ----------------------------------------------------------------------------- | ------------------------------------------------ | | ||
| `>= v0.5` | `>= v0.24` | | ||
| `~ v0.4` | `>= v0.23` | | ||
| `~ v0.3` | `>= v0.22` | | ||
| `<= v0.2` | `v0.21` | | ||
<br /> | ||
## Getting Started | ||
To you use this cache interceptor, you can apply to an existing instance or create a new | ||
one. | ||
```js | ||
import { setupCache } from 'axios-cache-interceptor'; | ||
// Your axios instance | ||
let axios; | ||
// Return the same axios instance, but with a modified Typescript type. | ||
axios = setupCache(axios, { | ||
/* options here */ | ||
}); | ||
``` | ||
After that, you can made your own requests normally, as this library respects axios API. | ||
Afterwards, the only thing you may need to configure is per-request configuration, you can | ||
change them with the `cache` property. | ||
```js | ||
import { setupCache } from 'axios-cache-interceptor'; | ||
// Your axios-cache-interceptor instance | ||
let axios; | ||
axios.get('url', { | ||
cache: { | ||
/** Options here */ | ||
} | ||
}); | ||
``` | ||
You will get syntax highlighting for all options and what they do. But you can also read | ||
here: [Per-request configuration](#per-request-configuration). | ||
<br /> | ||
## Compiled code | ||
### NodeJS | ||
The code is compiled with `tsc` with support to `>= ES6`. See the | ||
[build config](/tsconfig.build.json). | ||
- `axios-cache-interceptor`: Redirects to `/dist/index.js` | ||
- `axios-cache-interceptor/dist/index.js`: The main library file. | ||
- `axios-cache-interceptor/dist/index.d.ts`: The Typescript definition file. | ||
Every browser build is also compatible with CommonsJS because it builds with UMD, so you | ||
can use them too. | ||
### Browsers | ||
> _NOTE_: Axios itself requires [ES6 Promises](https://axios-http.com/docs/notes#promises) | ||
The UMD code is compiled with `webpack` with support to `>= ES5`. See the | ||
[build config](/webpack.config.js). You can import these files anywhere (Browser, | ||
CommonsJS and more) | ||
- `axios-cache-interceptor/dist/index.min.js`: Production file for ES6+ | ||
- `axios-cache-interceptor/dist/index.es5.min.js`: Production file for ES5+ | ||
- `axios-cache-interceptor/dist/index.development.js`: Development file | ||
```html | ||
<!-- You can use the cdn of your choice --> | ||
<!-- UNPKG --> | ||
<script crossorigin src="https://unpkg.com/axios-cache-interceptor@latest"></script> | ||
<!-- JSDELIVR --> | ||
<script | ||
crossorigin | ||
src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@latest" | ||
></script> | ||
<!-- Etc... --> | ||
``` | ||
<br /> | ||
## Typescript users | ||
This package does not pollute the global axios typings. Instead, the `setupCache` returns | ||
the same axios instance but with **extended** typings. | ||
```ts | ||
const axios = axios.create(); | ||
axios === setupCache(axios, {}); | ||
``` | ||
In this way, we recommend you to not use a global axios instance with typescript, so you | ||
can use all exported types from `axios-cache-interceptor` by creating a new variable. | ||
```ts | ||
import Axios from 'axios'; | ||
import { setupCache, AxiosCacheInstance } from 'axios-cache-interceptor'; | ||
// instance will have our custom typings from the return of this function | ||
const instance = setupCache( | ||
Axios.create({ | ||
// Axios options | ||
}), | ||
{ | ||
// Axios-cache-interceptor options | ||
} | ||
); | ||
// OR | ||
const instance = axios.create({ | ||
// Axios options | ||
}) as AxiosCacheInstance; | ||
// As this functions returns the same axios instance but only with | ||
// different typings, you can ignore the function return. | ||
setupCache(instance, { | ||
// Axios-cache-interceptor options | ||
}); | ||
``` | ||
<br /> | ||
## Basic Knowledge | ||
### Request id | ||
A good thing to know is that every request passed through this interceptor, has an id. | ||
**This does not mean that is a unique id**. The id is used in a number of ways, but the | ||
most important is to bind a request to its cache. | ||
The id generation is good enough to generate the same id for theoretically sames requests. | ||
The example of this is a request with `{ baseUrl: 'https://a.com/', url: '/b' }` results | ||
to the same id with `{ url: 'https://a.com/b/' }`. | ||
Also, a custom id can be used to treat two requests as the same. | ||
```js | ||
axios.get('...', { | ||
id: 'my-custom-id', | ||
cache: { | ||
// other properties... | ||
} | ||
}); | ||
``` | ||
The [default](src/util/key-generator.ts) id generation can clarify this idea. | ||
### Response object | ||
Every response that came from our custom axios instance, will have some extras properties, | ||
that you can retrieve like that: | ||
```js | ||
const result = await cache.get(/* ... */); | ||
const id = result['propertyName']; | ||
``` | ||
#### response.cached | ||
A simple boolean to check whether this request was cached or not. | ||
**NOTE**: The first response of a request capable of being cached will return | ||
`cached: false`, as only your next requests will return `cached: true`. | ||
#### response.id | ||
The [request id](#request-id) resolved. This property represents the ID used throughout | ||
the internal code. Remember that, depending on the | ||
[config.keyGenerator](#configgeneratekey), it can be different as the provided on the | ||
[request.id](#requestid). | ||
<br /> | ||
## Global configuration | ||
When applying the interceptor, you can customize some properties: | ||
```js | ||
const axios = setupCache(axios, { | ||
// Properties here | ||
}); | ||
``` | ||
### config.storage | ||
The storage used to save the cache. Here will probably be the most changed property. | ||
Defaults to [MemoryStorage](src/storage/memory.ts). | ||
You can create your own implementation by implementing | ||
[CacheStorage](src/storage/types.ts). | ||
There are few built in storage implementations, you can use them by importing: | ||
> With the cdn served bundle, the **MemoryStorage** and **BrowserAxiosStorage** comes by | ||
> default. Just get them by `window.AxiosCacheInterceptor.BrowserAxiosStorage` or | ||
> `window.AxiosCacheInterceptor.MemoryAxiosStorage`. | ||
```js | ||
import {} from 'axios-cache-interceptor/dist/storage/{name}'; | ||
``` | ||
- [MemoryAxiosStorage](src/storage/memory.ts) | ||
`import 'axios-cache-interceptor/dist/storage/memory';` | ||
- [BrowserAxiosStorage](src/storage/browser.ts) | ||
`import 'axios-cache-interceptor/dist/storage/browser';` | ||
- _Maybe your own?_ (PR's are welcome) | ||
### config.generateKey | ||
The function used to create different keys for each request. Defaults to a function that | ||
priorizes the id, and if not specified, a string is generated using the method, baseUrl, | ||
params, and url. | ||
### config.waiting | ||
A simple object that will hold a promise for each pending request. Used to handle | ||
concurrent requests. | ||
Can also be used as type of _listener_ to know when a request is finished. | ||
### config.headerInterpreter | ||
The function used to interpret all headers from a request and determine a time to live | ||
(`ttl`) number. | ||
Check out the [inline documentation](src/header/types.ts) to know how to modify your own. | ||
### config.requestInterceptor and config.responseInterceptor | ||
The used request and response interceptor. Basically the core function of this library. | ||
Check out the used [request](src/interceptors/request.ts) and | ||
[response](src/interceptors/response.ts) to see the default used. | ||
<br /> | ||
## Per-request configuration | ||
By using this axios client and using an ide with intellisense, you'll see a custom | ||
property called `cache`. | ||
The inline documentation is self explanatory, but here are some examples and information: | ||
### request.id | ||
You can override the request id used by this property. | ||
### request.cache.ttl | ||
The time that the request will remain in cache. Some custom storage implementations may | ||
not respect 100% the time. | ||
When using `interpretHeader`, this value is ignored. | ||
### request.cache.interpretHeader | ||
If activated, when the response is received, the `ttl` property will be inferred from the | ||
requests headers. See the actual implementation of the | ||
[`interpretHeader`](src/header/interpreter.ts) method for more information. You can | ||
override the default behavior by setting the `headerInterpreter` when creating the cached | ||
axios client. | ||
### request.cache.methods | ||
Specify what request methods should be cached. | ||
Defaults to only `GET` methods. | ||
### request.cache.cachePredicate | ||
An object or function that will be tested against the response to test if it can be | ||
cached. See the [inline documentation](src/util/cache-predicate.ts) for more. | ||
An simple example with all values: | ||
```js | ||
axios.get('url', { | ||
cache: { | ||
cachePredicate: { | ||
// Only cache if the response comes with a *good* status code | ||
statusCheck: [200, 399], | ||
// Tests against any header present in the response. | ||
containsHeader: { | ||
'x-custom-header': true, | ||
'x-custom-header-2': 'only if matches this string', | ||
'x-custom-header-3': (value) => /* some calculation */ true | ||
}, | ||
// Check custom response body | ||
responseMatch: (response) => { | ||
// Sample that only caches if the response is authenticated | ||
return response.auth.status === 'authenticated': | ||
} | ||
} | ||
} | ||
}); | ||
``` | ||
### request.cache.update | ||
Once the request is resolved, this specifies what other responses should change their | ||
cache. Can be used to update the request or delete other caches. It is a simple `Record` | ||
with the request id. | ||
Example: | ||
```js | ||
// Retrieved together with their responses | ||
let otherResponseId; | ||
let userInfoResponseId; | ||
axios.get('url', { | ||
cache: { | ||
update: { | ||
// Evict the otherRequestId cache when this response arrives | ||
[otherResponseId]: 'delete', | ||
// An example that update the "user info response cache" when doing a login. | ||
// Imagine this request is a login one. | ||
[userInfoResponseId]: (cachedValue, thisResponse) => { | ||
return { ...cachedValue, user: thisResponse.user.info }; | ||
} | ||
} | ||
} | ||
}); | ||
``` | ||
### request.cache.etag | ||
If the request should handle `ETag` and `If-None-Match support`. Use a string to force a | ||
custom static value or true to use the previous response ETag. To use `true` (automatic | ||
etag handling), `interpretHeader` option must be set to `true`. Default: `false` | ||
### request.cache.modifiedSince | ||
Use `If-Modified-Since` header in this request. Use a date to force a custom static value | ||
or true to use the last cached timestamp. If never cached before, the header is not set. | ||
If `interpretHeader` is set and a `Last-Modified` header is sent then value from that | ||
header is used, otherwise cache creation timestamp will be sent in `If-Modified-Since`. | ||
Default: `true` | ||
<br /> | ||
## License | ||
@@ -574,0 +113,0 @@ |
@@ -15,3 +15,3 @@ import type { | ||
export type CacheAxiosResponse<R = any, D = any> = AxiosResponse<R, D> & { | ||
config: CacheRequestConfig<D>; | ||
config: CacheRequestConfig<R, D>; | ||
@@ -28,5 +28,6 @@ /** The id used for this request. if config specified an id, the id will be returned */ | ||
* | ||
* @template R The type returned by this response | ||
* @template D The type for the request body | ||
*/ | ||
export type CacheRequestConfig<D = any> = AxiosRequestConfig<D> & { | ||
export type CacheRequestConfig<R = any, D = any> = AxiosRequestConfig<D> & { | ||
/** | ||
@@ -45,3 +46,3 @@ * An id for this request, if this request is used in cache, only the last request made | ||
*/ | ||
cache?: false | Partial<CacheProperties>; | ||
cache?: false | Partial<CacheProperties<R, D>>; | ||
}; | ||
@@ -64,3 +65,3 @@ | ||
<T = any, D = any, R = CacheAxiosResponse<T, D>>( | ||
config: CacheRequestConfig<D> | ||
config: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -74,3 +75,3 @@ /** | ||
url: string, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -83,8 +84,8 @@ | ||
interceptors: { | ||
request: AxiosInterceptorManager<CacheRequestConfig<any>>; | ||
response: AxiosInterceptorManager<CacheAxiosResponse<never, any>>; | ||
request: AxiosInterceptorManager<CacheRequestConfig<any, any>>; | ||
response: AxiosInterceptorManager<CacheAxiosResponse<any, any>>; | ||
}; | ||
/** @template D The type that the request body use */ | ||
getUri<D>(config?: CacheRequestConfig<D>): string; | ||
getUri<D>(config?: CacheRequestConfig<any, D>): string; | ||
@@ -97,3 +98,3 @@ /** | ||
request<T = any, D = any, R = CacheAxiosResponse<T, D>>( | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -108,3 +109,3 @@ | ||
url: string, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -119,3 +120,3 @@ | ||
url: string, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -130,3 +131,3 @@ | ||
url: string, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -141,3 +142,3 @@ | ||
url: string, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -153,3 +154,3 @@ | ||
data?: D, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -165,3 +166,3 @@ | ||
data?: D, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
@@ -177,4 +178,4 @@ | ||
data?: D, | ||
config?: CacheRequestConfig<D> | ||
config?: CacheRequestConfig<T, D> | ||
): Promise<R>; | ||
} |
@@ -5,20 +5,22 @@ import type { Method } from 'axios'; | ||
import type { AxiosInterceptor } from '../interceptors/types'; | ||
import type { AxiosStorage } from '../storage/storage'; | ||
import type { CachedResponse } from '../storage/types'; | ||
import type { CachePredicate, KeyGenerator } from '../util/types'; | ||
import type { CacheUpdater } from '../util/update-cache'; | ||
import type { AxiosStorage, CachedResponse } from '../storage/types'; | ||
import type { CachePredicate, CacheUpdater, KeyGenerator } from '../util/types'; | ||
import type { CacheAxiosResponse, CacheRequestConfig } from './axios'; | ||
export type CacheProperties = { | ||
/** | ||
* @template R The type returned by this response | ||
* @template D The type for the request body | ||
*/ | ||
export type CacheProperties<R = any, D = any> = { | ||
/** | ||
* The time until the cached value is expired in milliseconds. | ||
* | ||
* If a function is used, it will receive the complete response and waits to return a TTL value | ||
* | ||
* When using `interpretHeader: true`, this value will only be used if the interpreter | ||
* can't determine their TTL value to override this | ||
* | ||
* **Note**: a custom storage implementation may not respect this. | ||
* | ||
* @default 1000 * 60 * 5 // 5 Minutes | ||
*/ | ||
ttl: number; | ||
ttl: number | ((response: CacheAxiosResponse<R, D>) => number | Promise<number>); | ||
@@ -45,3 +47,3 @@ /** | ||
*/ | ||
cachePredicate: CachePredicate; | ||
cachePredicate: CachePredicate<R, D>; | ||
@@ -52,6 +54,6 @@ /** | ||
* | ||
* If the function returns nothing, the entry is deleted | ||
* | ||
* This is independent if the request made was cached or not. | ||
* | ||
* If an provided id represents and loading cache, he will be ignored. | ||
* | ||
* The id used is the same as the id on `CacheRequestConfig['id']`, auto-generated or not. | ||
@@ -61,3 +63,3 @@ * | ||
*/ | ||
update: Record<string, CacheUpdater>; | ||
update: Record<string, CacheUpdater<R, D>>; | ||
@@ -85,5 +87,5 @@ /** | ||
/** | ||
* The storage to save the cache data. | ||
* The storage to save the cache data. Defaults to an in-memory storage. | ||
* | ||
* @default new MemoryAxiosStorage() | ||
* @default buildMemoryStorage() | ||
*/ | ||
@@ -113,6 +115,6 @@ storage: AxiosStorage; | ||
/** The request interceptor that will be used to handle the cache. */ | ||
requestInterceptor: AxiosInterceptor<CacheRequestConfig<any>>; | ||
requestInterceptor: AxiosInterceptor<CacheRequestConfig<unknown, unknown>>; | ||
/** The response interceptor that will be used to handle the cache. */ | ||
responseInterceptor: AxiosInterceptor<CacheAxiosResponse<any, any>>; | ||
responseInterceptor: AxiosInterceptor<CacheAxiosResponse<unknown, unknown>>; | ||
} |
@@ -5,3 +5,4 @@ import type { AxiosInstance } from 'axios'; | ||
import { CacheResponseInterceptor } from '../interceptors/response'; | ||
import { MemoryAxiosStorage } from '../storage/memory'; | ||
import { isStorage } from '../storage/build'; | ||
import { buildMemoryStorage } from '../storage/memory'; | ||
import { defaultKeyGenerator } from '../util/key-generator'; | ||
@@ -13,2 +14,4 @@ import type { AxiosCacheInstance } from './axios'; | ||
const symbolKey = Symbol(); | ||
/** | ||
@@ -64,3 +67,8 @@ * Apply the caching interceptors for a already created axios instance. | ||
axiosCache.storage = storage || new MemoryAxiosStorage(); | ||
axiosCache.storage = storage || buildMemoryStorage(); | ||
if (!isStorage(axiosCache.storage)) { | ||
throw new Error('Use buildStorage()'); | ||
} | ||
axiosCache.generateKey = generateKey || defaultKeyGenerator; | ||
@@ -93,2 +101,5 @@ axiosCache.waiting = waiting || {}; | ||
// @ts-expect-error - internal only | ||
axiosCache[symbolKey] = 1; | ||
return axiosCache; | ||
@@ -101,1 +112,11 @@ } | ||
export const createCache = setupCache as unknown as 'use setupCache instead'; | ||
/** | ||
* Detects if the given parameter has caching enabled. The only way to this return true is | ||
* by using the {@link setupCache} function. | ||
* | ||
* @param axios The axios instance to use | ||
* @returns True if the axios instance is using the caching interceptor | ||
*/ | ||
export const isAxiosCacheInterceptor = (axios: any): axios is AxiosCacheInstance => | ||
!!axios && !!axios[symbolKey]; |
import { parse } from 'cache-parser'; | ||
import { Header } from '../util/headers'; | ||
import type { HeaderInterpreter, HeadersInterpreter } from './types'; | ||
import type { HeadersInterpreter } from './types'; | ||
export const defaultHeaderInterpreter: HeadersInterpreter = (headers = {}) => { | ||
if (Header.CacheControl in headers) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return interpretCacheControl(headers[Header.CacheControl]!, headers); | ||
} | ||
export const defaultHeaderInterpreter: HeadersInterpreter = (headers) => { | ||
if (!headers) return 'not enough headers'; | ||
if (Header.Expires in headers) { | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
return interpretExpires(headers[Header.Expires]!, headers); | ||
} | ||
const cacheControl = headers[Header.CacheControl]; | ||
return undefined; | ||
}; | ||
if (cacheControl) { | ||
const { noCache, noStore, mustRevalidate, maxAge, immutable } = parse(cacheControl); | ||
const interpretExpires: HeaderInterpreter = (expires) => { | ||
const milliseconds = Date.parse(expires) - Date.now(); | ||
return milliseconds >= 0 ? milliseconds : false; | ||
}; | ||
// Header told that this response should not be cached. | ||
if (noCache || noStore) { | ||
return 'dont cache'; | ||
} | ||
const interpretCacheControl: HeaderInterpreter = (cacheControl, headers) => { | ||
const { noCache, noStore, mustRevalidate, maxAge, immutable } = parse(cacheControl); | ||
if (immutable) { | ||
// 1 year is sufficient, as Infinity may cause more problems. | ||
// It might not be the best way, but a year is better than none. | ||
return 1000 * 60 * 60 * 24 * 365; | ||
} | ||
// Header told that this response should not be cached. | ||
if (noCache || noStore) { | ||
return false; | ||
} | ||
// Already out of date, for cache can be saved, but must be requested again | ||
if (mustRevalidate) { | ||
return 0; | ||
} | ||
if (immutable) { | ||
// 1 year is sufficient, as Infinity may cause more problems. | ||
// It might not be the best way, but a year is better than none. | ||
return 1000 * 60 * 60 * 24 * 365; | ||
} | ||
if (maxAge) { | ||
const age = headers[Header.Age]; | ||
// Already out of date, for cache can be saved, but must be requested again | ||
if (mustRevalidate) { | ||
return 0; | ||
if (!age) { | ||
return maxAge * 1000; | ||
} | ||
return (maxAge - Number(age)) * 1000; | ||
} | ||
} | ||
if (maxAge) { | ||
const age = headers[Header.Age]; | ||
const expires = headers[Header.Expires]; | ||
if (!age) { | ||
return maxAge * 1000; | ||
} | ||
return (maxAge - Number(age)) * 1000; | ||
if (expires) { | ||
const milliseconds = Date.parse(expires) - Date.now(); | ||
return milliseconds >= 0 ? milliseconds : 'dont cache'; | ||
} | ||
return undefined; | ||
return 'not enough headers'; | ||
}; |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
type MaybeTtl = false | undefined | number; | ||
type MaybeTtl = 'dont cache' | 'not enough headers' | number; | ||
@@ -11,0 +11,0 @@ /** |
@@ -1,10 +0,5 @@ | ||
/** Index file for webpack and cdn usage */ | ||
export * from './index'; | ||
export { createCache, setupCache, useCache } from './cache/create'; | ||
export { BrowserAxiosStorage } from './storage/browser'; | ||
export { MemoryAxiosStorage } from './storage/memory'; | ||
export { AxiosStorage } from './storage/storage'; | ||
console.warn( | ||
'You are using a development build. Make sure to use the correct build in production\nhttps://github.com/arthurfiorette/axios-cache-interceptor#installing' | ||
'You are using a development build. Make sure to use the correct build in production\nhttps://axios-cache-interceptor.js.org/#/pages/installing' | ||
); |
export * from './cache/axios'; | ||
export * from './cache/cache'; | ||
export * from './cache/create'; | ||
export * from './header/interpreter'; | ||
export * from './header/types'; | ||
export * from './interceptors/request'; | ||
export * from './interceptors/response'; | ||
export * from './interceptors/types'; | ||
export * from './storage/storage'; | ||
export * as InterceptorUtil from './interceptors/util'; | ||
export * from './storage/build'; | ||
export * from './storage/memory'; | ||
export * from './storage/types'; | ||
export * from './storage/web-api'; | ||
export * from './util/cache-predicate'; | ||
export * from './util/headers'; | ||
export * from './util/key-generator'; | ||
export * from './util/types'; | ||
export * from './util/update-cache'; |
@@ -1,4 +0,2 @@ | ||
import type { AxiosRequestConfig, Method } from 'axios'; | ||
import { deferred } from 'fast-defer'; | ||
import type { CacheProperties } from '..'; | ||
import type { | ||
@@ -12,10 +10,14 @@ AxiosCacheInstance, | ||
CachedStorageValue, | ||
LoadingStorageValue, | ||
StaleStorageValue | ||
LoadingStorageValue | ||
} from '../storage/types'; | ||
import { Header } from '../util/headers'; | ||
import type { AxiosInterceptor } from './types'; | ||
import { | ||
ConfigWithCache, | ||
createValidateStatus, | ||
isMethodIn, | ||
setRevalidationHeaders | ||
} from './util'; | ||
export class CacheRequestInterceptor<D> | ||
implements AxiosInterceptor<CacheRequestConfig<D>> | ||
export class CacheRequestInterceptor | ||
implements AxiosInterceptor<CacheRequestConfig<unknown, unknown>> | ||
{ | ||
@@ -29,4 +31,4 @@ constructor(readonly axios: AxiosCacheInstance) {} | ||
readonly onFulfilled = async ( | ||
config: CacheRequestConfig<D> | ||
): Promise<CacheRequestConfig<D>> => { | ||
config: CacheRequestConfig<unknown> | ||
): Promise<CacheRequestConfig<unknown>> => { | ||
if (config.cache === false) { | ||
@@ -41,3 +43,3 @@ return config; | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
!CacheRequestInterceptor.isMethodAllowed(config.method!, config.cache) | ||
!isMethodIn(config.method!, config.cache.methods) | ||
) { | ||
@@ -81,9 +83,6 @@ return config; | ||
if (cache.state === 'stale') { | ||
//@ts-expect-error type infer couldn't resolve this | ||
CacheRequestInterceptor.setRevalidationHeaders(cache, config); | ||
setRevalidationHeaders(cache, config as ConfigWithCache<unknown>); | ||
} | ||
config.validateStatus = CacheRequestInterceptor.createValidateStatus( | ||
config.validateStatus | ||
); | ||
config.validateStatus = createValidateStatus(config.validateStatus); | ||
@@ -120,4 +119,4 @@ return config; | ||
*/ | ||
Promise.resolve<CacheAxiosResponse<any, D>>({ | ||
config: config, | ||
Promise.resolve<CacheAxiosResponse<unknown, unknown>>({ | ||
config, | ||
data: cachedResponse.data, | ||
@@ -133,56 +132,2 @@ headers: cachedResponse.headers, | ||
}; | ||
static readonly isMethodAllowed = ( | ||
method: Method, | ||
properties: Partial<CacheProperties> | ||
): boolean => { | ||
const requestMethod = method.toLowerCase(); | ||
for (const method of properties.methods || []) { | ||
if (method.toLowerCase() === requestMethod) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
static readonly setRevalidationHeaders = <D>( | ||
cache: StaleStorageValue, | ||
config: CacheRequestConfig<D> & { cache: Partial<CacheProperties> } | ||
): void => { | ||
config.headers ||= {}; | ||
const { etag, modifiedSince } = config.cache; | ||
if (etag) { | ||
const etagValue = etag === true ? cache.data?.headers[Header.ETag] : etag; | ||
if (etagValue) { | ||
config.headers[Header.IfNoneMatch] = etagValue; | ||
} | ||
} | ||
if (modifiedSince) { | ||
config.headers[Header.IfModifiedSince] = | ||
modifiedSince === true | ||
? // If last-modified is not present, use the createdAt timestamp | ||
cache.data.headers[Header.LastModified] || | ||
new Date(cache.createdAt).toUTCString() | ||
: modifiedSince.toUTCString(); | ||
} | ||
}; | ||
/** | ||
* Creates a new validateStatus function that will use the one already used and also | ||
* accept status code 304. | ||
*/ | ||
static readonly createValidateStatus = ( | ||
oldValidate?: AxiosRequestConfig['validateStatus'] | ||
) => { | ||
return (status: number): boolean => { | ||
return oldValidate | ||
? oldValidate(status) || status === 304 | ||
: (status >= 200 && status < 300) || status === 304; | ||
}; | ||
}; | ||
} |
import type { AxiosResponse } from 'axios'; | ||
import type { AxiosCacheInstance, CacheAxiosResponse } from '../cache/axios'; | ||
import type { CacheProperties } from '../cache/cache'; | ||
import type { CachedResponse, CachedStorageValue } from '../storage/types'; | ||
import type { CachedStorageValue } from '../storage/types'; | ||
import { shouldCacheResponse } from '../util/cache-predicate'; | ||
@@ -9,5 +9,6 @@ import { Header } from '../util/headers'; | ||
import type { AxiosInterceptor } from './types'; | ||
import { setupCacheData } from './util'; | ||
export class CacheResponseInterceptor<R, D> | ||
implements AxiosInterceptor<CacheAxiosResponse<R, D>> | ||
export class CacheResponseInterceptor | ||
implements AxiosInterceptor<CacheAxiosResponse<unknown, unknown>> | ||
{ | ||
@@ -21,4 +22,4 @@ constructor(readonly axios: AxiosCacheInstance) {} | ||
readonly onFulfilled = async ( | ||
axiosResponse: AxiosResponse<R, D> | ||
): Promise<CacheAxiosResponse<R, D>> => { | ||
axiosResponse: AxiosResponse<unknown, unknown> | ||
): Promise<CacheAxiosResponse<unknown, unknown>> => { | ||
const response = this.cachedResponse(axiosResponse); | ||
@@ -82,3 +83,3 @@ | ||
// Cache should not be used | ||
if (expirationTime === false) { | ||
if (expirationTime === 'dont cache') { | ||
await this.rejectResponse(response.id); | ||
@@ -88,7 +89,11 @@ return response; | ||
ttl = expirationTime || expirationTime === 0 ? expirationTime : ttl; | ||
ttl = expirationTime === 'not enough headers' ? ttl : expirationTime; | ||
} | ||
const data = CacheResponseInterceptor.setupCacheData(response, cache.data); | ||
const data = setupCacheData(response, cache.data); | ||
if (typeof ttl === 'function') { | ||
ttl = await ttl(response); | ||
} | ||
const newCache: CachedStorageValue = { | ||
@@ -103,3 +108,3 @@ state: 'cached', | ||
if (cacheConfig?.update) { | ||
updateCache(this.axios.storage, response.data, cacheConfig.update); | ||
updateCache(this.axios.storage, response, cacheConfig.update); | ||
} | ||
@@ -129,3 +134,5 @@ | ||
readonly cachedResponse = (response: AxiosResponse<R, D>): CacheAxiosResponse<R, D> => { | ||
readonly cachedResponse = ( | ||
response: AxiosResponse<unknown, unknown> | ||
): CacheAxiosResponse<unknown, unknown> => { | ||
return { | ||
@@ -135,40 +142,6 @@ id: this.axios.generateKey(response.config), | ||
cached: (response as CacheAxiosResponse<R, D>).cached || false, | ||
cached: (response as CacheAxiosResponse<unknown, unknown>).cached || false, | ||
...response | ||
}; | ||
}; | ||
/** | ||
* Creates the new date to the cache by the provided response. Also handles possible 304 | ||
* Not Modified by updating response properties. | ||
*/ | ||
static readonly setupCacheData = <R, D>( | ||
response: CacheAxiosResponse<R, D>, | ||
cache?: CachedResponse | ||
): CachedResponse => { | ||
if (response.status === 304 && cache) { | ||
// Set the cache information into the response object | ||
response.cached = true; | ||
response.data = cache.data; | ||
response.status = cache.status; | ||
response.statusText = cache.statusText; | ||
// Update possible new headers | ||
response.headers = { | ||
...cache.headers, | ||
...response.headers | ||
}; | ||
// return the old cache | ||
return cache; | ||
} | ||
// New Response | ||
return { | ||
data: response.data, | ||
status: response.status, | ||
statusText: response.statusText, | ||
headers: response.headers | ||
}; | ||
}; | ||
} |
@@ -1,20 +0,34 @@ | ||
import { AxiosStorage } from './storage'; | ||
import type { NotEmptyStorageValue, StorageValue } from './types'; | ||
import { buildStorage } from './build'; | ||
import type { StorageValue } from './types'; | ||
export class MemoryAxiosStorage extends AxiosStorage { | ||
constructor(readonly storage: Record<string, StorageValue> = {}) { | ||
super(); | ||
} | ||
readonly find = async (key: string): Promise<StorageValue> => { | ||
return this.storage[key] || { state: 'empty' }; | ||
}; | ||
readonly set = async (key: string, value: NotEmptyStorageValue): Promise<void> => { | ||
this.storage[key] = value; | ||
}; | ||
readonly remove = async (key: string): Promise<void> => { | ||
delete this.storage[key]; | ||
}; | ||
/** | ||
* Creates a simple in-memory storage. This means that if you need to persist data between | ||
* page or server reloads, this will not help. | ||
* | ||
* This is the storage used by default. | ||
* | ||
* If you need to modify it's data, you can do by the `data` property. | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const memoryStorage = buildMemoryStorage(); | ||
* | ||
* setupCache(axios, { storage: memoryStorage }); | ||
* | ||
* // Simple example to force delete the request cache | ||
* | ||
* const { id } = axios.get('url'); | ||
* | ||
* delete memoryStorage.data[id]; | ||
* ``` | ||
*/ | ||
export function buildMemoryStorage() { | ||
const data: Record<string, StorageValue> = {}; | ||
const storage = buildStorage({ | ||
find: (key) => data[key], | ||
set: (key, value) => void (data[key] = value), | ||
remove: (key) => void delete data[key] | ||
}); | ||
return { ...storage, data }; | ||
} |
@@ -0,3 +1,5 @@ | ||
import type { MaybePromise } from '../util/types'; | ||
export type CachedResponse = { | ||
data?: any; | ||
data?: unknown; | ||
headers: Record<string, string>; | ||
@@ -53,1 +55,33 @@ status: number; | ||
}; | ||
/** | ||
* A storage implementation that stores data in memory. | ||
* | ||
* **You can create yours with {@link buildStorage} function** | ||
* | ||
* @example | ||
* | ||
* ```js | ||
* const myStorage = buildStorage({ | ||
* find: () => {...}, | ||
* set: () => {...}, | ||
* remove: () => {...} | ||
* }); | ||
* | ||
* const axios = setupCache(axios, { storage: myStorage }); | ||
* ``` | ||
*/ | ||
export type AxiosStorage = { | ||
/** | ||
* Sets a new value for the given key | ||
* | ||
* Use CacheStorage.remove(key) to define a key to 'empty' state. | ||
*/ | ||
set: (key: string, value: NotEmptyStorageValue) => MaybePromise<void>; | ||
/** Removes the value for the given key */ | ||
remove: (key: string) => MaybePromise<void>; | ||
/** Returns the value for the given key. This method make checks for cache invalidation or etc. */ | ||
get: (key: string) => MaybePromise<StorageValue>; | ||
}; |
@@ -1,8 +0,8 @@ | ||
import type { AxiosResponse } from 'axios'; | ||
import type { CacheProperties } from '..'; | ||
import type { CacheAxiosResponse } from '../cache/axios'; | ||
import type { CacheProperties } from '../cache/cache'; | ||
import type { CachePredicateObject } from './types'; | ||
/** Returns true if the response should be cached */ | ||
export function shouldCacheResponse<R>( | ||
response: AxiosResponse<R>, | ||
export function shouldCacheResponse<R, D>( | ||
response: CacheAxiosResponse<R, D>, | ||
{ cachePredicate }: CacheProperties | ||
@@ -17,5 +17,5 @@ ) { | ||
export function isCachePredicateValid<R>( | ||
response: AxiosResponse<R>, | ||
{ statusCheck, containsHeaders, responseMatch }: CachePredicateObject | ||
export function isCachePredicateValid<R, D>( | ||
response: CacheAxiosResponse<R, D>, | ||
{ statusCheck, containsHeaders, responseMatch }: CachePredicateObject<R, D> | ||
): boolean { | ||
@@ -64,3 +64,3 @@ if (statusCheck) { | ||
if (responseMatch && !responseMatch(response.data)) { | ||
if (responseMatch && !responseMatch(response)) { | ||
return false; | ||
@@ -67,0 +67,0 @@ } |
@@ -10,7 +10,9 @@ import type { KeyGenerator } from './types'; | ||
url = '', | ||
method: nullableMethod, | ||
method, | ||
params, | ||
id | ||
}) => { | ||
if (id) return String(id); | ||
if (id) { | ||
return id; | ||
} | ||
@@ -21,6 +23,12 @@ // Remove trailing slashes | ||
const method = nullableMethod?.toLowerCase() || 'get'; | ||
const jsonParams = params ? JSON.stringify(params, Object.keys(params).sort()) : '{}'; | ||
return `${method}::${baseURL + (url && baseURL ? '/' : '') + url}::${jsonParams}`; | ||
return `${ | ||
// method | ||
method?.toLowerCase() || 'get' | ||
}::${ | ||
// complete url | ||
baseURL + (baseURL && url ? '/' : '') + url | ||
}::${ | ||
//params | ||
params ? JSON.stringify(params, Object.keys(params).sort()) : '{}' | ||
}`; | ||
}; |
@@ -1,9 +0,13 @@ | ||
import type { AxiosResponse } from 'axios'; | ||
import type { CacheRequestConfig } from '../cache/axios'; | ||
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; | ||
import type { | ||
CachedStorageValue, | ||
LoadingStorageValue, | ||
StorageValue | ||
} from '../storage/types'; | ||
export type CachePredicate = | ||
| CachePredicateObject | ||
| (<R>(response: AxiosResponse<R>) => boolean); | ||
export type CachePredicate<R = any, D = any> = | ||
| CachePredicateObject<R, D> | ||
| (<R, D>(response: CacheAxiosResponse<R, D>) => boolean); | ||
export type CachePredicateObject = { | ||
export type CachePredicateObject<R = any, D = any> = { | ||
/** | ||
@@ -22,6 +26,17 @@ * The status predicate, if a tuple is returned, the first and seconds value means the | ||
/** Check if the desired response matches this predicate. */ | ||
responseMatch?: <T = any>(res: T | undefined) => boolean; | ||
responseMatch?: (res: CacheAxiosResponse<R, D>) => boolean; | ||
}; | ||
/** A simple function that receives a cache request config and should return a string id for it. */ | ||
export type KeyGenerator = <R>(options: CacheRequestConfig<R>) => string; | ||
export type KeyGenerator = <R = any, D = any>( | ||
options: CacheRequestConfig<R, D> | ||
) => string; | ||
export type MaybePromise<T> = T | Promise<T> | PromiseLike<T>; | ||
export type CacheUpdater<R, D> = | ||
| 'delete' | ||
| (( | ||
cached: Exclude<StorageValue, LoadingStorageValue>, | ||
response: CacheAxiosResponse<R, D> | ||
) => MaybePromise<CachedStorageValue | 'delete' | 'ignore'>); |
@@ -1,20 +0,10 @@ | ||
import type { AxiosStorage } from '../storage/storage'; | ||
import type { | ||
CachedStorageValue, | ||
LoadingStorageValue, | ||
StorageValue | ||
} from '../storage/types'; | ||
import type { CacheAxiosResponse } from '../cache/axios'; | ||
import type { AxiosStorage } from '../storage/types'; | ||
import type { CacheUpdater } from './types'; | ||
export type CacheUpdater = | ||
| 'delete' | ||
| (( | ||
cached: Exclude<StorageValue, LoadingStorageValue>, | ||
newData: any | ||
) => CachedStorageValue | void); | ||
/** Function to update all caches, from CacheProperties.update, with the new data. */ | ||
export async function updateCache<T = any>( | ||
export async function updateCache<T, D>( | ||
storage: AxiosStorage, | ||
data: T, | ||
entries: Record<string, CacheUpdater> | ||
data: CacheAxiosResponse<T, D>, | ||
entries: Record<string, CacheUpdater<T, D>> | ||
): Promise<void> { | ||
@@ -33,8 +23,8 @@ for (const cacheKey in entries) { | ||
if (oldValue.state === 'loading') { | ||
throw new Error('cannot update the cache while loading'); | ||
continue; | ||
} | ||
const newValue = value(oldValue, data); | ||
const newValue = await value(oldValue, data); | ||
if (newValue === undefined) { | ||
if (newValue === 'delete') { | ||
await storage.remove(cacheKey); | ||
@@ -44,4 +34,6 @@ continue; | ||
await storage.set(cacheKey, newValue); | ||
if (newValue !== 'ignore') { | ||
await storage.set(cacheKey, newValue); | ||
} | ||
} | ||
} |
@@ -5,6 +5,8 @@ { | ||
"noEmit": false, | ||
"target": "ES6" | ||
"target": "ESNext", | ||
"module": "ESNext", | ||
"declaration": false, | ||
"declarationMap": false | ||
}, | ||
"include": ["src"], | ||
"exclude": ["src/index.*.ts"] | ||
"include": ["src"] | ||
} |
@@ -52,4 +52,4 @@ { | ||
// "removeComments": true, /* Disable emitting comments. */ | ||
"noEmit": true, /* Disable emitting files from a compilation. */ | ||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ | ||
"noEmit": true, /* Disable emitting files from a compilation. */ | ||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ | ||
"importsNotUsedAsValues": "error" /* Specify emit/checking behavior for imports that are only used for types */, | ||
@@ -100,3 +100,4 @@ "downlevelIteration": true /* Emit more compliant, but verbose and less performant JavaScript for iteration. */, | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
} | ||
}, | ||
"include": ["src", "test", "examples"] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20
438585
76
2971
121