diff --git a/src/helpers/Encodings.ts b/src/helpers/Encodings.ts index 2c75f06..4f861f1 100644 --- a/src/helpers/Encodings.ts +++ b/src/helpers/Encodings.ts @@ -42,28 +42,25 @@ function encodeAndStripWhitespace(key: string): string { return encodeURIComponent(key.replace(' ', '')); } -export function encodeJsonAsURI(json: unknown, uriEncodedJsonProperties: string[] = []): string { - let parsedJson = json; - if (typeof parsedJson === 'string') { - parsedJson = JSON.parse(parsedJson); - } +export function encodeJsonAsURI(json: unknown, uriEncodedProperties: string[] = []): string { + const parsedJson = typeof json === 'string' ? JSON.parse(json) : json; // If no custom properties, we can just encode everything - if (uriEncodedJsonProperties.length === 0) { - return encodeAsUriValue(undefined, json); + if (uriEncodedProperties.length === 0) { + return encodeAsUriValue(undefined, parsedJson); } const results: string[] = []; - for (const [key, value] of Object.entries(json)) { + for (const [key, value] of Object.entries(parsedJson)) { // Value of property must be seen as a separate uri encoded property. - if (uriEncodedJsonProperties.includes(key)) { + if (uriEncodedProperties.includes(key)) { if (typeof value !== 'object' || Array.isArray(value) || value === null) { throw new Error('Cannot encode non-object value as URI encoded JSON property'); } - results.push(`${encodeAndStripWhitespace(key)}=${encodeURIComponent(encodeAsUriValue(undefined, value))}`); + results.push(`${encodeAndStripWhitespace(key)}=${encodeURIComponent(encodeAsUriValue(undefined, value, undefined))}`); } else { - results.push(encodeAsUriValue(key, value)); + results.push(encodeAsUriValue(key, value, undefined)); } } return results.join('&'); @@ -85,7 +82,7 @@ export function encodeAsUriValue(key: string | undefined, value: unknown, base: if (key && !base) { encodedKey = encodeAndStripWhitespace(key); } else if (key && base) { - encodedKey = `${base}[${encodeAndStripWhitespace(key)}]`; + encodedKey = `${base}${encodeAndStripWhitespace(`[${key}]`)}`; } else if (!key && base) { encodedKey = base; } @@ -98,13 +95,7 @@ export function encodeAsUriValue(key: string | undefined, value: unknown, base: results.push(`${encodedKey}=${encodeURIComponent(value)}`); } else if (Array.isArray(value)) { value.forEach((entry, index) => { - results.push( - encodeAsUriValue( - undefined, - entry, - base ? `${base}[${encodeAndStripWhitespace(key)}][${index}]` : `${encodeAndStripWhitespace(key)}[${index}]` - ) - ); + results.push(encodeAsUriValue(undefined, entry, encodedKey + encodeAndStripWhitespace(`[${index}]`))); }); } else if (typeof value === 'object') { for (const [subKey, subValue] of Object.entries(value)) { diff --git a/test/functions/Encodings.spec.ts b/test/functions/Encodings.spec.ts index 4750301..26294d7 100644 --- a/test/functions/Encodings.spec.ts +++ b/test/functions/Encodings.spec.ts @@ -2,9 +2,9 @@ import { encodeAsUriValue, encodeJsonAsURI } from '../../src'; describe('Encodings', () => { test('encodeAsUriValue', () => { - expect(encodeAsUriValue(undefined, { a: { b: { c: 'd', e: 'f' } } })).toBe('a[b][c]=d&a[b][e]=f'); + expect(encodeAsUriValue(undefined, { a: { b: { c: 'd', e: 'f' } } })).toBe('a%5Bb%5D%5Bc%5D=d&a%5Bb%5D%5Be%5D=f'); - expect(encodeAsUriValue(undefined, { a: ['b', 'c', 'd'] })).toBe('a[0]=b&a[1]=c&a[2]=d'); + expect(encodeAsUriValue(undefined, { a: ['b', 'c', 'd'] })).toBe('a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d'); expect( encodeAsUriValue(undefined, { @@ -16,7 +16,7 @@ describe('Encodings', () => { }, }, }) - ).toBe('a[b][a%24s939very-2eweird-%3D%3Dkey][c]=d'); + ).toBe('a%5Bb%5D%5Ba%24s939very-2eweird-%3D%3Dkey%5D%5Bc%5D=d'); }); test('encodeJsonAsURI', () => {