mirror of
https://github.com/arthurfiorette/axios-cache-interceptor.git
synced 2025-12-08 17:36:16 +00:00
Ådd feature to blacklist some paths (#754)
* add feature to blacklist some paths * format with biome * update exclude attr definition * improvements * style: formatted code * fix: lint --------- Co-authored-by: Arthur Fiorette <me@arthur.place>
This commit is contained in:
parent
b9da1fe1ed
commit
05712980df
@ -182,7 +182,7 @@ exceptions to the method rule.
|
|||||||
_(These default status codes follows RFC 7231)_
|
_(These default status codes follows RFC 7231)_
|
||||||
|
|
||||||
An object or function that will be tested against the response to indicate if it can be
|
An object or function that will be tested against the response to indicate if it can be
|
||||||
cached. You can use `statusCheck`, `containsHeader` and `responseMatch` to test against
|
cached. You can use `statusCheck`, `containsHeader`, `ignoreUrls` and `responseMatch` to test against
|
||||||
the response.
|
the response.
|
||||||
|
|
||||||
```ts{5,8,13}
|
```ts{5,8,13}
|
||||||
@ -201,7 +201,10 @@ axios.get<{ auth: { status: string } }>('url', {
|
|||||||
responseMatch: ({ data }) => {
|
responseMatch: ({ data }) => {
|
||||||
// Sample that only caches if the response is authenticated
|
// Sample that only caches if the response is authenticated
|
||||||
return data.auth.status === 'authenticated';
|
return data.auth.status === 'authenticated';
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// Ensures no request is cached if its url starts with "/api"
|
||||||
|
ignoreUrls: [/^\/api/]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,6 +12,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
|||||||
if (config.cache === false) {
|
if (config.cache === false) {
|
||||||
if (__ACI_DEV__) {
|
if (__ACI_DEV__) {
|
||||||
axios.debug({
|
axios.debug({
|
||||||
|
id: config.id,
|
||||||
msg: 'Ignoring cache because config.cache === false',
|
msg: 'Ignoring cache because config.cache === false',
|
||||||
data: config
|
data: config
|
||||||
});
|
});
|
||||||
@ -23,6 +24,35 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
|||||||
// merge defaults with per request configuration
|
// merge defaults with per request configuration
|
||||||
config.cache = { ...axios.defaults.cache, ...config.cache };
|
config.cache = { ...axios.defaults.cache, ...config.cache };
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof config.cache.cachePredicate === 'object' &&
|
||||||
|
config.cache.cachePredicate.ignoreUrls &&
|
||||||
|
config.url
|
||||||
|
) {
|
||||||
|
for (const url of config.cache.cachePredicate.ignoreUrls) {
|
||||||
|
if (
|
||||||
|
url instanceof RegExp
|
||||||
|
? // Handles stateful regexes
|
||||||
|
// biome-ignore lint: reduces the number of checks
|
||||||
|
((url.lastIndex = 0), url.test(config.url))
|
||||||
|
: config.url.includes(url)
|
||||||
|
) {
|
||||||
|
if (__ACI_DEV__) {
|
||||||
|
axios.debug({
|
||||||
|
id: config.id,
|
||||||
|
msg: `Ignored because url (${config.url}) matches ignoreUrls (${config.cache.cachePredicate.ignoreUrls})`,
|
||||||
|
data: {
|
||||||
|
url: config.url,
|
||||||
|
cachePredicate: config.cache.cachePredicate
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Applies sufficient headers to prevent other cache systems to work along with this one
|
// Applies sufficient headers to prevent other cache systems to work along with this one
|
||||||
//
|
//
|
||||||
// Its currently used before isMethodIn because if the isMethodIn returns false, the request
|
// Its currently used before isMethodIn because if the isMethodIn returns false, the request
|
||||||
@ -36,6 +66,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
|||||||
if (!isMethodIn(config.method, config.cache.methods)) {
|
if (!isMethodIn(config.method, config.cache.methods)) {
|
||||||
if (__ACI_DEV__) {
|
if (__ACI_DEV__) {
|
||||||
axios.debug({
|
axios.debug({
|
||||||
|
id: config.id,
|
||||||
msg: `Ignored because method (${config.method}) is not in cache.methods (${config.cache.methods})`
|
msg: `Ignored because method (${config.method}) is not in cache.methods (${config.cache.methods})`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios';
|
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios';
|
||||||
import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types';
|
import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types';
|
||||||
|
|
||||||
export type CachePredicate<R = unknown, D = unknown> = Exclude<
|
export type CachePredicate<R = unknown, D = unknown> = NonNullable<
|
||||||
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch'],
|
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch']
|
||||||
undefined
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export interface CachePredicateObject<R = unknown, D = unknown> {
|
export interface CachePredicateObject<R = unknown, D = unknown> {
|
||||||
@ -25,6 +24,14 @@ export interface CachePredicateObject<R = unknown, D = unknown> {
|
|||||||
|
|
||||||
/** Check if the response matches this predicate. */
|
/** Check if the response matches this predicate. */
|
||||||
responseMatch?: (res: CacheAxiosResponse<R, D>) => MaybePromise<boolean>;
|
responseMatch?: (res: CacheAxiosResponse<R, D>) => MaybePromise<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignores the request if their url matches any provided urls and/or regexes.
|
||||||
|
*
|
||||||
|
* - It checks against the `request.url` property, `baseURL` is not considered.
|
||||||
|
* - When only `baseURL` is specified, this property is ignored.
|
||||||
|
*/
|
||||||
|
ignoreUrls?: (RegExp | string)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -353,4 +353,45 @@ describe('Request Interceptor', () => {
|
|||||||
assert.equal(headers2[Header.Pragma], undefined);
|
assert.equal(headers2[Header.Pragma], undefined);
|
||||||
assert.equal(headers2[Header.Expires], undefined);
|
assert.equal(headers2[Header.Expires], undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ensures request with urls in exclude.paths are not cached', async () => {
|
||||||
|
const axios = mockAxios({
|
||||||
|
cachePredicate: {
|
||||||
|
ignoreUrls: ['url']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const [req0, req1] = await Promise.all([axios.get('url'), axios.get('url')]);
|
||||||
|
|
||||||
|
assert.equal(req0.cached, false);
|
||||||
|
assert.equal(req1.cached, false);
|
||||||
|
|
||||||
|
const [req2, req3] = await Promise.all([axios.get('some-other'), axios.get('some-other')]);
|
||||||
|
|
||||||
|
assert.equal(req2.cached, false);
|
||||||
|
assert.ok(req3.cached);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ensures request with urls in exclude.paths are not cached (regex)', async () => {
|
||||||
|
const axios = mockAxios({
|
||||||
|
cachePredicate: {
|
||||||
|
ignoreUrls: [/url/]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const [req0, req1] = await Promise.all([axios.get('my/url'), axios.get('my/url')]);
|
||||||
|
|
||||||
|
assert.equal(req0.cached, false);
|
||||||
|
assert.equal(req1.cached, false);
|
||||||
|
|
||||||
|
const [req2, req3] = await Promise.all([axios.get('some-other'), axios.get('some-other')]);
|
||||||
|
|
||||||
|
assert.equal(req2.cached, false);
|
||||||
|
assert.ok(req3.cached);
|
||||||
|
|
||||||
|
const [req4, req5] = await Promise.all([axios.get('other/url'), axios.get('other/url')]);
|
||||||
|
|
||||||
|
assert.equal(req4.cached, false);
|
||||||
|
assert.equal(req5.cached, false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user