Add enabled flag to CacheProperties with full implementation and tests

Co-authored-by: arthurfiorette <47537704+arthurfiorette@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-12-08 13:29:17 +00:00
parent 1cd5f74213
commit 8e877e0a6a
5 changed files with 224 additions and 1 deletions

3
src/cache/axios.ts vendored
View File

@ -81,10 +81,13 @@ export interface CacheRequestConfig<R = any, D = any> extends AxiosRequestConfig
*
* Setting the `cache` property to `false` will disable the cache for this request.
*
* **Note:** Setting `cache: false` is deprecated. Please use `cache: { enabled: false }` instead.
*
* This does not mean that the current cache will be excluded from the storage.
*
* @default 'inherits from global configuration'
* @see https://axios-cache-interceptor.js.org/config/response-object#cache
* @deprecated Setting `cache: false` is deprecated, use `cache: { enabled: false }` instead
*/
cache?: false | Partial<CacheProperties<R, D>>;
}

14
src/cache/cache.ts vendored
View File

@ -22,6 +22,20 @@ import type { CacheAxiosResponse, InternalCacheRequestConfig } from './axios.js'
* @template D The type for the request body
*/
export interface CacheProperties<R = unknown, D = unknown> {
/**
* Whether the cache is enabled for this request.
*
* When set to `false`, the cache will be completely disabled for this request,
* similar to setting `cache: false` in the request config.
*
* This is useful for opt-in cache scenarios where you want to disable cache globally
* but enable it for specific requests by setting `cache: { enabled: true }`.
*
* @default true
* @see https://axios-cache-interceptor.js.org/config/request-specifics#cache-enabled
*/
enabled: boolean;
/**
* The time until the cached value is expired in milliseconds.
*

2
src/cache/create.ts vendored
View File

@ -57,6 +57,8 @@ export function setupCache(axios: AxiosInstance, options: CacheOptions = {}): Ax
// CacheRequestConfig values
axiosCache.defaults.cache = {
enabled: options.enabled ?? true,
update: options.update || {},
ttl: options.ttl ?? 1000 * 60 * 5,

View File

@ -19,7 +19,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance): RequestInt
if (__ACI_DEV__) {
axios.debug({
id: config.id,
msg: 'Ignoring cache because config.cache === false',
msg: 'Ignoring cache because config.cache === false (deprecated, use cache.enabled = false)',
data: config
});
}
@ -30,6 +30,19 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance): RequestInt
// merge defaults with per request configuration
config.cache = { ...axios.defaults.cache, ...config.cache };
// Check if cache is disabled via enabled flag
if (config.cache.enabled === false) {
if (__ACI_DEV__) {
axios.debug({
id: config.id,
msg: 'Ignoring cache because config.cache.enabled === false',
data: config
});
}
return config;
}
// ignoreUrls (blacklist)
if (
typeof config.cache.cachePredicate === 'object' &&

View File

@ -0,0 +1,191 @@
import assert from 'node:assert';
import { describe, it } from 'node:test';
import { mockAxios } from '../mocks/axios.js';
describe('Cache Enabled Flag', () => {
it('Cache enabled by default (enabled: true)', async () => {
const axios = mockAxios();
const response1 = await axios.get('http://test.com');
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
const response2 = await axios.get('http://test.com');
assert.ok(response2.cached);
assert.equal(response2.stale, false);
});
it('Global cache disabled (enabled: false)', async () => {
const axios = mockAxios({ enabled: false });
const response1 = await axios.get('http://test.com');
const response2 = await axios.get('http://test.com');
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
assert.equal(response2.cached, false);
assert.equal(response2.stale, undefined);
// Verify cache is empty
const cacheKey = axios.generateKey(response1.config);
const cache = await axios.storage.get(cacheKey);
assert.equal(cache.state, 'empty');
});
it('Global cache disabled, per-request enabled', async () => {
const axios = mockAxios({ enabled: false });
// First request with cache enabled
const response1 = await axios.get('http://test.com', {
cache: { enabled: true }
});
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
// Second request with cache enabled - should be cached
const response2 = await axios.get('http://test.com', {
cache: { enabled: true }
});
assert.ok(response2.cached);
assert.equal(response2.stale, false);
// Third request without cache config - should not be cached (global default)
const response3 = await axios.get('http://test.com/other');
const response4 = await axios.get('http://test.com/other');
assert.equal(response3.cached, false);
assert.equal(response3.stale, undefined);
assert.equal(response4.cached, false);
assert.equal(response4.stale, undefined);
});
it('Global cache enabled, per-request disabled', async () => {
const axios = mockAxios({ enabled: true });
// First request with cache disabled
const response1 = await axios.get('http://test.com', {
cache: { enabled: false }
});
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
// Second request with cache disabled - should not be cached
const response2 = await axios.get('http://test.com', {
cache: { enabled: false }
});
assert.equal(response2.cached, false);
assert.equal(response2.stale, undefined);
// Third request without cache config - should be cached (global default)
const response3 = await axios.get('http://test.com/other');
const response4 = await axios.get('http://test.com/other');
assert.equal(response3.cached, false);
assert.equal(response3.stale, undefined);
assert.ok(response4.cached);
assert.equal(response4.stale, false);
});
it('Backward compatibility: cache: false still works', async () => {
const axios = mockAxios();
const response1 = await axios.get('http://test.com', { cache: false });
const response2 = await axios.get('http://test.com', { cache: false });
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
assert.equal(response2.cached, false);
assert.equal(response2.stale, undefined);
// Verify cache is empty
const cacheKey = axios.generateKey(response1.config);
const cache = await axios.storage.get(cacheKey);
assert.equal(cache.state, 'empty');
});
it('Enabled flag works with other cache options', async () => {
const axios = mockAxios({ enabled: false });
const response1 = await axios.get('http://test.com', {
cache: {
enabled: true,
ttl: 1000 * 60 * 10 // 10 minutes
}
});
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
const response2 = await axios.get('http://test.com', {
cache: {
enabled: true,
ttl: 1000 * 60 * 10
}
});
assert.ok(response2.cached);
assert.equal(response2.stale, false);
// Verify cache config is applied
assert.equal(response2.config.cache?.ttl, 1000 * 60 * 10);
});
it('Enabled flag overrides in request after global enabled', async () => {
const axios = mockAxios({ enabled: true });
// Request 1 with enabled: true (explicit)
const response1 = await axios.get('http://test.com', {
cache: { enabled: true }
});
assert.equal(response1.cached, false);
assert.equal(response1.stale, undefined);
// Request 2 - should be cached
const response2 = await axios.get('http://test.com');
assert.ok(response2.cached);
assert.equal(response2.stale, false);
// Request 3 with enabled: false - should not be cached even though cache exists
const response3 = await axios.get('http://test.com', {
cache: { enabled: false }
});
assert.equal(response3.cached, false);
assert.equal(response3.stale, undefined);
});
it('Concurrent requests respect enabled flag', async () => {
const axios = mockAxios({ enabled: false });
const [resp1, resp2] = await Promise.all([
axios.get('http://test.com', { cache: { enabled: true } }),
axios.get('http://test.com', { cache: { enabled: true } })
]);
assert.equal(resp1.cached, false);
assert.equal(resp1.stale, undefined);
assert.ok(resp2.cached);
assert.equal(resp2.stale, false);
});
it('Mixed enabled and disabled requests do not interfere', async () => {
const axios = mockAxios({ enabled: false });
// Disabled request
const resp1 = await axios.get('http://test.com');
assert.equal(resp1.cached, false);
// Enabled request - creates cache
const resp2 = await axios.get('http://test.com', {
cache: { enabled: true }
});
assert.equal(resp2.cached, false);
// Disabled request - does not use cache
const resp3 = await axios.get('http://test.com');
assert.equal(resp3.cached, false);
// Enabled request - uses cache
const resp4 = await axios.get('http://test.com', {
cache: { enabled: true }
});
assert.ok(resp4.cached);
});
});