base.d.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. export type ParseOptions = {
  2. /**
  3. Decode the keys and values. URI components are decoded with [`decode-uri-component`](https://github.com/SamVerschueren/decode-uri-component).
  4. @default true
  5. */
  6. readonly decode?: boolean;
  7. /**
  8. @default 'none'
  9. - `bracket`: Parse arrays with bracket representation:
  10. ```
  11. import queryString from 'query-string';
  12. queryString.parse('foo[]=1&foo[]=2&foo[]=3', {arrayFormat: 'bracket'});
  13. //=> {foo: ['1', '2', '3']}
  14. ```
  15. - `index`: Parse arrays with index representation:
  16. ```
  17. import queryString from 'query-string';
  18. queryString.parse('foo[0]=1&foo[1]=2&foo[3]=3', {arrayFormat: 'index'});
  19. //=> {foo: ['1', '2', '3']}
  20. ```
  21. - `comma`: Parse arrays with elements separated by comma:
  22. ```
  23. import queryString from 'query-string';
  24. queryString.parse('foo=1,2,3', {arrayFormat: 'comma'});
  25. //=> {foo: ['1', '2', '3']}
  26. ```
  27. - `separator`: Parse arrays with elements separated by a custom character:
  28. ```
  29. import queryString from 'query-string';
  30. queryString.parse('foo=1|2|3', {arrayFormat: 'separator', arrayFormatSeparator: '|'});
  31. //=> {foo: ['1', '2', '3']}
  32. ```
  33. - `bracket-separator`: Parse arrays (that are explicitly marked with brackets) with elements separated by a custom character:
  34. ```
  35. import queryString from 'query-string';
  36. queryString.parse('foo[]', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  37. //=> {foo: []}
  38. queryString.parse('foo[]=', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  39. //=> {foo: ['']}
  40. queryString.parse('foo[]=1', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  41. //=> {foo: ['1']}
  42. queryString.parse('foo[]=1|2|3', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  43. //=> {foo: ['1', '2', '3']}
  44. queryString.parse('foo[]=1||3|||6', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  45. //=> {foo: ['1', '', 3, '', '', '6']}
  46. queryString.parse('foo[]=1|2|3&bar=fluffy&baz[]=4', {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  47. //=> {foo: ['1', '2', '3'], bar: 'fluffy', baz:['4']}
  48. ```
  49. - `colon-list-separator`: Parse arrays with parameter names that are explicitly marked with `:list`:
  50. ```
  51. import queryString from 'query-string';
  52. queryString.parse('foo:list=one&foo:list=two', {arrayFormat: 'colon-list-separator'});
  53. //=> {foo: ['one', 'two']}
  54. ```
  55. - `none`: Parse arrays with elements using duplicate keys:
  56. ```
  57. import queryString from 'query-string';
  58. queryString.parse('foo=1&foo=2&foo=3');
  59. //=> {foo: ['1', '2', '3']}
  60. ```
  61. */
  62. readonly arrayFormat?:
  63. | 'bracket'
  64. | 'index'
  65. | 'comma'
  66. | 'separator'
  67. | 'bracket-separator'
  68. | 'colon-list-separator'
  69. | 'none';
  70. /**
  71. The character used to separate array elements when using `{arrayFormat: 'separator'}`.
  72. @default ,
  73. */
  74. readonly arrayFormatSeparator?: string;
  75. /**
  76. Supports both `Function` as a custom sorting function or `false` to disable sorting.
  77. If omitted, keys are sorted using `Array#sort`, which means, converting them to strings and comparing strings in Unicode code point order.
  78. @default true
  79. @example
  80. ```
  81. import queryString from 'query-string';
  82. const order = ['c', 'a', 'b'];
  83. queryString.parse('?a=one&b=two&c=three', {
  84. sort: (itemLeft, itemRight) => order.indexOf(itemLeft) - order.indexOf(itemRight)
  85. });
  86. //=> {c: 'three', a: 'one', b: 'two'}
  87. ```
  88. @example
  89. ```
  90. import queryString from 'query-string';
  91. queryString.parse('?a=one&c=three&b=two', {sort: false});
  92. //=> {a: 'one', c: 'three', b: 'two'}
  93. ```
  94. */
  95. readonly sort?: ((itemLeft: string, itemRight: string) => number) | false;
  96. /**
  97. Parse the value as a number type instead of string type if it's a number.
  98. @default false
  99. @example
  100. ```
  101. import queryString from 'query-string';
  102. queryString.parse('foo=1', {parseNumbers: true});
  103. //=> {foo: 1}
  104. ```
  105. */
  106. readonly parseNumbers?: boolean;
  107. /**
  108. Parse the value as a boolean type instead of string type if it's a boolean.
  109. @default false
  110. @example
  111. ```
  112. import queryString from 'query-string';
  113. queryString.parse('foo=true', {parseBooleans: true});
  114. //=> {foo: true}
  115. ```
  116. */
  117. readonly parseBooleans?: boolean;
  118. /**
  119. Parse the fragment identifier from the URL and add it to result object.
  120. @default false
  121. @example
  122. ```
  123. import queryString from 'query-string';
  124. queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
  125. //=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
  126. ```
  127. */
  128. readonly parseFragmentIdentifier?: boolean;
  129. /**
  130. Specify a pre-defined schema to be used when parsing values. The types specified will take precedence over options such as: `parseNumber`, `parseBooleans`, and `arrayFormat`.
  131. Use this feature to override the type of a value. This can be useful when the type is ambiguous such as a phone number (see example 1 and 2).
  132. It is possible to provide a custom function as the parameter type. The parameter's value will equal the function's return value (see example 4).
  133. NOTE: Array types (`string[]` and `number[]`) will have no effect if `arrayFormat` is set to `none` (see example 5).
  134. @default {}
  135. @example
  136. Parse `phoneNumber` as a string, overriding the `parseNumber` option:
  137. ```
  138. import queryString from 'query-string';
  139. queryString.parse('?phoneNumber=%2B380951234567&id=1', {
  140. parseNumbers: true,
  141. types: {
  142. phoneNumber: 'string',
  143. }
  144. });
  145. //=> {phoneNumber: '+380951234567', id: 1}
  146. ```
  147. @example
  148. Parse `items` as an array of strings, overriding the `parseNumber` option:
  149. ```
  150. import queryString from 'query-string';
  151. queryString.parse('?age=20&items=1%2C2%2C3', {
  152. parseNumber: true,
  153. types: {
  154. items: 'string[]',
  155. }
  156. });
  157. //=> {age: 20, items: ['1', '2', '3']}
  158. ```
  159. @example
  160. Parse `age` as a number, even when `parseNumber` is false:
  161. ```
  162. import queryString from 'query-string';
  163. queryString.parse('?age=20&id=01234&zipcode=90210', {
  164. types: {
  165. age: 'number',
  166. }
  167. });
  168. //=> {age: 20, id: '01234', zipcode: '90210 }
  169. ```
  170. @example
  171. Parse `age` using a custom value parser:
  172. ```
  173. import queryString from 'query-string';
  174. queryString.parse('?age=20&id=01234&zipcode=90210', {
  175. types: {
  176. age: (value) => value * 2,
  177. }
  178. });
  179. //=> {age: 40, id: '01234', zipcode: '90210 }
  180. ```
  181. @example
  182. Array types will have no effect when `arrayFormat` is set to `none`
  183. ```
  184. queryString.parse('ids=001%2C002%2C003&foods=apple%2Corange%2Cmango', {
  185. arrayFormat: 'none',
  186. types: {
  187. ids: 'number[]',
  188. foods: 'string[]',
  189. },
  190. }
  191. //=> {ids:'001,002,003', foods:'apple,orange,mango'}
  192. ```
  193. @example
  194. Parse a query utilizing all types:
  195. ```
  196. import queryString from 'query-string';
  197. queryString.parse('?ids=001%2C002%2C003&items=1%2C2%2C3&price=22%2E00&numbers=1%2C2%2C3&double=5&number=20', {
  198. arrayFormat: 'comma',
  199. types: {
  200. ids: 'string',
  201. items: 'string[]',
  202. price: 'string',
  203. numbers: 'number[]',
  204. double: (value) => value * 2,
  205. number: 'number',
  206. },
  207. });
  208. //=> {ids: '001,002,003', items: ['1', '2', '3'], price: '22.00', numbers: [1, 2, 3], double: 10, number: 20}
  209. ```
  210. */
  211. readonly types?: Record<
  212. string,
  213. 'number' | 'string' | 'string[]' | 'number[]' | ((value: string) => unknown)
  214. >;
  215. };
  216. // eslint-disable-next-line @typescript-eslint/ban-types
  217. export type ParsedQuery<T = string> = Record<string, T | null | Array<T | null>>;
  218. /**
  219. Parse a query string into an object. Leading `?` or `#` are ignored, so you can pass `location.search` or `location.hash` directly.
  220. 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`.
  221. @param query - The query string to parse.
  222. */
  223. export function parse(query: string, options: {parseBooleans: true; parseNumbers: true} & ParseOptions): ParsedQuery<string | boolean | number>;
  224. export function parse(query: string, options: {parseBooleans: true} & ParseOptions): ParsedQuery<string | boolean>;
  225. export function parse(query: string, options: {parseNumbers: true} & ParseOptions): ParsedQuery<string | number>;
  226. export function parse(query: string, options?: ParseOptions): ParsedQuery;
  227. export type ParsedUrl = {
  228. readonly url: string;
  229. readonly query: ParsedQuery;
  230. /**
  231. The fragment identifier of the URL.
  232. Present when the `parseFragmentIdentifier` option is `true`.
  233. */
  234. readonly fragmentIdentifier?: string;
  235. };
  236. /**
  237. Extract the URL and the query string as an object.
  238. If the `parseFragmentIdentifier` option is `true`, the object will also contain a `fragmentIdentifier` property.
  239. @param url - The URL to parse.
  240. @example
  241. ```
  242. import queryString from 'query-string';
  243. queryString.parseUrl('https://foo.bar?foo=bar');
  244. //=> {url: 'https://foo.bar', query: {foo: 'bar'}}
  245. queryString.parseUrl('https://foo.bar?foo=bar#xyz', {parseFragmentIdentifier: true});
  246. //=> {url: 'https://foo.bar', query: {foo: 'bar'}, fragmentIdentifier: 'xyz'}
  247. ```
  248. */
  249. export function parseUrl(url: string, options?: ParseOptions): ParsedUrl;
  250. export type StringifyOptions = {
  251. /**
  252. Strictly encode URI components. 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.
  253. @default true
  254. */
  255. readonly strict?: boolean;
  256. /**
  257. [URL encode](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) the keys and values.
  258. @default true
  259. */
  260. readonly encode?: boolean;
  261. /**
  262. @default 'none'
  263. - `bracket`: Serialize arrays using bracket representation:
  264. ```
  265. import queryString from 'query-string';
  266. queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket'});
  267. //=> 'foo[]=1&foo[]=2&foo[]=3'
  268. ```
  269. - `index`: Serialize arrays using index representation:
  270. ```
  271. import queryString from 'query-string';
  272. queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'index'});
  273. //=> 'foo[0]=1&foo[1]=2&foo[2]=3'
  274. ```
  275. - `comma`: Serialize arrays by separating elements with comma:
  276. ```
  277. import queryString from 'query-string';
  278. queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'comma'});
  279. //=> 'foo=1,2,3'
  280. queryString.stringify({foo: [1, null, '']}, {arrayFormat: 'comma'});
  281. //=> 'foo=1,,'
  282. // Note that typing information for null values is lost
  283. // and `.parse('foo=1,,')` would return `{foo: [1, '', '']}`.
  284. ```
  285. - `separator`: Serialize arrays by separating elements with character:
  286. ```
  287. import queryString from 'query-string';
  288. queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'separator', arrayFormatSeparator: '|'});
  289. //=> 'foo=1|2|3'
  290. ```
  291. - `bracket-separator`: Serialize arrays by explicitly post-fixing array names with brackets and separating elements with a custom character:
  292. ```
  293. import queryString from 'query-string';
  294. queryString.stringify({foo: []}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  295. //=> 'foo[]'
  296. queryString.stringify({foo: ['']}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  297. //=> 'foo[]='
  298. queryString.stringify({foo: [1]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  299. //=> 'foo[]=1'
  300. queryString.stringify({foo: [1, 2, 3]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  301. //=> 'foo[]=1|2|3'
  302. queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  303. //=> 'foo[]=1||3|||6'
  304. queryString.stringify({foo: [1, '', 3, null, null, 6]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|', skipNull: true});
  305. //=> 'foo[]=1||3|6'
  306. queryString.stringify({foo: [1, 2, 3], bar: 'fluffy', baz: [4]}, {arrayFormat: 'bracket-separator', arrayFormatSeparator: '|'});
  307. //=> 'foo[]=1|2|3&bar=fluffy&baz[]=4'
  308. ```
  309. - `colon-list-separator`: Serialize arrays with parameter names that are explicitly marked with `:list`:
  310. ```js
  311. import queryString from 'query-string';
  312. queryString.stringify({foo: ['one', 'two']}, {arrayFormat: 'colon-list-separator'});
  313. //=> 'foo:list=one&foo:list=two'
  314. ```
  315. - `none`: Serialize arrays by using duplicate keys:
  316. ```
  317. import queryString from 'query-string';
  318. queryString.stringify({foo: [1, 2, 3]});
  319. //=> 'foo=1&foo=2&foo=3'
  320. ```
  321. */
  322. readonly arrayFormat?: 'bracket' | 'index' | 'comma' | 'separator' | 'bracket-separator' | 'colon-list-separator' | 'none';
  323. /**
  324. The character used to separate array elements when using `{arrayFormat: 'separator'}`.
  325. @default ,
  326. */
  327. readonly arrayFormatSeparator?: string;
  328. /**
  329. Supports both `Function` as a custom sorting function or `false` to disable sorting.
  330. If omitted, keys are sorted using `Array#sort`, which means, converting them to strings and comparing strings in Unicode code point order.
  331. @default true
  332. @example
  333. ```
  334. import queryString from 'query-string';
  335. const order = ['c', 'a', 'b'];
  336. queryString.stringify({a: 1, b: 2, c: 3}, {
  337. sort: (itemLeft, itemRight) => order.indexOf(itemLeft) - order.indexOf(itemRight)
  338. });
  339. //=> 'c=3&a=1&b=2'
  340. ```
  341. @example
  342. ```
  343. import queryString from 'query-string';
  344. queryString.stringify({b: 1, c: 2, a: 3}, {sort: false});
  345. //=> 'b=1&c=2&a=3'
  346. ```
  347. */
  348. readonly sort?: ((itemLeft: string, itemRight: string) => number) | false;
  349. /**
  350. Skip keys with `null` as the value.
  351. Note that keys with `undefined` as the value are always skipped.
  352. @default false
  353. @example
  354. ```
  355. import queryString from 'query-string';
  356. queryString.stringify({a: 1, b: undefined, c: null, d: 4}, {
  357. skipNull: true
  358. });
  359. //=> 'a=1&d=4'
  360. queryString.stringify({a: undefined, b: null}, {
  361. skipNull: true
  362. });
  363. //=> ''
  364. ```
  365. */
  366. readonly skipNull?: boolean;
  367. /**
  368. Skip keys with an empty string as the value.
  369. @default false
  370. @example
  371. ```
  372. import queryString from 'query-string';
  373. queryString.stringify({a: 1, b: '', c: '', d: 4}, {
  374. skipEmptyString: true
  375. });
  376. //=> 'a=1&d=4'
  377. ```
  378. @example
  379. ```
  380. import queryString from 'query-string';
  381. queryString.stringify({a: '', b: ''}, {
  382. skipEmptyString: true
  383. });
  384. //=> ''
  385. ```
  386. */
  387. readonly skipEmptyString?: boolean;
  388. };
  389. export type Stringifiable = string | boolean | number | bigint | null | undefined; // eslint-disable-line @typescript-eslint/ban-types
  390. export type StringifiableRecord = Record<
  391. string,
  392. Stringifiable | readonly Stringifiable[]
  393. >;
  394. /**
  395. Stringify an object into a query string and sort the keys.
  396. */
  397. export function stringify(
  398. // TODO: Use the below instead when the following TS issues are fixed:
  399. // - https://github.com/microsoft/TypeScript/issues/15300
  400. // - https://github.com/microsoft/TypeScript/issues/42021
  401. // Context: https://github.com/sindresorhus/query-string/issues/298
  402. // object: StringifiableRecord,
  403. object: Record<string, any>,
  404. options?: StringifyOptions
  405. ): string;
  406. /**
  407. Extract a query string from a URL that can be passed into `.parse()`.
  408. Note: This behaviour can be changed with the `skipNull` option.
  409. */
  410. export function extract(url: string): string;
  411. export type UrlObject = {
  412. readonly url: string;
  413. /**
  414. Overrides queries in the `url` property.
  415. */
  416. readonly query?: StringifiableRecord;
  417. /**
  418. Overrides the fragment identifier in the `url` property.
  419. */
  420. readonly fragmentIdentifier?: string;
  421. };
  422. /**
  423. 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)
  424. Query items in the `query` property overrides queries in the `url` property.
  425. The `fragmentIdentifier` property overrides the fragment identifier in the `url` property.
  426. @example
  427. ```
  428. queryString.stringifyUrl({url: 'https://foo.bar', query: {foo: 'bar'}});
  429. //=> 'https://foo.bar?foo=bar'
  430. queryString.stringifyUrl({url: 'https://foo.bar?foo=baz', query: {foo: 'bar'}});
  431. //=> 'https://foo.bar?foo=bar'
  432. queryString.stringifyUrl({
  433. url: 'https://foo.bar',
  434. query: {
  435. top: 'foo'
  436. },
  437. fragmentIdentifier: 'bar'
  438. });
  439. //=> 'https://foo.bar?top=foo#bar'
  440. ```
  441. */
  442. export function stringifyUrl(
  443. object: UrlObject,
  444. options?: StringifyOptions
  445. ): string;
  446. /**
  447. Pick query parameters from a URL.
  448. @param url - The URL containing the query parameters to pick.
  449. @param keys - The names of the query parameters to keep. All other query parameters will be removed from the URL.
  450. @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`.
  451. @returns The URL with the picked query parameters.
  452. @example
  453. ```
  454. queryString.pick('https://foo.bar?foo=1&bar=2#hello', ['foo']);
  455. //=> 'https://foo.bar?foo=1#hello'
  456. queryString.pick('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
  457. //=> 'https://foo.bar?bar=2#hello'
  458. ```
  459. */
  460. export function pick(
  461. url: string,
  462. keys: readonly string[],
  463. options?: ParseOptions & StringifyOptions
  464. ): string;
  465. export function pick(
  466. url: string,
  467. filter: (key: string, value: string | boolean | number) => boolean,
  468. options?: {parseBooleans: true; parseNumbers: true} & ParseOptions & StringifyOptions
  469. ): string;
  470. export function pick(
  471. url: string,
  472. filter: (key: string, value: string | boolean) => boolean,
  473. options?: {parseBooleans: true} & ParseOptions & StringifyOptions
  474. ): string;
  475. export function pick(
  476. url: string,
  477. filter: (key: string, value: string | number) => boolean,
  478. options?: {parseNumbers: true} & ParseOptions & StringifyOptions
  479. ): string;
  480. /**
  481. Exclude query parameters from a URL. Like `.pick()` but reversed.
  482. @param url - The URL containing the query parameters to exclude.
  483. @param keys - The names of the query parameters to remove. All other query parameters will remain in the URL.
  484. @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`.
  485. @returns The URL without the excluded the query parameters.
  486. @example
  487. ```
  488. queryString.exclude('https://foo.bar?foo=1&bar=2#hello', ['foo']);
  489. //=> 'https://foo.bar?bar=2#hello'
  490. queryString.exclude('https://foo.bar?foo=1&bar=2#hello', (name, value) => value === 2, {parseNumbers: true});
  491. //=> 'https://foo.bar?foo=1#hello'
  492. ```
  493. */
  494. export function exclude(
  495. url: string,
  496. keys: readonly string[],
  497. options?: ParseOptions & StringifyOptions
  498. ): string;
  499. export function exclude(
  500. url: string,
  501. filter: (key: string, value: string | boolean | number) => boolean,
  502. options?: {parseBooleans: true; parseNumbers: true} & ParseOptions & StringifyOptions
  503. ): string;
  504. export function exclude(
  505. url: string,
  506. filter: (key: string, value: string | boolean) => boolean,
  507. options?: {parseBooleans: true} & ParseOptions & StringifyOptions
  508. ): string;
  509. export function exclude(
  510. url: string,
  511. filter: (key: string, value: string | number) => boolean,
  512. options?: {parseNumbers: true} & ParseOptions & StringifyOptions
  513. ): string;