rsnext/packages/next/shared/lib/router/utils/path-match.ts
hiro 6687f280cf
Fix typos: code comment (#41691)
## 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>
2022-10-24 01:24:32 +00:00

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 }
}
}