Created
February 27, 2019 07:53
-
-
Save Toxicable/be4b5ff2b290b9f93320cab61150d71d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as querystring from 'querystring'; | |
function isObject(arg: any) { | |
return typeof(arg) === 'object' && arg !== null; | |
} | |
const slashedProtocol = { | |
http: true, | |
https: true, | |
ftp: true, | |
gopher: true, | |
file: true, | |
ws: true, | |
wss: true, | |
'http:': true, | |
'https:': true, | |
'ftp:': true, | |
'gopher:': true, | |
'file:': true, | |
'ws:': true, | |
'wss:': true, | |
} | |
interface FormatUrlArgs { | |
protocol?: string, | |
slashes?: string, | |
auth?: string, | |
host?: string, | |
port?: string, | |
hostname?: string, | |
hash?: string, | |
search?: string, | |
query?: string, | |
pathname?: string, | |
path?: string, | |
href?: string, | |
} | |
// tslint:disable-next-line:cyclomatic-complexity | |
function formatUrl(url: FormatUrlArgs) { | |
let auth = url.auth || ''; | |
if (auth) { | |
auth = encodeURIComponent(auth); | |
auth = auth.replace(/%3A/i, ':'); | |
auth += '@'; | |
} | |
let protocol = url.protocol || ''; | |
let pathname = url.pathname || ''; | |
let hash = url.hash || ''; | |
let host = url.host || ''; | |
let query = ''; | |
if (url.host) { | |
host = auth + url.host; | |
} else if (url.hostname) { | |
host = auth + (typeof url.hostname === 'string' && url.hostname.indexOf(':') === -1 ? | |
url.hostname : | |
'[' + url.hostname + ']'); | |
if (url.port) { | |
host += ':' + url.port; | |
} | |
} | |
if (url.query && isObject(url.query) && Object.keys(url.query).length) { | |
query = querystring.stringify(url.query); | |
} | |
let search = url.search || (query && ('?' + query)) || ''; | |
if (protocol && protocol.substr(-1) !== ':') { | |
protocol += ':' | |
} | |
// only the slashedProtocols get the //. Not mailto:, xmpp:, etc. | |
// unless they had them to begin with. | |
if (url.slashes || | |
(!protocol || slashedProtocol[protocol])) { | |
host = '//' + (host || ''); | |
if (pathname && pathname.charAt(0) !== '/') { | |
pathname = '/' + pathname; | |
} | |
} else if (!host) { | |
host = ''; | |
} | |
if (hash && hash.charAt(0) !== '#') { | |
hash = '#' + hash; | |
} | |
if (search && search.charAt(0) !== '?') { | |
search = '?' + search; | |
} | |
pathname = pathname.replace(/[?#]/g, match => { | |
return encodeURIComponent(match); | |
}); | |
search = search.replace('#', '%23'); | |
return protocol + host + pathname + search + hash; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment