url.ts
1 /** 2 * Remove the scheme and separators from the given URL. 3 * 4 * @example 5 * ```javascript 6 * removeScheme('https://music.apple.com/browse') // => 'music.apple.com/browse' 7 * removeScheme('apple-music://music.apple.com/browse') // => 'music.apple.com/browse' 8 * removeScheme('music.apple.com/browse') // => 'music.apple.com/browse' 9 * ``` 10 */ 11 export function removeScheme( 12 url: string | URL | null | undefined, 13 ): string | undefined { 14 if (url === null || url === undefined) { 15 return undefined; 16 } 17 18 return String(url).replace(/^((?:[^:]*:[/]{0,2})|(?::?\/\/))/i, ''); 19 } 20 21 /** 22 * Strip scheme and host (hostname + port) from a URL, leaving just the path, query 23 * params, and hash. 24 * 25 * @param {string} url The URL possibly containing a host 26 * @returns {string} hostlessUrl The url without its host 27 */ 28 export function removeHost( 29 url: string | URL | null | undefined, 30 ): string | undefined { 31 return removeScheme(url)?.replace(/^([^/]*)/i, ''); 32 } 33 34 /** 35 * Strip query params and fragment from a URL. 36 */ 37 export function removeQueryParams( 38 url: string | URL | undefined, 39 ): string | undefined { 40 if (url === undefined) { 41 return undefined; 42 } 43 44 const value = String(url); 45 const splitIndex = value.indexOf('?'); 46 return splitIndex >= 0 ? value.slice(0, splitIndex) : value; 47 } 48 49 export function getBaseUrl(): string { 50 const currentUrl = new URL(window.location.href); 51 return `${currentUrl.protocol}//${currentUrl.host}`; 52 } 53 54 export function buildUrl(props: { 55 protocol?: string; 56 hostname: string; 57 pathname?: string | string[]; 58 queryParams?: string | Record<string, string>; 59 hash?: string; 60 }): URL { 61 const { 62 hostname, 63 pathname = '/', 64 queryParams = {}, 65 protocol = 'https', 66 hash = '', 67 } = props; 68 69 // Base URL with domain 70 const url = new URL(protocol + '://' + removeScheme(hostname)); 71 72 // URL path 73 url.pathname = Array.isArray(pathname) 74 ? '/' + pathname.map(encodeURIComponent).join('/').replace(/[/]+/, '/') 75 : pathname; 76 77 // URL search (a.k.a. queryParams) 78 if (typeof queryParams === 'string') { 79 url.search = queryParams; 80 } else { 81 for (const [key, value] of Object.entries(queryParams)) { 82 url.searchParams.set(key, value); 83 } 84 } 85 86 // URL hash 87 url.hash = hash; 88 89 return url; 90 }