2018-01-20 00:46:47 -08:00
|
|
|
import { encode, decode } from 'wherehows-web/utils/encode-decode-uri-component-with-space';
|
2018-09-11 11:11:36 -07:00
|
|
|
import { isBlank } from '@ember/utils';
|
2019-08-31 20:51:14 -07:00
|
|
|
import { isObject } from '@datahub/utils/validators/object';
|
2017-03-24 20:50:42 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct a url by appending a query pair (?key=value | &key=value) to a base url and
|
|
|
|
* encoding the query value in the pair
|
2018-09-26 21:57:16 -07:00
|
|
|
* @param baseUrl the base or original url that will be appended with a query string
|
|
|
|
* @param queryParamOrMap a map of query keys to values or a single query param key
|
|
|
|
* @param queryValue if a queryParam is supplied, then a queryValue can be expected
|
|
|
|
* @param useEncoding flag indicating if the query values should be encoded
|
2017-03-24 20:50:42 -07:00
|
|
|
* @returns {string}
|
|
|
|
*/
|
2018-09-26 21:57:16 -07:00
|
|
|
function buildUrl(baseUrl: string, queryParamOrMap?: {}, useEncoding?: boolean): string;
|
|
|
|
function buildUrl(baseUrl: string, queryParamOrMap?: string, queryValue?: string, useEncoding?: boolean): string;
|
|
|
|
function buildUrl(
|
|
|
|
baseUrl: string,
|
|
|
|
queryParamOrMap: string | Record<string, any> = {},
|
|
|
|
queryValue?: string | boolean,
|
|
|
|
useEncoding: boolean = true
|
|
|
|
): string {
|
2018-03-07 13:31:17 -08:00
|
|
|
if (!baseUrl) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2018-09-11 11:11:36 -07:00
|
|
|
if (!queryParamOrMap) {
|
2018-03-07 13:31:17 -08:00
|
|
|
return baseUrl;
|
|
|
|
}
|
2018-09-11 11:11:36 -07:00
|
|
|
|
2018-09-26 21:57:16 -07:00
|
|
|
let paramMap: Record<string, any> = {};
|
|
|
|
|
|
|
|
// queryParamOrMap is a string then, reify paramMap object with supplied value
|
2018-09-11 11:11:36 -07:00
|
|
|
if (typeof queryParamOrMap === 'string') {
|
|
|
|
paramMap = {
|
2018-09-26 21:57:16 -07:00
|
|
|
[queryParamOrMap]: queryValue
|
2018-09-11 11:11:36 -07:00
|
|
|
};
|
2018-09-26 21:57:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (isObject(queryParamOrMap)) {
|
2018-09-11 11:11:36 -07:00
|
|
|
paramMap = queryParamOrMap;
|
2018-09-26 21:57:16 -07:00
|
|
|
|
|
|
|
if (typeof queryValue === 'boolean') {
|
|
|
|
useEncoding = queryValue;
|
|
|
|
}
|
2018-09-11 11:11:36 -07:00
|
|
|
}
|
|
|
|
|
2018-09-26 21:57:16 -07:00
|
|
|
return Object.keys(paramMap).reduce((url: string, paramKey: string): string => {
|
2018-09-11 11:11:36 -07:00
|
|
|
// If the query string already contains the initial question mark append
|
|
|
|
// kv-pair with ampersand
|
|
|
|
const separator = String(url).includes('?') ? '&' : '?';
|
|
|
|
let paramValue = paramMap[paramKey];
|
|
|
|
|
2018-09-13 18:24:05 -07:00
|
|
|
if (Array.isArray(paramValue)) {
|
|
|
|
paramValue = paramValue.toString();
|
|
|
|
}
|
|
|
|
|
2018-09-11 11:11:36 -07:00
|
|
|
if (isBlank(paramValue)) {
|
|
|
|
return url;
|
2017-03-24 20:50:42 -07:00
|
|
|
}
|
2018-09-11 11:11:36 -07:00
|
|
|
|
2018-09-26 21:57:16 -07:00
|
|
|
if (useEncoding) {
|
|
|
|
// Malformed URL will cause decodeURIComponent to throw
|
|
|
|
// handle and encode queryValue in such instance
|
|
|
|
try {
|
|
|
|
// Check if queryValue is already encoded,
|
|
|
|
// otherwise encode queryValue before composing url
|
|
|
|
// e.g. if user directly enters query in location bar
|
|
|
|
if (decode(paramValue) === paramValue) {
|
|
|
|
paramValue = encode(paramValue);
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (err instanceof URIError) {
|
|
|
|
paramValue = encode(paramValue);
|
|
|
|
}
|
2018-09-11 11:11:36 -07:00
|
|
|
|
2018-09-26 21:57:16 -07:00
|
|
|
throw err;
|
|
|
|
}
|
2017-03-24 20:50:42 -07:00
|
|
|
}
|
|
|
|
|
2018-09-11 11:11:36 -07:00
|
|
|
return `${url}${separator}${paramKey}=${paramValue}`;
|
|
|
|
}, baseUrl);
|
|
|
|
}
|
2017-03-24 20:50:42 -07:00
|
|
|
|
2018-09-11 11:11:36 -07:00
|
|
|
export default buildUrl;
|