query-string 9.2.2 → 9.3.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/base.d.ts +100 -11
- package/base.js +24 -6
- package/package.json +1 -1
- package/readme.md +71 -7
package/base.d.ts
CHANGED
|
@@ -182,14 +182,14 @@ export type ParseOptions = {
|
|
|
182
182
|
|
|
183
183
|
Use this option to explicitly define the type of a specific parameter—particularly useful in cases where the type might otherwise be ambiguous (e.g., phone numbers or IDs).
|
|
184
184
|
|
|
185
|
-
You can also provide a custom function to transform the value. The function will receive the raw string and should return the desired parsed result (
|
|
185
|
+
You can also provide a custom function to transform the value. The function will receive the raw string and should return the desired parsed result. When used with array formats (like `comma`, `separator`, `bracket`, etc.), the function is applied to each array element individually.
|
|
186
186
|
|
|
187
|
-
NOTE: Array types (`string[]`, `number[]`) are ignored if `arrayFormat` is set to `'none'`.
|
|
187
|
+
NOTE: Array types (`string[]`, `number[]`) are ignored if `arrayFormat` is set to `'none'`.
|
|
188
188
|
|
|
189
189
|
@default {}
|
|
190
190
|
|
|
191
191
|
@example
|
|
192
|
-
Parse `phoneNumber` as a string, overriding the `
|
|
192
|
+
Parse `phoneNumber` as a string, overriding the `parseNumbers` option:
|
|
193
193
|
```
|
|
194
194
|
import queryString from 'query-string';
|
|
195
195
|
|
|
@@ -203,12 +203,12 @@ export type ParseOptions = {
|
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
@example
|
|
206
|
-
Parse `items` as an array of strings, overriding the `
|
|
206
|
+
Parse `items` as an array of strings, overriding the `parseNumbers` option:
|
|
207
207
|
```
|
|
208
208
|
import queryString from 'query-string';
|
|
209
209
|
|
|
210
210
|
queryString.parse('?age=20&items=1%2C2%2C3', {
|
|
211
|
-
|
|
211
|
+
parseNumbers: true,
|
|
212
212
|
types: {
|
|
213
213
|
items: 'string[]',
|
|
214
214
|
}
|
|
@@ -236,12 +236,27 @@ export type ParseOptions = {
|
|
|
236
236
|
|
|
237
237
|
queryString.parse('?age=20&id=01234&zipcode=90210', {
|
|
238
238
|
types: {
|
|
239
|
-
age:
|
|
239
|
+
age: value => value * 2,
|
|
240
240
|
}
|
|
241
241
|
});
|
|
242
242
|
//=> {age: 40, id: '01234', zipcode: '90210'}
|
|
243
243
|
```
|
|
244
244
|
|
|
245
|
+
@example
|
|
246
|
+
Custom functions are applied to each array element when using array formats:
|
|
247
|
+
```
|
|
248
|
+
import queryString from 'query-string';
|
|
249
|
+
|
|
250
|
+
// With arrays, the function is applied to each element
|
|
251
|
+
queryString.parse('?scores=10,20,30', {
|
|
252
|
+
arrayFormat: 'comma',
|
|
253
|
+
types: {
|
|
254
|
+
scores: value => Number(value) * 2,
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
//=> {scores: [20, 40, 60]}
|
|
258
|
+
```
|
|
259
|
+
|
|
245
260
|
@example
|
|
246
261
|
Array types are ignored when `arrayFormat` is set to `'none'`:
|
|
247
262
|
```
|
|
@@ -267,7 +282,7 @@ export type ParseOptions = {
|
|
|
267
282
|
items: 'string[]',
|
|
268
283
|
price: 'string',
|
|
269
284
|
numbers: 'number[]',
|
|
270
|
-
double:
|
|
285
|
+
double: value => value * 2,
|
|
271
286
|
number: 'number',
|
|
272
287
|
},
|
|
273
288
|
});
|
|
@@ -325,9 +340,10 @@ export type ParsedUrl = {
|
|
|
325
340
|
/**
|
|
326
341
|
Extract the URL and the query string as an object.
|
|
327
342
|
|
|
328
|
-
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
329
|
-
|
|
330
343
|
@param url - The URL to parse.
|
|
344
|
+
@returns An object with a `url` and `query` property.
|
|
345
|
+
|
|
346
|
+
If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
|
|
331
347
|
|
|
332
348
|
@example
|
|
333
349
|
```
|
|
@@ -534,17 +550,80 @@ export type StringifyOptions = {
|
|
|
534
550
|
```
|
|
535
551
|
*/
|
|
536
552
|
readonly skipEmptyString?: boolean;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
A function that transforms key-value pairs before stringification.
|
|
556
|
+
|
|
557
|
+
Similar to the `replacer` parameter of `JSON.stringify()`, this function is called for each key-value pair and can be used to transform values before they are stringified.
|
|
558
|
+
|
|
559
|
+
The function receives the key and value, and should return the transformed value. Returning `undefined` will omit the key-value pair from the resulting query string.
|
|
560
|
+
|
|
561
|
+
This is useful for custom serialization of non-primitive types like `Date`:
|
|
562
|
+
|
|
563
|
+
@example
|
|
564
|
+
```
|
|
565
|
+
import queryString from 'query-string';
|
|
566
|
+
|
|
567
|
+
queryString.stringify({
|
|
568
|
+
date: new Date('2024-01-15T10:30:00Z'),
|
|
569
|
+
name: 'John'
|
|
570
|
+
}, {
|
|
571
|
+
replacer: (key, value) => {
|
|
572
|
+
if (value instanceof Date) {
|
|
573
|
+
return value.toISOString();
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return value;
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
//=> 'date=2024-01-15T10%3A30%3A00.000Z&name=John'
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
@example
|
|
583
|
+
```
|
|
584
|
+
import queryString from 'query-string';
|
|
585
|
+
|
|
586
|
+
// Omit keys with null values using replacer instead of skipNull
|
|
587
|
+
queryString.stringify({
|
|
588
|
+
a: 1,
|
|
589
|
+
b: null,
|
|
590
|
+
c: 3
|
|
591
|
+
}, {
|
|
592
|
+
replacer: (key, value) => value === null ? undefined : value
|
|
593
|
+
});
|
|
594
|
+
//=> 'a=1&c=3'
|
|
595
|
+
```
|
|
596
|
+
*/
|
|
597
|
+
readonly replacer?: (key: string, value: unknown) => unknown;
|
|
537
598
|
};
|
|
538
599
|
|
|
600
|
+
/**
|
|
601
|
+
Supported value types for query string parameters.
|
|
602
|
+
|
|
603
|
+
Note: `Symbol`, functions, and objects (except arrays) are not supported and will throw an error when stringified.
|
|
604
|
+
*/
|
|
539
605
|
export type Stringifiable = string | boolean | number | bigint | null | undefined; // eslint-disable-line @typescript-eslint/ban-types
|
|
540
606
|
|
|
607
|
+
/**
|
|
608
|
+
A record of stringifiable values.
|
|
609
|
+
*/
|
|
541
610
|
export type StringifiableRecord = Record<
|
|
542
611
|
string,
|
|
543
612
|
Stringifiable | readonly Stringifiable[]
|
|
544
613
|
>;
|
|
545
614
|
|
|
546
615
|
/**
|
|
547
|
-
Stringify an object into a query string and
|
|
616
|
+
Stringify an object into a query string and sorting the keys.
|
|
617
|
+
|
|
618
|
+
@param object - Object to stringify. Supported value types are: `string`, `number`, `bigint`, `boolean`, `null`, `undefined`, and arrays of these types. Other types like `Symbol`, functions, or objects (except arrays) will throw an error.
|
|
619
|
+
|
|
620
|
+
@example
|
|
621
|
+
```
|
|
622
|
+
import queryString from 'query-string';
|
|
623
|
+
|
|
624
|
+
queryString.stringify({foo: 'bar', baz: 42, qux: true});
|
|
625
|
+
//=> 'baz=42&foo=bar&qux=true'
|
|
626
|
+
```
|
|
548
627
|
*/
|
|
549
628
|
export function stringify(
|
|
550
629
|
// TODO: Use the below instead when the following TS issues are fixed:
|
|
@@ -559,7 +638,13 @@ export function stringify(
|
|
|
559
638
|
/**
|
|
560
639
|
Extract a query string from a URL that can be passed into `.parse()`.
|
|
561
640
|
|
|
562
|
-
|
|
641
|
+
@example
|
|
642
|
+
```
|
|
643
|
+
import queryString from 'query-string';
|
|
644
|
+
|
|
645
|
+
queryString.extract('https://foo.bar?foo=bar');
|
|
646
|
+
//=> 'foo=bar'
|
|
647
|
+
```
|
|
563
648
|
*/
|
|
564
649
|
export function extract(url: string): string;
|
|
565
650
|
|
|
@@ -580,6 +665,10 @@ export type UrlObject = {
|
|
|
580
665
|
/**
|
|
581
666
|
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)
|
|
582
667
|
|
|
668
|
+
The `options` are the same as for `.stringify()`.
|
|
669
|
+
|
|
670
|
+
@returns A string with the URL and a query string.
|
|
671
|
+
|
|
583
672
|
Query items in the `query` property overrides queries in the `url` property.
|
|
584
673
|
|
|
585
674
|
The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
|
package/base.js
CHANGED
|
@@ -202,9 +202,7 @@ function parserForArrayFormat(options) {
|
|
|
202
202
|
case 'separator': {
|
|
203
203
|
return (key, value, accumulator) => {
|
|
204
204
|
const isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);
|
|
205
|
-
const
|
|
206
|
-
value = isEncodedArray ? decode(value, options) : value;
|
|
207
|
-
const newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : (value === null ? value : decode(value, options));
|
|
205
|
+
const newValue = isArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : (value === null ? value : decode(value, options));
|
|
208
206
|
accumulator[key] = newValue;
|
|
209
207
|
};
|
|
210
208
|
}
|
|
@@ -405,7 +403,8 @@ export function parse(query, options) {
|
|
|
405
403
|
for (const [key, value] of Object.entries(returnValue)) {
|
|
406
404
|
if (typeof value === 'object' && value !== null && options.types[key] !== 'string') {
|
|
407
405
|
for (const [key2, value2] of Object.entries(value)) {
|
|
408
|
-
const
|
|
406
|
+
const typeOption = options.types[key];
|
|
407
|
+
const type = typeof typeOption === 'function' ? typeOption : (typeOption ? typeOption.replace('[]', '') : undefined);
|
|
409
408
|
value[key2] = parseValue(value2, options, type);
|
|
410
409
|
}
|
|
411
410
|
} else if (typeof value === 'object' && value !== null && options.types[key] === 'string') {
|
|
@@ -465,7 +464,17 @@ export function stringify(object, options) {
|
|
|
465
464
|
}
|
|
466
465
|
|
|
467
466
|
return keys.map(key => {
|
|
468
|
-
|
|
467
|
+
let value = object[key];
|
|
468
|
+
|
|
469
|
+
// Apply replacer function if provided
|
|
470
|
+
if (options.replacer) {
|
|
471
|
+
value = options.replacer(key, value);
|
|
472
|
+
|
|
473
|
+
// If replacer returns undefined, skip this key
|
|
474
|
+
if (value === undefined) {
|
|
475
|
+
return '';
|
|
476
|
+
}
|
|
477
|
+
}
|
|
469
478
|
|
|
470
479
|
if (value === undefined) {
|
|
471
480
|
return '';
|
|
@@ -480,7 +489,16 @@ export function stringify(object, options) {
|
|
|
480
489
|
return encode(key, options) + '[]';
|
|
481
490
|
}
|
|
482
491
|
|
|
483
|
-
|
|
492
|
+
// Apply replacer to array elements if provided
|
|
493
|
+
// Note: We don't re-apply replacer to the array itself, only to elements
|
|
494
|
+
let processedArray = value;
|
|
495
|
+
if (options.replacer) {
|
|
496
|
+
processedArray = value.map((item, index) =>
|
|
497
|
+
options.replacer(`${key}[${index}]`, item),
|
|
498
|
+
).filter(item => item !== undefined);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return processedArray
|
|
484
502
|
.reduce(formatter(key), [])
|
|
485
503
|
.join('&');
|
|
486
504
|
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -52,6 +52,14 @@ Parse a query string into an object. Leading `?` or `#` are ignored, so you can
|
|
|
52
52
|
|
|
53
53
|
The returned object is created with [`Object.create(null)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) and thus does not have a `prototype`.
|
|
54
54
|
|
|
55
|
+
```js
|
|
56
|
+
queryString.parse('?foo=bar');
|
|
57
|
+
//=> {foo: 'bar'}
|
|
58
|
+
|
|
59
|
+
queryString.parse('#token=secret&name=jhon');
|
|
60
|
+
//=> {token: 'secret', name: 'jhon'}
|
|
61
|
+
```
|
|
62
|
+
|
|
55
63
|
#### options
|
|
56
64
|
|
|
57
65
|
Type: `object`
|
|
@@ -193,13 +201,11 @@ Parse the value as a boolean type instead of string type if it's a boolean.
|
|
|
193
201
|
Type: `object`\
|
|
194
202
|
Default: `{}`
|
|
195
203
|
|
|
196
|
-
|
|
197
204
|
Specifies a schema for parsing query values with explicit type declarations. When defined, the types provided here take precedence over general parsing options such as `parseNumbers`, `parseBooleans`, and `arrayFormat`.
|
|
198
205
|
|
|
199
206
|
Use this option to explicitly define the type of a specific parameter—particularly useful in cases where the type might otherwise be ambiguous (e.g., phone numbers or IDs).
|
|
200
207
|
|
|
201
|
-
You can also provide a custom function to transform the value. The function will receive the raw string and should return the desired parsed result.
|
|
202
|
-
|
|
208
|
+
You can also provide a custom function to transform the value. The function will receive the raw string and should return the desired parsed result. When used with array formats (like `comma`, `separator`, `bracket`, etc.), the function is applied to each array element individually.
|
|
203
209
|
|
|
204
210
|
Supported Types:
|
|
205
211
|
|
|
@@ -273,17 +279,26 @@ queryString.parse('?age=20&items=1%2C2%2C3', {
|
|
|
273
279
|
//=> {age: '20', items: [1, 2, 3]}
|
|
274
280
|
```
|
|
275
281
|
|
|
276
|
-
- `'Function'`: Provide a custom function as the parameter type. The parameter's value will equal the function's return value.
|
|
282
|
+
- `'Function'`: Provide a custom function as the parameter type. The parameter's value will equal the function's return value. When used with array formats (like `comma`, `separator`, `bracket`, etc.), the function is applied to each array element individually.
|
|
277
283
|
|
|
278
284
|
```js
|
|
279
285
|
import queryString from 'query-string';
|
|
280
286
|
|
|
281
287
|
queryString.parse('?age=20&id=01234&zipcode=90210', {
|
|
282
288
|
types: {
|
|
283
|
-
age:
|
|
289
|
+
age: value => value * 2,
|
|
284
290
|
}
|
|
285
291
|
});
|
|
286
292
|
//=> {age: 40, id: '01234', zipcode: '90210'}
|
|
293
|
+
|
|
294
|
+
// With arrays, the function is applied to each element
|
|
295
|
+
queryString.parse('?scores=10,20,30', {
|
|
296
|
+
arrayFormat: 'comma',
|
|
297
|
+
types: {
|
|
298
|
+
scores: value => Number(value) * 2,
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
//=> {scores: [20, 40, 60]}
|
|
287
302
|
```
|
|
288
303
|
|
|
289
304
|
NOTE: Array types (`string[]`, `number[]`) are ignored if `arrayFormat` is set to `'none'`.
|
|
@@ -306,7 +321,7 @@ import queryString from 'query-string';
|
|
|
306
321
|
|
|
307
322
|
queryString.parse('?age=20&id=01234&zipcode=90210', {
|
|
308
323
|
types: {
|
|
309
|
-
age:
|
|
324
|
+
age: value => value * 2,
|
|
310
325
|
}
|
|
311
326
|
});
|
|
312
327
|
//=> {age: 40, id: '01234', zipcode: '90210'}
|
|
@@ -318,6 +333,8 @@ Parse the value as a boolean type instead of string type if it's a boolean.
|
|
|
318
333
|
|
|
319
334
|
Stringify an object into a query string and sorting the keys.
|
|
320
335
|
|
|
336
|
+
**Supported value types:** `string`, `number`, `bigint`, `boolean`, `null`, `undefined`, and arrays of these types. Other types like `Symbol`, functions, or objects (except arrays) will throw an error.
|
|
337
|
+
|
|
321
338
|
#### options
|
|
322
339
|
|
|
323
340
|
Type: `object`
|
|
@@ -512,11 +529,58 @@ queryString.stringify({a: '', b: ''}, {
|
|
|
512
529
|
//=> ''
|
|
513
530
|
```
|
|
514
531
|
|
|
532
|
+
##### replacer
|
|
533
|
+
|
|
534
|
+
A function that transforms key-value pairs before stringification.
|
|
535
|
+
|
|
536
|
+
Type: `function`\
|
|
537
|
+
Default: `undefined`
|
|
538
|
+
|
|
539
|
+
Similar to the `replacer` parameter of `JSON.stringify()`, this function is called for each key-value pair and can be used to transform values before they are stringified. The function receives the key and value, and should return the transformed value. Returning `undefined` will omit the key-value pair from the resulting query string.
|
|
540
|
+
|
|
541
|
+
This is useful for custom serialization of non-primitive types like `Date`:
|
|
542
|
+
|
|
543
|
+
```js
|
|
544
|
+
import queryString from 'query-string';
|
|
545
|
+
|
|
546
|
+
queryString.stringify({
|
|
547
|
+
date: new Date('2024-01-15T10:30:00Z'),
|
|
548
|
+
name: 'John'
|
|
549
|
+
}, {
|
|
550
|
+
replacer: (key, value) => {
|
|
551
|
+
if (value instanceof Date) {
|
|
552
|
+
return value.toISOString();
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return value;
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
//=> 'date=2024-01-15T10%3A30%3A00.000Z&name=John'
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
You can also use it to filter out keys:
|
|
562
|
+
|
|
563
|
+
```js
|
|
564
|
+
import queryString from 'query-string';
|
|
565
|
+
|
|
566
|
+
queryString.stringify({
|
|
567
|
+
a: 1,
|
|
568
|
+
b: null,
|
|
569
|
+
c: 3
|
|
570
|
+
}, {
|
|
571
|
+
replacer: (key, value) => value === null ? undefined : value
|
|
572
|
+
});
|
|
573
|
+
//=> 'a=1&c=3'
|
|
574
|
+
```
|
|
575
|
+
|
|
515
576
|
### .extract(string)
|
|
516
577
|
|
|
517
578
|
Extract a query string from a URL that can be passed into `.parse()`.
|
|
518
579
|
|
|
519
|
-
|
|
580
|
+
```js
|
|
581
|
+
queryString.extract('https://foo.bar?foo=bar');
|
|
582
|
+
//=> 'foo=bar'
|
|
583
|
+
```
|
|
520
584
|
|
|
521
585
|
### .parseUrl(string, options?)
|
|
522
586
|
|