75 lines
2.0 KiB
TypeScript
75 lines
2.0 KiB
TypeScript
import { readdirSync } from "node:fs";
|
|
import { join, relative } from "node:path";
|
|
import type { LegacyPage, LegacySurface } from "./types";
|
|
|
|
const pageFileName = "page.tsx";
|
|
|
|
function toLegacyPath(
|
|
surface: LegacySurface,
|
|
segments: readonly string[],
|
|
): string {
|
|
const routeSegments = segments
|
|
.filter((segment) => !(segment.startsWith("(") && segment.endsWith(")")))
|
|
.map((segment) =>
|
|
segment.replace(/^\[\.\.\.(.+)\]$/, ":$1*").replace(/^\[(.+)\]$/, ":$1"),
|
|
);
|
|
|
|
return `/${[surface, ...routeSegments].join("/")}`;
|
|
}
|
|
|
|
function discoverSurface(
|
|
rootDir: string,
|
|
surface: LegacySurface,
|
|
): LegacyPage[] {
|
|
const surfaceDirectory = join(rootDir, "src", "app", surface);
|
|
const pages: LegacyPage[] = [];
|
|
|
|
function walk(directory: string): void {
|
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
const entryPath = join(directory, entry.name);
|
|
|
|
if (entry.isDirectory()) {
|
|
walk(entryPath);
|
|
continue;
|
|
}
|
|
|
|
if (!entry.isFile() || entry.name !== pageFileName) continue;
|
|
|
|
const sourceFile = relative(rootDir, entryPath).replaceAll("\\", "/");
|
|
const routeSegments = relative(surfaceDirectory, directory)
|
|
.split(/[/\\]/)
|
|
.filter((segment) => segment && segment !== ".");
|
|
pages.push({
|
|
surface,
|
|
legacyPath: toLegacyPath(surface, routeSegments),
|
|
sourceFile,
|
|
});
|
|
}
|
|
}
|
|
|
|
walk(surfaceDirectory);
|
|
return pages;
|
|
}
|
|
|
|
export function discoverLegacyPages(rootDir = process.cwd()): LegacyPage[] {
|
|
return (["admin", "mod"] as const)
|
|
.flatMap((surface) => discoverSurface(rootDir, surface))
|
|
.sort((a, b) =>
|
|
`${a.surface}:${a.legacyPath}:${a.sourceFile}`.localeCompare(
|
|
`${b.surface}:${b.legacyPath}:${b.sourceFile}`,
|
|
),
|
|
);
|
|
}
|
|
|
|
export function ownedLegacyPages(
|
|
prefixes: readonly string[],
|
|
pages: readonly LegacyPage[] = discoverLegacyPages(),
|
|
): LegacyPage[] {
|
|
return pages.filter((page) =>
|
|
prefixes.some(
|
|
(prefix) =>
|
|
page.legacyPath === prefix || page.legacyPath.startsWith(`${prefix}/`),
|
|
),
|
|
);
|
|
}
|