import { describe, expect, test } from "bun:test"; import { readdirSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { isReservedName } from "./reserved-names"; const SRC = join(import.meta.dir, ".."); function topLevelRouteSegments(): string[] { return readdirSync(join(SRC, "routes")) .filter((file) => file.endsWith(".tsx") && !file.startsWith("$") && !file.startsWith("__")) .map((file) => file.split(".")[0].replace(/_$/, "")) .filter((segment) => segment !== "index"); } function linkedPages(): string[] { const files = ["lib/legal.ts", "components/SiteFooter.tsx", "components/SiteHeader.tsx", "lib/marketing/catalog.ts"]; const segments = new Set(); for (const file of files) { for (const match of readFileSync(join(SRC, file), "utf8").matchAll(/["'`]\/([a-z][a-z0-9-]*)/g)) { segments.add(match[1]); } } return [...segments]; } describe("reserved account names", () => { test("every top-level route is reserved", () => { const missing = topLevelRouteSegments().filter((segment) => !isReservedName(segment)); expect(missing).toEqual([]); }); test("every page linked from the footer, header and marketing catalog is reserved", () => { const missing = linkedPages().filter((segment) => !isReservedName(segment)); expect(missing).toEqual([]); }); test("raw handler prefixes and special accounts are reserved", () => { for (const name of [ "ingest", "mcp", "camo", "og", "site", "feature", "stripe", "email", "workbench", "ghost", "oauth", "api", "auth", ]) { expect(isReservedName(name)).toBe(true); } }); test("matching is case-insensitive", () => { expect(isReservedName("Ingest")).toBe(true); expect(isReservedName("GHOST")).toBe(true); }); });