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)_
|
||||
|
||||
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.
|
||||
|
||||
```ts{5,8,13}
|
||||
@ -201,7 +201,10 @@ axios.get<{ auth: { status: string } }>('url', {
|
||||
responseMatch: ({ data }) => {
|
||||
// Sample that only caches if the response is 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 (__ACI_DEV__) {
|
||||
axios.debug({
|
||||
id: config.id,
|
||||
msg: 'Ignoring cache because config.cache === false',
|
||||
data: config
|
||||
});
|
||||
@ -23,6 +24,35 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
||||
// merge defaults with per request configuration
|
||||
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
|
||||
//
|
||||
// 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 (__ACI_DEV__) {
|
||||
axios.debug({
|
||||
id: config.id,
|
||||
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 { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types';
|
||||
|
||||
export type CachePredicate<R = unknown, D = unknown> = Exclude<
|
||||
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch'],
|
||||
undefined
|
||||
export type CachePredicate<R = unknown, D = unknown> = NonNullable<
|
||||
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch']
|
||||
>;
|
||||
|
||||
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. */
|
||||
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.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