Skip to content

Commit

Permalink
Make updateLocation not script crash (#245)
Browse files Browse the repository at this point in the history
* issue244

* use try/catch

* follow function convention

Co-authored-by: Jason McPeak <jmcpeak@payrailz.com>
  • Loading branch information
jmcpeak and Jason McPeak authored Oct 21, 2022
1 parent 17c8d61 commit cb5010b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
5 changes: 5 additions & 0 deletions packages/serialize-query-params/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## serialize-query-params v2.0.2

**Fixes**
- `updateLocation` returns an empty string for `href` when the original `location.href` is not defined. This allows `updateLocation` to be recursively recalled without crashing when creating a `new URL()` (#244)

## serialize-query-params v2.0.1

**Fixes**
Expand Down
2 changes: 1 addition & 1 deletion packages/serialize-query-params/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "serialize-query-params",
"version": "2.0.1",
"version": "2.0.2",
"description": "A library for simplifying encoding and decoding URL query parameters.",
"main": "./dist/index.cjs.js",
"types": "./dist/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/serialize-query-params/src/__tests__/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { stringify } from 'query-string';
import { EncodedQuery } from '..';

export function makeMockLocation(query: EncodedQuery): Location {
export function makeMockLocation(query: EncodedQuery, includeHref: boolean = true): Location {
const queryStr = stringify(query);
const search = queryStr.length ? `?${queryStr}` : '';
return {
protocol: 'http:',
host: 'localhost:3000',
pathname: '/',
search,
href: 'http://localhost:3000/' + search,
href: includeHref ? 'http://localhost:3000/' + search : undefined,
key: `mock-${Date.now()}`,
} as Location & { key: string };
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ describe('updateLocation', () => {
);
expect(newLocation2.search).toBe('?bar=[({1,2:6:4,5})]&foo=o%20t%20h');
});
it('call it twice, should not throw exception', () => {
const location = makeMockLocation({
foo: 'one two',
bar: '[({1,2:3:4,5})]',
}, false);
const newLocationAsReturned = updateLocation(
{ foo: 'o t h', bar: '[({1,2:3:6,5})]' },
location,
(params) => stringify(params, { encode: false })
);
const newLocation2 = updateLocation(
{ foo: 'o t h', bar: '[({1,2:6:4,5})]' },
newLocationAsReturned,
(params) => {
const str = stringify(params, { encode: false });
return transformSearchStringJsonSafe(str).replace(/ /g, '%20');
}
);
expect(newLocation2.search).toBe('?bar=[({1,2:6:4,5})]&foo=o%20t%20h');
});
});

describe('updateInLocation', () => {
Expand Down
27 changes: 19 additions & 8 deletions packages/serialize-query-params/src/updateLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ const JSON_SAFE_CHARS = `{}[],":`
.split('')
.map((d) => [d, encodeURIComponent(d)]);

function getHrefFromLocation(location: Location, search: string): string {
// https://developer.mozilla.org/en-US/docs/Web/API/URL/URL
let href: string = search;

if (location.href) {
// TODO - implement base option if location.href is relative
// see https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#syntax
try {
const url = new URL(location.href);
href = `${url.origin}${url.pathname}${search}`;
} catch (e) {
href = '';
}
}

return href;
}

export function transformSearchStringJsonSafe(searchString: string): string {
let str = searchString;
for (let [char, code] of JSON_SAFE_CHARS) {
Expand All @@ -30,21 +48,14 @@ export function updateLocation(
let encodedSearchString = objectToSearchStringFn(encodedQuery);

const search = encodedSearchString.length ? `?${encodedSearchString}` : '';
let href: string;
if (location.href) {
const url = new URL(location.href);
href = `${url.origin}${url.pathname}${search}`;
} else {
href = search;
}

const newLocation: Location & {
key: string;
query: EncodedQuery;
} = {
...location,
key: `${Date.now()}`, // needed for some routers (e.g. react-router)
href,
href: getHrefFromLocation(location, search),
search,
query: encodedQuery, // needed for some routers (e.g. found)
};
Expand Down

0 comments on commit cb5010b

Please # to comment.