diff --git a/README.md b/README.md index 2b2cb02..8f1727b 100644 --- a/README.md +++ b/README.md @@ -119,18 +119,19 @@ instance.interceptors.request.use((request) => { #### Enable config list -| Property | Type | Default | Description | -| ------------ | ------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `method` | boolean | `true` | Whether to include HTTP method or not. | -| `url` | boolean | `true` | Whether to include the URL or not. | -| `params` | boolean | `false` | Whether to include the URL params or not. | -| `data` | boolean | `true` | Whether to include request/response data or not. | -| `status` | boolean | `true` | Whether to include response statuses or not. | -| `statusText` | boolean | `true` | Whether to include response status text or not. | -| `headers` | boolean | `false` | Whether to include HTTP headers or not. | -| `prefixText` | string \| `false` | `'Axios'` | `false` => no prefix, otherwise, customize the prefix wanted. | -| `dateFormat` | [dateformat](https://github.com/felixge/node-dateformat) \| `false` | `false` | `false` => no timestamp, otherwise, customize its format | -| `logger` | function | `console.log` | Allows users to customize the logger function to be used. e.g. Winston's `logger.info` could be leveraged, like this: `logger.info.bind(this)` | +| Property | Type | Default | Description | +| ------------ | ------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `method` | boolean | `true` | Whether to include HTTP method or not. | +| `url` | boolean | `true` | Whether to include the URL or not. | +| `params` | boolean | `false` | Whether to include the URL params or not. | +| `data` | boolean | `true` | Whether to include request/response data or not. | +| `dataLimit` | number | `0` (no limit) | If `data` equals `true` then the request/response data is truncated if length is bigger than `dataLimit`. | +| `status` | boolean | `true` | Whether to include response statuses or not. | +| `statusText` | boolean | `true` | Whether to include response status text or not. | +| `headers` | boolean | `false` | Whether to include HTTP headers or not. | +| `prefixText` | string \| `false` | `'Axios'` | `false` => no prefix, otherwise, customize the prefix wanted. | +| `dateFormat` | [dateformat](https://github.com/felixge/node-dateformat) \| `false` | `false` | `false` => no timestamp, otherwise, customize its format | +| `logger` | function | `console.log` | Allows users to customize the logger function to be used. e.g. Winston's `logger.info` could be leveraged, like this: `logger.info.bind(this)` | ## CONTRIBUTE diff --git a/package-lock.json b/package-lock.json index 0852605..fde0448 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "axios-logger", - "version": "2.6.1", + "version": "2.6.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "axios-logger", - "version": "2.6.1", + "version": "2.6.2", "license": "MIT", "dependencies": { "chalk": "^4.1.0", diff --git a/src/common/__test__/config.spec.js b/src/common/__test__/config.spec.js index ba5dda8..1da2cb3 100644 --- a/src/common/__test__/config.spec.js +++ b/src/common/__test__/config.spec.js @@ -9,6 +9,7 @@ test('Default globalConfig properties should be equal to default values', () => url: true, params: false, data: true, + dataLimit: 0, status: true, statusText: true, logger: console.log, @@ -31,6 +32,7 @@ test('setGlobalConfig should set config. getGlobalConfig should return globalCon url: false, params: false, data: true, + dataLimit: 0, status: true, statusText: true, logger: customLoggerFunction, @@ -58,6 +60,7 @@ test('assembleBuildConfig should return merged with globalConfig object.', () => url: true, params: false, data: false, + dataLimit: 0, status: true, statusText: true, logger: console.log, diff --git a/src/common/__test__/string-builder.spec.js b/src/common/__test__/string-builder.spec.js index cbf329f..ef0cfb1 100644 --- a/src/common/__test__/string-builder.spec.js +++ b/src/common/__test__/string-builder.spec.js @@ -85,3 +85,38 @@ test('makeData should not stringify data if configured not to', () => { const result = sb.makeData(a).build(); expect(result).toEqual(''); }); + +test('makeData should truncate if data length exceeds dataLimit', () => { + const config = { + ...getGlobalConfig(), + data: true, + dataLimit: 10, + }; + const a = '12345678901234567890'; + const sb = new StringBuilder(config); + const result = sb.makeData(a).build(); + expect(result).toEqual('1234567890...'); +}); + +test('makeData should not truncate if dataLimit is not specified', () => { + const config = { + ...getGlobalConfig(), + data: true, + }; + const a = '12345678901234567890'; + const sb = new StringBuilder(config); + const result = sb.makeData(a).build(); + expect(result).toEqual(a); +}); + +test('makeData should not crash if data has circular references', () => { + const config = { + ...getGlobalConfig(), + data: true, + }; + const a = {}; + a.b = { a }; + const sb = new StringBuilder(config); + const result = sb.makeData(a).build(); + expect(result).toEqual(''); +}); diff --git a/src/common/config.ts b/src/common/config.ts index 54aa650..f9fb40a 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -5,6 +5,7 @@ let globalConfig: Required = { url: true, params: false, data: true, + dataLimit: 0, status: true, statusText: true, logger: console.log, diff --git a/src/common/string-builder.ts b/src/common/string-builder.ts index 7a92288..fb1dce7 100644 --- a/src/common/string-builder.ts +++ b/src/common/string-builder.ts @@ -62,9 +62,22 @@ class StringBuilder { } makeData(data: object) { - if(this.config.data && data) { - const str = typeof data === `string` ? data : JSON.stringify(data); + if (this.config.data && data) { + let str; + try { + str = typeof data === `string` ? data : JSON.stringify(data); + } catch (e) { + // stringify failed, ignore + return this; + } + + let dataLimit = this.config.dataLimit; + if (dataLimit && str?.length > dataLimit) { + str = str.substring(0, dataLimit) + '...'; + } + this.printQueue.push(str); + } return this; } diff --git a/src/common/types.ts b/src/common/types.ts index 42c8e9e..b3c4d62 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -8,6 +8,7 @@ export interface CommonConfig { export interface GlobalLogConfig extends CommonConfig { data?: boolean, + dataLimit?: number; method?: boolean, url?: boolean, status?: boolean, @@ -16,18 +17,21 @@ export interface GlobalLogConfig extends CommonConfig { export interface RequestLogConfig extends CommonConfig { data?: boolean, + dataLimit?: number; method?: boolean, url?: boolean, } export interface ResponseLogConfig extends CommonConfig { data?: boolean, + dataLimit?: number; status?: boolean, statusText?: boolean, } export interface ErrorLogConfig extends CommonConfig { data?: boolean, + dataLimit?: number; status?: boolean, statusText?: boolean, }