import "server-only"; import { readFileSync, statSync } from "node:fs"; import { join } from "node:path"; import { getOgImagePath, PROJECT_VIDEO_IDS } from "./project-showcase"; const brandMark = `data:image/png;base64,${readFileSync( join(process.cwd(), "public/brand/mark-dark.png"), ).toString("base64")}`; export const OG_SIZE = { width: 1200, height: 630 } as const; export const OG_CONTENT_TYPE = "image/png"; export const OG_PHOTO_CONTENT_TYPE = "image/jpeg"; /** Teto de uma imagem de compartilhamento: quem recebe o link baixa a imagem a cada prévia, então ela precisa ser leve. */ export const OG_IMAGE_MAX_BYTES = 150_000; /** * Capa 1200x630 gravada da página do projeto (public/videos//og.jpg), usada como está na imagem de compartilhamento. * `undefined` se não existir ou se pesar o teto ou mais: nesse caso quem chama gera o cartão simples, sem imagem de fundo. */ export function readProjectOgImage(id: string): Buffer | undefined { if (!PROJECT_VIDEO_IDS.includes(id)) return undefined; const path = join(process.cwd(), "public", getOgImagePath(id)); try { if (statSync(path).size >= OG_IMAGE_MAX_BYTES) return undefined; return readFileSync(path); } catch { return undefined; } } export function OgCard({ eyebrow, title, description, backgroundImage, }: { eyebrow: string; title: string; description: string; /** Imagem de fundo (data URI), escurecida da esquerda para a direita para o texto continuar legível. */ backgroundImage?: string; }) { return (
{backgroundImage && ( <> {/* biome-ignore lint/performance/noImgElement: o ImageResponse (satori) só desenha */}
)} {/* biome-ignore lint/performance/noImgElement: o ImageResponse (satori) só desenha */} Evandro.dev.br
{eyebrow}
{title}
{description}
EVANDRO.DEV.BR / ENGENHARIA DE SOFTWARE
); }