feat: correct ESM and CJS support, move to microbundle. (#764)

This commit is contained in:
Arthur Fiorette 2024-01-18 23:48:33 -03:00 committed by GitHub
parent 2ddd61e1b6
commit ed99d775bb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
52 changed files with 3563 additions and 1226 deletions

View File

@ -34,9 +34,6 @@ jobs:
- name: Build code - name: Build code
run: pnpm build run: pnpm build
- name: ESCheck
run: pnpm run check
- name: Publish to Codecov - name: Publish to Codecov
uses: codecov/codecov-action@v3 uses: codecov/codecov-action@v3
continue-on-error: true continue-on-error: true

59
build.sh Normal file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env bash
# This script is used to build the project.
# It is intended to be run from the project's root directory.
echo "Starting build..."
rm -rf dev/ dist/
mkdir dev/ dist/
echo "Target cleared..."
microbundle --define __ACI_DEV__=true -o dev/index.js --tsconfig tsconfig.build.json --generateTypes=false &
microbundle --define __ACI_DEV__=false -o dist/index.js --tsconfig tsconfig.build.json --generateTypes &
# Add a simple index.d.ts file to type all dev builds
echo "export * from '../dist/index.js';" | tee dev/index.d.ts \
dev/index.d.cts \
dev/index.modern.d.ts \
dev/index.module.d.ts \
dev/index.bundle.d.ts > /dev/null &
echo "export * from './index.js';" | tee dist/index.d.cts \
dist/index.modern.d.ts \
dist/index.module.d.ts \
dist/index.bundle.d.ts > /dev/null &
wait
# Creates a .d.mts copy of the .d.ts files with .mjs imports
find dist -name '*.d.ts' ! -name 'index.bundle.d.ts' -exec sh -c 'i="$1"; cp "$i" "${i%.ts}.mts"' shell {} \;
find dist -name '*.d.mts' -exec sed -i'.bak' -e "s/from '\(.*\)\.js'/from '\1.mjs'/" -e 's/import("\([a-z./-]*\)\.js")/import("\1.mjs")/g' {} \+
find dist -name '*.d.mts.bak' -delete
echo "Adding license to build files..."
# Get the version from package.json
VERSION=$(node -e "console.log(require('./package.json').version)")
# Text to prepend
HEADER="/*!
* Axios Cache Interceptor ${VERSION}
* (c) 2021-present Arthur Fiorette & Contributors
* Released under the MIT License.
*/
"
# Function to prepend text to files
prepend_header() {
find "$1" -type f \( -name '*.js' -o -name '*.d.ts' -o -name '*.d.mts' \) -print0 | while IFS= read -r -d '' file; do
printf "%s%s" "$HEADER" "$(cat "$file")" > "$file"
done
}
# Prepend header to files in 'dist' and 'dev' folders
prepend_header "dist"
prepend_header "dev"
echo "Build done!"

View File

@ -1,22 +0,0 @@
#!/usr/bin/env bash
# This script is used to build the project.
# It is intended to be run from the project's root directory.
echo "\nStarting build...\n"
rm -rf dev/ dist/
mkdir dev/ dist/
echo "Target cleared...\n"
tsc -p build/tsconfig.types.json &
webpack --config build/webpack.config.js &
# Add a simple index.d.ts file to type all dev builds
echo "export * from '../dist/index';" | tee dev/index.d.ts dev/index.bundle.d.ts > /dev/null &
echo "export * from './index';" | tee dist/index.bundle.d.ts > /dev/null &
wait
echo "\nBuild done!"

View File

@ -1,24 +0,0 @@
#!/usr/bin/env bash
# This script is used to check the umd's ecmascript compatibility.
# It is intended to be run from the project's root directory.
pnpm es-check es2017 dist/index.cjs dev/index.cjs
if [ $? -eq 1 ]; then
exit 1
fi
pnpm es-check es2017 dist/index.mjs dev/index.mjs --module
if [ $? -eq 1 ]; then
exit 1
fi
pnpm es-check es5 dist/index.bundle.js
if [ $? -eq 1 ]; then
exit 1
fi
# :)

View File

@ -1,20 +0,0 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
// webpack converts to UMD or CJS if needed
"module": "ESNext",
"target": "ESNext",
// Emits all import helpers as an import to tslib
// This allows webpack to be better at tree shaking
"importHelpers": true,
// No declaration
"declaration": false,
"declarationMap": false,
// This allow us to import javascript files from node_modules.
"allowJs": true
},
"include": ["../src"]
}

View File

@ -1,10 +0,0 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"emitDeclarationOnly": true,
"outDir": "../dist",
"declaration": true,
"declarationMap": true
},
"include": ["../src"]
}

View File

@ -1,159 +0,0 @@
const path = require('path');
const TerserWebpackPlugin = require('terser-webpack-plugin');
const { DefinePlugin } = require('webpack');
const { version } = require('../package.json');
const COPYRIGHT = `
/*!
* Axios Cache Interceptor v${version}
* (c) 2021-present Arthur Fiorette & Contributors
* Released under the MIT License.
*/
`.trim();
/** @type {(...args: string[]) => string} */
const root = (...p) => path.resolve(__dirname, '..', ...p);
/**
* @param {{
* output: string;
* esTarget?: string;
* libraryType: import('webpack').LibraryOptions['type'];
* libraryName?: import('webpack').LibraryOptions['name'];
* inlineDeps?: boolean;
* devBuild?: boolean;
* }} options
* @returns {import('webpack').Configuration}
*/
const config = ({
output,
esTarget = 'es2017',
libraryType,
libraryName,
inlineDeps = false,
devBuild = false
}) => ({
mode: 'production',
entry: root('src', 'index.ts'),
output: {
path: root(),
globalObject: `typeof self !== 'undefined' ? self : this`,
filename: output,
sourceMapFilename: output + '.map',
chunkFormat: 'module',
module: libraryType === 'module',
library: {
type: libraryType,
name: libraryName
}
},
target: esTarget,
devtool: devBuild ? 'source-map' : false,
experiments: { outputModule: true },
resolve: { extensions: ['.ts', '.js'] },
externals: inlineDeps
? {
'cache-parser': 'cache-parser',
'object-code': 'object-code',
'fast-defer': 'fast-defer'
}
: undefined,
module: {
rules: [
{
// Include node_modules to parse all javascript files imported
include: /src|node_modules/,
test: /\.(ts|js)$/,
loader: 'ts-loader',
options: {
configFile: root('build', 'tsconfig.build.json'),
compilerOptions: {
target: esTarget
}
}
}
]
},
optimization: {
minimize: true,
sideEffects: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
concatenateModules: true,
minimizer: [new TerserWebpackPlugin({ parallel: true })]
},
plugins: [
// Chooses the right environment
new DefinePlugin({ __ACI_DEV__: devBuild }),
// Add a banner to the top of each file
{
apply: (compiler) => {
compiler.hooks.emit.tapAsync('FileListPlugin', (comp, cb) => {
for (const chunk of comp.chunks) {
for (const filename of chunk.files) {
const assets = comp.assets[filename];
// @ts-expect-error - _value is not a public property
assets._value = COPYRIGHT + '\n' + assets._value;
}
}
cb();
});
}
}
]
});
module.exports = [
// ESModule
config({
output: 'dist/index.mjs',
libraryType: 'module',
inlineDeps: true
}),
config({
output: 'dev/index.mjs',
libraryType: 'module',
inlineDeps: true,
devBuild: true
}),
// CommonJS
config({
output: 'dist/index.cjs',
libraryType: 'commonjs2',
inlineDeps: true
}),
config({
output: 'dev/index.cjs',
libraryType: 'commonjs2',
inlineDeps: true,
devBuild: true
}),
// Browser Bundle
config({
// Uses ES5 for UMD builds to support more browsers
esTarget: 'es5',
output: 'dist/index.bundle.js',
libraryType: 'umd',
libraryName: 'AxiosCacheInterceptor'
}),
config({
output: 'dev/index.bundle.js',
libraryType: 'umd',
libraryName: 'AxiosCacheInterceptor',
devBuild: true
})
];

View File

@ -18,16 +18,16 @@
"license": "MIT", "license": "MIT",
"author": "Arthur Fiorette <npm@arthur.place>", "author": "Arthur Fiorette <npm@arthur.place>",
"sideEffects": false, "sideEffects": false,
"type": "module",
"source": "./src/index.ts",
"exports": { "exports": {
".": { ".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs", "require": "./dist/index.cjs",
"types": "./dist/index.d.ts" "default": "./dist/index.modern.js"
}, },
"./dev": { "./dev": {
"import": "./dev/index.mjs",
"require": "./dev/index.cjs", "require": "./dev/index.cjs",
"types": "./dist/index.d.ts" "default": "./dev/index.modern.js"
}, },
"./package.json": "./package.json", "./package.json": "./package.json",
"./*": "./*" "./*": "./*"
@ -39,13 +39,12 @@
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"scripts": { "scripts": {
"benchmark": "cd benchmark && pnpm start", "benchmark": "cd benchmark && pnpm start",
"build": "sh build/build.sh", "build": "bash build.sh",
"check": "sh build/check.sh",
"docs:build": "vitepress build docs", "docs:build": "vitepress build docs",
"docs:dev": "vitepress dev docs --port 1227", "docs:dev": "vitepress dev docs --port 1227",
"docs:serve": "vitepress serve docs", "docs:serve": "vitepress serve docs",
"test": "c8 --reporter lcov --reporter text node --trace-warnings -r @swc-node/register -r ./test/setup --enable-source-maps --trace-warnings --test test/**/*.test.ts", "test": "c8 --reporter lcov --reporter text node --import ./test/setup.js --enable-source-maps --test test/**/*.test.ts",
"test:only": "c8 --reporter lcov --reporter text node --trace-warnings -r @swc-node/register -r ./test/setup --enable-source-maps --trace-warnings --test-only", "test:only": "c8 --reporter lcov --reporter text node --import ./test/setup.js --enable-source-maps --test-only",
"version": "auto-changelog -p && cp CHANGELOG.md docs/src/others/changelog.md && git add CHANGELOG.md docs/src/others/changelog.md", "version": "auto-changelog -p && cp CHANGELOG.md docs/src/others/changelog.md && git add CHANGELOG.md docs/src/others/changelog.md",
"format": "biome format --write .", "format": "biome format --write .",
"lint": "biome check .", "lint": "biome check .",
@ -65,19 +64,15 @@
"@swc-node/register": "1.6.8", "@swc-node/register": "1.6.8",
"@swc/helpers": "0.5.3", "@swc/helpers": "0.5.3",
"@types/jsdom": "21.1.6", "@types/jsdom": "21.1.6",
"@types/node": "20.10.4", "@types/node": "20.11.5",
"@types/webpack": "5.28.5",
"auto-changelog": "2.4.0", "auto-changelog": "2.4.0",
"axios": "1.6.5", "axios": "1.6.5",
"c8": "9.1.0", "c8": "9.1.0",
"es-check": "7.1.1",
"jsdom": "23.2.0", "jsdom": "23.2.0",
"ts-loader": "9.5.1", "microbundle": "^0.15.1",
"tslib": "2.6.2", "tslib": "2.6.2",
"typescript": "5.3.3", "typescript": "5.3.3",
"vitepress": "1.0.0-rc.39", "vitepress": "1.0.0-rc.39"
"webpack": "5.89.0",
"webpack-cli": "5.1.4"
}, },
"peerDependencies": { "peerDependencies": {
"axios": "^1" "axios": "^1"

4156
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

2
src/cache/axios.ts vendored
View File

@ -6,7 +6,7 @@ import type {
AxiosResponseHeaders, AxiosResponseHeaders,
InternalAxiosRequestConfig InternalAxiosRequestConfig
} from 'axios'; } from 'axios';
import type { CacheInstance, CacheProperties } from './cache'; import type { CacheInstance, CacheProperties } from './cache.js';
/** /**
* A slightly changed than the original axios response. Containing information about the * A slightly changed than the original axios response. Containing information about the

10
src/cache/cache.ts vendored
View File

@ -1,21 +1,21 @@
import type { Method } from 'axios'; import type { Method } from 'axios';
import type { Deferred } from 'fast-defer'; import type { Deferred } from 'fast-defer';
import type { HeaderInterpreter } from '../header/types'; import type { HeaderInterpreter } from '../header/types.js';
import type { AxiosInterceptor } from '../interceptors/build'; import type { AxiosInterceptor } from '../interceptors/build.js';
import type { import type {
AxiosStorage, AxiosStorage,
CachedResponse, CachedResponse,
CachedStorageValue, CachedStorageValue,
LoadingStorageValue, LoadingStorageValue,
StaleStorageValue StaleStorageValue
} from '../storage/types'; } from '../storage/types.js';
import type { import type {
CachePredicate, CachePredicate,
CacheUpdater, CacheUpdater,
KeyGenerator, KeyGenerator,
StaleIfErrorPredicate StaleIfErrorPredicate
} from '../util/types'; } from '../util/types.js';
import type { CacheAxiosResponse, CacheRequestConfig } from './axios'; import type { CacheAxiosResponse, CacheRequestConfig } from './axios.js';
/** /**
* @template R The type returned by this response * @template R The type returned by this response

20
src/cache/create.ts vendored
View File

@ -1,12 +1,12 @@
import type { Axios } from 'axios'; import type { AxiosInstance } from 'axios';
import { defaultHeaderInterpreter } from '../header/interpreter'; import { defaultHeaderInterpreter } from '../header/interpreter.js';
import { defaultRequestInterceptor } from '../interceptors/request'; import { defaultRequestInterceptor } from '../interceptors/request.js';
import { defaultResponseInterceptor } from '../interceptors/response'; import { defaultResponseInterceptor } from '../interceptors/response.js';
import { isStorage } from '../storage/build'; import { isStorage } from '../storage/build.js';
import { buildMemoryStorage } from '../storage/memory'; import { buildMemoryStorage } from '../storage/memory.js';
import { defaultKeyGenerator } from '../util/key-generator'; import { defaultKeyGenerator } from '../util/key-generator.js';
import type { AxiosCacheInstance } from './axios'; import type { AxiosCacheInstance } from './axios.js';
import type { CacheInstance, CacheProperties } from './cache'; import type { CacheInstance, CacheProperties } from './cache.js';
export interface CacheOptions extends Partial<CacheInstance>, Partial<CacheProperties> {} export interface CacheOptions extends Partial<CacheInstance>, Partial<CacheProperties> {}
@ -26,7 +26,7 @@ export interface CacheOptions extends Partial<CacheInstance>, Partial<CachePrope
* @returns The same instance with extended typescript types. * @returns The same instance with extended typescript types.
* @see https://axios-cache-interceptor.js.org/config * @see https://axios-cache-interceptor.js.org/config
*/ */
export function setupCache(axios: Axios, options: CacheOptions = {}): AxiosCacheInstance { export function setupCache(axios: AxiosInstance, options: CacheOptions = {}): AxiosCacheInstance {
const axiosCache = axios as AxiosCacheInstance; const axiosCache = axios as AxiosCacheInstance;
if (axiosCache.defaults.cache) { if (axiosCache.defaults.cache) {

View File

@ -1,6 +1,6 @@
import { parse } from 'cache-parser'; import { parse } from 'cache-parser';
import { Header } from './headers'; import { Header } from './headers.js';
import type { HeaderInterpreter } from './types'; import type { HeaderInterpreter } from './types.js';
export const defaultHeaderInterpreter: HeaderInterpreter = (headers) => { export const defaultHeaderInterpreter: HeaderInterpreter = (headers) => {
if (!headers) return 'not enough headers'; if (!headers) return 'not enough headers';

View File

@ -1,4 +1,4 @@
import type { CacheAxiosResponse } from '../cache/axios'; import type { CacheAxiosResponse } from '../cache/axios.js';
/** /**
* The possible values are: * The possible values are:

View File

@ -1,21 +1,21 @@
export * from './cache/axios'; export * from './cache/axios.js';
export * from './cache/cache'; export * from './cache/cache.js';
export * from './cache/create'; export * from './cache/create.js';
export * from './header/headers'; export * from './header/headers.js';
export * from './header/interpreter'; export * from './header/interpreter.js';
export * from './header/types'; export * from './header/types.js';
export * from './interceptors/build'; export * from './interceptors/build.js';
export * from './interceptors/request'; export * from './interceptors/request.js';
export * from './interceptors/response'; export * from './interceptors/response.js';
export * from './interceptors/util'; export * from './interceptors/util.js';
export * from './storage/build'; export * from './storage/build.js';
export * from './storage/memory'; export * from './storage/memory.js';
export * from './storage/types'; export * from './storage/types.js';
export * from './storage/web-api'; export * from './storage/web-api.js';
export * from './util/cache-predicate'; export * from './util/cache-predicate.js';
export * from './util/key-generator'; export * from './util/key-generator.js';
export * from './util/types'; export * from './util/types.js';
export * from './util/update-cache'; export * from './util/update-cache.js';
/** @internal */ /** @internal */
declare global { declare global {

View File

@ -1,4 +1,4 @@
import type { CacheAxiosResponse, InternalCacheRequestConfig } from '../cache/axios'; import type { CacheAxiosResponse, InternalCacheRequestConfig } from '../cache/axios.js';
/** See {@link AxiosInterceptorManager} */ /** See {@link AxiosInterceptorManager} */
export interface AxiosInterceptor<T> { export interface AxiosInterceptor<T> {

View File

@ -1,9 +1,14 @@
import { deferred } from 'fast-defer'; import { deferred } from 'fast-defer';
import type { AxiosCacheInstance, CacheAxiosResponse } from '../cache/axios'; import type { AxiosCacheInstance, CacheAxiosResponse } from '../cache/axios.js';
import { Header } from '../header/headers'; import { Header } from '../header/headers.js';
import type { CachedResponse, CachedStorageValue, LoadingStorageValue } from '../storage/types'; import type { CachedResponse, CachedStorageValue, LoadingStorageValue } from '../storage/types.js';
import type { RequestInterceptor } from './build'; import type { RequestInterceptor } from './build.js';
import { ConfigWithCache, createValidateStatus, isMethodIn, updateStaleRequest } from './util'; import {
type ConfigWithCache,
createValidateStatus,
isMethodIn,
updateStaleRequest
} from './util.js';
export function defaultRequestInterceptor(axios: AxiosCacheInstance) { export function defaultRequestInterceptor(axios: AxiosCacheInstance) {
const onFulfilled: RequestInterceptor['onFulfilled'] = async (config) => { const onFulfilled: RequestInterceptor['onFulfilled'] = async (config) => {

View File

@ -1,13 +1,13 @@
import type { AxiosResponseHeaders } from 'axios'; import type { AxiosResponseHeaders } from 'axios';
import { parse } from 'cache-parser'; import { parse } from 'cache-parser';
import type { AxiosCacheInstance, CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; import type { AxiosCacheInstance, CacheAxiosResponse, CacheRequestConfig } from '../cache/axios.js';
import type { CacheProperties } from '../cache/cache'; import type { CacheProperties } from '../cache/cache.js';
import { Header } from '../header/headers'; import { Header } from '../header/headers.js';
import type { CachedStorageValue } from '../storage/types'; import type { CachedStorageValue } from '../storage/types.js';
import { testCachePredicate } from '../util/cache-predicate'; import { testCachePredicate } from '../util/cache-predicate.js';
import { updateCache } from '../util/update-cache'; import { updateCache } from '../util/update-cache.js';
import type { ResponseInterceptor } from './build'; import type { ResponseInterceptor } from './build.js';
import { createCacheResponse, isMethodIn } from './util'; import { createCacheResponse, isMethodIn } from './util.js';
export function defaultResponseInterceptor(axios: AxiosCacheInstance): ResponseInterceptor { export function defaultResponseInterceptor(axios: AxiosCacheInstance): ResponseInterceptor {
/** /**

View File

@ -1,8 +1,8 @@
import type { Method } from 'axios'; import type { Method } from 'axios';
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios.js';
import type { CacheProperties } from '../cache/cache'; import type { CacheProperties } from '../cache/cache.js';
import { Header } from '../header/headers'; import { Header } from '../header/headers.js';
import type { CachedResponse, StaleStorageValue } from '../storage/types'; import type { CachedResponse, StaleStorageValue } from '../storage/types.js';
/** /**
* Creates a new validateStatus function that will use the one already used and also * Creates a new validateStatus function that will use the one already used and also

View File

@ -1,7 +1,7 @@
import type { CacheRequestConfig } from '../cache/axios'; import type { CacheRequestConfig } from '../cache/axios.js';
import { Header } from '../header/headers'; import { Header } from '../header/headers.js';
import type { MaybePromise } from '../util/types'; import type { MaybePromise } from '../util/types.js';
import type { AxiosStorage, CachedStorageValue, StaleStorageValue, StorageValue } from './types'; import type { AxiosStorage, CachedStorageValue, StaleStorageValue, StorageValue } from './types.js';
/** Returns true if the provided object was created from {@link buildStorage} function. */ /** Returns true if the provided object was created from {@link buildStorage} function. */
export const isStorage = (obj: unknown): obj is AxiosStorage => export const isStorage = (obj: unknown): obj is AxiosStorage =>

View File

@ -1,5 +1,5 @@
import { buildStorage, canStale, isExpired } from './build'; import { buildStorage, canStale, isExpired } from './build.js';
import type { AxiosStorage, NotEmptyStorageValue, StorageValue } from './types'; import type { AxiosStorage, NotEmptyStorageValue, StorageValue } from './types.js';
/** /**
* Modern function to natively deep clone. * Modern function to natively deep clone.

View File

@ -1,5 +1,5 @@
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios.js';
import type { MaybePromise } from '../util/types'; import type { MaybePromise } from '../util/types.js';
export interface CachedResponse { export interface CachedResponse {
data?: unknown; data?: unknown;

View File

@ -1,5 +1,5 @@
import { buildStorage, canStale, isExpired } from './build'; import { buildStorage, canStale, isExpired } from './build.js';
import type { StorageValue } from './types'; import type { StorageValue } from './types.js';
/** /**
* Creates a simple storage. You can persist his data by using `sessionStorage` or * Creates a simple storage. You can persist his data by using `sessionStorage` or

View File

@ -1,6 +1,6 @@
import type { CacheAxiosResponse } from '../cache/axios'; import type { CacheAxiosResponse } from '../cache/axios.js';
import type { CachePredicate, CachePredicateObject } from './types'; import type { CachePredicate, CachePredicateObject } from './types.js';
/** Tests an response against a {@link CachePredicateObject}. */ /** Tests an response against a {@link CachePredicateObject}. */
export async function testCachePredicate<R = unknown, D = unknown>( export async function testCachePredicate<R = unknown, D = unknown>(

View File

@ -1,7 +1,7 @@
import type { Method } from 'axios'; import type { Method } from 'axios';
import { hash } from 'object-code'; import { hash } from 'object-code';
import type { CacheRequestConfig } from '../cache/axios'; import type { CacheRequestConfig } from '../cache/axios.js';
import type { KeyGenerator } from './types'; import type { KeyGenerator } from './types.js';
// Remove first and last '/' char, if present // Remove first and last '/' char, if present
const SLASHES_REGEX = /^\/|\/$/g; const SLASHES_REGEX = /^\/|\/$/g;

View File

@ -1,5 +1,5 @@
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios'; import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios.js';
import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types'; import type { CachedStorageValue, LoadingStorageValue, StorageValue } from '../storage/types.js';
export type CachePredicate<R = unknown, D = unknown> = NonNullable< export type CachePredicate<R = unknown, D = unknown> = NonNullable<
CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch'] CachePredicateObject<R, D> | CachePredicateObject<R, D>['responseMatch']

View File

@ -1,6 +1,6 @@
import type { CacheAxiosResponse } from '../cache/axios'; import type { CacheAxiosResponse } from '../cache/axios.js';
import type { AxiosStorage } from '../storage/types'; import type { AxiosStorage } from '../storage/types.js';
import type { CacheUpdater } from './types'; import type { CacheUpdater } from './types.js';
/** Function to update all caches, from CacheProperties.update, with the new data. */ /** Function to update all caches, from CacheProperties.update, with the new data. */
export async function updateCache<R, D>( export async function updateCache<R, D>(

View File

@ -1,7 +1,7 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it, mock } from 'node:test'; import { describe, it, mock } from 'node:test';
import Axios from 'axios'; import Axios from 'axios';
import { setupCache } from '../../src/cache/create'; import { setupCache } from '../../src/cache/create.js';
describe('Axios Cache Interceptor instances', () => { describe('Axios Cache Interceptor instances', () => {
it('Argument composition', () => { it('Argument composition', () => {
@ -21,7 +21,7 @@ describe('Axios Cache Interceptor instances', () => {
assert.throws(() => setupCache(axios)); assert.throws(() => setupCache(axios));
}); });
it('Importing with __ACI_DEV__ true prints console warning', () => { it('Importing with __ACI_DEV__ true prints console warning', async () => {
assert.ok(__ACI_DEV__); assert.ok(__ACI_DEV__);
const oldLog = console.error; const oldLog = console.error;
@ -29,7 +29,7 @@ describe('Axios Cache Interceptor instances', () => {
const consoleMock = mock.fn(); const consoleMock = mock.fn();
console.error = consoleMock; console.error = consoleMock;
require('../../src/index'); await import('../../src/index.js');
assert.equal(consoleMock.mock.callCount(), 1); assert.equal(consoleMock.mock.callCount(), 1);

View File

@ -1,7 +1,7 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { defaultHeaderInterpreter } from '../../src/header/interpreter'; import { defaultHeaderInterpreter } from '../../src/header/interpreter.js';
describe('Cache-Control HTTP Header', () => { describe('Cache-Control HTTP Header', () => {
it('Cache preventing headers', () => { it('Cache preventing headers', () => {

View File

@ -1,7 +1,7 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { defaultHeaderInterpreter } from '../../src/header/interpreter'; import { defaultHeaderInterpreter } from '../../src/header/interpreter.js';
describe('Expires HTTP Header', () => { describe('Expires HTTP Header', () => {
it('Future Expires', () => { it('Future Expires', () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { defaultHeaderInterpreter } from '../../src/header/interpreter'; import { defaultHeaderInterpreter } from '../../src/header/interpreter.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
describe('Header Interpreter', () => { describe('Header Interpreter', () => {
it('Without CacheControl HTTP Header', () => { it('Without CacheControl HTTP Header', () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { mockDateNow } from '../utils'; import { mockDateNow } from '../utils.js';
describe('ETag handling', () => { describe('ETag handling', () => {
it('Etag Header', async () => { it('Etag Header', async () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it, mock } from 'node:test'; import { describe, it, mock } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { mockDateNow } from '../utils'; import { mockDateNow } from '../utils.js';
describe('Hydrate handling', () => { describe('Hydrate handling', () => {
it('Hydrate is only called when a cache exists', async () => { it('Hydrate is only called when a cache exists', async () => {

View File

@ -1,9 +1,9 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import type { CacheRequestConfig } from '../../src'; import type { CacheRequestConfig } from '../../src/cache/axios.js';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { XMockRandom, mockAxios } from '../mocks/axios'; import { XMockRandom, mockAxios } from '../mocks/axios.js';
import { mockDateNow } from '../utils'; import { mockDateNow } from '../utils.js';
describe('LastModified handling', () => { describe('LastModified handling', () => {
it('Last modified header handling', async () => { it('Last modified header handling', async () => {

View File

@ -2,11 +2,11 @@ import assert from 'node:assert';
import { describe, it, mock } from 'node:test'; import { describe, it, mock } from 'node:test';
import type { AxiosAdapter, AxiosResponse } from 'axios'; import type { AxiosAdapter, AxiosResponse } from 'axios';
import { setTimeout } from 'timers/promises'; import { setTimeout } from 'timers/promises';
import type { CacheRequestConfig, InternalCacheRequestConfig } from '../../src/cache/axios'; import type { CacheRequestConfig, InternalCacheRequestConfig } from '../../src/cache/axios.js';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import type { LoadingStorageValue } from '../../src/storage/types'; import type { LoadingStorageValue } from '../../src/storage/types.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { mockDateNow } from '../utils'; import { mockDateNow } from '../utils.js';
describe('Request Interceptor', () => { describe('Request Interceptor', () => {
it('Against specified methods', async () => { it('Against specified methods', async () => {

View File

@ -2,9 +2,9 @@ import assert from 'node:assert';
import { describe, it, mock } from 'node:test'; import { describe, it, mock } from 'node:test';
import { setImmediate } from 'node:timers/promises'; import { setImmediate } from 'node:timers/promises';
import Axios from 'axios'; import Axios from 'axios';
import { setupCache } from '../../src/cache/create'; import { setupCache } from '../../src/cache/create.js';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { XMockRandom, mockAxios } from '../mocks/axios'; import { XMockRandom, mockAxios } from '../mocks/axios.js';
describe('Response Interceptor', () => { describe('Response Interceptor', () => {
it('`storage.get` call without specified methods', async () => { it('`storage.get` call without specified methods', async () => {

View File

@ -1,10 +1,10 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import Axios, { AxiosError } from 'axios'; import Axios, { AxiosError } from 'axios';
import { setupCache } from '../../src/cache/create'; import { setupCache } from '../../src/cache/create.js';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { mockDateNow } from '../utils'; import { mockDateNow } from '../utils.js';
describe('StaleIfError handling', () => { describe('StaleIfError handling', () => {
it('Handles thrown errors', async () => { it('Handles thrown errors', async () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import Axios from 'axios'; import Axios from 'axios';
import { createValidateStatus, isMethodIn } from '../../src/interceptors/util'; import { createValidateStatus, isMethodIn } from '../../src/interceptors/util.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
describe('Util Functions', () => { describe('Util Functions', () => {
it('validateStatus function', () => { it('validateStatus function', () => {

View File

@ -1,8 +1,8 @@
import { setTimeout } from 'node:timers/promises'; import { setTimeout } from 'node:timers/promises';
import Axios, { AxiosError } from 'axios'; import Axios, { AxiosError } from 'axios';
import type { AxiosCacheInstance } from '../../src/cache/axios'; import type { AxiosCacheInstance } from '../../src/cache/axios.js';
import { CacheOptions, setupCache } from '../../src/cache/create'; import { type CacheOptions, setupCache } from '../../src/cache/create.js';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
export const XMockRandom = 'x-mock-random'; export const XMockRandom = 'x-mock-random';

7
test/setup.js Normal file
View File

@ -0,0 +1,7 @@
// @ts-expect-error __ACI_DEV__ is declared as const
global.__ACI_DEV__ = true;
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';
register('@swc-node/register/esm', pathToFileURL('./'));

View File

@ -1,2 +0,0 @@
// @ts-expect-error __ACI_DEV__ is declared as const
global.__ACI_DEV__ = true;

View File

@ -1,10 +1,10 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Header } from '../../src/header/headers'; import { Header } from '../../src/header/headers.js';
import { buildMemoryStorage } from '../../src/storage/memory'; import { buildMemoryStorage } from '../../src/storage/memory.js';
import type { CachedStorageValue } from '../../src/storage/types'; import type { CachedStorageValue } from '../../src/storage/types.js';
import { EMPTY_RESPONSE, mockDateNow } from '../utils'; import { EMPTY_RESPONSE, mockDateNow } from '../utils.js';
import { testStorage } from './storages'; import { testStorage } from './storages.js';
describe('MemoryStorage', () => { describe('MemoryStorage', () => {
testStorage('MemoryStorage', buildMemoryStorage()); testStorage('MemoryStorage', buildMemoryStorage());

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { it } from 'node:test'; import { it } from 'node:test';
import { buildWebStorage } from '../../src/storage/web-api'; import { buildWebStorage } from '../../src/storage/web-api.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { EMPTY_RESPONSE } from '../utils'; import { EMPTY_RESPONSE } from '../utils.js';
const MAXIMUM_LIMIT = 5_000_000; const MAXIMUM_LIMIT = 5_000_000;

View File

@ -1,12 +1,12 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { Axios } from 'axios'; import { Axios } from 'axios';
import { buildStorage, canStale, isStorage } from '../../src/storage/build'; import { buildStorage, canStale, isStorage } from '../../src/storage/build.js';
import { buildMemoryStorage } from '../../src/storage/memory'; import { buildMemoryStorage } from '../../src/storage/memory.js';
import type { AxiosStorage, StorageValue } from '../../src/storage/types'; import type { AxiosStorage, StorageValue } from '../../src/storage/types.js';
import { buildWebStorage } from '../../src/storage/web-api'; import { buildWebStorage } from '../../src/storage/web-api.js';
import { localStorage } from '../dom'; import { localStorage } from '../dom.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
describe('General storage functions', () => { describe('General storage functions', () => {
it('isStorage() function', () => { it('isStorage() function', () => {

View File

@ -1,7 +1,7 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { it } from 'node:test'; import { it } from 'node:test';
import type { AxiosStorage } from '../../src/storage/types'; import type { AxiosStorage } from '../../src/storage/types.js';
import { EMPTY_RESPONSE, mockDateNow } from '../utils'; import { EMPTY_RESPONSE, mockDateNow } from '../utils.js';
export function testStorage(name: string, storage: AxiosStorage): void { export function testStorage(name: string, storage: AxiosStorage): void {
it(`${name} storage methods`, async () => { it(`${name} storage methods`, async () => {

View File

@ -1,10 +1,10 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { afterEach, describe, it } from 'node:test'; import { afterEach, describe, it } from 'node:test';
import { buildWebStorage } from '../../src/storage/web-api'; import { buildWebStorage } from '../../src/storage/web-api.js';
import { localStorage, sessionStorage } from '../dom'; import { localStorage, sessionStorage } from '../dom.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { testStorageQuota } from './quota'; import { testStorageQuota } from './quota.js';
import { testStorage } from './storages'; import { testStorage } from './storages.js';
describe('Web Storages', () => { describe('Web Storages', () => {
afterEach(() => { afterEach(() => {

View File

@ -1,10 +1,10 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import { setImmediate } from 'node:timers/promises'; import { setImmediate } from 'node:timers/promises';
import type { CachedStorageValue } from '../../src/storage/types'; import type { CachedStorageValue } from '../../src/storage/types.js';
import { testCachePredicate } from '../../src/util/cache-predicate'; import { testCachePredicate } from '../../src/util/cache-predicate.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
import { createResponse } from '../utils'; import { createResponse } from '../utils.js';
describe('CachePredicate', () => { describe('CachePredicate', () => {
it('Empty usage', () => { it('Empty usage', () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it } from 'node:test'; import { describe, it } from 'node:test';
import type { CacheRequestConfig } from '../../src/cache/axios'; import type { CacheRequestConfig } from '../../src/cache/axios.js';
import { buildKeyGenerator, defaultKeyGenerator } from '../../src/util/key-generator'; import { buildKeyGenerator, defaultKeyGenerator } from '../../src/util/key-generator.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
describe('KeyGeneration', () => { describe('KeyGeneration', () => {
it('Generates different key for and id', () => { it('Generates different key for and id', () => {

View File

@ -1,8 +1,8 @@
import assert from 'node:assert'; import assert from 'node:assert';
import { describe, it, mock } from 'node:test'; import { describe, it, mock } from 'node:test';
import type { CachedStorageValue } from '../../src/storage/types'; import type { CachedStorageValue } from '../../src/storage/types.js';
import { defaultKeyGenerator } from '../../src/util/key-generator'; import { defaultKeyGenerator } from '../../src/util/key-generator.js';
import { mockAxios } from '../mocks/axios'; import { mockAxios } from '../mocks/axios.js';
const CACHE_KEY = defaultKeyGenerator({ url: 'https://example.com/' }); const CACHE_KEY = defaultKeyGenerator({ url: 'https://example.com/' });
const CACHED_VALUE: CachedStorageValue = Object.freeze({ const CACHED_VALUE: CachedStorageValue = Object.freeze({

View File

@ -1,6 +1,6 @@
import { mock } from 'node:test'; import { mock } from 'node:test';
import { AxiosHeaders } from 'axios'; import { AxiosHeaders } from 'axios';
import type { CacheAxiosResponse } from '../src/cache/axios'; import type { CacheAxiosResponse } from '../src/cache/axios.js';
export const EMPTY_RESPONSE = Object.freeze({ export const EMPTY_RESPONSE = Object.freeze({
headers: {}, headers: {},

4
tsconfig.build.json Normal file
View File

@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["src"]
}

View File

@ -2,21 +2,22 @@
"compilerOptions": { "compilerOptions": {
"incremental": true, "incremental": true,
"target": "ESNext", "target": "ESNext",
"module": "ESNext", "module": "NodeNext",
"moduleResolution": "node", "moduleResolution": "NodeNext",
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"outDir": "./dist", "outDir": "./dist",
"newLine": "lf", "newLine": "lf",
"stripInternal": true, "stripInternal": true,
"isolatedModules": true, "isolatedModules": true,
"verbatimModuleSyntax": false, "verbatimModuleSyntax": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"esModuleInterop": true, "esModuleInterop": true,
"preserveSymlinks": true, "preserveSymlinks": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,
"noImplicitAny": true, "noImplicitAny": true,
"noEmit": true,
"strictNullChecks": true, "strictNullChecks": true,
"strictFunctionTypes": true, "strictFunctionTypes": true,
"strictBindCallApply": true, "strictBindCallApply": true,