cefbcadf45
URL paths are case sensitive, MacOS file system is case insensitive. This PR makes sure development mode doesn't find pages that don't have the casing as specified in the URL. Will clean up and write a test when agreed on this approach. Fixes https://github.com/zeit/next.js/issues/8825 Fixes https://github.com/zeit/next.js/issues/8847 Fixes https://github.com/zeit/next.js/issues/9080
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
import { join, sep as pathSeparator, normalize } from 'path'
|
|
import chalk from 'next/dist/compiled/chalk'
|
|
import { isWriteable } from '../../build/is-writeable'
|
|
import { warn } from '../../build/output/log'
|
|
import fs from 'fs'
|
|
import { promisify } from 'util'
|
|
|
|
const readdir = promisify(fs.readdir)
|
|
|
|
async function isTrueCasePagePath(pagePath: string, pagesDir: string) {
|
|
const pageSegments = normalize(pagePath).split(pathSeparator).filter(Boolean)
|
|
|
|
const segmentExistsPromises = pageSegments.map(async (segment, i) => {
|
|
const segmentParentDir = join(pagesDir, ...pageSegments.slice(0, i))
|
|
const parentDirEntries = await readdir(segmentParentDir)
|
|
return parentDirEntries.includes(segment)
|
|
})
|
|
|
|
return (await Promise.all(segmentExistsPromises)).every(Boolean)
|
|
}
|
|
|
|
export async function findPageFile(
|
|
rootDir: string,
|
|
normalizedPagePath: string,
|
|
pageExtensions: string[]
|
|
): Promise<string | null> {
|
|
let foundPagePaths: string[] = []
|
|
|
|
for (const extension of pageExtensions) {
|
|
const relativePagePath = `${normalizedPagePath}.${extension}`
|
|
const pagePath = join(rootDir, relativePagePath)
|
|
|
|
// only /index and /sub/index when /sub/index/index.js is allowed
|
|
// see test/integration/route-indexes for expected index handling
|
|
if (
|
|
normalizedPagePath.startsWith('/index') ||
|
|
!normalizedPagePath.endsWith('/index')
|
|
) {
|
|
if (await isWriteable(pagePath)) {
|
|
foundPagePaths.push(relativePagePath)
|
|
}
|
|
}
|
|
|
|
const relativePagePathWithIndex = join(
|
|
normalizedPagePath,
|
|
`index.${extension}`
|
|
)
|
|
const pagePathWithIndex = join(rootDir, relativePagePathWithIndex)
|
|
if (await isWriteable(pagePathWithIndex)) {
|
|
foundPagePaths.push(relativePagePathWithIndex)
|
|
}
|
|
}
|
|
|
|
if (foundPagePaths.length < 1) {
|
|
return null
|
|
}
|
|
|
|
if (!(await isTrueCasePagePath(foundPagePaths[0], rootDir))) {
|
|
return null
|
|
}
|
|
|
|
if (foundPagePaths.length > 1) {
|
|
warn(
|
|
`Duplicate page detected. ${chalk.cyan(
|
|
join('pages', foundPagePaths[0])
|
|
)} and ${chalk.cyan(
|
|
join('pages', foundPagePaths[1])
|
|
)} both resolve to ${chalk.cyan(normalizedPagePath)}.`
|
|
)
|
|
}
|
|
|
|
return foundPagePaths[0]
|
|
}
|