Skip to content

Commit 751c212

Browse files
authored
V3.0.0 (#111)
v3.0.0: - deprecated `skipWhileRefresh` - renamed `skipWhileRefresh` flag to `pauseInstanceWhileRefreshing` - changed default behavior of `pauseInstanceWhileRefreshing`
1 parent 92bdabb commit 751c212

File tree

6 files changed

+70
-25
lines changed

6 files changed

+70
-25
lines changed

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ In order to activate the interceptors, you need to import a function from `axios
4949
which is *exported by default* and call it with the **axios instance** you want the interceptors for,
5050
as well as the **refresh authorization function** where you need to write the logic for refreshing the authorization.
5151

52-
The interceptors will then be bound onto the axios instance and the specified logic will be run whenever a [401 (Unauthorized)](https://httpstatuses.com/401) status code
52+
The interceptors will then be bound onto the axios instance, and the specified logic will be run whenever a [401 (Unauthorized)](https://httpstatuses.com/401) status code
5353
is returned from a server (or any other status code you provide in options). All the new requests created while the refreshAuthLogic has been processing will be bound onto the
5454
Promise returned from the refreshAuthLogic function. This means that the requests will be resolved when a new access token has been fetched or when the refreshing logic faleid.
5555

@@ -144,17 +144,22 @@ stalled request is called with the request configuration object.
144144
}
145145
```
146146

147-
#### Unpause the instance while refreshing
147+
#### Pause the instance while "refresh logic" is running
148148

149-
While your refresh logic is ran, the instance is marked as "to-be-skipped"
150-
in order to prevent the "interceptors loop" when refreshing causes one of the statuses specified
151-
in `options.statusCodes`. If that's behavior is not wanted, you can set the `skipWhileRefreshing` option to false,
152-
but keep in mind that you need to implement skipping the requests by yourself using `skipAuthRefresh` flag
153-
in request's configuration
149+
While your refresh logic is running, the interceptor will be triggered for every request
150+
which returns one of the `options.statusCodes` specified (HTTP 401 by default).
151+
152+
In order to prevent the interceptors loop (when your refresh logic fails with any of the status
153+
codes specified in `options.statusCodes`) you need to use a [`skipAuthRefresh`](#skipping-the-interceptor)
154+
flag on your refreshing call inside the `refreshAuthLogic` function.
155+
156+
In case your refresh logic does not make any calls, you should consider using the following flag
157+
when initializing the interceptor to pause the whole axios instance while the refreshing is pending.
158+
This prevents interceptor from running for each failed request.
154159

155160
```javascript
156161
{
157-
skipWhileRefreshing: false // default: true
162+
pauseInstanceWhileRefreshing: true // default: false
158163
}
159164
```
160165

@@ -168,6 +173,14 @@ have you used it for something else? Create a PR with your use case to share it.
168173

169174
---
170175

176+
### Changelog
177+
178+
- **v3.0.0**
179+
- `skipWhileRefresh` flag has been deprecated due to its unclear name and its logic has been moved to `pauseInstanceWhileRefreshing` flag
180+
- `pauseInstanceWhileRefreshing` is set to `false` by default
181+
182+
---
183+
171184
#### Want to help?
172185
Check out [contribution guide](CONTRIBUTING.md) or my [patreon page!](https://www.patreon.com/dawidzbinski)
173186

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "axios-auth-refresh",
3-
"version": "2.2.8",
3+
"version": "3.0.0",
44
"description": "Axios plugin which makes it very easy to automatically refresh the authorization tokens of your clients",
55
"keywords": [
66
"axios",

src/__tests__/index.spec.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@ describe('Merges configs', () => {
7777
});
7878
});
7979

80-
describe('Uses options correctly', () => {
81-
82-
});
83-
8480
describe('Determines if the response should be intercepted', () => {
8581

8682
let cache: AxiosAuthRefreshCache = undefined;
@@ -133,6 +129,30 @@ describe('Determines if the response should be intercepted', () => {
133129
};
134130
expect(shouldInterceptError(error, options, axios, cache)).toBeTruthy();
135131
});
132+
133+
it('when pauseInstanceWhileRefreshing flag is not provided', () => {
134+
const error = {
135+
response: { status: 401 },
136+
};
137+
expect(shouldInterceptError(error, options, axios, cache)).toBeTruthy();
138+
});
139+
140+
it('when pauseInstanceWhileRefreshing flag is set to true', () => {
141+
const error = {
142+
response: { status: 401 },
143+
};
144+
const newCache = { ...cache, skipInstances: [ axios ] };
145+
const newOptions = { ...options, pauseInstanceWhileRefreshing: true };
146+
expect(shouldInterceptError(error, newOptions, axios, newCache)).toBeFalsy();
147+
});
148+
149+
it('when pauseInstanceWhileRefreshing flag is set to false', () => {
150+
const error = {
151+
response: { status: 401 },
152+
};
153+
const newOptions = { ...options, pauseInstanceWhileRefreshing: false };
154+
expect(shouldInterceptError(error, newOptions, axios, cache)).toBeTruthy();
155+
});
136156
});
137157

138158
describe('Creates refresh call', () => {

src/index.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ import {
99
shouldInterceptError,
1010
AxiosAuthRefreshCache,
1111
createRequestQueueInterceptor,
12-
} from "./utils";
12+
} from './utils';
1313

1414
export interface AxiosAuthRefreshOptions {
1515
statusCodes?: Array<number>;
1616
retryInstance?: AxiosInstance;
17+
/**
18+
* @deprecated
19+
* This flag has been deprecated in favor of `pauseInstanceWhileRefreshing` flag.
20+
* Use `pauseInstanceWhileRefreshing` instead.
21+
*/
1722
skipWhileRefreshing?: boolean;
23+
pauseInstanceWhileRefreshing?: boolean;
1824
onRetry?: (requestConfig: AxiosRequestConfig) => AxiosRequestConfig
1925
}
2026

@@ -60,7 +66,9 @@ export default function createAuthRefreshInterceptor(
6066
return Promise.reject(error);
6167
}
6268

63-
cache.skipInstances.push(instance);
69+
if (options.pauseInstanceWhileRefreshing) {
70+
cache.skipInstances.push(instance);
71+
}
6472

6573
// If refresh call does not exist, create one
6674
const refreshing = createRefreshCall(error, refreshAuthCall, cache);

src/utils.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { AxiosAuthRefreshOptions } from "./index";
2-
import axios, { AxiosInstance, AxiosPromise } from "axios";
1+
import { AxiosAuthRefreshOptions } from './index';
2+
import axios, { AxiosInstance, AxiosPromise } from 'axios';
33

44
export interface AxiosAuthRefreshCache {
55
skipInstances: AxiosInstance[];
@@ -9,19 +9,23 @@ export interface AxiosAuthRefreshCache {
99

1010
export const defaultOptions: AxiosAuthRefreshOptions = {
1111
statusCodes: [ 401 ],
12-
skipWhileRefreshing: true,
12+
pauseInstanceWhileRefreshing: false,
1313
};
1414

1515
/**
16-
* Merges two options objects (source rewrites target).
16+
* Merges two options objects (options overwrites defaults).
1717
*
1818
* @return {AxiosAuthRefreshOptions}
1919
*/
2020
export function mergeOptions(
21-
target: AxiosAuthRefreshOptions,
22-
source: AxiosAuthRefreshOptions,
21+
defaults: AxiosAuthRefreshOptions,
22+
options: AxiosAuthRefreshOptions,
2323
): AxiosAuthRefreshOptions {
24-
return { ...target, ...source };
24+
return {
25+
...defaults,
26+
pauseInstanceWhileRefreshing: options.skipWhileRefreshing,
27+
...options,
28+
};
2529
}
2630

2731
/**
@@ -40,15 +44,15 @@ export function shouldInterceptError(
4044
return false;
4145
}
4246

43-
if (error.config && error.config.skipAuthRefresh) {
47+
if (error.config?.skipAuthRefresh) {
4448
return false;
4549
}
4650

4751
if (!error.response || !options.statusCodes.includes(parseInt(error.response.status))) {
4852
return false;
4953
}
5054

51-
return !options.skipWhileRefreshing || !cache.skipInstances.includes(instance);
55+
return !options.pauseInstanceWhileRefreshing || !cache.skipInstances.includes(instance);
5256
}
5357

5458
/**

0 commit comments

Comments
 (0)