import { readFileSync } from "node:fs"; import { join } from "node:path"; import type { APIRequestContext } from "@playwright/test"; /** Caminhos (`/`, `/cases/…`) de todas as rotas do /sitemap.xml, sem o domínio de produção. */ export async function sitemapPaths(request: APIRequestContext) { const response = await request.get("/sitemap.xml"); if (response.status() !== 200) throw new Error(`/sitemap.xml respondeu ${response.status()}`); const xml = await response.text(); const paths = [...xml.matchAll(/\s*([^<\s]+)\s*<\/loc>/g)].map( ([, loc]) => { const { pathname } = new URL(loc); return pathname === "" ? "/" : pathname; }, ); return [...new Set(paths)]; } let devServer: Promise | undefined; /** * O `BASE_URL` é um servidor de desenvolvimento (`next dev`)? O HTML dele traz o cliente de recarga a quente (HMR) e o * React Refresh, que o build de produção não tem. Serve para as poucas coisas que só existem em um dos dois: a barra * de cookies (só em produção) e avisos do React (só no desenvolvimento). */ export function isDevServer(request: APIRequestContext) { devServer ??= request .get("/") .then((response) => response.text()) .then((html) => /hmr-client|react-refresh/.test(html)) .catch((error) => { devServer = undefined; throw error; }); return devServer; } /** Nomes dos projetos de cliente, como a home os lista (public/portfolio-data.json, kind "cliente"). */ export function clientProjectNames() { const data = JSON.parse( readFileSync( join(__dirname, "..", "public", "portfolio-data.json"), "utf8", ), ) as { projects: Array<{ title: string; kind?: string }> }; return data.projects .filter((project) => project.kind === "cliente") .map((project) => project.title); } /** Texto do cabeçalho da seção de contato da home. */ export const CONTACT_HEADING = "Vamos conversar sobre o que sua empresa precisa."; export const DESKTOP = { width: 1440, height: 900 } as const; export const PHONE = { width: 390, height: 844 } as const;