e65c56e7e6
Currently there is a lot of mutation in the Next.js Server and the checks for Locale are directly coded in the general request handler. Ideally, we should have a function where we just pass the request input (url + headers + config) and generate a bunch of metadata that analyzes it generating all metadata we might require for both the URL and i18n + basePath information. This PR brings: - A new parsing function `parseUrl` that joins parsing an absolute/relative URL into a data structure compatible with the Node parsing output but missing redundant properties. - A wrapper `parseNextURL` that extends `parseUrl` analyzing `i18n` and `basePath` based on the provided configuration, url and headers. This function is pure and stateless so it can be used outside of the Next.js context. - Types improvements and reuse. - Refactors `next-server.ts` request handling using the above mentioned functions so that the code there just apply effects to the `req` object and the `parsedUrl.query` leaving the code much more straightforward. - Refactors `getRouteRegex` decomposing in two different functions where `getParametrizedRoute` can be used to retrieve the serializable data that is used to generate the Regex.
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import { getCookieParser } from '../../../../server/api-utils'
|
|
import { getLocaleMetadata } from '../../i18n/get-locale-metadata'
|
|
import { parseUrl } from './parse-url'
|
|
import type { NextConfig, DomainLocale } from '../../../../server/config-shared'
|
|
import type { ParsedUrl } from './parse-url'
|
|
import type { PathLocale } from '../../i18n/normalize-locale-path'
|
|
|
|
interface Params {
|
|
headers?: { [key: string]: string | string[] | undefined }
|
|
nextConfig: NextConfig
|
|
url?: string
|
|
}
|
|
|
|
export function parseNextUrl({ headers, nextConfig, url = '/' }: Params) {
|
|
const urlParsed: ParsedNextUrl = parseUrl(url)
|
|
const { basePath } = nextConfig
|
|
|
|
if (basePath && urlParsed.pathname.startsWith(basePath)) {
|
|
urlParsed.pathname = urlParsed.pathname.replace(basePath, '') || '/'
|
|
urlParsed.basePath = basePath
|
|
}
|
|
|
|
if (nextConfig.i18n) {
|
|
urlParsed.locale = getLocaleMetadata({
|
|
cookies: getCookieParser(headers || {}),
|
|
headers: headers,
|
|
nextConfig: {
|
|
basePath: nextConfig.basePath,
|
|
i18n: nextConfig.i18n,
|
|
trailingSlash: nextConfig.trailingSlash,
|
|
},
|
|
url: urlParsed,
|
|
})
|
|
|
|
if (urlParsed.locale?.path.detectedLocale) {
|
|
urlParsed.pathname = urlParsed.locale.path.pathname
|
|
}
|
|
}
|
|
|
|
return urlParsed
|
|
}
|
|
|
|
export interface ParsedNextUrl extends ParsedUrl {
|
|
basePath?: string
|
|
locale?: {
|
|
defaultLocale: string
|
|
domain?: DomainLocale
|
|
locale: string
|
|
path: PathLocale
|
|
redirect?: string
|
|
trailingSlash?: boolean
|
|
}
|
|
}
|