Fix rewrite/dynamic interpolation E2E cases (#37669)

This commit is contained in:
JJ Kasper 2022-06-13 15:46:19 -05:00 committed by GitHub
parent 3b9f180d25
commit 668466bc07
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 27 deletions

View file

@ -340,7 +340,10 @@ export function getUtils({
}
}
function normalizeDynamicRouteParams(params: ParsedUrlQuery) {
function normalizeDynamicRouteParams(
params: ParsedUrlQuery,
ignoreOptional?: boolean
) {
let hasValidParams = true
if (!defaultRouteRegex) return { params, hasValidParams: false }
@ -361,7 +364,10 @@ export function getUtils({
})
: value?.includes(defaultValue as string)
if (isDefaultValue || (typeof value === 'undefined' && !isOptional)) {
if (
isDefaultValue ||
(typeof value === 'undefined' && !(isOptional && ignoreOptional))
) {
hasValidParams = false
}

View file

@ -517,27 +517,20 @@ export default abstract class Server<ServerOptions extends Options = Options> {
parsedUrl.query
)
// for prerendered ISR paths we attempt parsing the route
// params from the URL directly as route-matches may not
// contain the correct values due to the filesystem path
// matching before the dynamic route has been matched
if (
!isDynamicRoute(normalizedUrlPath) ||
!isDynamicRoute(matchedPath)
!paramsResult.hasValidParams &&
pageIsDynamic &&
!isDynamicRoute(normalizedUrlPath)
) {
// we favor matching against req.url although if there's a
// rewrite and it's SSR we use the x-matched-path instead
let matcherRes = utils.dynamicRouteMatcher?.(normalizedUrlPath)
let matcherParams = utils.dynamicRouteMatcher?.(normalizedUrlPath)
if (!matcherRes) {
matcherRes = utils.dynamicRouteMatcher?.(matchedPath)
}
const parsedResult = utils.normalizeDynamicRouteParams(
matcherRes || {}
)
if (parsedResult.hasValidParams) {
if (paramsResult.hasValidParams) {
Object.assign(paramsResult.params, parsedResult.params)
} else {
paramsResult = parsedResult
}
if (matcherParams) {
Object.assign(paramsResult.params, matcherParams)
paramsResult.hasValidParams = true
}
}
@ -547,9 +540,8 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (
req.headers['x-now-route-matches'] &&
(!paramsResult.hasValidParams ||
(isDynamicRoute(matchedPath) &&
isDynamicRoute(normalizedUrlPath)))
isDynamicRoute(matchedPath) &&
!paramsResult.hasValidParams
) {
const opts: Record<string, string> = {}
const routeParams = utils.getParamsFromRouteMatches(
@ -561,17 +553,29 @@ export default abstract class Server<ServerOptions extends Options = Options> {
if (opts.locale) {
parsedUrl.query.__nextLocale = opts.locale
}
paramsResult = utils.normalizeDynamicRouteParams(routeParams)
paramsResult = utils.normalizeDynamicRouteParams(
routeParams,
true
)
if (paramsResult.hasValidParams) {
params = paramsResult.params
}
}
// handle the actual dynamic route name being requested
if (
pageIsDynamic &&
utils.defaultRouteMatches &&
normalizedUrlPath === srcPathname &&
!paramsResult.hasValidParams &&
!utils.normalizeDynamicRouteParams({ ...params }, true)
.hasValidParams
) {
params = utils.defaultRouteMatches
}
if (params) {
if (!paramsResult.hasValidParams) {
params = utils.normalizeDynamicRouteParams(params).params
}
matchedPath = utils.interpolateDynamicPath(srcPathname, params)
req.url = utils.interpolateDynamicPath(req.url!, params)
}

View file

@ -1029,6 +1029,23 @@ describe('should set-up next', () => {
const html = await res.text()
const $ = cheerio.load(html)
expect($('#slug-page').text()).toBe('[slug] page')
expect(JSON.parse($('#router').text()).query).toEqual({
slug: 'slug-1',
})
const res2 = await fetchViaHTTP(appPort, '/[slug]', undefined, {
headers: {
'x-matched-path': '/[slug]',
},
redirect: 'manual',
})
const html2 = await res2.text()
const $2 = cheerio.load(html2)
expect($2('#slug-page').text()).toBe('[slug] page')
expect(JSON.parse($2('#router').text()).query).toEqual({
slug: '[slug]',
})
})
it('should have correct asPath on dynamic SSG page correctly', async () => {