2020-08-13 14:39:36 +02:00
|
|
|
import { ParsedUrlQuery } from 'querystring'
|
2020-08-21 21:11:25 +02:00
|
|
|
import pathMatch from './path-match'
|
2021-03-24 17:50:16 +01:00
|
|
|
import prepareDestination, { matchHas } from './prepare-destination'
|
2020-08-13 14:39:36 +02:00
|
|
|
import { Rewrite } from '../../../../lib/load-custom-routes'
|
2020-09-10 02:55:22 +02:00
|
|
|
import { removePathTrailingSlash } from '../../../../client/normalize-trailing-slash'
|
2020-12-04 11:14:55 +01:00
|
|
|
import { normalizeLocalePath } from '../../i18n/normalize-locale-path'
|
2021-01-22 00:40:23 +01:00
|
|
|
import { parseRelativeUrl } from './parse-relative-url'
|
|
|
|
import { delBasePath } from '../router'
|
2020-08-13 14:39:36 +02:00
|
|
|
|
|
|
|
const customRouteMatcher = pathMatch(true)
|
|
|
|
|
|
|
|
export default function resolveRewrites(
|
|
|
|
asPath: string,
|
|
|
|
pages: string[],
|
|
|
|
rewrites: Rewrite[],
|
2020-08-22 07:15:45 +02:00
|
|
|
query: ParsedUrlQuery,
|
2020-12-04 11:14:55 +01:00
|
|
|
resolveHref: (path: string) => string,
|
|
|
|
locales?: string[]
|
2021-01-22 00:40:23 +01:00
|
|
|
): {
|
|
|
|
matchedPage: boolean
|
|
|
|
parsedAs: ReturnType<typeof parseRelativeUrl>
|
|
|
|
asPath: string
|
|
|
|
resolvedHref?: string
|
|
|
|
} {
|
|
|
|
let matchedPage = false
|
|
|
|
let parsedAs = parseRelativeUrl(asPath)
|
|
|
|
let fsPathname = removePathTrailingSlash(
|
|
|
|
normalizeLocalePath(delBasePath(parsedAs.pathname), locales).pathname
|
|
|
|
)
|
|
|
|
let resolvedHref
|
|
|
|
|
|
|
|
if (!pages.includes(fsPathname)) {
|
2020-08-13 14:39:36 +02:00
|
|
|
for (const rewrite of rewrites) {
|
|
|
|
const matcher = customRouteMatcher(rewrite.source)
|
2021-03-24 17:50:16 +01:00
|
|
|
let params = matcher(parsedAs.pathname)
|
|
|
|
|
|
|
|
if (rewrite.has && params) {
|
|
|
|
const hasParams = matchHas(
|
|
|
|
{
|
|
|
|
headers: {
|
|
|
|
host: document.location.hostname,
|
|
|
|
},
|
|
|
|
cookies: Object.fromEntries(
|
|
|
|
document.cookie.split('; ').map((item) => {
|
|
|
|
const [key, ...value] = item.split('=')
|
|
|
|
return [key, value.join('=')]
|
|
|
|
})
|
|
|
|
),
|
|
|
|
} as any,
|
|
|
|
rewrite.has,
|
|
|
|
parsedAs.query
|
|
|
|
)
|
|
|
|
|
|
|
|
if (hasParams) {
|
|
|
|
Object.assign(params, hasParams)
|
|
|
|
} else {
|
|
|
|
params = false
|
|
|
|
}
|
|
|
|
}
|
2020-08-13 14:39:36 +02:00
|
|
|
|
|
|
|
if (params) {
|
|
|
|
if (!rewrite.destination) {
|
|
|
|
// this is a proxied rewrite which isn't handled on the client
|
|
|
|
break
|
|
|
|
}
|
|
|
|
const destRes = prepareDestination(
|
|
|
|
rewrite.destination,
|
|
|
|
params,
|
|
|
|
query,
|
2020-12-04 11:14:55 +01:00
|
|
|
true
|
2020-08-13 14:39:36 +02:00
|
|
|
)
|
2021-01-22 00:40:23 +01:00
|
|
|
parsedAs = destRes.parsedDestination
|
|
|
|
asPath = destRes.newUrl
|
2020-08-13 14:39:36 +02:00
|
|
|
Object.assign(query, destRes.parsedDestination.query)
|
|
|
|
|
2021-01-22 00:40:23 +01:00
|
|
|
fsPathname = removePathTrailingSlash(
|
|
|
|
normalizeLocalePath(delBasePath(asPath), locales).pathname
|
|
|
|
)
|
2020-12-04 11:14:55 +01:00
|
|
|
|
|
|
|
if (pages.includes(fsPathname)) {
|
2020-08-13 14:39:36 +02:00
|
|
|
// check if we now match a page as this means we are done
|
|
|
|
// resolving the rewrites
|
2021-01-22 00:40:23 +01:00
|
|
|
matchedPage = true
|
|
|
|
resolvedHref = fsPathname
|
2020-08-13 14:39:36 +02:00
|
|
|
break
|
|
|
|
}
|
2020-08-22 07:15:45 +02:00
|
|
|
|
|
|
|
// check if we match a dynamic-route, if so we break the rewrites chain
|
2021-01-22 00:40:23 +01:00
|
|
|
resolvedHref = resolveHref(fsPathname)
|
2020-08-22 07:15:45 +02:00
|
|
|
|
|
|
|
if (resolvedHref !== asPath && pages.includes(resolvedHref)) {
|
2021-01-22 00:40:23 +01:00
|
|
|
matchedPage = true
|
2020-08-22 07:15:45 +02:00
|
|
|
break
|
|
|
|
}
|
2020-08-13 14:39:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-22 00:40:23 +01:00
|
|
|
return {
|
|
|
|
asPath,
|
|
|
|
parsedAs,
|
|
|
|
matchedPage,
|
|
|
|
resolvedHref,
|
|
|
|
}
|
2020-08-13 14:39:36 +02:00
|
|
|
}
|