2022-06-16 23:43:01 +02:00
|
|
|
import type { NextConfig } from './config'
|
2021-10-20 19:52:11 +02:00
|
|
|
import type { ParsedUrlQuery } from 'querystring'
|
2022-02-11 20:56:25 +01:00
|
|
|
import type { BaseNextRequest, BaseNextResponse } from './base-http'
|
2022-05-19 17:46:21 +02:00
|
|
|
import type {
|
|
|
|
RouteMatch,
|
|
|
|
Params,
|
|
|
|
} from '../shared/lib/router/utils/route-matcher'
|
2022-07-26 23:41:59 +02:00
|
|
|
import type { RouteHas } from '../lib/load-custom-routes'
|
2020-08-13 14:39:36 +02:00
|
|
|
|
2022-02-11 20:56:25 +01:00
|
|
|
import { getNextInternalQuery, NextUrlWithParsedQuery } from './request-meta'
|
2022-04-27 11:50:29 +02:00
|
|
|
import { getPathMatch } from '../shared/lib/router/utils/path-match'
|
2022-05-27 20:29:04 +02:00
|
|
|
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
|
2021-06-30 13:44:40 +02:00
|
|
|
import { normalizeLocalePath } from '../shared/lib/i18n/normalize-locale-path'
|
|
|
|
import { matchHas } from '../shared/lib/router/utils/prepare-destination'
|
2022-05-27 20:29:04 +02:00
|
|
|
import { removePathPrefix } from '../shared/lib/router/utils/remove-path-prefix'
|
2021-11-09 02:28:39 +01:00
|
|
|
import { getRequestMeta } from './request-meta'
|
2022-06-16 23:43:01 +02:00
|
|
|
import { formatNextPathnameInfo } from '../shared/lib/router/utils/format-next-pathname-info'
|
|
|
|
import { getNextPathnameInfo } from '../shared/lib/router/utils/get-next-pathname-info'
|
2018-12-09 22:46:45 +01:00
|
|
|
|
2019-11-18 01:12:48 +01:00
|
|
|
type RouteResult = {
|
|
|
|
finished: boolean
|
|
|
|
pathname?: string
|
2021-10-20 19:52:11 +02:00
|
|
|
query?: ParsedUrlQuery
|
2019-11-18 01:12:48 +01:00
|
|
|
}
|
|
|
|
|
2018-12-09 22:46:45 +01:00
|
|
|
export type Route = {
|
2019-05-27 20:20:33 +02:00
|
|
|
match: RouteMatch
|
2021-03-24 17:50:16 +01:00
|
|
|
has?: RouteHas[]
|
2019-11-18 01:12:48 +01:00
|
|
|
type: string
|
2019-12-23 22:20:17 +01:00
|
|
|
check?: boolean
|
2019-11-18 01:12:48 +01:00
|
|
|
statusCode?: number
|
|
|
|
name: string
|
2022-06-16 23:43:01 +02:00
|
|
|
matchesBasePath?: true
|
|
|
|
matchesLocale?: true
|
|
|
|
matchesLocaleAPIRoutes?: true
|
|
|
|
matchesTrailingSlash?: true
|
2020-12-07 18:36:46 +01:00
|
|
|
internal?: true
|
2019-05-13 15:40:24 +02:00
|
|
|
fn: (
|
2022-01-14 22:01:35 +01:00
|
|
|
req: BaseNextRequest,
|
|
|
|
res: BaseNextResponse,
|
2019-05-13 15:40:24 +02:00
|
|
|
params: Params,
|
2022-08-10 19:00:30 +02:00
|
|
|
parsedUrl: NextUrlWithParsedQuery,
|
2022-09-08 01:38:10 +02:00
|
|
|
upgradeHead?: Buffer
|
2019-11-18 01:12:48 +01:00
|
|
|
) => Promise<RouteResult> | RouteResult
|
2018-12-09 22:46:45 +01:00
|
|
|
}
|
|
|
|
|
2019-12-23 22:20:17 +01:00
|
|
|
export type DynamicRoutes = Array<{ page: string; match: RouteMatch }>
|
|
|
|
|
|
|
|
export type PageChecker = (pathname: string) => Promise<boolean>
|
|
|
|
|
2018-12-09 22:46:45 +01:00
|
|
|
export default class Router {
|
2022-09-08 01:38:10 +02:00
|
|
|
public catchAllMiddleware: ReadonlyArray<Route>
|
|
|
|
|
|
|
|
private readonly headers: ReadonlyArray<Route>
|
|
|
|
private readonly fsRoutes: Route[]
|
|
|
|
private readonly redirects: ReadonlyArray<Route>
|
|
|
|
private readonly rewrites: {
|
|
|
|
beforeFiles: ReadonlyArray<Route>
|
|
|
|
afterFiles: ReadonlyArray<Route>
|
|
|
|
fallback: ReadonlyArray<Route>
|
2021-03-26 16:19:48 +01:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
private readonly catchAllRoute: Route
|
|
|
|
private readonly pageChecker: PageChecker
|
|
|
|
private dynamicRoutes: DynamicRoutes
|
|
|
|
private readonly useFileSystemPublicRoutes: boolean
|
|
|
|
private readonly nextConfig: NextConfig
|
|
|
|
private compiledRoutes: ReadonlyArray<Route>
|
|
|
|
private needsRecompilation: boolean
|
|
|
|
|
|
|
|
/**
|
|
|
|
* context stores information used by the router.
|
|
|
|
*/
|
|
|
|
private readonly context = new WeakMap<
|
|
|
|
BaseNextRequest,
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* pageChecks is the memoized record of all checks made against pages to
|
|
|
|
* help de-duplicate work.
|
|
|
|
*/
|
|
|
|
pageChecks: Record<string, boolean>
|
|
|
|
}
|
|
|
|
>()
|
2019-12-23 22:20:17 +01:00
|
|
|
|
|
|
|
constructor({
|
2020-02-11 00:06:38 +01:00
|
|
|
headers = [],
|
2019-12-23 22:20:17 +01:00
|
|
|
fsRoutes = [],
|
2021-03-26 16:19:48 +01:00
|
|
|
rewrites = {
|
|
|
|
beforeFiles: [],
|
|
|
|
afterFiles: [],
|
|
|
|
fallback: [],
|
|
|
|
},
|
2020-02-11 00:06:38 +01:00
|
|
|
redirects = [],
|
2019-12-23 22:20:17 +01:00
|
|
|
catchAllRoute,
|
2022-06-21 21:04:48 +02:00
|
|
|
catchAllMiddleware = [],
|
2019-12-23 22:20:17 +01:00
|
|
|
dynamicRoutes = [],
|
|
|
|
pageChecker,
|
2020-02-11 00:06:38 +01:00
|
|
|
useFileSystemPublicRoutes,
|
2022-06-16 23:43:01 +02:00
|
|
|
nextConfig,
|
2019-12-23 22:20:17 +01:00
|
|
|
}: {
|
2022-09-08 01:38:10 +02:00
|
|
|
headers: ReadonlyArray<Route>
|
|
|
|
fsRoutes: ReadonlyArray<Route>
|
2021-03-26 16:19:48 +01:00
|
|
|
rewrites: {
|
2022-09-08 01:38:10 +02:00
|
|
|
beforeFiles: ReadonlyArray<Route>
|
|
|
|
afterFiles: ReadonlyArray<Route>
|
|
|
|
fallback: ReadonlyArray<Route>
|
2021-03-26 16:19:48 +01:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
redirects: ReadonlyArray<Route>
|
2019-12-23 22:20:17 +01:00
|
|
|
catchAllRoute: Route
|
2022-09-08 01:38:10 +02:00
|
|
|
catchAllMiddleware: ReadonlyArray<Route>
|
2019-12-23 22:20:17 +01:00
|
|
|
dynamicRoutes: DynamicRoutes | undefined
|
|
|
|
pageChecker: PageChecker
|
2020-02-11 00:06:38 +01:00
|
|
|
useFileSystemPublicRoutes: boolean
|
2022-06-16 23:43:01 +02:00
|
|
|
nextConfig: NextConfig
|
2019-12-23 22:20:17 +01:00
|
|
|
}) {
|
2022-06-16 23:43:01 +02:00
|
|
|
this.nextConfig = nextConfig
|
2020-02-11 00:06:38 +01:00
|
|
|
this.headers = headers
|
2022-09-08 01:38:10 +02:00
|
|
|
this.fsRoutes = [...fsRoutes]
|
2020-02-11 00:06:38 +01:00
|
|
|
this.rewrites = rewrites
|
|
|
|
this.redirects = redirects
|
2019-12-23 22:20:17 +01:00
|
|
|
this.pageChecker = pageChecker
|
|
|
|
this.catchAllRoute = catchAllRoute
|
2022-04-06 16:35:52 +02:00
|
|
|
this.catchAllMiddleware = catchAllMiddleware
|
2019-12-23 22:20:17 +01:00
|
|
|
this.dynamicRoutes = dynamicRoutes
|
2020-02-11 00:06:38 +01:00
|
|
|
this.useFileSystemPublicRoutes = useFileSystemPublicRoutes
|
2022-09-08 01:38:10 +02:00
|
|
|
|
|
|
|
// Perform the initial route compilation.
|
|
|
|
this.compiledRoutes = this.compileRoutes()
|
|
|
|
this.needsRecompilation = false
|
|
|
|
}
|
|
|
|
|
|
|
|
private async checkPage(
|
|
|
|
req: BaseNextRequest,
|
|
|
|
pathname: string
|
|
|
|
): Promise<boolean> {
|
|
|
|
pathname = normalizeLocalePath(pathname, this.locales).pathname
|
|
|
|
|
|
|
|
const context = this.context.get(req)
|
|
|
|
if (!context) {
|
|
|
|
throw new Error(
|
|
|
|
'Invariant: request is not available inside the context, this is an internal error please open an issue.'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (context.pageChecks[pathname] !== undefined) {
|
|
|
|
return context.pageChecks[pathname]
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await this.pageChecker(pathname)
|
|
|
|
context.pageChecks[pathname] = result
|
|
|
|
return result
|
2019-12-23 22:20:17 +01:00
|
|
|
}
|
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
get locales() {
|
|
|
|
return this.nextConfig.i18n?.locales || []
|
|
|
|
}
|
|
|
|
|
|
|
|
get basePath() {
|
|
|
|
return this.nextConfig.basePath || ''
|
|
|
|
}
|
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
public setDynamicRoutes(dynamicRoutes: DynamicRoutes) {
|
|
|
|
this.dynamicRoutes = dynamicRoutes
|
|
|
|
this.needsRecompilation = true
|
2018-12-09 22:46:45 +01:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
public setCatchallMiddleware(catchAllMiddleware: ReadonlyArray<Route>) {
|
|
|
|
this.catchAllMiddleware = catchAllMiddleware
|
|
|
|
this.needsRecompilation = true
|
2022-06-10 19:35:12 +02:00
|
|
|
}
|
2018-12-09 22:46:45 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
public addFsRoute(fsRoute: Route) {
|
|
|
|
// We use unshift so that we're sure the routes is defined before Next's
|
|
|
|
// default routes.
|
2020-06-01 23:00:22 +02:00
|
|
|
this.fsRoutes.unshift(fsRoute)
|
2022-09-08 01:38:10 +02:00
|
|
|
this.needsRecompilation = true
|
2022-08-30 19:56:44 +02:00
|
|
|
}
|
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
private compileRoutes(): ReadonlyArray<Route> {
|
|
|
|
/*
|
|
|
|
Desired routes order
|
|
|
|
- headers
|
|
|
|
- redirects
|
|
|
|
- Check filesystem (including pages), if nothing found continue
|
|
|
|
- User rewrites (checking filesystem and pages each match)
|
|
|
|
*/
|
|
|
|
|
|
|
|
const [middlewareCatchAllRoute] = this.catchAllMiddleware
|
|
|
|
|
|
|
|
return [
|
|
|
|
...(middlewareCatchAllRoute
|
|
|
|
? this.fsRoutes
|
|
|
|
.filter((route) => route.name === '_next/data catchall')
|
|
|
|
.map((route) => ({ ...route, check: false }))
|
|
|
|
: []),
|
|
|
|
...this.headers,
|
|
|
|
...this.redirects,
|
|
|
|
...(this.useFileSystemPublicRoutes && middlewareCatchAllRoute
|
|
|
|
? [middlewareCatchAllRoute]
|
|
|
|
: []),
|
|
|
|
...this.rewrites.beforeFiles,
|
|
|
|
...this.fsRoutes,
|
|
|
|
// We only check the catch-all route if public page routes hasn't been
|
|
|
|
// disabled
|
|
|
|
...(this.useFileSystemPublicRoutes
|
|
|
|
? [
|
|
|
|
{
|
|
|
|
type: 'route',
|
|
|
|
name: 'page checker',
|
|
|
|
match: getPathMatch('/:path*'),
|
|
|
|
fn: async (req, res, params, parsedUrl, upgradeHead) => {
|
|
|
|
const pathname = removeTrailingSlash(parsedUrl.pathname || '/')
|
|
|
|
if (!pathname) {
|
|
|
|
return { finished: false }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (await this.checkPage(req, pathname)) {
|
|
|
|
return this.catchAllRoute.fn(
|
|
|
|
req,
|
|
|
|
res,
|
|
|
|
params,
|
|
|
|
parsedUrl,
|
|
|
|
upgradeHead
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return { finished: false }
|
|
|
|
},
|
|
|
|
} as Route,
|
|
|
|
]
|
|
|
|
: []),
|
|
|
|
...this.rewrites.afterFiles,
|
|
|
|
...(this.rewrites.fallback.length
|
|
|
|
? [
|
|
|
|
{
|
|
|
|
type: 'route',
|
|
|
|
name: 'dynamic route/page check',
|
|
|
|
match: getPathMatch('/:path*'),
|
|
|
|
fn: async (req, res, _params, parsedCheckerUrl, upgradeHead) => {
|
|
|
|
return {
|
|
|
|
finished: await this.checkFsRoutes(
|
|
|
|
req,
|
|
|
|
res,
|
|
|
|
parsedCheckerUrl,
|
|
|
|
upgradeHead
|
|
|
|
),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
} as Route,
|
|
|
|
...this.rewrites.fallback,
|
|
|
|
]
|
|
|
|
: []),
|
|
|
|
|
|
|
|
// We only check the catch-all route if public page routes hasn't been
|
|
|
|
// disabled
|
|
|
|
...(this.useFileSystemPublicRoutes ? [this.catchAllRoute] : []),
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
|
|
|
private async checkFsRoutes(
|
2022-01-14 22:01:35 +01:00
|
|
|
req: BaseNextRequest,
|
|
|
|
res: BaseNextResponse,
|
2022-08-10 19:00:30 +02:00
|
|
|
parsedUrl: NextUrlWithParsedQuery,
|
2022-09-08 01:38:10 +02:00
|
|
|
upgradeHead?: Buffer
|
|
|
|
) {
|
|
|
|
const originalFsPathname = parsedUrl.pathname
|
|
|
|
const fsPathname = removePathPrefix(originalFsPathname!, this.basePath)
|
|
|
|
|
|
|
|
for (const route of this.fsRoutes) {
|
|
|
|
const params = route.match(fsPathname)
|
2022-08-30 19:56:44 +02:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
if (params) {
|
|
|
|
parsedUrl.pathname = fsPathname
|
|
|
|
|
|
|
|
const { finished } = await route.fn(req, res, params, parsedUrl)
|
|
|
|
if (finished) {
|
|
|
|
return true
|
2022-08-30 19:56:44 +02:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
|
|
|
|
parsedUrl.pathname = originalFsPathname
|
2022-08-30 19:56:44 +02:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
let matchedPage = await this.checkPage(req, fsPathname)
|
|
|
|
|
|
|
|
// If we didn't match a page check dynamic routes
|
|
|
|
if (!matchedPage) {
|
|
|
|
const normalizedFsPathname = normalizeLocalePath(
|
|
|
|
fsPathname,
|
|
|
|
this.locales
|
|
|
|
).pathname
|
2019-12-23 22:20:17 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
for (const dynamicRoute of this.dynamicRoutes) {
|
|
|
|
if (dynamicRoute.match(normalizedFsPathname)) {
|
|
|
|
matchedPage = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
// Matched a page or dynamic route so render it using catchAllRoute
|
|
|
|
if (matchedPage) {
|
|
|
|
const params = this.catchAllRoute.match(parsedUrl.pathname)
|
|
|
|
if (!params) {
|
|
|
|
throw new Error(
|
|
|
|
`Invariant: could not match params, this is an internal error please open an issue.`
|
|
|
|
)
|
|
|
|
}
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
parsedUrl.pathname = fsPathname
|
|
|
|
parsedUrl.query._nextBubbleNoFallback = '1'
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
const { finished } = await this.catchAllRoute.fn(
|
|
|
|
req,
|
|
|
|
res,
|
|
|
|
params,
|
|
|
|
parsedUrl,
|
|
|
|
upgradeHead
|
|
|
|
)
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
return finished
|
|
|
|
}
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
return false
|
|
|
|
}
|
2021-03-26 16:19:48 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
async execute(
|
|
|
|
req: BaseNextRequest,
|
|
|
|
res: BaseNextResponse,
|
|
|
|
parsedUrl: NextUrlWithParsedQuery,
|
|
|
|
upgradeHead?: Buffer
|
|
|
|
): Promise<boolean> {
|
|
|
|
// Only recompile if the routes need to be recompiled, this should only
|
|
|
|
// happen in development.
|
|
|
|
if (this.needsRecompilation) {
|
|
|
|
this.compiledRoutes = this.compileRoutes()
|
|
|
|
this.needsRecompilation = false
|
|
|
|
}
|
2022-04-18 20:16:39 +02:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
if (this.context.has(req)) {
|
|
|
|
throw new Error(
|
|
|
|
`Invariant: request has already been processed: ${req.url}, this is an internal error please open an issue.`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
this.context.set(req, { pageChecks: {} })
|
2022-09-07 22:24:29 +02:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
try {
|
|
|
|
// Create a deep copy of the parsed URL.
|
|
|
|
const parsedUrlUpdated = {
|
|
|
|
...parsedUrl,
|
|
|
|
query: {
|
|
|
|
...parsedUrl.query,
|
|
|
|
},
|
2021-03-26 16:19:48 +01:00
|
|
|
}
|
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
for (const route of this.compiledRoutes) {
|
2022-08-10 19:00:30 +02:00
|
|
|
// only process rewrites for upgrade request
|
2022-09-08 01:38:10 +02:00
|
|
|
if (upgradeHead && route.type !== 'rewrite') {
|
2022-08-10 19:00:30 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
const originalPathname = parsedUrlUpdated.pathname as string
|
|
|
|
const pathnameInfo = getNextPathnameInfo(originalPathname, {
|
|
|
|
nextConfig: this.nextConfig,
|
|
|
|
parseData: false,
|
|
|
|
})
|
|
|
|
|
|
|
|
if (
|
|
|
|
pathnameInfo.locale &&
|
2022-09-08 01:38:10 +02:00
|
|
|
!route.matchesLocaleAPIRoutes &&
|
2022-06-16 23:43:01 +02:00
|
|
|
pathnameInfo.pathname.match(/^\/api(?:\/|$)/)
|
|
|
|
) {
|
|
|
|
continue
|
2022-04-18 20:16:39 +02:00
|
|
|
}
|
2020-07-12 21:03:49 +02:00
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
if (getRequestMeta(req, '_nextHadBasePath')) {
|
|
|
|
pathnameInfo.basePath = this.basePath
|
|
|
|
}
|
2022-03-01 21:53:25 +01:00
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
const basePath = pathnameInfo.basePath
|
2022-09-08 01:38:10 +02:00
|
|
|
if (!route.matchesBasePath) {
|
2022-06-16 23:43:01 +02:00
|
|
|
pathnameInfo.basePath = ''
|
|
|
|
}
|
2022-03-01 21:53:25 +01:00
|
|
|
|
2020-12-07 18:36:46 +01:00
|
|
|
if (
|
2022-09-08 01:38:10 +02:00
|
|
|
route.matchesLocale &&
|
|
|
|
parsedUrlUpdated.query.__nextLocale &&
|
2022-06-16 23:43:01 +02:00
|
|
|
!pathnameInfo.locale
|
2020-12-07 18:36:46 +01:00
|
|
|
) {
|
2022-09-08 01:38:10 +02:00
|
|
|
pathnameInfo.locale = parsedUrlUpdated.query.__nextLocale
|
2020-11-12 06:26:48 +01:00
|
|
|
}
|
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
if (
|
2022-09-08 01:38:10 +02:00
|
|
|
!route.matchesLocale &&
|
2022-06-16 23:43:01 +02:00
|
|
|
pathnameInfo.locale === this.nextConfig.i18n?.defaultLocale &&
|
|
|
|
pathnameInfo.locale
|
|
|
|
) {
|
|
|
|
pathnameInfo.locale = undefined
|
|
|
|
}
|
2022-04-18 20:16:39 +02:00
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
if (
|
2022-09-08 01:38:10 +02:00
|
|
|
route.matchesTrailingSlash &&
|
2022-06-16 23:43:01 +02:00
|
|
|
getRequestMeta(req, '__nextHadTrailingSlash')
|
|
|
|
) {
|
|
|
|
pathnameInfo.trailingSlash = true
|
2020-11-17 22:46:46 +01:00
|
|
|
}
|
2020-10-29 18:48:54 +01:00
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
const matchPathname = formatNextPathnameInfo({
|
|
|
|
ignorePrefix: true,
|
|
|
|
...pathnameInfo,
|
|
|
|
})
|
2021-03-24 17:50:16 +01:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
let params = route.match(matchPathname)
|
|
|
|
if (route.has && params) {
|
|
|
|
const hasParams = matchHas(req, route.has, parsedUrlUpdated.query)
|
2022-04-18 20:16:39 +02:00
|
|
|
if (hasParams) {
|
2022-09-08 01:38:10 +02:00
|
|
|
Object.assign(params, hasParams)
|
2022-04-18 20:16:39 +02:00
|
|
|
} else {
|
2022-09-08 01:38:10 +02:00
|
|
|
params = false
|
2022-04-18 20:16:39 +02:00
|
|
|
}
|
2021-03-24 17:50:16 +01:00
|
|
|
}
|
2019-11-18 01:12:48 +01:00
|
|
|
|
2022-06-16 23:43:01 +02:00
|
|
|
/**
|
|
|
|
* If it is a matcher that doesn't match the basePath (like the public
|
|
|
|
* directory) but Next.js is configured to use a basePath that was
|
|
|
|
* never there, we consider this an invalid match and keep routing.
|
|
|
|
*/
|
|
|
|
if (
|
2022-09-08 01:38:10 +02:00
|
|
|
params &&
|
2022-06-16 23:43:01 +02:00
|
|
|
this.basePath &&
|
2022-09-08 01:38:10 +02:00
|
|
|
!route.matchesBasePath &&
|
2022-06-16 23:43:01 +02:00
|
|
|
!getRequestMeta(req, '_nextDidRewrite') &&
|
|
|
|
!basePath
|
|
|
|
) {
|
|
|
|
continue
|
|
|
|
}
|
2020-07-12 21:03:49 +02:00
|
|
|
|
2022-09-08 01:38:10 +02:00
|
|
|
if (params) {
|
2022-06-16 23:43:01 +02:00
|
|
|
parsedUrlUpdated.pathname = matchPathname
|
2022-09-08 01:38:10 +02:00
|
|
|
const result = await route.fn(
|
2022-04-18 20:16:39 +02:00
|
|
|
req,
|
|
|
|
res,
|
2022-09-08 01:38:10 +02:00
|
|
|
params,
|
2022-08-10 19:00:30 +02:00
|
|
|
parsedUrlUpdated,
|
|
|
|
upgradeHead
|
2022-04-18 20:16:39 +02:00
|
|
|
)
|
|
|
|
if (result.finished) {
|
|
|
|
return true
|
|
|
|
}
|
2019-11-18 01:12:48 +01:00
|
|
|
|
2022-04-18 20:16:39 +02:00
|
|
|
if (result.pathname) {
|
|
|
|
parsedUrlUpdated.pathname = result.pathname
|
2022-09-08 01:38:10 +02:00
|
|
|
} else {
|
|
|
|
// since the fs route didn't finish routing we need to re-add the
|
|
|
|
// basePath to continue checking with the basePath present
|
|
|
|
parsedUrlUpdated.pathname = originalPathname
|
2022-04-18 20:16:39 +02:00
|
|
|
}
|
2019-12-23 22:20:17 +01:00
|
|
|
|
2022-04-18 20:16:39 +02:00
|
|
|
if (result.query) {
|
|
|
|
parsedUrlUpdated.query = {
|
|
|
|
...getNextInternalQuery(parsedUrlUpdated.query),
|
|
|
|
...result.query,
|
|
|
|
}
|
2019-12-31 21:13:55 +01:00
|
|
|
}
|
|
|
|
|
2022-04-18 20:16:39 +02:00
|
|
|
// check filesystem
|
2022-09-08 01:38:10 +02:00
|
|
|
if (
|
|
|
|
route.check &&
|
|
|
|
(await this.checkFsRoutes(req, res, parsedUrlUpdated))
|
|
|
|
) {
|
|
|
|
return true
|
2019-12-23 22:20:17 +01:00
|
|
|
}
|
|
|
|
}
|
2018-12-09 22:46:45 +01:00
|
|
|
}
|
2022-09-08 01:38:10 +02:00
|
|
|
|
|
|
|
// All routes were tested, none were found.
|
2022-04-18 20:16:39 +02:00
|
|
|
return false
|
|
|
|
} finally {
|
2022-09-08 01:38:10 +02:00
|
|
|
this.context.delete(req)
|
2018-12-09 22:46:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|