rsnext/packages/next/next-server/lib/router/utils/parse-relative-url.ts
Cowboy Ho 28e12876b8
Fix router not working on some protocol (#16650)
Co-authored-by: Tim Neutkens <timneutkens@me.com>
Co-authored-by: Joe Haddad <joe.haddad@zeit.co>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2020-11-03 16:18:02 -05:00

29 lines
974 B
TypeScript

import { getLocationOrigin } from '../../utils'
import { searchParamsToUrlQuery } from './querystring'
/**
* Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
* (e.g. `./hello`) then at least base must be.
* Absolute urls are rejected with one exception, in the browser, absolute urls that are on
* the current origin will be parsed as relative
*/
export function parseRelativeUrl(url: string, base?: string) {
const globalBase = new URL(
typeof window === 'undefined' ? 'http://n' : getLocationOrigin()
)
const resolvedBase = base ? new URL(base, globalBase) : globalBase
const { pathname, searchParams, search, hash, href, origin } = new URL(
url,
resolvedBase
)
if (origin !== globalBase.origin) {
throw new Error('invariant: invalid relative URL')
}
return {
pathname,
query: searchParamsToUrlQuery(searchParams),
search,
hash,
href: href.slice(globalBase.origin.length),
}
}