query-string 6.13.5 → 6.14.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.
- package/index.d.ts +85 -2
- package/index.js +44 -18
- package/package.json +4 -2
- package/readme.md +60 -2
package/index.d.ts
CHANGED
|
@@ -343,14 +343,19 @@ export type Stringifiable = string | boolean | number | null | undefined;
|
|
|
343
343
|
|
|
344
344
|
export type StringifiableRecord = Record<
|
|
345
345
|
string,
|
|
346
|
-
Stringifiable | Stringifiable[]
|
|
346
|
+
Stringifiable | readonly Stringifiable[]
|
|
347
347
|
>;
|
|
348
348
|
|
|
349
349
|
/**
|
|
350
350
|
Stringify an object into a query string and sort the keys.
|
|
351
351
|
*/
|
|
352
352
|
export function stringify(
|
|
353
|
-
|
|
353
|
+
// TODO: Use the below instead when the following TS issues are fixed:
|
|
354
|
+
// - https://github.com/microsoft/TypeScript/issues/15300
|
|
355
|
+
// - https://github.com/microsoft/TypeScript/issues/42021
|
|
356
|
+
// Context: https://github.com/sindresorhus/query-string/issues/298
|
|
357
|
+
// object: StringifiableRecord,
|
|
358
|
+
object: Record<string, any>,
|
|
354
359
|
options?: StringifyOptions
|
|
355
360
|
): string;
|
|
356
361
|
|
|
@@ -404,3 +409,81 @@ export function stringifyUrl(
|
|
|
404
409
|
object: UrlObject,
|
|
405
410
|
options?: StringifyOptions
|
|
406
411
|
): string;
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
Pick query parameters from a URL.
|
|
415
|
+
|
|
416
|
+
@param url - The URL containing the query parameters to pick.
|
|
417
|
+
@param keys - The names of the query parameters to keep. All other query parameters will be removed from the URL.
|
|
418
|
+
@param filter - A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
419
|
+
|
|
420
|
+
@returns The URL with the picked query parameters.
|
|
421
|
+
|
|
422
|
+
@example
|
|
423
|
+
```
|
|
424
|
+
queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
425
|
+
//=> 'https://foo.bar?foo=1#hello'
|
|
426
|
+
|
|
427
|
+
queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
428
|
+
//=> 'https://foo.bar?bar=2#hello'
|
|
429
|
+
```
|
|
430
|
+
*/
|
|
431
|
+
export function pick(
|
|
432
|
+
url: string,
|
|
433
|
+
keys: readonly string[],
|
|
434
|
+
options?: ParseOptions & StringifyOptions
|
|
435
|
+
): string
|
|
436
|
+
export function pick(
|
|
437
|
+
url: string,
|
|
438
|
+
filter: (key: string, value: string | boolean | number) => boolean,
|
|
439
|
+
options?: {parseBooleans: true, parseNumbers: true} & ParseOptions & StringifyOptions
|
|
440
|
+
): string
|
|
441
|
+
export function pick(
|
|
442
|
+
url: string,
|
|
443
|
+
filter: (key: string, value: string | boolean) => boolean,
|
|
444
|
+
options?: {parseBooleans: true} & ParseOptions & StringifyOptions
|
|
445
|
+
): string
|
|
446
|
+
export function pick(
|
|
447
|
+
url: string,
|
|
448
|
+
filter: (key: string, value: string | number) => boolean,
|
|
449
|
+
options?: {parseNumbers: true} & ParseOptions & StringifyOptions
|
|
450
|
+
): string
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
Exclude query parameters from a URL. Like `.pick()` but reversed.
|
|
454
|
+
|
|
455
|
+
@param url - The URL containing the query parameters to exclude.
|
|
456
|
+
@param keys - The names of the query parameters to remove. All other query parameters will remain in the URL.
|
|
457
|
+
@param filter - A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
458
|
+
|
|
459
|
+
@returns The URL without the excluded the query parameters.
|
|
460
|
+
|
|
461
|
+
@example
|
|
462
|
+
```
|
|
463
|
+
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
464
|
+
//=> 'https://foo.bar?bar=2#hello'
|
|
465
|
+
|
|
466
|
+
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
467
|
+
//=> 'https://foo.bar?foo=1#hello'
|
|
468
|
+
```
|
|
469
|
+
*/
|
|
470
|
+
export function exclude(
|
|
471
|
+
url: string,
|
|
472
|
+
keys: readonly string[],
|
|
473
|
+
options?: ParseOptions & StringifyOptions
|
|
474
|
+
): string
|
|
475
|
+
export function exclude(
|
|
476
|
+
url: string,
|
|
477
|
+
filter: (key: string, value: string | boolean | number) => boolean,
|
|
478
|
+
options?: {parseBooleans: true, parseNumbers: true} & ParseOptions & StringifyOptions
|
|
479
|
+
): string
|
|
480
|
+
export function exclude(
|
|
481
|
+
url: string,
|
|
482
|
+
filter: (key: string, value: string | boolean) => boolean,
|
|
483
|
+
options?: {parseBooleans: true} & ParseOptions & StringifyOptions
|
|
484
|
+
): string
|
|
485
|
+
export function exclude(
|
|
486
|
+
url: string,
|
|
487
|
+
filter: (key: string, value: string | number) => boolean,
|
|
488
|
+
options?: {parseNumbers: true} & ParseOptions & StringifyOptions
|
|
489
|
+
): string
|
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const strictUriEncode = require('strict-uri-encode');
|
|
3
3
|
const decodeComponent = require('decode-uri-component');
|
|
4
4
|
const splitOnFirst = require('split-on-first');
|
|
5
|
+
const filterObject = require('filter-obj');
|
|
5
6
|
|
|
6
7
|
const isNullOrUndefined = value => value === null || value === undefined;
|
|
7
8
|
|
|
@@ -122,8 +123,10 @@ function parserForArrayFormat(options) {
|
|
|
122
123
|
case 'comma':
|
|
123
124
|
case 'separator':
|
|
124
125
|
return (key, value, accumulator) => {
|
|
125
|
-
const isArray = typeof value === 'string' && value.
|
|
126
|
-
const
|
|
126
|
+
const isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);
|
|
127
|
+
const isEncodedArray = (typeof value === 'string' && !isArray && decode(value, options).includes(options.arrayFormatSeparator));
|
|
128
|
+
value = isEncodedArray ? decode(value, options) : value;
|
|
129
|
+
const newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : value === null ? value : decode(value, options);
|
|
127
130
|
accumulator[key] = newValue;
|
|
128
131
|
};
|
|
129
132
|
|
|
@@ -214,7 +217,7 @@ function parseValue(value, options) {
|
|
|
214
217
|
return value;
|
|
215
218
|
}
|
|
216
219
|
|
|
217
|
-
function parse(
|
|
220
|
+
function parse(query, options) {
|
|
218
221
|
options = Object.assign({
|
|
219
222
|
decode: true,
|
|
220
223
|
sort: true,
|
|
@@ -231,17 +234,21 @@ function parse(input, options) {
|
|
|
231
234
|
// Create an object with no prototype
|
|
232
235
|
const ret = Object.create(null);
|
|
233
236
|
|
|
234
|
-
if (typeof
|
|
237
|
+
if (typeof query !== 'string') {
|
|
235
238
|
return ret;
|
|
236
239
|
}
|
|
237
240
|
|
|
238
|
-
|
|
241
|
+
query = query.trim().replace(/^[?#&]/, '');
|
|
239
242
|
|
|
240
|
-
if (!
|
|
243
|
+
if (!query) {
|
|
241
244
|
return ret;
|
|
242
245
|
}
|
|
243
246
|
|
|
244
|
-
for (const param of
|
|
247
|
+
for (const param of query.split('&')) {
|
|
248
|
+
if (param === '') {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
|
|
245
252
|
let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '=');
|
|
246
253
|
|
|
247
254
|
// Missing `=` should be `null`:
|
|
@@ -337,42 +344,61 @@ exports.stringify = (object, options) => {
|
|
|
337
344
|
}).filter(x => x.length > 0).join('&');
|
|
338
345
|
};
|
|
339
346
|
|
|
340
|
-
exports.parseUrl = (
|
|
347
|
+
exports.parseUrl = (url, options) => {
|
|
341
348
|
options = Object.assign({
|
|
342
349
|
decode: true
|
|
343
350
|
}, options);
|
|
344
351
|
|
|
345
|
-
const [
|
|
352
|
+
const [url_, hash] = splitOnFirst(url, '#');
|
|
346
353
|
|
|
347
354
|
return Object.assign(
|
|
348
355
|
{
|
|
349
|
-
url:
|
|
350
|
-
query: parse(extract(
|
|
356
|
+
url: url_.split('?')[0] || '',
|
|
357
|
+
query: parse(extract(url), options)
|
|
351
358
|
},
|
|
352
359
|
options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}
|
|
353
360
|
);
|
|
354
361
|
};
|
|
355
362
|
|
|
356
|
-
exports.stringifyUrl = (
|
|
363
|
+
exports.stringifyUrl = (object, options) => {
|
|
357
364
|
options = Object.assign({
|
|
358
365
|
encode: true,
|
|
359
366
|
strict: true
|
|
360
367
|
}, options);
|
|
361
368
|
|
|
362
|
-
const url = removeHash(
|
|
363
|
-
const queryFromUrl = exports.extract(
|
|
369
|
+
const url = removeHash(object.url).split('?')[0] || '';
|
|
370
|
+
const queryFromUrl = exports.extract(object.url);
|
|
364
371
|
const parsedQueryFromUrl = exports.parse(queryFromUrl, {sort: false});
|
|
365
372
|
|
|
366
|
-
const query = Object.assign(parsedQueryFromUrl,
|
|
373
|
+
const query = Object.assign(parsedQueryFromUrl, object.query);
|
|
367
374
|
let queryString = exports.stringify(query, options);
|
|
368
375
|
if (queryString) {
|
|
369
376
|
queryString = `?${queryString}`;
|
|
370
377
|
}
|
|
371
378
|
|
|
372
|
-
let hash = getHash(
|
|
373
|
-
if (
|
|
374
|
-
hash = `#${encode(
|
|
379
|
+
let hash = getHash(object.url);
|
|
380
|
+
if (object.fragmentIdentifier) {
|
|
381
|
+
hash = `#${encode(object.fragmentIdentifier, options)}`;
|
|
375
382
|
}
|
|
376
383
|
|
|
377
384
|
return `${url}${queryString}${hash}`;
|
|
378
385
|
};
|
|
386
|
+
|
|
387
|
+
exports.pick = (input, filter, options) => {
|
|
388
|
+
options = Object.assign({
|
|
389
|
+
parseFragmentIdentifier: true
|
|
390
|
+
}, options);
|
|
391
|
+
|
|
392
|
+
const {url, query, fragmentIdentifier} = exports.parseUrl(input, options);
|
|
393
|
+
return exports.stringifyUrl({
|
|
394
|
+
url,
|
|
395
|
+
query: filterObject(query, filter),
|
|
396
|
+
fragmentIdentifier
|
|
397
|
+
}, options);
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
exports.exclude = (input, filter, options) => {
|
|
401
|
+
const exclusionFilter = Array.isArray(filter) ? key => !filter.includes(key) : (key, value) => !filter(key, value);
|
|
402
|
+
|
|
403
|
+
return exports.pick(input, exclusionFilter, options);
|
|
404
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "query-string",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.14.0",
|
|
4
4
|
"description": "Parse and stringify URL query strings",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/query-string",
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
"stringify",
|
|
35
35
|
"encode",
|
|
36
36
|
"decode",
|
|
37
|
-
"searchparams"
|
|
37
|
+
"searchparams",
|
|
38
|
+
"filter"
|
|
38
39
|
],
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"decode-uri-component": "^0.2.0",
|
|
42
|
+
"filter-obj": "^1.1.0",
|
|
41
43
|
"split-on-first": "^1.0.0",
|
|
42
44
|
"strict-uri-encode": "^2.0.0"
|
|
43
45
|
},
|
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# query-string
|
|
1
|
+
# query-string
|
|
2
2
|
|
|
3
3
|
> Parse and stringify URL [query strings](https://en.wikipedia.org/wiki/Query_string)
|
|
4
4
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<sup>Special thanks to:</sup>
|
|
17
17
|
<br>
|
|
18
18
|
<br>
|
|
19
|
-
<a href="https://standardresume.co">
|
|
19
|
+
<a href="https://standardresume.co/tech">
|
|
20
20
|
<img src="https://sindresorhus.com/assets/thanks/standard-resume-logo.svg" width="200"/>
|
|
21
21
|
</a>
|
|
22
22
|
</p>
|
|
@@ -415,6 +415,64 @@ Type: `object`
|
|
|
415
415
|
|
|
416
416
|
Query items to add to the URL.
|
|
417
417
|
|
|
418
|
+
### .pick(url, keys, options?)
|
|
419
|
+
### .pick(url, filter, options?)
|
|
420
|
+
|
|
421
|
+
Pick query parameters from a URL.
|
|
422
|
+
|
|
423
|
+
Returns a string with the new URL.
|
|
424
|
+
|
|
425
|
+
```js
|
|
426
|
+
const queryString = require('query-string');
|
|
427
|
+
|
|
428
|
+
queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
429
|
+
//=> 'https://foo.bar?foo=1#hello'
|
|
430
|
+
|
|
431
|
+
queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
432
|
+
//=> 'https://foo.bar?bar=2#hello'
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### .exclude(url, keys, options?)
|
|
436
|
+
### .exclude(url, filter, options?)
|
|
437
|
+
|
|
438
|
+
Exclude query parameters from a URL.
|
|
439
|
+
|
|
440
|
+
Returns a string with the new URL.
|
|
441
|
+
|
|
442
|
+
```js
|
|
443
|
+
const queryString = require('query-string');
|
|
444
|
+
|
|
445
|
+
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
|
|
446
|
+
//=> 'https://foo.bar?bar=2#hello'
|
|
447
|
+
|
|
448
|
+
queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
|
|
449
|
+
//=> 'https://foo.bar?foo=1#hello'
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
#### url
|
|
453
|
+
|
|
454
|
+
Type: `string`
|
|
455
|
+
|
|
456
|
+
The URL containing the query parameters to filter.
|
|
457
|
+
|
|
458
|
+
#### keys
|
|
459
|
+
|
|
460
|
+
Type: `string[]`
|
|
461
|
+
|
|
462
|
+
The names of the query parameters to filter based on the function used.
|
|
463
|
+
|
|
464
|
+
#### filter
|
|
465
|
+
|
|
466
|
+
Type: `(key, value) => boolean`
|
|
467
|
+
|
|
468
|
+
A filter predicate that will be provided the name of each query parameter and its value. The `parseNumbers` and `parseBooleans` options also affect `value`.
|
|
469
|
+
|
|
470
|
+
#### options
|
|
471
|
+
|
|
472
|
+
Type: `object`
|
|
473
|
+
|
|
474
|
+
[Parse options](#options) and [stringify options](#options-1).
|
|
475
|
+
|
|
418
476
|
## Nesting
|
|
419
477
|
|
|
420
478
|
This module intentionally doesn't support nesting as it's not spec'd and varies between implementations, which causes a lot of [edge cases](https://github.com/visionmedia/node-querystring/issues).
|