rsnext/packages/next/lib/try-to-parse-path.ts
Tim Neutkens 4cd8b23032
Enable @typescript-eslint/no-use-before-define for functions (#39602)
Follow-up to the earlier enabling of classes/variables etc.

Bug

 Related issues linked using fixes #number
 Integration tests added
 Errors have 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 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

Co-authored-by: Steven <steven@ceriously.com>
2022-08-15 10:29:51 -04:00

65 lines
1.9 KiB
TypeScript

import type { Token } from 'next/dist/compiled/path-to-regexp'
import { parse, tokensToRegexp } from 'next/dist/compiled/path-to-regexp'
import { parse as parseURL } from 'url'
import isError from './is-error'
interface ParseResult {
error?: any
parsedPath: string
regexStr?: string
route: string
tokens?: Token[]
}
/**
* If there is an error show our error link but still show original error or
* a formatted one if we can
*/
function reportError({ route, parsedPath }: ParseResult, err: any) {
let errMatches
if (isError(err) && (errMatches = err.message.match(/at (\d{0,})/))) {
const position = parseInt(errMatches[1], 10)
console.error(
`\nError parsing \`${route}\` ` +
`https://nextjs.org/docs/messages/invalid-route-source\n` +
`Reason: ${err.message}\n\n` +
` ${parsedPath}\n` +
` ${new Array(position).fill(' ').join('')}^\n`
)
} else {
console.error(
`\nError parsing ${route} https://nextjs.org/docs/messages/invalid-route-source`,
err
)
}
}
/**
* Attempts to parse a given route with `path-to-regexp` and returns an object
* with the result. Whenever an error happens on parse, it will print an error
* attempting to find the error position and showing a link to the docs. When
* `handleUrl` is set to `true` it will also attempt to parse the route
* and use the resulting pathname to parse with `path-to-regexp`.
*/
export function tryToParsePath(
route: string,
options?: {
handleUrl?: boolean
}
): ParseResult {
const result: ParseResult = { route, parsedPath: route }
try {
if (options?.handleUrl) {
const parsed = parseURL(route, true)
result.parsedPath = `${parsed.pathname!}${parsed.hash || ''}`
}
result.tokens = parse(result.parsedPath)
result.regexStr = tokensToRegexp(result.tokens).source
} catch (err) {
reportError(result, err)
result.error = err
}
return result
}