diff --git a/index.js b/index.js index d19e1381..f9a88a0c 100644 --- a/index.js +++ b/index.js @@ -96,7 +96,12 @@ function parserForArrayFormat(options) { } if (accumulator[key] === undefined) { - accumulator[key] = [value]; + if (options.allowEmptyArrays) { + accumulator[key] = []; + } else { + accumulator[key] = [value]; + } + return; } @@ -197,7 +202,8 @@ function parse(input, options) { sort: true, arrayFormat: 'none', parseNumbers: false, - parseBooleans: false + parseBooleans: false, + allowEmptyArrays: false }, options); const formatter = parserForArrayFormat(options); @@ -263,7 +269,8 @@ exports.stringify = (object, options) => { options = Object.assign({ encode: true, strict: true, - arrayFormat: 'none' + arrayFormat: 'none', + allowEmptyArrays: false }, options); const formatter = encoderForArrayFormat(options); @@ -295,6 +302,10 @@ exports.stringify = (object, options) => { } if (Array.isArray(value)) { + if (options.allowEmptyArrays && value.length === 0) { + return key + '[]='; + } + return value .reduce(formatter(key), []) .join('&'); diff --git a/test/parse.js b/test/parse.js index b2f4da02..2e549080 100644 --- a/test/parse.js +++ b/test/parse.js @@ -293,3 +293,9 @@ test('query strings having comma encoded and format option as `comma`', t => { ] }); }); + +test('should decode empty arrays when allowEmptyArrays is set', t => { + t.deepEqual(queryString.parse('a[]=', {allowEmptyArrays: true, arrayFormat: 'bracket'}), { + a: [] + }); +}); diff --git a/test/stringify.js b/test/stringify.js index 09b6371b..76edd92d 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -259,3 +259,7 @@ test('should ignore both null and undefined when skipNull is set for arrayFormat arrayFormat: 'index' }), 'a[0]=1&a[1]=2&c=1'); }); + +test('should encode empty arrays when allowEmptyArrays is set', t => { + t.is(queryString.stringify({a: []}, {allowEmptyArrays: true, arrayFormat: 'bracket'}), 'a[]='); +});