101 lines
3.3 KiB
JavaScript
101 lines
3.3 KiB
JavaScript
import { readdir, readFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
const APP_DIR = path.resolve("apps/sn/app");
|
|
const POPUP_DEFINITIONS = path.resolve(
|
|
"apps/sn/src/features/windowPopup/model/popupDefinitions.ts",
|
|
);
|
|
const POPUP_REGISTRY = path.resolve(
|
|
"apps/sn/src/features/windowPopup/registry.tsx",
|
|
);
|
|
|
|
const routeAliases = new Set([
|
|
"/map/agedPipePopup",
|
|
"/map2",
|
|
]);
|
|
const developmentRoutes = new Set([
|
|
"/ii/fileupload",
|
|
"/ii/test",
|
|
"/oper/operStore",
|
|
]);
|
|
const infrastructureRoutes = new Set(["/", "/popup/[popupKey]"]);
|
|
|
|
async function collectPageFiles(directory) {
|
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
const nested = await Promise.all(
|
|
entries.map(async (entry) => {
|
|
const absolutePath = path.join(directory, entry.name);
|
|
if (entry.isDirectory()) return collectPageFiles(absolutePath);
|
|
return entry.name === "page.tsx" ? [absolutePath] : [];
|
|
}),
|
|
);
|
|
return nested.flat();
|
|
}
|
|
|
|
function toRoute(filePath) {
|
|
const relative = path.relative(APP_DIR, path.dirname(filePath));
|
|
const segments = relative
|
|
.split(path.sep)
|
|
.filter(Boolean)
|
|
.filter((segment) => !/^\(.+\)$/.test(segment));
|
|
return `/${segments.join("/")}`.replace(/\/$/, "") || "/";
|
|
}
|
|
|
|
function extractDefinitionKeys(source) {
|
|
const objectStart = source.indexOf("export const windowPopupDefinitions = {");
|
|
const objectEnd = source.indexOf("} as const satisfies", objectStart);
|
|
return [...source.slice(objectStart, objectEnd).matchAll(/^ ([A-Za-z][A-Za-z0-9]*): \{/gm)]
|
|
.map((match) => match[1]);
|
|
}
|
|
|
|
function extractRegistryKeys(source) {
|
|
const objectStart = source.indexOf("export const windowPopupRegistry = {");
|
|
const objectEnd = source.indexOf("} satisfies", objectStart);
|
|
return [...source.slice(objectStart, objectEnd).matchAll(/^ ([A-Za-z][A-Za-z0-9]*):/gm)]
|
|
.map((match) => match[1]);
|
|
}
|
|
|
|
const pageFiles = await collectPageFiles(APP_DIR);
|
|
const routes = pageFiles.map(toRoute).sort();
|
|
const definitions = extractDefinitionKeys(
|
|
await readFile(POPUP_DEFINITIONS, "utf8"),
|
|
);
|
|
const registry = extractRegistryKeys(await readFile(POPUP_REGISTRY, "utf8"));
|
|
|
|
const popupMissingInRegistry = definitions.filter((key) => !registry.includes(key));
|
|
const registryMissingInDefinitions = registry.filter(
|
|
(key) => !definitions.includes(key),
|
|
);
|
|
const routeCategory = (route) => {
|
|
if (route === "/auth/login") return "authentication";
|
|
if (routeAliases.has(route)) return "alias-or-preview";
|
|
if (developmentRoutes.has(route)) return "development";
|
|
if (infrastructureRoutes.has(route)) return "infrastructure";
|
|
return "main-content";
|
|
};
|
|
|
|
const routeCounts = routes.reduce((groups, route) => {
|
|
const category = routeCategory(route);
|
|
groups[category] ??= [];
|
|
groups[category].push(route);
|
|
return groups;
|
|
}, {});
|
|
const report = {
|
|
routeFileCount: routes.length,
|
|
routeCounts: Object.fromEntries(
|
|
Object.entries(routeCounts).map(([key, value]) => [key, value.length]),
|
|
),
|
|
routes: routes.map((route) => ({ route, category: routeCategory(route) })),
|
|
popupDefinitionCount: definitions.length,
|
|
popupRegistryCount: registry.length,
|
|
popupMissingInRegistry,
|
|
registryMissingInDefinitions,
|
|
popupKeys: definitions,
|
|
};
|
|
|
|
console.log(JSON.stringify(report, null, 2));
|
|
|
|
if (popupMissingInRegistry.length || registryMissingInDefinitions.length) {
|
|
process.exitCode = 1;
|
|
}
|