query-string 6.8.3 → 6.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/index.d.ts +115 -3
  2. package/index.js +60 -12
  3. package/package.json +2 -1
  4. package/readme.md +158 -23
package/index.d.ts CHANGED
@@ -12,6 +12,8 @@ export interface ParseOptions {
12
12
  - `bracket`: Parse arrays with bracket representation:
13
13
 
14
14
  ```
15
+ import queryString = require('query-string');
16
+
15
17
  queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
16
18
  //=> {foo: ['1', '2', '3']}
17
19
  ```
@@ -19,6 +21,8 @@ export interface ParseOptions {
19
21
  - `index`: Parse arrays with index representation:
20
22
 
21
23
  ```
24
+ import queryString = require('query-string');
25
+
22
26
  queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
23
27
  //=> {foo: ['1', '2', '3']}
24
28
  ```
@@ -26,18 +30,38 @@ export interface ParseOptions {
26
30
  - `comma`: Parse arrays with elements separated by comma:
27
31
 
28
32
  ```
33
+ import queryString = require('query-string');
34
+
29
35
  queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
30
36
  //=> {foo: ['1', '2', '3']}
31
37
  ```
32
38
 
39
+ - `separator`: Parse arrays with elements separated by a custom character:
40
+
41
+ ```
42
+ import queryString = require('query-string');
43
+
44
+ queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
45
+ //=> {foo: ['1', '2', '3']}
46
+ ```
47
+
33
48
  - `none`: Parse arrays with elements using duplicate keys:
34
49
 
35
50
  ```
51
+ import queryString = require('query-string');
52
+
36
53
  queryString.parse('foo=1&foo=2&foo=3');
37
54
  //=> {foo: ['1', '2', '3']}
38
55
  ```
39
56
  */
40
- readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'none';
57
+ readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'none';
58
+
59
+ /**
60
+ The character used to separate array elements when using `{arrayFormat: 'separator'}`.
61
+
62
+ @default ,
63
+ */
64
+ readonly arrayFormatSeparator?: 'string';
41
65
 
42
66
  /**
43
67
  Supports both `Function` as a custom sorting function or `false` to disable sorting.
@@ -48,6 +72,8 @@ export interface ParseOptions {
48
72
 
49
73
  @example
50
74
  ```
75
+ import queryString = require('query-string');
76
+
51
77
  const order = ['c', 'a', 'b'];
52
78
 
53
79
  queryString.parse('?a=one&b=two&c=three', {
@@ -56,6 +82,10 @@ export interface ParseOptions {
56
82
  //=> {c: 'three', a: 'one', b: 'two'}
57
83
  ```
58
84
 
85
+ @example
86
+ ```
87
+ import queryString = require('query-string');
88
+
59
89
  queryString.parse('?a=one&c=three&b=two', {sort: false});
60
90
  //=> {a: 'one', c: 'three', b: 'two'}
61
91
  ```
@@ -68,7 +98,9 @@ export interface ParseOptions {
68
98
  @default false
69
99
 
70
100
  @example
71
- ```js
101
+ ```
102
+ import queryString = require('query-string');
103
+
72
104
  queryString.parse('foo=1', {parseNumbers: true});
73
105
  //=> {foo: 1}
74
106
  ```
@@ -82,6 +114,8 @@ export interface ParseOptions {
82
114
 
83
115
  @example
84
116
  ```
117
+ import queryString = require('query-string');
118
+
85
119
  queryString.parse('foo=true', {parseBooleans: true});
86
120
  //=> {foo: true}
87
121
  ```
@@ -117,6 +151,8 @@ Extract the URL and the query string as an object.
117
151
 
118
152
  @example
119
153
  ```
154
+ import queryString = require('query-string');
155
+
120
156
  queryString.parseUrl('https://foo.bar?foo=bar');
121
157
  //=> {url: 'https://foo.bar', query: {foo: 'bar'}}
122
158
  ```
@@ -144,6 +180,8 @@ export interface StringifyOptions {
144
180
  - `bracket`: Serialize arrays using bracket representation:
145
181
 
146
182
  ```
183
+ import queryString = require('query-string');
184
+
147
185
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
148
186
  //=> 'foo[]=1&foo[]=2&foo[]=3'
149
187
  ```
@@ -151,6 +189,8 @@ export interface StringifyOptions {
151
189
  - `index`: Serialize arrays using index representation:
152
190
 
153
191
  ```
192
+ import queryString = require('query-string');
193
+
154
194
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
155
195
  //=> 'foo[0]=1&foo[1]=2&foo[2]=3'
156
196
  ```
@@ -158,18 +198,38 @@ export interface StringifyOptions {
158
198
  - `comma`: Serialize arrays by separating elements with comma:
159
199
 
160
200
  ```
201
+ import queryString = require('query-string');
202
+
161
203
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
162
204
  //=> 'foo=1,2,3'
163
205
  ```
164
206
 
207
+ - `separator`: Serialize arrays by separating elements with character:
208
+
209
+ ```
210
+ import queryString = require('query-string');
211
+
212
+ queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'separator', arrayFormatSeparator: '|'});
213
+ //=> 'foo=1|2|3'
214
+ ```
215
+
165
216
  - `none`: Serialize arrays by using duplicate keys:
166
217
 
167
218
  ```
219
+ import queryString = require('query-string');
220
+
168
221
  queryString.stringify({foo: [1, 2, 3]});
169
222
  //=> 'foo=1&foo=2&foo=3'
170
223
  ```
171
224
  */
172
- readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'none';
225
+ readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'none';
226
+
227
+ /**
228
+ The character used to separate array elements when using `{arrayFormat: 'separator'}`.
229
+
230
+ @default ,
231
+ */
232
+ readonly arrayFormatSeparator?: 'string';
173
233
 
174
234
  /**
175
235
  Supports both `Function` as a custom sorting function or `false` to disable sorting.
@@ -180,18 +240,49 @@ export interface StringifyOptions {
180
240
 
181
241
  @example
182
242
  ```
243
+ import queryString = require('query-string');
244
+
183
245
  const order = ['c', 'a', 'b'];
184
246
 
185
247
  queryString.stringify({a: 1, b: 2, c: 3}, {
186
248
  sort: (itemLeft, itemRight) => order.indexOf(itemLeft) - order.indexOf(itemRight)
187
249
  });
188
250
  //=> 'c=3&a=1&b=2'
251
+ ```
252
+
253
+ @example
254
+ ```
255
+ import queryString = require('query-string');
189
256
 
190
257
  queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
191
258
  //=> 'b=1&c=2&a=3'
192
259
  ```
193
260
  */
194
261
  readonly sort?: ((itemLeft: string, itemRight: string) => number) | false;
262
+
263
+ /**
264
+ Skip keys with `null` as the value.
265
+
266
+ Note that keys with `undefined` as the value are always skipped.
267
+
268
+ @default false
269
+
270
+ @example
271
+ ```
272
+ import queryString = require('query-string');
273
+
274
+ queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
275
+ skipNull: true
276
+ });
277
+ //=> 'a=1&d=4'
278
+
279
+ queryString.stringify({a: undefined, b: null}, {
280
+ skipNull: true
281
+ });
282
+ //=> ''
283
+ ```
284
+ */
285
+ readonly skipNull?: boolean;
195
286
  }
196
287
 
197
288
  /**
@@ -204,5 +295,26 @@ export function stringify(
204
295
 
205
296
  /**
206
297
  Extract a query string from a URL that can be passed into `.parse()`.
298
+
299
+ Note: This behaviour can be changed with the `skipNull` option.
207
300
  */
208
301
  export function extract(url: string): string;
302
+
303
+ /**
304
+ Stringify an object into a URL with a query string and sorting the keys. The inverse of [`.parseUrl()`](https://github.com/sindresorhus/query-string#parseurlstring-options)
305
+
306
+ Query items in the `query` property overrides queries in the `url` property.
307
+
308
+ @example
309
+ ```
310
+ queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
311
+ //=> 'https://foo.bar?foo=bar'
312
+
313
+ queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
314
+ //=> 'https://foo.bar?foo=bar'
315
+ ```
316
+ */
317
+ export function stringifyUrl(
318
+ object: ParsedUrl,
319
+ options?: StringifyOptions
320
+ ): string;
package/index.js CHANGED
@@ -8,7 +8,7 @@ function encoderForArrayFormat(options) {
8
8
  case 'index':
9
9
  return key => (result, value) => {
10
10
  const index = result.length;
11
- if (value === undefined) {
11
+ if (value === undefined || (options.skipNull && value === null)) {
12
12
  return result;
13
13
  }
14
14
 
@@ -24,7 +24,7 @@ function encoderForArrayFormat(options) {
24
24
 
25
25
  case 'bracket':
26
26
  return key => (result, value) => {
27
- if (value === undefined) {
27
+ if (value === undefined || (options.skipNull && value === null)) {
28
28
  return result;
29
29
  }
30
30
 
@@ -36,21 +36,22 @@ function encoderForArrayFormat(options) {
36
36
  };
37
37
 
38
38
  case 'comma':
39
- return key => (result, value, index) => {
39
+ case 'separator':
40
+ return key => (result, value) => {
40
41
  if (value === null || value === undefined || value.length === 0) {
41
42
  return result;
42
43
  }
43
44
 
44
- if (index === 0) {
45
+ if (result.length === 0) {
45
46
  return [[encode(key, options), '=', encode(value, options)].join('')];
46
47
  }
47
48
 
48
- return [[result, encode(value, options)].join(',')];
49
+ return [[result, encode(value, options)].join(options.arrayFormatSeparator)];
49
50
  };
50
51
 
51
52
  default:
52
53
  return key => (result, value) => {
53
- if (value === undefined) {
54
+ if (value === undefined || (options.skipNull && value === null)) {
54
55
  return result;
55
56
  }
56
57
 
@@ -104,9 +105,10 @@ function parserForArrayFormat(options) {
104
105
  };
105
106
 
106
107
  case 'comma':
108
+ case 'separator':
107
109
  return (key, value, accumulator) => {
108
- const isArray = typeof value === 'string' && value.split('').indexOf(',') > -1;
109
- const newValue = isArray ? value.split(',') : value;
110
+ const isArray = typeof value === 'string' && value.split('').indexOf(options.arrayFormatSeparator) > -1;
111
+ const newValue = isArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options);
110
112
  accumulator[key] = newValue;
111
113
  };
112
114
 
@@ -122,6 +124,12 @@ function parserForArrayFormat(options) {
122
124
  }
123
125
  }
124
126
 
127
+ function validateArrayFormatSeparator(value) {
128
+ if (typeof value !== 'string' || value.length !== 1) {
129
+ throw new TypeError('arrayFormatSeparator must be single character string');
130
+ }
131
+ }
132
+
125
133
  function encode(value, options) {
126
134
  if (options.encode) {
127
135
  return options.strict ? strictUriEncode(value) : encodeURIComponent(value);
@@ -161,6 +169,16 @@ function removeHash(input) {
161
169
  return input;
162
170
  }
163
171
 
172
+ function getHash(url) {
173
+ let hash = '';
174
+ const hashStart = url.indexOf('#');
175
+ if (hashStart !== -1) {
176
+ hash = url.slice(hashStart);
177
+ }
178
+
179
+ return hash;
180
+ }
181
+
164
182
  function extract(input) {
165
183
  input = removeHash(input);
166
184
  const queryStart = input.indexOf('?');
@@ -186,10 +204,13 @@ function parse(input, options) {
186
204
  decode: true,
187
205
  sort: true,
188
206
  arrayFormat: 'none',
207
+ arrayFormatSeparator: ',',
189
208
  parseNumbers: false,
190
209
  parseBooleans: false
191
210
  }, options);
192
211
 
212
+ validateArrayFormatSeparator(options.arrayFormatSeparator);
213
+
193
214
  const formatter = parserForArrayFormat(options);
194
215
 
195
216
  // Create an object with no prototype
@@ -206,11 +227,11 @@ function parse(input, options) {
206
227
  }
207
228
 
208
229
  for (const param of input.split('&')) {
209
- let [key, value] = splitOnFirst(param.replace(/\+/g, ' '), '=');
230
+ let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '=');
210
231
 
211
232
  // Missing `=` should be `null`:
212
233
  // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
213
- value = value === undefined ? null : decode(value, options);
234
+ value = value === undefined ? null : options.arrayFormat === 'comma' ? value : decode(value, options);
214
235
  formatter(decode(key, options), value, ret);
215
236
  }
216
237
 
@@ -253,11 +274,24 @@ exports.stringify = (object, options) => {
253
274
  options = Object.assign({
254
275
  encode: true,
255
276
  strict: true,
256
- arrayFormat: 'none'
277
+ arrayFormat: 'none',
278
+ arrayFormatSeparator: ','
257
279
  }, options);
258
280
 
281
+ validateArrayFormatSeparator(options.arrayFormatSeparator);
282
+
259
283
  const formatter = encoderForArrayFormat(options);
260
- const keys = Object.keys(object);
284
+
285
+ const objectCopy = Object.assign({}, object);
286
+ if (options.skipNull) {
287
+ for (const key of Object.keys(objectCopy)) {
288
+ if (objectCopy[key] === undefined || objectCopy[key] === null) {
289
+ delete objectCopy[key];
290
+ }
291
+ }
292
+ }
293
+
294
+ const keys = Object.keys(objectCopy);
261
295
 
262
296
  if (options.sort !== false) {
263
297
  keys.sort(options.sort);
@@ -290,3 +324,17 @@ exports.parseUrl = (input, options) => {
290
324
  query: parse(extract(input), options)
291
325
  };
292
326
  };
327
+
328
+ exports.stringifyUrl = (input, options) => {
329
+ const url = removeHash(input.url).split('?')[0] || '';
330
+ const queryFromUrl = exports.extract(input.url);
331
+ const parsedQueryFromUrl = exports.parse(queryFromUrl);
332
+ const hash = getHash(input.url);
333
+ const query = Object.assign(parsedQueryFromUrl, input.query);
334
+ let queryString = exports.stringify(query, options);
335
+ if (queryString) {
336
+ queryString = `?${queryString}`;
337
+ }
338
+
339
+ return `${url}${queryString}${hash}`;
340
+ };
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "query-string",
3
- "version": "6.8.3",
3
+ "version": "6.11.0",
4
4
  "description": "Parse and stringify URL query strings",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/query-string",
7
+ "funding": "https://github.com/sponsors/sindresorhus",
7
8
  "author": {
8
9
  "name": "Sindre Sorhus",
9
10
  "email": "sindresorhus@gmail.com",
package/readme.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  > Parse and stringify URL [query strings](https://en.wikipedia.org/wiki/Query_string)
4
4
 
5
+ <br>
6
+
7
+ ---
8
+
9
+ <div align="center">
10
+ <p>
11
+ <p>
12
+ <sup>
13
+ <a href="https://github.com/sponsors/sindresorhus">My open source work is supported by the community</a>
14
+ </sup>
15
+ </p>
16
+ <sup>Special thanks to:</sup>
17
+ <br>
18
+ <br>
19
+ <a href="https://github.com/botpress/botpress">
20
+ <img src="https://sindresorhus.com/assets/thanks/botpress-logo.svg" width="260" alt="Botpress">
21
+ </a>
22
+ <br>
23
+ <sub><b>Botpress is an open-source conversational assistant creation platform.</b></sub>
24
+ <br>
25
+ <sub>They <a href="https://github.com/botpress/botpress/blob/master/.github/CONTRIBUTING.md">welcome contributions</a> from anyone, whether you're into machine learning,<br>want to get started in open-source, or just have an improvement idea.</sub>
26
+ <br>
27
+ </p>
28
+ </div>
29
+
30
+ ---
31
+
32
+ <br>
5
33
 
6
34
  ## Install
7
35
 
@@ -9,8 +37,7 @@
9
37
  $ npm install query-string
10
38
  ```
11
39
 
12
- This module targets Node.js 6 or later and the latest version of Chrome, Firefox, and Safari. If you want support for older browsers, or, [if your project is using create-react-app v1](https://github.com/sindresorhus/query-string/pull/148#issuecomment-399656020), use version 5: `npm install query-string@5`.
13
-
40
+ This module targets Node.js 6 or later and the latest version of Chrome, Firefox, and Safari. If you want support for older browsers, or, if your project is using create-react-app v1, use version 5: `npm install query-string@5`.
14
41
 
15
42
  ## Usage
16
43
 
@@ -43,7 +70,6 @@ console.log(location.search);
43
70
  //=> '?foo=unicorn&ilike=pizza'
44
71
  ```
45
72
 
46
-
47
73
  ## API
48
74
 
49
75
  ### .parse(string, options?)
@@ -58,19 +84,21 @@ Type: `object`
58
84
 
59
85
  ##### decode
60
86
 
61
- Type: `boolean`<br>
87
+ Type: `boolean`\
62
88
  Default: `true`
63
89
 
64
90
  Decode the keys and values. URL components are decoded with [`decode-uri-component`](https://github.com/SamVerschueren/decode-uri-component).
65
91
 
66
92
  ##### arrayFormat
67
93
 
68
- Type: `string`<br>
94
+ Type: `string`\
69
95
  Default: `'none'`
70
96
 
71
97
  - `'bracket'`: Parse arrays with bracket representation:
72
98
 
73
99
  ```js
100
+ const queryString = require('query-string');
101
+
74
102
  queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
75
103
  //=> {foo: ['1', '2', '3']}
76
104
  ```
@@ -78,6 +106,8 @@ queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
78
106
  - `'index'`: Parse arrays with index representation:
79
107
 
80
108
  ```js
109
+ const queryString = require('query-string');
110
+
81
111
  queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
82
112
  //=> {foo: ['1', '2', '3']}
83
113
  ```
@@ -85,30 +115,52 @@ queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
85
115
  - `'comma'`: Parse arrays with elements separated by comma:
86
116
 
87
117
  ```js
118
+ const queryString = require('query-string');
119
+
88
120
  queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
89
121
  //=> {foo: ['1', '2', '3']}
90
122
  ```
91
123
 
124
+ - `'separator'`: Parse arrays with elements separated by a custom character:
125
+
126
+ ```js
127
+ const queryString = require('query-string');
128
+
129
+ queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
130
+ //=> {foo: ['1', '2', '3']}
131
+ ```
132
+
92
133
  - `'none'`: Parse arrays with elements using duplicate keys:
93
134
 
94
135
  ```js
136
+ const queryString = require('query-string');
137
+
95
138
  queryString.parse('foo=1&foo=2&foo=3');
96
139
  //=> {foo: ['1', '2', '3']}
97
140
  ```
98
141
 
142
+ ##### arrayFormatSeparator
143
+
144
+ Type: `string`\
145
+ Default: `','`
146
+
147
+ The character used to separate array elements when using `{arrayFormat: 'separator'}`.
148
+
99
149
  ##### sort
100
150
 
101
- Type: `Function | boolean`<br>
151
+ Type: `Function | boolean`\
102
152
  Default: `true`
103
153
 
104
154
  Supports both `Function` as a custom sorting function or `false` to disable sorting.
105
155
 
106
156
  ##### parseNumbers
107
157
 
108
- Type: `boolean`<br>
158
+ Type: `boolean`\
109
159
  Default: `false`
110
160
 
111
161
  ```js
162
+ const queryString = require('query-string');
163
+
112
164
  queryString.parse('foo=1', {parseNumbers: true});
113
165
  //=> {foo: 1}
114
166
  ```
@@ -117,17 +169,19 @@ Parse the value as a number type instead of string type if it's a number.
117
169
 
118
170
  ##### parseBooleans
119
171
 
120
- Type: `boolean`<br>
172
+ Type: `boolean`\
121
173
  Default: `false`
122
174
 
123
175
  ```js
176
+ const queryString = require('query-string');
177
+
124
178
  queryString.parse('foo=true', {parseBooleans: true});
125
179
  //=> {foo: true}
126
180
  ```
127
181
 
128
182
  Parse the value as a boolean type instead of string type if it's a boolean.
129
183
 
130
- ### .stringify(object, [options])
184
+ ### .stringify(object, options?)
131
185
 
132
186
  Stringify an object into a query string and sorting the keys.
133
187
 
@@ -137,26 +191,28 @@ Type: `object`
137
191
 
138
192
  ##### strict
139
193
 
140
- Type: `boolean`<br>
194
+ Type: `boolean`\
141
195
  Default: `true`
142
196
 
143
197
  Strictly encode URI components with [strict-uri-encode](https://github.com/kevva/strict-uri-encode). It uses [encodeURIComponent](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) if set to false. You probably [don't care](https://github.com/sindresorhus/query-string/issues/42) about this option.
144
198
 
145
199
  ##### encode
146
200
 
147
- Type: `boolean`<br>
201
+ Type: `boolean`\
148
202
  Default: `true`
149
203
 
150
204
  [URL encode](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the keys and values.
151
205
 
152
206
  ##### arrayFormat
153
207
 
154
- Type: `string`<br>
208
+ Type: `string`\
155
209
  Default: `'none'`
156
210
 
157
211
  - `'bracket'`: Serialize arrays using bracket representation:
158
212
 
159
213
  ```js
214
+ const queryString = require('query-string');
215
+
160
216
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
161
217
  //=> 'foo[]=1&foo[]=2&foo[]=3'
162
218
  ```
@@ -164,6 +220,8 @@ queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
164
220
  - `'index'`: Serialize arrays using index representation:
165
221
 
166
222
  ```js
223
+ const queryString = require('query-string');
224
+
167
225
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
168
226
  //=> 'foo[0]=1&foo[1]=2&foo[2]=3'
169
227
  ```
@@ -171,6 +229,8 @@ queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
171
229
  - `'comma'`: Serialize arrays by separating elements with comma:
172
230
 
173
231
  ```js
232
+ const queryString = require('query-string');
233
+
174
234
  queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
175
235
  //=> 'foo=1,2,3'
176
236
  ```
@@ -178,10 +238,19 @@ queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
178
238
  - `'none'`: Serialize arrays by using duplicate keys:
179
239
 
180
240
  ```js
241
+ const queryString = require('query-string');
242
+
181
243
  queryString.stringify({foo: [1, 2, 3]});
182
244
  //=> 'foo=1&foo=2&foo=3'
183
245
  ```
184
246
 
247
+ ##### arrayFormatSeparator
248
+
249
+ Type: `string`\
250
+ Default: `','`
251
+
252
+ The character used to separate array elements when using `{arrayFormat: 'separator'}`.
253
+
185
254
  ##### sort
186
255
 
187
256
  Type: `Function | boolean`
@@ -189,6 +258,8 @@ Type: `Function | boolean`
189
258
  Supports both `Function` as a custom sorting function or `false` to disable sorting.
190
259
 
191
260
  ```js
261
+ const queryString = require('query-string');
262
+
192
263
  const order = ['c', 'a', 'b'];
193
264
 
194
265
  queryString.stringify({a: 1, b: 2, c: 3}, {
@@ -198,16 +269,47 @@ queryString.stringify({a: 1, b: 2, c: 3}, {
198
269
  ```
199
270
 
200
271
  ```js
272
+ const queryString = require('query-string');
273
+
201
274
  queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
202
275
  //=> 'b=1&c=2&a=3'
203
276
  ```
204
277
 
205
278
  If omitted, keys are sorted using `Array#sort()`, which means, converting them to strings and comparing strings in Unicode code point order.
206
279
 
280
+ ##### skipNull
281
+
282
+ Skip keys with `null` as the value.
283
+
284
+ Note that keys with `undefined` as the value are always skipped.
285
+
286
+ Type: `boolean`\
287
+ Default: `false`
288
+
289
+ ```js
290
+ const queryString = require('query-string');
291
+
292
+ queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
293
+ skipNull: true
294
+ });
295
+ //=> 'a=1&d=4'
296
+ ```
297
+
298
+ ```js
299
+ const queryString = require('query-string');
300
+
301
+ queryString.stringify({a: undefined, b: null}, {
302
+ skipNull: true
303
+ });
304
+ //=> ''
305
+ ```
306
+
207
307
  ### .extract(string)
208
308
 
209
309
  Extract a query string from a URL that can be passed into `.parse()`.
210
310
 
311
+ Note: This behaviour can be changed with the `skipNull` option.
312
+
211
313
  ### .parseUrl(string, options?)
212
314
 
213
315
  Extract the URL and the query string as an object.
@@ -217,10 +319,45 @@ The `options` are the same as for `.parse()`.
217
319
  Returns an object with a `url` and `query` property.
218
320
 
219
321
  ```js
322
+ const queryString = require('query-string');
323
+
220
324
  queryString.parseUrl('https://foo.bar?foo=bar');
221
325
  //=> {url: 'https://foo.bar', query: {foo: 'bar'}}
222
326
  ```
223
327
 
328
+ ### .stringifyUrl(object, options?)
329
+
330
+ Stringify an object into a URL with a query string and sorting the keys. The inverse of [`.parseUrl()`](https://github.com/sindresorhus/query-string#parseurlstring-options)
331
+
332
+ The `options` are the same as for `.stringify()`.
333
+
334
+ Returns a string with the URL and a query string.
335
+
336
+ Query items in the `query` property overrides queries in the `url` property.
337
+
338
+ ```js
339
+ queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
340
+ //=> 'https://foo.bar?foo=bar'
341
+
342
+ queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
343
+ //=> 'https://foo.bar?foo=bar'
344
+ ```
345
+
346
+ #### object
347
+
348
+ Type: `object`
349
+
350
+ ##### url
351
+
352
+ Type: `string`
353
+
354
+ The URL to stringify.
355
+
356
+ ##### query
357
+
358
+ Type: `object`
359
+
360
+ Query items to add to the URL.
224
361
 
225
362
  ## Nesting
226
363
 
@@ -229,6 +366,8 @@ This module intentionally doesn't support nesting as it's not spec'd and varies
229
366
  You're much better off just converting the object to a JSON string:
230
367
 
231
368
  ```js
369
+ const queryString = require('query-string');
370
+
232
371
  queryString.stringify({
233
372
  foo: 'bar',
234
373
  nested: JSON.stringify({
@@ -241,6 +380,8 @@ queryString.stringify({
241
380
  However, there is support for multiple instances of the same key:
242
381
 
243
382
  ```js
383
+ const queryString = require('query-string');
384
+
244
385
  queryString.parse('likes=cake&name=bob&likes=icecream');
245
386
  //=> {likes: ['cake', 'icecream'], name: 'bob'}
246
387
 
@@ -248,12 +389,13 @@ queryString.stringify({color: ['taupe', 'chartreuse'], id: '515'});
248
389
  //=> 'color=taupe&color=chartreuse&id=515'
249
390
  ```
250
391
 
251
-
252
392
  ## Falsy values
253
393
 
254
394
  Sometimes you want to unset a key, or maybe just make it present without assigning a value to it. Here is how falsy values are stringified:
255
395
 
256
396
  ```js
397
+ const queryString = require('query-string');
398
+
257
399
  queryString.stringify({foo: false});
258
400
  //=> 'foo=false'
259
401
 
@@ -264,15 +406,8 @@ queryString.stringify({foo: undefined});
264
406
  //=> ''
265
407
  ```
266
408
 
409
+ ## query-string for enterprise
267
410
 
268
- ---
411
+ Available as part of the Tidelift Subscription.
269
412
 
270
- <div align="center">
271
- <b>
272
- <a href="https://tidelift.com/subscription/pkg/npm-query-string?utm_source=npm-query-string&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
273
- </b>
274
- <br>
275
- <sub>
276
- Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
277
- </sub>
278
- </div>
413
+ The maintainers of query-string and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-query-string?utm_source=npm-query-string&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)