// Generates public/_redirects (Cloudflare Pages) mapping old flat tool URLs // (/tools/) to the new section-nested URLs (/tools/
//). // Both slash variants are emitted because Cloudflare matches paths exactly. // // buildRedirects() is exported (side-effect-free) so a drift test can assert the // committed public/_redirects still matches the catalog; the file is only // written when this script runs directly (the landing prebuild). import { writeFileSync } from "node:fs"; import { fileURLToPath, pathToFileURL } from "node:url"; import { TOOLS, toolSection } from "@snapotter/shared"; /** Build the full _redirects file contents from the shared TOOLS catalog. */ export function buildRedirects() { const lines = ["# Generated by scripts/generate-redirects.mjs -- do not edit by hand"]; for (const tool of TOOLS) { const to = `/tools/${toolSection(tool)}/${tool.id}/`; lines.push(`/tools/${tool.id}/ ${to} 301`); lines.push(`/tools/${tool.id} ${to} 301`); } return `${lines.join("\n")}\n`; } /** Absolute path to the generated file. */ export const REDIRECTS_PATH = fileURLToPath(new URL("../public/_redirects", import.meta.url)); function writeRedirects() { const content = buildRedirects(); writeFileSync(REDIRECTS_PATH, content); const redirectLines = content.trimEnd().split("\n").length - 1; console.log(`wrote ${REDIRECTS_PATH} (${TOOLS.length} tools, ${redirectLines} redirect lines)`); } // Write only when executed directly (prebuild); importing for the drift test // stays side-effect-free. if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) { writeRedirects(); }