query-string 6.13.6 → 6.14.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 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
- object: StringifiableRecord,
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
 
@@ -367,7 +372,7 @@ export interface UrlObject {
367
372
  /**
368
373
  Overrides queries in the `url` property.
369
374
  */
370
- readonly query: StringifiableRecord;
375
+ readonly query?: StringifiableRecord;
371
376
 
372
377
  /**
373
378
  Overrides the fragment identifier in the `url` property.
@@ -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
 
@@ -244,6 +245,10 @@ function parse(query, options) {
244
245
  }
245
246
 
246
247
  for (const param of query.split('&')) {
248
+ if (param === '') {
249
+ continue;
250
+ }
251
+
247
252
  let [key, value] = splitOnFirst(options.decode ? param.replace(/\+/g, ' ') : param, '=');
248
253
 
249
254
  // Missing `=` should be `null`:
@@ -378,3 +383,22 @@ exports.stringifyUrl = (object, options) => {
378
383
 
379
384
  return `${url}${queryString}${hash}`;
380
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.13.6",
3
+ "version": "6.14.1",
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 [![Build Status](https://travis-ci.com/sindresorhus/query-string.svg?branch=master)](https://travis-ci.com/github/sindresorhus/query-string) [![](https://badgen.net/bundlephobia/minzip/query-string)](https://bundlephobia.com/result?p=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).