6687f280cf
## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import type { Key } from 'next/dist/compiled/path-to-regexp'
|
|
import { pathToRegexp } from 'next/dist/compiled/path-to-regexp'
|
|
import { regexpToFunction } from 'next/dist/compiled/path-to-regexp'
|
|
|
|
interface Options {
|
|
/**
|
|
* A transformer function that will be applied to the regexp generated
|
|
* from the provided path and path-to-regexp.
|
|
*/
|
|
regexModifier?: (regex: string) => string
|
|
/**
|
|
* When true the function will remove all unnamed parameters
|
|
* from the matched parameters.
|
|
*/
|
|
removeUnnamedParams?: boolean
|
|
/**
|
|
* When true the regexp won't allow an optional trailing delimiter
|
|
* to match.
|
|
*/
|
|
strict?: boolean
|
|
}
|
|
|
|
/**
|
|
* Generates a path matcher function for a given path and options based on
|
|
* path-to-regexp. By default the match will be case insensitive, non strict
|
|
* and delimited by `/`.
|
|
*/
|
|
export function getPathMatch(path: string, options?: Options) {
|
|
const keys: Key[] = []
|
|
const regexp = pathToRegexp(path, keys, {
|
|
delimiter: '/',
|
|
sensitive: false,
|
|
strict: options?.strict,
|
|
})
|
|
|
|
const matcher = regexpToFunction(
|
|
options?.regexModifier
|
|
? new RegExp(options.regexModifier(regexp.source), regexp.flags)
|
|
: regexp,
|
|
keys
|
|
)
|
|
|
|
/**
|
|
* A matcher function that will check if a given pathname matches the path
|
|
* given in the builder function. When the path does not match it will return
|
|
* `false` but if it does it will return an object with the matched params
|
|
* merged with the params provided in the second argument.
|
|
*/
|
|
return <T extends { [key: string]: any }>(
|
|
pathname?: string | null,
|
|
params?: any
|
|
): false | T => {
|
|
const res = pathname == null ? false : matcher(pathname)
|
|
if (!res) {
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* If unnamed params are not allowed they must be removed from
|
|
* the matched parameters. path-to-regexp uses "string" for named and
|
|
* "number" for unnamed parameters.
|
|
*/
|
|
if (options?.removeUnnamedParams) {
|
|
for (const key of keys) {
|
|
if (typeof key.name === 'number') {
|
|
delete (res.params as any)[key.name]
|
|
}
|
|
}
|
|
}
|
|
|
|
return { ...params, ...res.params }
|
|
}
|
|
}
|