/
find-page-file.ts
72 lines (64 loc) · 2.39 KB
/
find-page-file.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { fileExists } from '../../lib/file-exists'
import { getPagePaths } from '../../shared/lib/page-path/get-page-paths'
import { nonNullable } from '../../lib/non-nullable'
import { join, sep, normalize } from 'path'
import { promises } from 'fs'
import { warn } from '../../build/output/log'
import chalk from '../../lib/chalk'
async function isTrueCasePagePath(pagePath: string, pagesDir: string) {
const pageSegments = normalize(pagePath).split(sep).filter(Boolean)
const segmentExistsPromises = pageSegments.map(async (segment, i) => {
const segmentParentDir = join(pagesDir, ...pageSegments.slice(0, i))
const parentDirEntries = await promises.readdir(segmentParentDir)
return parentDirEntries.includes(segment)
})
return (await Promise.all(segmentExistsPromises)).every(Boolean)
}
/**
* Finds a page file with the given parameters. If the page is duplicated with
* multiple extensions it will throw, otherwise it will return the *relative*
* path to the page file or null if it is not found.
*
* @param pagesDir Absolute path to the pages folder with trailing `/pages`.
* @param normalizedPagePath The page normalized (it will be denormalized).
* @param pageExtensions Array of page extensions.
*/
export async function findPageFile(
pagesDir: string,
normalizedPagePath: string,
pageExtensions: string[],
isAppDir: boolean
): Promise<string | null> {
const pagePaths = getPagePaths(normalizedPagePath, pageExtensions, isAppDir)
const [existingPath, ...others] = (
await Promise.all(
pagePaths.map(async (path) => {
const filePath = join(pagesDir, path)
return (await fileExists(filePath)) ? path : null
})
)
).filter(nonNullable)
if (!existingPath) {
return null
}
if (!(await isTrueCasePagePath(existingPath, pagesDir))) {
return null
}
if (others.length > 0) {
warn(
`Duplicate page detected. ${chalk.cyan(
join('pages', existingPath)
)} and ${chalk.cyan(
join('pages', others[0])
)} both resolve to ${chalk.cyan(normalizedPagePath)}.`
)
}
return existingPath
}
// Determine if the file is leaf node page file under layouts,
// The filename should start with 'page' and end with one of the allowed extensions
export function isLayoutsLeafPage(filePath: string, pageExtensions: string[]) {
return new RegExp(`(^page|/page)\\.(?:${pageExtensions.join('|')})$`).test(
filePath
)
}