1- import { stringify , parse as parseQueryString , parseUrl } from 'query-string' ;
1+ import {
2+ stringify ,
3+ StringifyOptions ,
4+ parse as parseQueryString ,
5+ parseUrl ,
6+ } from 'query-string' ;
27import { EncodedQuery } from './types' ;
38
9+ /**
10+ * options passed to query-string stringify plus an
11+ * addition of transformSearchString: a function that takes
12+ * the result of stringify and runs a transformation on it.
13+ * (e.g. replacing all instances of character x with y)
14+ */
15+ export type ExtendedStringifyOptions = StringifyOptions & {
16+ transformSearchString ?: ( searchString : string ) => string ;
17+ } ;
18+
19+ /**
20+ * An example of a transformSearchString function that undoes encoding of
21+ * common JSON characters that are technically allowed in URLs.
22+ */
23+ const JSON_SAFE_CHARS = `{}[],":`
24+ . split ( '' )
25+ . map ( ( d ) => [ d , encodeURIComponent ( d ) ] ) ;
26+ export function transformSearchStringJsonSafe ( searchString : string ) : string {
27+ let str = searchString ;
28+ for ( let [ char , code ] of JSON_SAFE_CHARS ) {
29+ str = str . replace ( new RegExp ( '\\' + code , 'g' ) , char ) ;
30+ }
31+ return str ;
32+ }
33+
434/**
535 * Update a location, wiping out parameters not included in encodedQuery
636 * If a param is set to undefined it will be removed from the URL.
737 */
838export function updateLocation (
939 encodedQuery : EncodedQuery ,
10- location : Location
40+ location : Location ,
41+ stringifyOptions ?: ExtendedStringifyOptions
1142) : Location {
12- const encodedSearchString = stringify ( encodedQuery ) ;
43+ let encodedSearchString = stringify ( encodedQuery , stringifyOptions ) ;
44+ if ( stringifyOptions && stringifyOptions . transformSearchString ) {
45+ encodedSearchString = stringifyOptions . transformSearchString (
46+ encodedSearchString
47+ ) ;
48+ }
1349 const search = encodedSearchString . length ? `?${ encodedSearchString } ` : '' ;
1450 const href = parseUrl ( location . href || '' ) . url + search ;
1551
@@ -33,7 +69,8 @@ export function updateLocation(
3369 */
3470export function updateInLocation (
3571 encodedQueryReplacements : EncodedQuery ,
36- location : Location
72+ location : Location ,
73+ stringifyOptions ?: ExtendedStringifyOptions
3774) : Location {
3875 // if a query is there, use it, otherwise parse the search string
3976 const currQuery =
@@ -44,5 +81,5 @@ export function updateInLocation(
4481 ...encodedQueryReplacements ,
4582 } ;
4683
47- return updateLocation ( newQuery , location ) ;
84+ return updateLocation ( newQuery , location , stringifyOptions ) ;
4885}
0 commit comments