-
Notifications
You must be signed in to change notification settings - Fork 278
/
Copy pathresolve-url.ts
49 lines (44 loc) · 1.77 KB
/
resolve-url.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import isServer from './is-server';
import querystring from 'querystring';
/**
* note: encodeURIComponent is available via browser (window) or natively in node.js
* if you use another js engine for server-side rendering you may not have native encodeURIComponent
* and would then need to install a package for that functionality
* @param {Object} params
*/
function getQueryString(params: querystring.ParsedUrlQueryInput) {
return Object.keys(params)
.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(String(params[k]))}`)
.join('&');
}
/**
* Resolves a base URL that may contain query string parameters and an additional set of query
* string parameters into a unified string representation.
* @param {string} urlBase the base URL that may contain query string parameters
* @param {Object} params query string parameters
* @returns a URL string
* @throws {RangeError} if the provided url is an empty string
*/
function resolveUrl(urlBase: string, params: querystring.ParsedUrlQueryInput = {}): string {
if (!urlBase) {
throw new RangeError('url must be a non-empty string');
}
// This is a better way to work with URLs since it handles different user input
// edge cases. This works in Node and all browser except IE11.
// https://developer.mozilla.org/en-US/docs/Web/API/URL
// TODO: Verify our browser support requirements.
if (isServer()) {
const url = new URL(urlBase);
for (const key in params) {
if ({}.hasOwnProperty.call(params, key)) {
url.searchParams.append(key, String(params[key]));
}
}
const result = url.toString();
return result;
}
const qs = getQueryString(params);
const result = urlBase.indexOf('?') !== -1 ? `${urlBase}&${qs}` : `${urlBase}?${qs}`;
return result;
}
export default resolveUrl;