#!/usr/bin/env node /** Move app/accounting page logic to src/modules/accounting/pages and leave thin route adapters. */ import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, } from "node:fs"; import { join, dirname, relative, sep } from "node:path"; import { fileURLToPath } from "node:url"; const ROOT = join(fileURLToPath(new URL(".", import.meta.url)), ".."); const APP = join(ROOT, "app", "accounting"); const PAGES = join(ROOT, "src", "modules", "accounting", "pages"); function walkPages(dir, acc = []) { for (const entry of readdirSync(dir)) { const full = join(dir, entry); if (statSync(full).isDirectory()) walkPages(full, acc); else if (entry === "page.tsx") acc.push(full); } return acc; } function routeToExportName(routeRel) { const base = routeRel.replace(/\/page\.tsx$/, "").replace(/^\.\/?/, ""); if (!base || base === "page.tsx") return "AccountingDashboardPage"; const segments = base.split("/").map((part) => { if (part.startsWith("[") && part.endsWith("]")) { const inner = part.slice(1, -1); return inner.charAt(0).toUpperCase() + inner.slice(1); } return part .split("-") .map((w) => w.charAt(0).toUpperCase() + w.slice(1)) .join(""); }); return `${segments.join("")}Page`; } function moduleRelFromRoute(routePagePath) { const relDir = relative(APP, dirname(routePagePath)).split(sep).join("/"); if (!relDir || relDir === ".") return "dashboard"; return relDir.replace(/\[(\w+)\]/g, "$1"); } function convertToNamedExport(content, exportName) { if (/export default function \w+/.test(content)) { return content.replace(/export default function (\w+)/, "export function $1"); } if (/export default function Page/.test(content)) { return content.replace(/export default function Page/, `export function ${exportName}`); } if (/export default function/.test(content)) { return content.replace(/export default function/, "export function"); } return `${content}\nexport { ${exportName} };\n`; } function resolveExportName(content, fallback) { const named = content.match(/export default function (\w+)/); if (named && named[1] !== "Page") return named[1]; return fallback; } let moved = 0; for (const pageFile of walkPages(APP)) { const routeRel = relative(APP, pageFile).split(sep).join("/"); const moduleRel = moduleRelFromRoute(pageFile); const fallbackName = routeToExportName(routeRel); const original = readFileSync(pageFile, "utf8"); const exportName = resolveExportName(original, fallbackName); const moduleContent = convertToNamedExport(original, exportName); const targetPath = join(PAGES, `${moduleRel}.tsx`); mkdirSync(dirname(targetPath), { recursive: true }); writeFileSync(targetPath, moduleContent, "utf8"); const importPath = `@/src/modules/accounting/pages/${moduleRel}`; const thin = `"use client";\n\nexport { ${exportName} as default } from "${importPath}";\n`; writeFileSync(pageFile, thin, "utf8"); moved++; } console.log(`Migrated ${moved} accounting pages to src/modules/accounting/pages/`);