mirror of
https://github.com/arthurfiorette/axios-cache-interceptor.git
synced 2025-12-08 17:36:16 +00:00
style: linted code
This commit is contained in:
parent
37e2f1e85a
commit
ecbc27e466
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@ -6,14 +6,7 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "pnpm",
|
||||
"runtimeArgs": [
|
||||
"--inspect-brk",
|
||||
"jest",
|
||||
"--",
|
||||
"--runInBand",
|
||||
"--watch",
|
||||
"--coverage"
|
||||
],
|
||||
"runtimeArgs": ["--inspect-brk", "jest", "--", "--runInBand", "--watch", "--coverage"],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen"
|
||||
}
|
||||
|
||||
@ -10,9 +10,7 @@ const VERSION = isVersion > -1 ? process.argv[isVersion + 1].slice(1, -1) : 'Lat
|
||||
const BASE_URL = isVersion > -1 ? process.argv[isVersion + 1] : '/';
|
||||
|
||||
console.log(
|
||||
isVersion > -1
|
||||
? `Building docs for version ${VERSION}`
|
||||
: 'Building docs for latest version'
|
||||
isVersion > -1 ? `Building docs for version ${VERSION}` : 'Building docs for latest version'
|
||||
);
|
||||
|
||||
const description =
|
||||
@ -44,22 +42,10 @@ export default defineConfig({
|
||||
head: [
|
||||
// Attach a custom favicon
|
||||
['link', { rel: 'icon', href: `${BASE_URL}favicon.ico', type: 'image/x-icon` }],
|
||||
[
|
||||
'link',
|
||||
{ rel: 'apple-touch-icon', sizes: '57x57', href: `${BASE_URL}apple-icon-57x57.png` }
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{ rel: 'apple-touch-icon', sizes: '60x60', href: `${BASE_URL}apple-icon-60x60.png` }
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{ rel: 'apple-touch-icon', sizes: '72x72', href: `${BASE_URL}apple-icon-72x72.png` }
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{ rel: 'apple-touch-icon', sizes: '76x76', href: `${BASE_URL}apple-icon-76x76.png` }
|
||||
],
|
||||
['link', { rel: 'apple-touch-icon', sizes: '57x57', href: `${BASE_URL}apple-icon-57x57.png` }],
|
||||
['link', { rel: 'apple-touch-icon', sizes: '60x60', href: `${BASE_URL}apple-icon-60x60.png` }],
|
||||
['link', { rel: 'apple-touch-icon', sizes: '72x72', href: `${BASE_URL}apple-icon-72x72.png` }],
|
||||
['link', { rel: 'apple-touch-icon', sizes: '76x76', href: `${BASE_URL}apple-icon-76x76.png` }],
|
||||
[
|
||||
'link',
|
||||
{
|
||||
@ -139,10 +125,7 @@ export default defineConfig({
|
||||
|
||||
['link', { rel: 'manifest', href: `${BASE_URL}manifest.json` }],
|
||||
['meta', { name: 'msapplication-TileColor', content: '#e5972a' }],
|
||||
[
|
||||
'meta',
|
||||
{ name: 'msapplication-TileImage', content: `${BASE_URL}ms-icon-144x144.png` }
|
||||
],
|
||||
['meta', { name: 'msapplication-TileImage', content: `${BASE_URL}ms-icon-144x144.png` }],
|
||||
['meta', { name: 'theme-color', content: '#e5972a' }],
|
||||
['meta', { name: 'description', content: description }],
|
||||
|
||||
@ -171,10 +154,7 @@ export default defineConfig({
|
||||
content: 'u9Nw6WpRrWDhdPTAv-LGIE9aJ0C15t7zkjuaUizDJnA'
|
||||
}
|
||||
],
|
||||
[
|
||||
'script',
|
||||
{ async: 'true', src: 'https://www.googletagmanager.com/gtag/js?id=G-K548ZF395X' }
|
||||
],
|
||||
['script', { async: 'true', src: 'https://www.googletagmanager.com/gtag/js?id=G-K548ZF395X' }],
|
||||
[
|
||||
'script',
|
||||
{},
|
||||
@ -228,24 +208,21 @@ export default defineConfig({
|
||||
],
|
||||
|
||||
nav: [
|
||||
{ text: 'Guide', link: `/guide` },
|
||||
{ text: 'Config', link: `/config` },
|
||||
{ text: 'Others', link: `/others/license` },
|
||||
{ text: 'Guide', link: '/guide' },
|
||||
{ text: 'Config', link: '/config' },
|
||||
{ text: 'Others', link: '/others/license' },
|
||||
{
|
||||
text: VERSION,
|
||||
items: [
|
||||
{ text: 'Latest', link: url },
|
||||
{ text: 'v0.x', link: `${url}/v0/` }
|
||||
].filter((i) =>
|
||||
BASE_URL === '/' ? i.text !== 'Latest' : !i.link.includes(BASE_URL)
|
||||
)
|
||||
].filter((i) => (BASE_URL === '/' ? i.text !== 'Latest' : !i.link.includes(BASE_URL)))
|
||||
}
|
||||
],
|
||||
|
||||
//! Temp link for testing, will be changed to the real one before merged to production
|
||||
editLink: {
|
||||
pattern:
|
||||
'https://github.com/arthurfiorette/axios-cache-interceptor/edit/main/docs/src/:path'
|
||||
pattern: 'https://github.com/arthurfiorette/axios-cache-interceptor/edit/main/docs/src/:path'
|
||||
},
|
||||
|
||||
footer: {
|
||||
|
||||
@ -36,7 +36,7 @@ const { log } = console;
|
||||
//
|
||||
|
||||
log(`Fetched response Cache-Control: ${fetchedResponse.headers['cache-control']}`);
|
||||
log(`Fetched response Age: ${fetchedResponse.headers['age']}`);
|
||||
log(`Fetched response Age: ${fetchedResponse.headers.age}`);
|
||||
|
||||
const cacheInformation = await axios.storage.get(fetchedResponse.id);
|
||||
|
||||
|
||||
5
src/cache/axios.ts
vendored
5
src/cache/axios.ts
vendored
@ -5,7 +5,6 @@ import type {
|
||||
AxiosRequestConfig,
|
||||
AxiosResponse,
|
||||
AxiosResponseHeaders,
|
||||
|
||||
InternalAxiosRequestConfig
|
||||
} from 'axios';
|
||||
import type { CacheInstance, CacheProperties } from './cache';
|
||||
@ -84,8 +83,7 @@ export interface CacheRequestConfig<R = any, D = any> extends AxiosRequestConfig
|
||||
}
|
||||
|
||||
/** Cached version of type {@link InternalAxiosRequestConfig} */
|
||||
export interface InternalCacheRequestConfig<R = any, D = any>
|
||||
extends CacheRequestConfig<R, D> {
|
||||
export interface InternalCacheRequestConfig<R = any, D = any> extends CacheRequestConfig<R, D> {
|
||||
headers: AxiosResponseHeaders;
|
||||
}
|
||||
|
||||
@ -96,7 +94,6 @@ export interface InternalCacheRequestConfig<R = any, D = any>
|
||||
* @see https://axios-cache-interceptor.js.org/guide/getting-started
|
||||
*/
|
||||
export interface AxiosCacheInstance extends CacheInstance, AxiosInstance {
|
||||
|
||||
new (config?: CacheRequestConfig): AxiosCacheInstance;
|
||||
|
||||
/**
|
||||
|
||||
9
src/cache/create.ts
vendored
9
src/cache/create.ts
vendored
@ -26,10 +26,7 @@ export interface CacheOptions extends Partial<CacheInstance>, Partial<CachePrope
|
||||
* @returns The same instance with extended typescript types.
|
||||
* @see https://axios-cache-interceptor.js.org/config
|
||||
*/
|
||||
export function setupCache(
|
||||
axios: AxiosInstance,
|
||||
options: CacheOptions = {}
|
||||
): AxiosCacheInstance {
|
||||
export function setupCache(axios: AxiosInstance, options: CacheOptions = {}): AxiosCacheInstance {
|
||||
const axiosCache = axios as AxiosCacheInstance;
|
||||
|
||||
if (axiosCache.defaults.cache) {
|
||||
@ -54,7 +51,6 @@ export function setupCache(
|
||||
axiosCache.responseInterceptor =
|
||||
options.responseInterceptor || defaultResponseInterceptor(axiosCache);
|
||||
|
||||
|
||||
axiosCache.debug = options.debug || function noop() {};
|
||||
|
||||
// CacheRequestConfig values
|
||||
@ -69,8 +65,7 @@ export function setupCache(
|
||||
|
||||
cachePredicate: options.cachePredicate || {
|
||||
// All cacheable status codes defined in RFC 7231
|
||||
statusCheck: (status) =>
|
||||
[200, 203, 300, 301, 302, 404, 405, 410, 414, 501].includes(status)
|
||||
statusCheck: (status) => [200, 203, 300, 301, 302, 404, 405, 410, 414, 501].includes(status)
|
||||
},
|
||||
|
||||
etag: options.etag ?? true,
|
||||
|
||||
@ -34,6 +34,4 @@ export type InterpreterResult =
|
||||
* **milliseconds** to cache the response.
|
||||
* @see https://axios-cache-interceptor.js.org/config#headerinterpreter
|
||||
*/
|
||||
export type HeaderInterpreter = (
|
||||
headers?: CacheAxiosResponse['headers']
|
||||
) => InterpreterResult;
|
||||
export type HeaderInterpreter = (headers?: CacheAxiosResponse['headers']) => InterpreterResult;
|
||||
|
||||
@ -10,7 +10,5 @@ export interface AxiosInterceptor<T> {
|
||||
apply: () => void;
|
||||
}
|
||||
|
||||
export type RequestInterceptor = AxiosInterceptor<
|
||||
InternalCacheRequestConfig<unknown, unknown>
|
||||
>;
|
||||
export type RequestInterceptor = AxiosInterceptor<InternalCacheRequestConfig<unknown, unknown>>;
|
||||
export type ResponseInterceptor = AxiosInterceptor<CacheAxiosResponse<unknown, unknown>>;
|
||||
|
||||
@ -1,18 +1,9 @@
|
||||
import { deferred } from 'fast-defer';
|
||||
import type { AxiosCacheInstance, CacheAxiosResponse } from '../cache/axios';
|
||||
import { Header } from '../header/headers';
|
||||
import type {
|
||||
CachedResponse,
|
||||
CachedStorageValue,
|
||||
LoadingStorageValue
|
||||
} from '../storage/types';
|
||||
import type { CachedResponse, CachedStorageValue, LoadingStorageValue } from '../storage/types';
|
||||
import type { RequestInterceptor } from './build';
|
||||
import {
|
||||
ConfigWithCache,
|
||||
createValidateStatus,
|
||||
isMethodIn,
|
||||
updateStaleRequest
|
||||
} from './util';
|
||||
import { ConfigWithCache, createValidateStatus, isMethodIn, updateStaleRequest } from './util';
|
||||
|
||||
export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
||||
const onFulfilled: RequestInterceptor['onFulfilled'] = async (config) => {
|
||||
@ -58,11 +49,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
||||
|
||||
// Not cached, continue the request, and mark it as fetching
|
||||
// biome-ignore lint/suspicious/noConfusingLabels: required to break condition in simultaneous accesses
|
||||
ignoreAndRequest: if (
|
||||
cache.state === 'empty' ||
|
||||
cache.state === 'stale' ||
|
||||
overrideCache
|
||||
) {
|
||||
ignoreAndRequest: if (cache.state === 'empty' || cache.state === 'stale' || overrideCache) {
|
||||
/**
|
||||
* This checks for simultaneous access to a new key. The js event loop jumps on the
|
||||
* first await statement, so the second (asynchronous call) request may have already
|
||||
@ -121,8 +108,7 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
|
||||
|
||||
// If the cache is empty and asked to override it, use the current timestamp
|
||||
|
||||
createdAt:
|
||||
overrideCache && !cache.createdAt ? Date.now() : (cache.createdAt as any)
|
||||
createdAt: overrideCache && !cache.createdAt ? Date.now() : (cache.createdAt as any)
|
||||
},
|
||||
config
|
||||
);
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
import type { AxiosResponseHeaders } from 'axios';
|
||||
import { parse } from 'cache-parser';
|
||||
import type {
|
||||
AxiosCacheInstance,
|
||||
CacheAxiosResponse,
|
||||
CacheRequestConfig
|
||||
} from '../cache/axios';
|
||||
import type { AxiosCacheInstance, CacheAxiosResponse, CacheRequestConfig } from '../cache/axios';
|
||||
import type { CacheProperties } from '../cache/cache';
|
||||
import { Header } from '../header/headers';
|
||||
import type { CachedStorageValue } from '../storage/types';
|
||||
@ -13,9 +9,7 @@ import { updateCache } from '../util/update-cache';
|
||||
import type { ResponseInterceptor } from './build';
|
||||
import { createCacheResponse, isMethodIn } from './util';
|
||||
|
||||
export function defaultResponseInterceptor(
|
||||
axios: AxiosCacheInstance
|
||||
): ResponseInterceptor {
|
||||
export function defaultResponseInterceptor(axios: AxiosCacheInstance): ResponseInterceptor {
|
||||
/**
|
||||
* Rejects cache for an response response.
|
||||
*
|
||||
@ -45,7 +39,6 @@ export function defaultResponseInterceptor(
|
||||
throw response;
|
||||
}
|
||||
|
||||
|
||||
response.id = response.config.id!;
|
||||
response.cached ??= false;
|
||||
|
||||
|
||||
@ -33,17 +33,13 @@ export interface ConfigWithCache<D> extends CacheRequestConfig<unknown, D> {
|
||||
* This function updates the cache when the request is stale. So, the next request to the
|
||||
* server will be made with proper header / settings.
|
||||
*/
|
||||
export function updateStaleRequest<D>(
|
||||
cache: StaleStorageValue,
|
||||
config: ConfigWithCache<D>
|
||||
): void {
|
||||
export function updateStaleRequest<D>(cache: StaleStorageValue, config: ConfigWithCache<D>): void {
|
||||
config.headers ||= {};
|
||||
|
||||
const { etag, modifiedSince } = config.cache;
|
||||
|
||||
if (etag) {
|
||||
const etagValue =
|
||||
etag === true ? (cache.data?.headers[Header.ETag] as unknown) : etag;
|
||||
const etagValue = etag === true ? (cache.data?.headers[Header.ETag] as unknown) : etag;
|
||||
|
||||
if (etagValue) {
|
||||
config.headers[Header.IfNoneMatch] = etagValue;
|
||||
|
||||
@ -1,20 +1,13 @@
|
||||
import type { CacheRequestConfig } from '../cache/axios';
|
||||
import { Header } from '../header/headers';
|
||||
import type { MaybePromise } from '../util/types';
|
||||
import type {
|
||||
AxiosStorage,
|
||||
CachedStorageValue,
|
||||
StaleStorageValue,
|
||||
StorageValue
|
||||
} from './types';
|
||||
import type { AxiosStorage, CachedStorageValue, StaleStorageValue, StorageValue } from './types';
|
||||
|
||||
/** Returns true if the provided object was created from {@link buildStorage} function. */
|
||||
export const isStorage = (obj: unknown): obj is AxiosStorage =>
|
||||
!!obj && !!(obj as Record<string, boolean>)['is-storage'];
|
||||
|
||||
function hasUniqueIdentifierHeader(
|
||||
value: CachedStorageValue | StaleStorageValue
|
||||
): boolean {
|
||||
function hasUniqueIdentifierHeader(value: CachedStorageValue | StaleStorageValue): boolean {
|
||||
const headers = value.data.headers;
|
||||
|
||||
return (
|
||||
@ -102,7 +95,7 @@ export interface BuildStorage extends Omit<AxiosStorage, 'get'> {
|
||||
export function buildStorage({ set, find, remove }: BuildStorage): AxiosStorage {
|
||||
return {
|
||||
//@ts-expect-error - we don't want to expose this
|
||||
['is-storage']: 1,
|
||||
'is-storage': 1,
|
||||
set,
|
||||
remove,
|
||||
get: async (key, config) => {
|
||||
|
||||
@ -108,9 +108,9 @@ export function buildMemoryStorage(
|
||||
storage.cleanup = () => {
|
||||
const keys = Object.keys(storage.data);
|
||||
|
||||
let i = -1,
|
||||
value: StorageValue,
|
||||
key: string;
|
||||
let i = -1;
|
||||
let value: StorageValue;
|
||||
let key: string;
|
||||
|
||||
// Looping forward, as older entries are more likely to be expired
|
||||
// than newer ones.
|
||||
|
||||
@ -45,35 +45,33 @@ export function buildKeyGenerator<R = unknown, D = unknown>(
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultKeyGenerator = buildKeyGenerator(
|
||||
({ baseURL, url, method, params, data }) => {
|
||||
// Remove trailing slashes to avoid generating different keys for the "same" final url.
|
||||
if (baseURL !== undefined) {
|
||||
baseURL = baseURL.replace(SLASHES_REGEX, '');
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
baseURL = '';
|
||||
}
|
||||
|
||||
if (url !== undefined) {
|
||||
url = url.replace(SLASHES_REGEX, '');
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
url = '';
|
||||
}
|
||||
|
||||
if (method !== undefined) {
|
||||
method = method.toLowerCase() as Method;
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
method = 'get';
|
||||
}
|
||||
|
||||
return {
|
||||
url: baseURL + (baseURL && url ? '/' : '') + url,
|
||||
params: params,
|
||||
method: method,
|
||||
data: data
|
||||
};
|
||||
export const defaultKeyGenerator = buildKeyGenerator(({ baseURL, url, method, params, data }) => {
|
||||
// Remove trailing slashes to avoid generating different keys for the "same" final url.
|
||||
if (baseURL !== undefined) {
|
||||
baseURL = baseURL.replace(SLASHES_REGEX, '');
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
baseURL = '';
|
||||
}
|
||||
);
|
||||
|
||||
if (url !== undefined) {
|
||||
url = url.replace(SLASHES_REGEX, '');
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
url = '';
|
||||
}
|
||||
|
||||
if (method !== undefined) {
|
||||
method = method.toLowerCase() as Method;
|
||||
} else {
|
||||
// just to have a consistent hash
|
||||
method = 'get';
|
||||
}
|
||||
|
||||
return {
|
||||
url: baseURL + (baseURL && url ? '/' : '') + url,
|
||||
params: params,
|
||||
method: method,
|
||||
data: data
|
||||
};
|
||||
});
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
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<
|
||||
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch'],
|
||||
@ -35,9 +31,7 @@ export interface CachePredicateObject<R = unknown, D = unknown> {
|
||||
* A simple function that receives a cache request config and should return a string id
|
||||
* for it.
|
||||
*/
|
||||
export type KeyGenerator<R = unknown, D = unknown> = (
|
||||
options: CacheRequestConfig<R, D>
|
||||
) => string;
|
||||
export type KeyGenerator<R = unknown, D = unknown> = (options: CacheRequestConfig<R, D>) => string;
|
||||
|
||||
export type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;
|
||||
|
||||
@ -58,9 +52,7 @@ export type StaleIfErrorPredicate<R, D> =
|
||||
error: Record<string, unknown>
|
||||
) => MaybePromise<number | boolean>);
|
||||
|
||||
export type CacheUpdaterFn<R, D> = (
|
||||
response: CacheAxiosResponse<R, D>
|
||||
) => MaybePromise<void>;
|
||||
export type CacheUpdaterFn<R, D> = (response: CacheAxiosResponse<R, D>) => MaybePromise<void>;
|
||||
|
||||
/**
|
||||
* A record for a custom cache updater for each specified request id.
|
||||
|
||||
@ -9,7 +9,7 @@ export async function updateCache<R, D>(
|
||||
cacheUpdater: CacheUpdater<R, D>
|
||||
): Promise<void> {
|
||||
// Global cache update function.
|
||||
if (typeof cacheUpdater === `function`) {
|
||||
if (typeof cacheUpdater === 'function') {
|
||||
return cacheUpdater(data);
|
||||
}
|
||||
|
||||
|
||||
2
test/cache/create.test.ts
vendored
2
test/cache/create.test.ts
vendored
@ -1,6 +1,6 @@
|
||||
import Axios from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it, mock } from 'node:test';
|
||||
import Axios from 'axios';
|
||||
import { setupCache } from '../../src/cache/create';
|
||||
|
||||
describe('Axios Cache Interceptor instances', () => {
|
||||
|
||||
@ -10,15 +10,9 @@ describe('Header Interpreter', () => {
|
||||
|
||||
assert.equal(defaultHeaderInterpreter({}), 'not enough headers');
|
||||
|
||||
assert.equal(
|
||||
defaultHeaderInterpreter({ [Header.CacheControl]: '' }),
|
||||
'not enough headers'
|
||||
);
|
||||
assert.equal(defaultHeaderInterpreter({ [Header.CacheControl]: '' }), 'not enough headers');
|
||||
|
||||
assert.equal(
|
||||
defaultHeaderInterpreter({ ['x-random-header']: '' }),
|
||||
'not enough headers'
|
||||
);
|
||||
assert.equal(defaultHeaderInterpreter({ 'x-random-header': '' }), 'not enough headers');
|
||||
});
|
||||
|
||||
it('MaxAge=10 and Age=3', () => {
|
||||
|
||||
@ -73,10 +73,7 @@ describe('Hydrate handling', () => {
|
||||
});
|
||||
|
||||
it('Only hydrates when stale while revalidate is set', async () => {
|
||||
const axios = mockAxios(
|
||||
{},
|
||||
{ [Header.CacheControl]: 'max-age=0, stale-while-revalidate=0' }
|
||||
);
|
||||
const axios = mockAxios({}, { [Header.CacheControl]: 'max-age=0, stale-while-revalidate=0' });
|
||||
const id = 'some-unique-id';
|
||||
|
||||
const m = mock.fn();
|
||||
@ -98,10 +95,7 @@ describe('Hydrate handling', () => {
|
||||
});
|
||||
|
||||
it('Only hydrates when stale while revalidate is not expired', async () => {
|
||||
const axios = mockAxios(
|
||||
{},
|
||||
{ [Header.CacheControl]: 'max-age=0, stale-while-revalidate=1' }
|
||||
);
|
||||
const axios = mockAxios({}, { [Header.CacheControl]: 'max-age=0, stale-while-revalidate=1' });
|
||||
const id = 'some-unique-id';
|
||||
|
||||
const m = mock.fn();
|
||||
@ -126,7 +120,7 @@ describe('Hydrate handling', () => {
|
||||
});
|
||||
|
||||
it('Hydrates when force stale', async () => {
|
||||
const axios = mockAxios({}, { [Header.CacheControl]: `max-age=100` });
|
||||
const axios = mockAxios({}, { [Header.CacheControl]: 'max-age=100' });
|
||||
const id = 'some-unique-id';
|
||||
|
||||
const m = mock.fn();
|
||||
|
||||
@ -1,11 +1,8 @@
|
||||
import type { AxiosAdapter, AxiosResponse } from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it, mock } from 'node:test';
|
||||
import type { AxiosAdapter, AxiosResponse } from 'axios';
|
||||
import { setTimeout } from 'timers/promises';
|
||||
import type {
|
||||
CacheRequestConfig,
|
||||
InternalCacheRequestConfig
|
||||
} from '../../src/cache/axios';
|
||||
import type { CacheRequestConfig, InternalCacheRequestConfig } from '../../src/cache/axios';
|
||||
import { Header } from '../../src/header/headers';
|
||||
import type { LoadingStorageValue } from '../../src/storage/types';
|
||||
import { mockAxios } from '../mocks/axios';
|
||||
@ -100,10 +97,7 @@ describe('Request Interceptor', () => {
|
||||
});
|
||||
|
||||
it('Cache expiration', async () => {
|
||||
const axios = mockAxios(
|
||||
{},
|
||||
{ [Header.CacheControl]: 'max-age=1,stale-while-revalidate=10' }
|
||||
);
|
||||
const axios = mockAxios({}, { [Header.CacheControl]: 'max-age=1,stale-while-revalidate=10' });
|
||||
|
||||
await axios.get('http://test.com', { cache: { interpretHeader: true } });
|
||||
|
||||
@ -240,9 +234,7 @@ describe('Request Interceptor', () => {
|
||||
adapter: async (config: InternalCacheRequestConfig) => {
|
||||
await setTimeout(150);
|
||||
|
||||
const response = (await (axios.defaults.adapter as AxiosAdapter)(
|
||||
config
|
||||
)) as AxiosResponse;
|
||||
const response = (await (axios.defaults.adapter as AxiosAdapter)(config)) as AxiosResponse;
|
||||
|
||||
// Changes the response to be different from `true` (default)
|
||||
response.data = 'overridden response';
|
||||
@ -347,7 +339,7 @@ describe('Request Interceptor', () => {
|
||||
|
||||
assert.deepEqual(Object.assign({}, req1.request.config.headers), {
|
||||
[Header.CacheControl]: 'no-cache',
|
||||
['Accept']: 'application/json, text/plain, */*',
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'Content-Type': undefined,
|
||||
[Header.Pragma]: 'no-cache',
|
||||
[Header.Expires]: '0'
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import Axios from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it, mock } from 'node:test';
|
||||
import { setImmediate } from 'node:timers/promises';
|
||||
import Axios from 'axios';
|
||||
import { setupCache } from '../../src/cache/create';
|
||||
import { Header } from '../../src/header/headers';
|
||||
import { XMockRandom, mockAxios } from '../mocks/axios';
|
||||
@ -92,10 +92,7 @@ describe('Response Interceptor', () => {
|
||||
|
||||
assert.equal(resultNoCache.cached, false);
|
||||
|
||||
const axiosCache = mockAxios(
|
||||
{},
|
||||
{ [Header.CacheControl]: `max-age=${60 * 60 * 24 * 365}` }
|
||||
);
|
||||
const axiosCache = mockAxios({}, { [Header.CacheControl]: `max-age=${60 * 60 * 24 * 365}` });
|
||||
|
||||
// Make first request to cache it
|
||||
await axiosCache.get('http://test.com', { cache: { interpretHeader: true } });
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Axios, { AxiosError } from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it } from 'node:test';
|
||||
import Axios, { AxiosError } from 'axios';
|
||||
import { setupCache } from '../../src/cache/create';
|
||||
import { Header } from '../../src/header/headers';
|
||||
import { mockAxios } from '../mocks/axios';
|
||||
@ -406,7 +406,7 @@ describe('StaleIfError handling', () => {
|
||||
|
||||
// https://github.com/arthurfiorette/axios-cache-interceptor/issues/685
|
||||
it('ensure failed responses always cleans up waiting promise', async () => {
|
||||
const axios = mockAxios({ staleIfError: false, ttl: -1 });
|
||||
const axios = mockAxios({ staleIfError: false, ttl: -1 });
|
||||
|
||||
axios.defaults.adapter = async (config) => {
|
||||
if (config.params?.fail) {
|
||||
@ -431,7 +431,7 @@ describe('StaleIfError handling', () => {
|
||||
|
||||
const id = 'arthurfiorette/axios-cache-interceptor#685';
|
||||
|
||||
let data = await axios.get('url', { id });
|
||||
const data = await axios.get('url', { id });
|
||||
|
||||
assert.equal(data.cached, false);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Axios from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it } from 'node:test';
|
||||
import Axios from 'axios';
|
||||
import { createValidateStatus, isMethodIn } from '../../src/interceptors/util';
|
||||
import { mockAxios } from '../mocks/axios';
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import Axios, { AxiosError } from 'axios';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import Axios, { AxiosError } from 'axios';
|
||||
import type { AxiosCacheInstance } from '../../src/cache/axios';
|
||||
import { CacheOptions, setupCache } from '../../src/cache/create';
|
||||
import { Header } from '../../src/header/headers';
|
||||
|
||||
@ -30,7 +30,7 @@ describe('MemoryStorage', () => {
|
||||
assert.equal(result.data.data, 'data');
|
||||
|
||||
// Deletes the value
|
||||
delete result.data.data;
|
||||
result.data.data = undefined;
|
||||
|
||||
// Check if the value has been modified
|
||||
const result2 = await storage.get('key');
|
||||
@ -58,10 +58,10 @@ describe('MemoryStorage', () => {
|
||||
|
||||
data.data = 'another data';
|
||||
|
||||
assert.notEqual(storage.data['key'], null);
|
||||
assert.equal(storage.data['key']!.state, 'cached');
|
||||
assert.notEqual(storage.data['key']!.data, null);
|
||||
assert.equal(storage.data['key']!.data!.data, 'data');
|
||||
assert.notEqual(storage.data.key, null);
|
||||
assert.equal(storage.data.key!.state, 'cached');
|
||||
assert.notEqual(storage.data.key!.data, null);
|
||||
assert.equal(storage.data.key!.data!.data, 'data');
|
||||
|
||||
const result = (await storage.get('key')) as CachedStorageValue;
|
||||
|
||||
@ -118,12 +118,12 @@ describe('MemoryStorage', () => {
|
||||
});
|
||||
|
||||
// Ensure that the values are still there
|
||||
assert.equal(storage.data['empty']?.state, 'empty');
|
||||
assert.equal(storage.data['stale']?.state, 'stale');
|
||||
assert.equal(storage.data['expiredStale']?.state, 'stale');
|
||||
assert.equal(storage.data['loading']?.state, 'loading');
|
||||
assert.equal(storage.data['cached']?.state, 'cached');
|
||||
assert.equal(storage.data['expiredCache']?.state, 'cached');
|
||||
assert.equal(storage.data.empty?.state, 'empty');
|
||||
assert.equal(storage.data.stale?.state, 'stale');
|
||||
assert.equal(storage.data.expiredStale?.state, 'stale');
|
||||
assert.equal(storage.data.loading?.state, 'loading');
|
||||
assert.equal(storage.data.cached?.state, 'cached');
|
||||
assert.equal(storage.data.expiredCache?.state, 'cached');
|
||||
|
||||
// Waits for the cleanup function to run
|
||||
await mockDateNow(600);
|
||||
@ -157,9 +157,9 @@ describe('MemoryStorage', () => {
|
||||
});
|
||||
|
||||
assert.equal(Object.keys(storage.data).length, 2);
|
||||
assert.ok(storage.data['key']);
|
||||
assert.ok(storage.data['key2']);
|
||||
assert.equal(storage.data['key3'], undefined);
|
||||
assert.ok(storage.data.key);
|
||||
assert.ok(storage.data.key2);
|
||||
assert.equal(storage.data.key3, undefined);
|
||||
|
||||
await storage.set('key3', {
|
||||
state: 'cached',
|
||||
@ -170,9 +170,9 @@ describe('MemoryStorage', () => {
|
||||
|
||||
assert.equal(Object.keys(storage.data).length, 2);
|
||||
|
||||
assert.equal(storage.data['key'], undefined);
|
||||
assert.ok(storage.data['key2']);
|
||||
assert.ok(storage.data['key3']);
|
||||
assert.equal(storage.data.key, undefined);
|
||||
assert.ok(storage.data.key2);
|
||||
assert.ok(storage.data.key3);
|
||||
});
|
||||
|
||||
it('tests maxEntries with cleanup', async () => {
|
||||
@ -200,10 +200,10 @@ describe('MemoryStorage', () => {
|
||||
});
|
||||
|
||||
assert.equal(Object.keys(storage.data).length, 3);
|
||||
assert.ok(storage.data['exp']);
|
||||
assert.ok(storage.data.exp);
|
||||
assert.ok(storage.data['not exp']);
|
||||
assert.ok(storage.data['exp2']);
|
||||
assert.equal(storage.data['key'], undefined);
|
||||
assert.ok(storage.data.exp2);
|
||||
assert.equal(storage.data.key, undefined);
|
||||
|
||||
await storage.set('key', {
|
||||
state: 'cached',
|
||||
@ -214,9 +214,9 @@ describe('MemoryStorage', () => {
|
||||
|
||||
assert.equal(Object.keys(storage.data).length, 2);
|
||||
|
||||
assert.equal(storage.data['exp'], undefined);
|
||||
assert.equal(storage.data['exp2'], undefined);
|
||||
assert.equal(storage.data.exp, undefined);
|
||||
assert.equal(storage.data.exp2, undefined);
|
||||
assert.ok(storage.data['not exp']);
|
||||
assert.ok(storage.data['key']);
|
||||
assert.ok(storage.data.key);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Axios } from 'axios';
|
||||
import assert from 'node:assert';
|
||||
import { describe, it } from 'node:test';
|
||||
import { Axios } from 'axios';
|
||||
import { buildStorage, canStale, isStorage } from '../../src/storage/build';
|
||||
import { buildMemoryStorage } from '../../src/storage/memory';
|
||||
import type { AxiosStorage, StorageValue } from '../../src/storage/types';
|
||||
|
||||
@ -127,10 +127,7 @@ describe('CachePredicate', () => {
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
await testCachePredicate(
|
||||
response,
|
||||
({ data }) => data && data.a === true && data.b === 1
|
||||
)
|
||||
await testCachePredicate(response, ({ data }) => data && data.a === true && data.b === 1)
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
@ -224,10 +221,7 @@ describe('CachePredicate', () => {
|
||||
}
|
||||
},
|
||||
update: {
|
||||
id: (
|
||||
_,
|
||||
{ data: { a, b }, headers, status, statusText }
|
||||
): CachedStorageValue => {
|
||||
id: (_, { data: { a, b }, headers, status, statusText }): CachedStorageValue => {
|
||||
return {
|
||||
state: 'cached',
|
||||
ttl: Number.MAX_SAFE_INTEGER,
|
||||
|
||||
@ -101,10 +101,7 @@ describe('KeyGeneration', () => {
|
||||
];
|
||||
|
||||
for (const [first, second] of groups) {
|
||||
assert.equal(
|
||||
defaultKeyGenerator({ url: first }),
|
||||
defaultKeyGenerator({ url: second })
|
||||
);
|
||||
assert.equal(defaultKeyGenerator({ url: first }), defaultKeyGenerator({ url: second }));
|
||||
|
||||
assert.equal(
|
||||
defaultKeyGenerator({ baseURL: first }),
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { AxiosHeaders } from 'axios';
|
||||
import { mock } from 'node:test';
|
||||
import { AxiosHeaders } from 'axios';
|
||||
import type { CacheAxiosResponse } from '../src/cache/axios';
|
||||
|
||||
export const EMPTY_RESPONSE = Object.freeze({
|
||||
@ -9,9 +9,7 @@ export const EMPTY_RESPONSE = Object.freeze({
|
||||
data: true
|
||||
});
|
||||
|
||||
export function createResponse<R>(
|
||||
config: Partial<CacheAxiosResponse<R>>
|
||||
): CacheAxiosResponse {
|
||||
export function createResponse<R>(config: Partial<CacheAxiosResponse<R>>): CacheAxiosResponse {
|
||||
return {
|
||||
...EMPTY_RESPONSE,
|
||||
config: { headers: new AxiosHeaders() },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user