Skip to content

Commit

Permalink
Implement skips for stringify array format comma (#304)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
decimoseptimo and sindresorhus committed Mar 17, 2021
1 parent 44abc66 commit 828f032
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
5 changes: 5 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ export interface StringifyOptions {
queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
//=> 'foo=1,2,3'
queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
//=> 'foo=1,,'
// Note that typing information for null values is lost
// and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
```
- `separator`: Serialize arrays by separating elements with character:
Expand Down
12 changes: 10 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,20 @@ function encoderForArrayFormat(options) {
case 'comma':
case 'separator':
return key => (result, value) => {
if (value === null || value === undefined || value.length === 0) {
if (
value === undefined ||
(options.skipNull && value === null) ||
(options.skipEmptyString && value === '')
) {
return result;
}

if (result.length === 0) {
return [[encode(key, options), '=', encode(value, options)].join('')];
return [[encode(key, options), '=', encode(value === null ? '' : value, options)].join('')];
}

if (value === null || value === '') {
return [[result, ''].join(options.arrayFormatSeparator)];
}

return [[result, encode(value, options)].join(options.arrayFormatSeparator)];
Expand Down
5 changes: 5 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ const queryString = require('query-string');

queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
//=> 'foo=1,2,3'

queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
//=> 'foo=1,,'
// Note that typing information for null values is lost
// and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
```

- `'none'`: Serialize arrays by using duplicate keys:
Expand Down
31 changes: 29 additions & 2 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ test('query strings having ordered index arrays and format option as `index`', t
}), {bat: 'buz', foo: ['zero', 'two', 'one', 'three']});
});

test('circuit parse -> stringify', t => {
test('circuit parse stringify', t => {
const original = 'foo[3]=foo&foo[2]&foo[1]=one&foo[0]=&bat=buz';
const sortedOriginal = 'bat=buz&foo[0]=&foo[1]=one&foo[2]&foo[3]=foo';
const expected = {bat: 'buz', foo: ['', 'one', null, 'foo']};
Expand All @@ -231,7 +231,7 @@ test('circuit parse -> stringify', t => {
t.is(queryString.stringify(expected, options), sortedOriginal);
});

test('circuit original -> parse - > stringify -> sorted original', t => {
test('circuit original parse stringify sorted original', t => {
const original = 'foo[21474836471]=foo&foo[21474836470]&foo[1]=one&foo[0]=&bat=buz';
const sortedOriginal = 'bat=buz&foo[0]=&foo[1]=one&foo[2]&foo[3]=foo';
const options = {
Expand All @@ -241,6 +241,33 @@ test('circuit original -> parse - > stringify -> sorted original', t => {
t.deepEqual(queryString.stringify(queryString.parse(original, options), options), sortedOriginal);
});

test('circuit parse → stringify with array commas', t => {
const original = 'c=,a,,&b=&a=';
const sortedOriginal = 'a=&b=&c=,a,,';
const expected = {
c: ['', 'a', '', ''],
b: '',
a: ''
};
const options = {
arrayFormat: 'comma'
};

t.deepEqual(queryString.parse(original, options), expected);

t.is(queryString.stringify(expected, options), sortedOriginal);
});

test('circuit original → parse → stringify with array commas → sorted original', t => {
const original = 'c=,a,,&b=&a=';
const sortedOriginal = 'a=&b=&c=,a,,';
const options = {
arrayFormat: 'comma'
};

t.deepEqual(queryString.stringify(queryString.parse(original, options), options), sortedOriginal);
});

test('decode keys and values', t => {
t.deepEqual(queryString.parse('st%C3%A5le=foo'), {ståle: 'foo'});
t.deepEqual(queryString.parse('foo=%7B%ab%%7C%de%%7D+%%7Bst%C3%A5le%7D%'), {foo: '{%ab%|%de%} %{ståle}%'});
Expand Down
23 changes: 18 additions & 5 deletions test/stringify.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,26 @@ test('array stringify representation with array commas', t => {
}), 'bar=one,two&foo');
});

test('array stringify representation with array commas and null value', t => {
test('array stringify representation with array commas, null & empty string', t => {
t.is(queryString.stringify({
foo: [null, 'a', null, ''],
bar: [null]
c: [null, 'a', '', null],
b: [null],
a: ['']
}, {
arrayFormat: 'comma'
}), 'a=&b=&c=,a,,');
});

test('array stringify representation with array commas, null & empty string (skip both)', t => {
t.is(queryString.stringify({
c: [null, 'a', '', null],
b: [null],
a: ['']
}, {
skipNull: true,
skipEmptyString: true,
arrayFormat: 'comma'
}), 'foo=a');
}), 'c=a');
});

test('array stringify representation with array commas and 0 value', t => {
Expand All @@ -141,7 +154,7 @@ test('array stringify representation with array commas and 0 value', t => {
bar: [null]
}, {
arrayFormat: 'comma'
}), 'foo=a,0');
}), 'bar=&foo=a,,0');
});

test('array stringify representation with a bad array format', t => {
Expand Down

0 comments on commit 828f032

Please sign in to comment.