Skip to content

Commit

Permalink
v0.4.1: remove undefined in params and body
Browse files Browse the repository at this point in the history
  • Loading branch information
suhaotian committed Apr 29, 2024
1 parent 241bb14 commit d0984a9
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 49 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
# CHANGELOG 📝

## v0.4.1 2024/04/29

- Feat: remove `undefined` value in `params` / `data`

## v0.4.0 2024/04/24

**Breaking Change**
Expand Down
8 changes: 4 additions & 4 deletions Mock-plugin.md
Expand Up @@ -61,8 +61,8 @@ instance.get('/api/hello').then((res) => {
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/mock.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/mock.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -79,8 +79,8 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.0/plugins/mock.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/mock.umd.js"></script>

<!-- Usage -->
<script>
Expand Down
53 changes: 27 additions & 26 deletions README.md
Expand Up @@ -121,7 +121,7 @@ yarn add xior
Use jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -136,7 +136,7 @@ Use jsDelivr CDN:
Use unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -660,9 +660,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/error-retry.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/error-retry.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -675,10 +675,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/error-retry.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/error-retry.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -771,9 +771,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/throttle.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/throttle.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -786,10 +786,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/throttle.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/throttle.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -844,9 +844,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/dedupe.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/dedupe.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -859,10 +859,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/dedupe.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/dedupe.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -924,9 +924,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/error-cache.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/error-cache.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -939,10 +939,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/error-cache.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/error-cache.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -1087,9 +1087,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/progress.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/progress.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -1102,10 +1102,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/progress.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/progress.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -1212,9 +1212,9 @@ Use CDN:
Using jsDelivr CDN:

```html
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/dist/xior.umd.js"></script>
<!-- Load plugin -->
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.0/plugins/mock.umd.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xior@0.4.1/plugins/mock.umd.js"></script>

<!-- Usage -->
<script>
Expand All @@ -1227,10 +1227,10 @@ Using jsDelivr CDN:
Using unpkg CDN:

```html
<script src="https://unpkg.com/xior@0.4.0/dist/xior.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/dist/xior.umd.js"></script>

<!-- Load plugin -->
<script src="https://unpkg.com/xior@0.4.0/plugins/mock.umd.js"></script>
<script src="https://unpkg.com/xior@0.4.1/plugins/mock.umd.js"></script>

<!-- Usage -->
<script>
Expand Down Expand Up @@ -1319,6 +1319,7 @@ import {
isAbsoluteURL,
joinPath,
isXiorError,
trimUndefined,
} from 'xior';
```

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "xior",
"version": "0.4.0",
"version": "0.4.1",
"description": "A lite request lib based on fetch with plugin support and similar API to axios.",
"repository": "suhaotian/xior",
"bugs": "https://github.com/suhaotian/xior/issues",
Expand Down
3 changes: 2 additions & 1 deletion src/interceptors.ts
Expand Up @@ -2,6 +2,7 @@
import { encodeParams, merge } from 'xior/utils';

import type { XiorInterceptorRequestConfig } from './types';
import { trimUndefined } from './utils';

const appPrefix = 'application/';
const formUrl = `${appPrefix}x-www-form-urlencoded`;
Expand Down Expand Up @@ -45,7 +46,7 @@ export default async function defaultRequestInterceptor(req: XiorInterceptorRequ
newParams = merge({}, data || {}, newParams);
}
if (contentType === jsonType) {
_data = JSON.stringify(data);
_data = JSON.stringify(trimUndefined(data));
} else if (!isGet && contentType === formUrl && data && typeof data === 'object') {
_data = paramsSerializer(data);
}
Expand Down
73 changes: 73 additions & 0 deletions src/plugins/token-refresh.ts
@@ -0,0 +1,73 @@
import xior, { XiorError as AxiosError, XiorInstance, XiorResponse } from 'xior';

Check failure on line 1 in src/plugins/token-refresh.ts

View workflow job for this annotation

GitHub Actions / Build

Cannot find module 'xior' or its corresponding type declarations.
import errorRetry from 'xior/plugins/error-retry';

Check failure on line 2 in src/plugins/token-refresh.ts

View workflow job for this annotation

GitHub Actions / Build

Cannot find module 'xior/plugins/error-retry' or its corresponding type declarations.

const http = xior.create();

http.plugins.use(
errorRetry({
enableRetry: (config, error) => {

Check failure on line 8 in src/plugins/token-refresh.ts

View workflow job for this annotation

GitHub Actions / Build

Parameter 'config' implicitly has an 'any' type.

Check failure on line 8 in src/plugins/token-refresh.ts

View workflow job for this annotation

GitHub Actions / Build

Parameter 'error' implicitly has an 'any' type.
if (error.response && shouldRefreshToken(error.response)) {
return true;
}
},
})
);
setupTokenRefresh(
http,
// eslint-disable-next-line node/handle-callback-err
async (error) => {
const { data } = await http.post('/new/token');
if (data.token) {
// Set new token here
// localStorage.setItem('TOKEN', token);
// or
// http.defaults.headers['Authorization'] = `Beare ${data.token}`;
} else {
return Promise.reject(new Error('Wrong token'));
}
},
{
shouldRefresh(response) {
return Boolean(response?.status && [401, 403].includes(response.status));
},
}
);

export function shouldRefreshToken(response: XiorResponse) {
return response?.status && [401].includes(response.status);
}
export default function setupTokenRefresh(
instance: XiorInstance,
getToken: (error: AxiosError) => Promise<any>,
options?: {
shouldRefresh: (response: XiorResponse) => boolean;
}
) {
const shouldRefresh = options?.shouldRefresh || shouldRefreshToken;

let refreshingToken = false;
const queue: (() => void)[] = [];
instance.interceptors.response.use(
async (response) => {

Check failure on line 51 in src/plugins/token-refresh.ts

View workflow job for this annotation

GitHub Actions / Build

Parameter 'response' implicitly has an 'any' type.
return response;
},
async (error: AxiosError) => {
if (error?.response && shouldRefresh(error.response)) {
if (refreshingToken) {
await new Promise<void>((resolve) => {
queue.push(resolve);
});
} else {
refreshingToken = true;
try {
await getToken(error);
} finally {
refreshingToken = false;
queue.forEach((r) => r());
}
}
}
return Promise.reject(error);
}
);
}
49 changes: 34 additions & 15 deletions src/utils.ts
Expand Up @@ -4,40 +4,59 @@ export * from './any-signals';
export * from './merge';
export * from './plugins/utils';

const undefinedValue = undefined;
export function encodeParams<T = any>(
params: T,
encodeURI = true,
parentKey: string | null = null
): string {
if (params === undefined || params === null) return '';
if (params === undefinedValue || params === null) return '';
const encodedParams = [];
const encodeURIFunc = encodeURI ? encodeURIComponent : (v: string) => v;

for (const key in params) {
if (Object.prototype.hasOwnProperty.call(params, key)) {
const value = (params as any)[key];
const encodedKey = parentKey ? `${parentKey}[${encodeURIFunc(key)}]` : encodeURIFunc(key);
if (value !== undefinedValue) {
const encodedKey = parentKey ? `${parentKey}[${encodeURIFunc(key)}]` : encodeURIFunc(key);

if (typeof value === 'object') {
// If the value is an object or array, recursively encode its contents
const result = encodeParams(value, encodeURI, encodedKey);
if (result !== '') encodedParams.push(result);
} else if (Array.isArray(value)) {
// If the value is an array, encode each element individually
value.forEach((element, index) => {
const arrayKey = `${encodedKey}[${index}]`;
encodedParams.push(`${encodeURIFunc(arrayKey)}=${encodeURIFunc(element)}`);
});
} else {
// Otherwise, encode the key-value pair
encodedParams.push(`${encodeURIFunc(encodedKey)}=${encodeURIFunc(value)}`);
if (typeof value === 'object') {
// If the value is an object or array, recursively encode its contents
const result = encodeParams(value, encodeURI, encodedKey);
if (result !== '') encodedParams.push(result);
} else if (Array.isArray(value)) {
// If the value is an array, encode each element individually
value.forEach((element, index) => {
const arrayKey = `${encodedKey}[${index}]`;
encodedParams.push(`${encodeURIFunc(arrayKey)}=${encodeURIFunc(element)}`);
});
} else {
// Otherwise, encode the key-value pair
encodedParams.push(`${encodeURIFunc(encodedKey)}=${encodeURIFunc(value)}`);
}
}
}
}

return encodedParams.join('&');
}

export function trimUndefined(obj: any): any {
if (Array.isArray(obj)) {
return obj.map(trimUndefined);
} else if (obj && typeof obj === 'object') {
Object.keys(obj).forEach((key) => {
const value = obj[key];
if (value === undefinedValue) {
delete obj[key];
} else {
return trimUndefined(value);
}
});
}
return obj;
}

/**
* Determines whether the specified URL is absolute
*
Expand Down

0 comments on commit d0984a9

Please sign in to comment.