rsnext/packages/next/shared/lib/router/utils/parse-relative-url.ts
Javi Velasco 7584b02b34
Remove Middleware Preflight (#37490)
* Refactor data fetching to support getting headers

* Relax `getNextPathnameInfo` type

* Add test for middleware internal redirects

* Export `ParsedRelativeUrl` type

* Refactor `getMiddlewareEffects`

* Move rewrite i18n test to middleware rewrite tests

* Fix bug parsing pathname info

* Normalize data requests to page requests for middleware

* Ensure there is a header `x-nextjs-matched-path` for middleware rewrites on data requests

* Extract `getDataHref` to a function

* Stop using `getDataHref` for flight

* Always set the query in `dataHref` independently of if it is SSG

* Add test for recursive rewrites

* Refactor dynamicPath validation to `matchHrefAndAsPath`

* Add `dataHref` to `FetchDataOutput`

* Extract `matchesMiddleware` function

* Add `hasMiddleware` option to `fetchNextData`

* Move preflight test

* Remove preflight test

* Add middleware prefetch tests

* Remove preflight

* Attempt to reduce bundle size

Include `withMiddlewareEffects` and `matchHrefAndAsPath` into `router`

Bring `getDataHref` back to `page-loader`

Bring `resolveDynamicRoute` back to `router`

* Reduce arg duplication for `withMiddlewareEffects`

* Remove some async/await and spreads to reduce bundle size

* Upgrade `edge-runtime` & clone `Request` on redirects to mutate headers

* Add some rewrite tests

Co-authored-by: Kiko Beats <josefrancisco.verdu@gmail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-06-08 10:41:28 -05:00

47 lines
1.3 KiB
TypeScript

import type { ParsedUrlQuery } from 'querystring'
import { getLocationOrigin } from '../../utils'
import { searchParamsToUrlQuery } from './querystring'
export interface ParsedRelativeUrl {
hash: string
href: string
pathname: string
query: ParsedUrlQuery
search: string
}
/**
* 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
): ParsedRelativeUrl {
const globalBase = new URL(
typeof window === 'undefined' ? 'http://n' : getLocationOrigin()
)
const resolvedBase = base
? new URL(base, globalBase)
: url.startsWith('.')
? new URL(typeof window === 'undefined' ? 'http://n' : window.location.href)
: globalBase
const { pathname, searchParams, search, hash, href, origin } = new URL(
url,
resolvedBase
)
if (origin !== globalBase.origin) {
throw new Error(`invariant: invalid relative URL, router received ${url}`)
}
return {
pathname,
query: searchParamsToUrlQuery(searchParams),
search,
hash,
href: href.slice(globalBase.origin.length),
}
}