diff --git a/CHANGELOG.md b/CHANGELOG.md index 97bac07a..f13c43c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## [unreleased] +### Features +- add support for better Buffer JSON stringify (#796) + ### Fix - handle dom parser exception for invalid xml (#821) - do not log stack on assertions error (AnWeber/vscode-httpyac#338) diff --git a/src/utils/stringUtils.spec.ts b/src/utils/stringUtils.spec.ts index 3c6a6df6..4c2947be 100644 --- a/src/utils/stringUtils.spec.ts +++ b/src/utils/stringUtils.spec.ts @@ -1,4 +1,4 @@ -import { stateGenerator } from './stringUtils'; +import { stateGenerator, stringifySafe } from './stringUtils'; describe('state generator', () => { it('generates strings of the expected length', () => { @@ -12,3 +12,38 @@ describe('state generator', () => { expect(encoded).toBe(result); }); }); + +describe('stringifySafe', () => { + it('should return json representation', () => { + expect( + stringifySafe({ + foo: 'bar', + foo2: 2, + foo3: true, + }) + ).toEqual('{"foo":"bar","foo2":2,"foo3":true}'); + }); + it('should convert buffer to base64', () => { + expect( + stringifySafe({ + value: Buffer.from('\n\x17outbound|3000||test0629'), + }) + ).toEqual('{"value":"ChdvdXRib3VuZHwzMDAwfHx0ZXN0MDYyOQ=="}'); + }); + it('should return base64 for buffer object', () => { + expect(stringifySafe(Buffer.from('\n\x17outbound|3000||test0629'))).toEqual( + '"ChdvdXRib3VuZHwzMDAwfHx0ZXN0MDYyOQ=="' + ); + }); + it('should handle circular object', () => { + const foo: Record = { + foo: 'foo', + }; + const bar: Record = { + bar: 'bar', + foo, + }; + foo.bar = bar; + expect(stringifySafe(foo)).toEqual('{"foo":"foo","bar":{"bar":"bar"}}'); + }); +}); diff --git a/src/utils/stringUtils.ts b/src/utils/stringUtils.ts index 3ff7eb63..340f9a96 100644 --- a/src/utils/stringUtils.ts +++ b/src/utils/stringUtils.ts @@ -58,7 +58,16 @@ export function toString(value: unknown): string | undefined { export function stringifySafe(obj: unknown, indent = 0) { try { - return JSON.stringify(obj, null, indent); + return JSON.stringify( + obj, + (_, value) => { + if (isJsonBuffer(value)) { + return Buffer.from(value.data).toString('base64'); + } + return value; + }, + indent + ); } catch (err) { log.debug(`JSON.stringify error`, err); const getCircularReplacer = () => { @@ -86,3 +95,8 @@ export function ensureString(value: unknown): string | null | undefined { } return `${value}`; } + +function isJsonBuffer(value: unknown): value is { type: string; data: Array } { + const val = value as { type: string; data: Array }; + return val?.type === 'Buffer' && Array.isArray(val.data) && !!val.data.length; +}