Skip to content

Commit

Permalink
Add support for parameters with an explicit :list marker (#335)
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed Jan 6, 2022
1 parent b03e2e7 commit 6d220e6
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 2 deletions.
22 changes: 20 additions & 2 deletions index.d.ts
Expand Up @@ -69,6 +69,15 @@ export interface ParseOptions {
//=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
```
- `colon-list-separator`: Parse arrays with parameter names that are explicitly marked with `:list`:
```
import queryString = require('query-string');
queryString.parse('foo:list=one&foo:list=two', {arrayFormat: 'colon-list-separator'});
//=> {foo: ['one', 'two']}
```
- `none`: Parse arrays with elements using duplicate keys:
```
Expand All @@ -78,7 +87,7 @@ export interface ParseOptions {
//=> {foo: ['1', '2', '3']}
```
*/
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'none';
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'colon-list-separator' | 'none';

/**
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
Expand Down Expand Up @@ -296,6 +305,15 @@ export interface StringifyOptions {
//=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
```
- `colon-list-separator`: Serialize arrays with parameter names that are explicitly marked with `:list`:
```js
import queryString = require('query-string');
queryString.stringify({foo: ['one', 'two']}, {arrayFormat: 'colon-list-separator'});
//=> 'foo:list=one&foo:list=two'
```
- `none`: Serialize arrays by using duplicate keys:
```
Expand All @@ -305,7 +323,7 @@ export interface StringifyOptions {
//=> 'foo=1&foo=2&foo=3'
```
*/
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'none';
readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'colon-list-separator' | 'none';

/**
The character used to separate array elements when using `{arrayFormat: 'separator'}`.
Expand Down
35 changes: 35 additions & 0 deletions index.js
Expand Up @@ -49,6 +49,23 @@ function encoderForArrayFormat(options) {
return [...result, [encode(key, options), '[]=', encode(value, options)].join('')];
};

case 'colon-list-separator':
return key => (result, value) => {
if (
value === undefined ||
(options.skipNull && value === null) ||
(options.skipEmptyString && value === '')
) {
return result;
}

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

return [...result, [encode(key, options), ':list=', encode(value, options)].join('')];
};

case 'comma':
case 'separator':
case 'bracket-separator': {
Expand Down Expand Up @@ -135,6 +152,24 @@ function parserForArrayFormat(options) {
accumulator[key] = [].concat(accumulator[key], value);
};

case 'colon-list-separator':
return (key, value, accumulator) => {
result = /(:list)$/.exec(key);
key = key.replace(/:list$/, '');

if (!result) {
accumulator[key] = value;
return;
}

if (accumulator[key] === undefined) {
accumulator[key] = [value];
return;
}

accumulator[key] = [].concat(accumulator[key], value);
};

case 'comma':
case 'separator':
return (key, value, accumulator) => {
Expand Down
18 changes: 18 additions & 0 deletions readme.md
Expand Up @@ -184,6 +184,15 @@ queryString.parse('foo[]=1|2|3&bar=fluffy&baz[]=4', {arrayFormat: 'bracket-separ
//=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
```

- `'colon-list-separator'`: Parse arrays with parameter names that are explicitly marked with `:list`:

```js
const queryString = require('query-string');

queryString.parse('foo:list=one&foo:list=two', {arrayFormat: 'colon-list-separator'});
//=> {foo: ['one', 'two']}
```

- `'none'`: Parse arrays with elements using duplicate keys:

```js
Expand Down Expand Up @@ -330,6 +339,15 @@ queryString.stringify({foo: [1, 2, 3], bar: 'fluffy', baz: [4]}, {arrayFormat: '
//=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
```

- `'colon-list-separator'`: Serialize arrays with parameter names that are explicitly marked with `:list`:

```js
const queryString = require('query-string');

queryString.stringify({foo: ['one', 'two']}, {arrayFormat: 'colon-list-separator'});
//=> 'foo:list=one&foo:list=two'
```

- `'none'`: Serialize arrays by using duplicate keys:

```js
Expand Down
8 changes: 8 additions & 0 deletions test/parse.js
Expand Up @@ -390,3 +390,11 @@ test('value separated by encoded comma will not be parsed as array with `arrayFo
id: [1, 2, 3]
});
});

test('query strings having (:list) colon-list-separator arrays', t => {
t.deepEqual(queryString.parse('bar:list=one&bar:list=two', {arrayFormat: 'colon-list-separator'}), {bar: ['one', 'two']});
});

test('query strings having (:list) colon-list-separator arrays including null values', t => {
t.deepEqual(queryString.parse('bar:list=one&bar:list=two&foo', {arrayFormat: 'colon-list-separator'}), {bar: ['one', 'two'], foo: null});
});
24 changes: 24 additions & 0 deletions test/stringify.js
Expand Up @@ -400,3 +400,27 @@ test('stringify throws TypeError for invalid arrayFormatSeparator', t => {
instanceOf: TypeError
});
});

test('array stringify representation with (:list) colon-list-separator', t => {
t.is(queryString.stringify({
foo: null,
bar: ['one', 'two']
}, {
arrayFormat: 'colon-list-separator'
}), 'bar:list=one&bar:list=two&foo');
});

test('array stringify representation with (:list) colon-list-separator with null values', t => {
t.is(queryString.stringify({
foo: null,
bar: ['one', '']
}, {
arrayFormat: 'colon-list-separator'
}), 'bar:list=one&bar:list=&foo');
t.is(queryString.stringify({
foo: null,
bar: ['one', null]
}, {
arrayFormat: 'colon-list-separator'
}), 'bar:list=one&bar:list=&foo');
});

0 comments on commit 6d220e6

Please sign in to comment.