Files
Epicnabbo-Catalogus-Updated…/src/features/housekeeping/migration/discover-legacy-pages.ts
T

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}/`),
),
);
}