rsnext/packages/next/lib/try-to-parse-path.ts
Javi Velasco f354f46b3f
Deprecate nested Middleware in favor of root middleware (#36772)
This PR deprecates declaring a middleware under `pages` in favour of the project root naming it after `middleware` instead of `_middleware`. This is in the context of having a simpler execution model for middleware and also ships some refactor work. There is a ton of a code to be simplified after this deprecation but I think it is best to do it progressively.

With this PR, when in development, we will **fail** whenever we find a nested middleware but we do **not** include it in the compiler so if the project is using it, it will no longer work. For production we will **fail** too so it will not be possible to build and deploy a deprecated middleware. The error points to a page that should also be reviewed as part of **documentation**.

Aside from the deprecation, this migrates all middleware tests to work with a single middleware. It also splits tests into multiple folders to make them easier to isolate and work with. Finally it ships some small code refactor and simplifications.
2022-05-19 15:46:21 +00: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[]
}
/**
* 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
}
/**
* 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
)
}
}