query-string 6.11.1 → 6.13.1
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.
- package/index.d.ts +65 -0
- package/index.js +54 -16
- package/license +1 -1
- package/package.json +5 -3
- package/readme.md +66 -10
package/index.d.ts
CHANGED
|
@@ -121,6 +121,21 @@ export interface ParseOptions {
|
|
|
121
121
|
```
|
|
122
122
|
*/
|
|
123
123
|
readonly parseBooleans?: boolean;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
Parse the fragment identifier from the URL and add it to result object.
|
|
127
|
+
|
|
128
|
+
@default false
|
|
129
|
+
|
|
130
|
+
@example
|
|
131
|
+
```
|
|
132
|
+
import queryString = require('query-string');
|
|
133
|
+
|
|
134
|
+
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
135
|
+
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
136
|
+
```
|
|
137
|
+
*/
|
|
138
|
+
readonly parseFragmentIdentifier?: boolean;
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
export interface ParsedQuery<T = string> {
|
|
@@ -142,11 +157,20 @@ export function parse(query: string, options?: ParseOptions): ParsedQuery;
|
|
|
142
157
|
export interface ParsedUrl {
|
|
143
158
|
readonly url: string;
|
|
144
159
|
readonly query: ParsedQuery;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
The fragment identifier of the URL.
|
|
163
|
+
|
|
164
|
+
Present when the `parseFragmentIdentifier` option is `true`.
|
|
165
|
+
*/
|
|
166
|
+
readonly fragmentIdentifier?: string;
|
|
145
167
|
}
|
|
146
168
|
|
|
147
169
|
/**
|
|
148
170
|
Extract the URL and the query string as an object.
|
|
149
171
|
|
|
172
|
+
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
173
|
+
|
|
150
174
|
@param url - The URL to parse.
|
|
151
175
|
|
|
152
176
|
@example
|
|
@@ -155,6 +179,9 @@ import queryString = require('query-string');
|
|
|
155
179
|
|
|
156
180
|
queryString.parseUrl('https://foo.bar?foo=bar');
|
|
157
181
|
//=> {url: 'https://foo.bar', query: {foo: 'bar'}}
|
|
182
|
+
|
|
183
|
+
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
184
|
+
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
158
185
|
```
|
|
159
186
|
*/
|
|
160
187
|
export function parseUrl(url: string, options?: ParseOptions): ParsedUrl;
|
|
@@ -283,6 +310,33 @@ export interface StringifyOptions {
|
|
|
283
310
|
```
|
|
284
311
|
*/
|
|
285
312
|
readonly skipNull?: boolean;
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
Skip keys with an empty string as the value.
|
|
316
|
+
|
|
317
|
+
@default false
|
|
318
|
+
|
|
319
|
+
@example
|
|
320
|
+
```
|
|
321
|
+
import queryString = require('query-string');
|
|
322
|
+
|
|
323
|
+
queryString.stringify({a: 1, b: '', c: '', d: 4}, {
|
|
324
|
+
skipEmptyString: true
|
|
325
|
+
});
|
|
326
|
+
//=> 'a=1&d=4'
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
@example
|
|
330
|
+
```
|
|
331
|
+
import queryString = require('query-string');
|
|
332
|
+
|
|
333
|
+
queryString.stringify({a: '', b: ''}, {
|
|
334
|
+
skipEmptyString: true
|
|
335
|
+
});
|
|
336
|
+
//=> ''
|
|
337
|
+
```
|
|
338
|
+
*/
|
|
339
|
+
readonly skipEmptyString?: boolean;
|
|
286
340
|
}
|
|
287
341
|
|
|
288
342
|
/**
|
|
@@ -305,6 +359,8 @@ Stringify an object into a URL with a query string and sorting the keys. The inv
|
|
|
305
359
|
|
|
306
360
|
Query items in the `query` property overrides queries in the `url` property.
|
|
307
361
|
|
|
362
|
+
The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
|
|
363
|
+
|
|
308
364
|
@example
|
|
309
365
|
```
|
|
310
366
|
queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
|
|
@@ -312,6 +368,15 @@ queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
|
|
|
312
368
|
|
|
313
369
|
queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
|
|
314
370
|
//=> 'https://foo.bar?foo=bar'
|
|
371
|
+
|
|
372
|
+
queryString.stringifyUrl({
|
|
373
|
+
url: 'https://foo.bar',
|
|
374
|
+
query: {
|
|
375
|
+
top: 'foo'
|
|
376
|
+
},
|
|
377
|
+
fragmentIdentifier: 'bar'
|
|
378
|
+
});
|
|
379
|
+
//=> 'https://foo.bar?top=foo#bar'
|
|
315
380
|
```
|
|
316
381
|
*/
|
|
317
382
|
export function stringifyUrl(
|
package/index.js
CHANGED
|
@@ -3,12 +3,19 @@ const strictUriEncode = require('strict-uri-encode');
|
|
|
3
3
|
const decodeComponent = require('decode-uri-component');
|
|
4
4
|
const splitOnFirst = require('split-on-first');
|
|
5
5
|
|
|
6
|
+
const isNullOrUndefined = value => value === null || value === undefined;
|
|
7
|
+
|
|
6
8
|
function encoderForArrayFormat(options) {
|
|
7
9
|
switch (options.arrayFormat) {
|
|
8
10
|
case 'index':
|
|
9
11
|
return key => (result, value) => {
|
|
10
12
|
const index = result.length;
|
|
11
|
-
|
|
13
|
+
|
|
14
|
+
if (
|
|
15
|
+
value === undefined ||
|
|
16
|
+
(options.skipNull && value === null) ||
|
|
17
|
+
(options.skipEmptyString && value === '')
|
|
18
|
+
) {
|
|
12
19
|
return result;
|
|
13
20
|
}
|
|
14
21
|
|
|
@@ -24,7 +31,11 @@ function encoderForArrayFormat(options) {
|
|
|
24
31
|
|
|
25
32
|
case 'bracket':
|
|
26
33
|
return key => (result, value) => {
|
|
27
|
-
if (
|
|
34
|
+
if (
|
|
35
|
+
value === undefined ||
|
|
36
|
+
(options.skipNull && value === null) ||
|
|
37
|
+
(options.skipEmptyString && value === '')
|
|
38
|
+
) {
|
|
28
39
|
return result;
|
|
29
40
|
}
|
|
30
41
|
|
|
@@ -51,7 +62,11 @@ function encoderForArrayFormat(options) {
|
|
|
51
62
|
|
|
52
63
|
default:
|
|
53
64
|
return key => (result, value) => {
|
|
54
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
value === undefined ||
|
|
67
|
+
(options.skipNull && value === null) ||
|
|
68
|
+
(options.skipEmptyString && value === '')
|
|
69
|
+
) {
|
|
55
70
|
return result;
|
|
56
71
|
}
|
|
57
72
|
|
|
@@ -231,7 +246,7 @@ function parse(input, options) {
|
|
|
231
246
|
|
|
232
247
|
// Missing `=` should be `null`:
|
|
233
248
|
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
|
|
234
|
-
value = value === undefined ? null : options.arrayFormat
|
|
249
|
+
value = value === undefined ? null : ['comma', 'separator'].includes(options.arrayFormat) ? value : decode(value, options);
|
|
235
250
|
formatter(decode(key, options), value, ret);
|
|
236
251
|
}
|
|
237
252
|
|
|
@@ -280,14 +295,18 @@ exports.stringify = (object, options) => {
|
|
|
280
295
|
|
|
281
296
|
validateArrayFormatSeparator(options.arrayFormatSeparator);
|
|
282
297
|
|
|
298
|
+
const shouldFilter = key => (
|
|
299
|
+
(options.skipNull && isNullOrUndefined(object[key])) ||
|
|
300
|
+
(options.skipEmptyString && object[key] === '')
|
|
301
|
+
);
|
|
302
|
+
|
|
283
303
|
const formatter = encoderForArrayFormat(options);
|
|
284
304
|
|
|
285
|
-
const objectCopy =
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
305
|
+
const objectCopy = {};
|
|
306
|
+
|
|
307
|
+
for (const key of Object.keys(object)) {
|
|
308
|
+
if (!shouldFilter(key)) {
|
|
309
|
+
objectCopy[key] = object[key];
|
|
291
310
|
}
|
|
292
311
|
}
|
|
293
312
|
|
|
@@ -319,22 +338,41 @@ exports.stringify = (object, options) => {
|
|
|
319
338
|
};
|
|
320
339
|
|
|
321
340
|
exports.parseUrl = (input, options) => {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
341
|
+
options = Object.assign({
|
|
342
|
+
decode: true
|
|
343
|
+
}, options);
|
|
344
|
+
|
|
345
|
+
const [url, hash] = splitOnFirst(input, '#');
|
|
346
|
+
|
|
347
|
+
return Object.assign(
|
|
348
|
+
{
|
|
349
|
+
url: url.split('?')[0] || '',
|
|
350
|
+
query: parse(extract(input), options)
|
|
351
|
+
},
|
|
352
|
+
options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}
|
|
353
|
+
);
|
|
326
354
|
};
|
|
327
355
|
|
|
328
356
|
exports.stringifyUrl = (input, options) => {
|
|
357
|
+
options = Object.assign({
|
|
358
|
+
encode: true,
|
|
359
|
+
strict: true
|
|
360
|
+
}, options);
|
|
361
|
+
|
|
329
362
|
const url = removeHash(input.url).split('?')[0] || '';
|
|
330
363
|
const queryFromUrl = exports.extract(input.url);
|
|
331
|
-
const parsedQueryFromUrl = exports.parse(queryFromUrl);
|
|
332
|
-
|
|
364
|
+
const parsedQueryFromUrl = exports.parse(queryFromUrl, {sort: false});
|
|
365
|
+
|
|
333
366
|
const query = Object.assign(parsedQueryFromUrl, input.query);
|
|
334
367
|
let queryString = exports.stringify(query, options);
|
|
335
368
|
if (queryString) {
|
|
336
369
|
queryString = `?${queryString}`;
|
|
337
370
|
}
|
|
338
371
|
|
|
372
|
+
let hash = getHash(input.url);
|
|
373
|
+
if (input.fragmentIdentifier) {
|
|
374
|
+
hash = `#${encode(input.fragmentIdentifier, options)}`;
|
|
375
|
+
}
|
|
376
|
+
|
|
339
377
|
return `${url}${queryString}${hash}`;
|
|
340
378
|
};
|
package/license
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
|
|
3
|
+
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (http://sindresorhus.com)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "query-string",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.13.1",
|
|
4
4
|
"description": "Parse and stringify URL query strings",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/query-string",
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Sindre Sorhus",
|
|
10
10
|
"email": "sindresorhus@gmail.com",
|
|
11
|
-
"url": "sindresorhus.com"
|
|
11
|
+
"url": "https://sindresorhus.com"
|
|
12
12
|
},
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=6"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
+
"benchmark": "node benchmark.js",
|
|
17
18
|
"test": "xo && ava && tsd"
|
|
18
19
|
},
|
|
19
20
|
"files": [
|
|
@@ -36,12 +37,13 @@
|
|
|
36
37
|
"searchparams"
|
|
37
38
|
],
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"split-on-first": "^1.0.0",
|
|
40
40
|
"decode-uri-component": "^0.2.0",
|
|
41
|
+
"split-on-first": "^1.0.0",
|
|
41
42
|
"strict-uri-encode": "^2.0.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"ava": "^1.4.1",
|
|
46
|
+
"benchmark": "^2.1.4",
|
|
45
47
|
"deep-equal": "^1.0.1",
|
|
46
48
|
"fast-check": "^1.5.0",
|
|
47
49
|
"tsd": "^0.7.3",
|
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# query-string [](https://travis-ci.com/github/sindresorhus/query-string) [](https://bundlephobia.com/result?p=query-string)
|
|
2
2
|
|
|
3
3
|
> Parse and stringify URL [query strings](https://en.wikipedia.org/wiki/Query_string)
|
|
4
4
|
|
|
@@ -16,14 +16,9 @@
|
|
|
16
16
|
<sup>Special thanks to:</sup>
|
|
17
17
|
<br>
|
|
18
18
|
<br>
|
|
19
|
-
<a href="https://
|
|
20
|
-
<img src="https://sindresorhus.com/assets/thanks/
|
|
19
|
+
<a href="https://standardresume.co">
|
|
20
|
+
<img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="200"/>
|
|
21
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
22
|
</p>
|
|
28
23
|
</div>
|
|
29
24
|
|
|
@@ -304,6 +299,31 @@ queryString.stringify({a: undefined, b: null}, {
|
|
|
304
299
|
//=> ''
|
|
305
300
|
```
|
|
306
301
|
|
|
302
|
+
##### skipEmptyString
|
|
303
|
+
|
|
304
|
+
Skip keys with an empty string as the value.
|
|
305
|
+
|
|
306
|
+
Type: `boolean`\
|
|
307
|
+
Default: `false`
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
const queryString = require('query-string');
|
|
311
|
+
|
|
312
|
+
queryString.stringify({a: 1, b: '', c: '', d: 4}, {
|
|
313
|
+
skipEmptyString: true
|
|
314
|
+
});
|
|
315
|
+
//=> 'a=1&d=4'
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
```js
|
|
319
|
+
const queryString = require('query-string');
|
|
320
|
+
|
|
321
|
+
queryString.stringify({a: '', b: ''}, {
|
|
322
|
+
skipEmptyString: true
|
|
323
|
+
});
|
|
324
|
+
//=> ''
|
|
325
|
+
```
|
|
326
|
+
|
|
307
327
|
### .extract(string)
|
|
308
328
|
|
|
309
329
|
Extract a query string from a URL that can be passed into `.parse()`.
|
|
@@ -314,15 +334,40 @@ Note: This behaviour can be changed with the `skipNull` option.
|
|
|
314
334
|
|
|
315
335
|
Extract the URL and the query string as an object.
|
|
316
336
|
|
|
317
|
-
The `options` are the same as for `.parse()`.
|
|
318
|
-
|
|
319
337
|
Returns an object with a `url` and `query` property.
|
|
320
338
|
|
|
339
|
+
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
340
|
+
|
|
321
341
|
```js
|
|
322
342
|
const queryString = require('query-string');
|
|
323
343
|
|
|
324
344
|
queryString.parseUrl('https://foo.bar?foo=bar');
|
|
325
345
|
//=> {url: 'https://foo.bar', query: {foo: 'bar'}}
|
|
346
|
+
|
|
347
|
+
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
348
|
+
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### options
|
|
352
|
+
|
|
353
|
+
Type: `object`
|
|
354
|
+
|
|
355
|
+
The options are the same as for `.parse()`.
|
|
356
|
+
|
|
357
|
+
Extra options are as below.
|
|
358
|
+
|
|
359
|
+
##### parseFragmentIdentifier
|
|
360
|
+
|
|
361
|
+
Parse the fragment identifier from the URL.
|
|
362
|
+
|
|
363
|
+
Type: `boolean`\
|
|
364
|
+
Default: `false`
|
|
365
|
+
|
|
366
|
+
```js
|
|
367
|
+
const queryString = require('query-string');
|
|
368
|
+
|
|
369
|
+
queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
|
|
370
|
+
//=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
|
|
326
371
|
```
|
|
327
372
|
|
|
328
373
|
### .stringifyUrl(object, options?)
|
|
@@ -335,12 +380,23 @@ Returns a string with the URL and a query string.
|
|
|
335
380
|
|
|
336
381
|
Query items in the `query` property overrides queries in the `url` property.
|
|
337
382
|
|
|
383
|
+
The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
|
|
384
|
+
|
|
338
385
|
```js
|
|
339
386
|
queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
|
|
340
387
|
//=> 'https://foo.bar?foo=bar'
|
|
341
388
|
|
|
342
389
|
queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
|
|
343
390
|
//=> 'https://foo.bar?foo=bar'
|
|
391
|
+
|
|
392
|
+
queryString.stringifyUrl({
|
|
393
|
+
url: 'https://foo.bar',
|
|
394
|
+
query: {
|
|
395
|
+
top: 'foo'
|
|
396
|
+
},
|
|
397
|
+
fragmentIdentifier: 'bar'
|
|
398
|
+
});
|
|
399
|
+
//=> 'https://foo.bar?top=foo#bar'
|
|
344
400
|
```
|
|
345
401
|
|
|
346
402
|
#### object
|