import { mkdir, readFile, rename, writeFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import { ImageResponse } from 'next/og.js'; import { ogImageSize, socialLocales, socialPages } from '../lib/social.mjs'; import { createOgImage } from '../lib/og-template.mjs'; const projectRoot = new URL('../', import.meta.url); const outputDirectory = new URL('public/images/og/', projectRoot); async function svgAsset(path, color) { const svg = (await readFile(new URL(path, projectRoot), 'utf8')) .replaceAll('currentColor', color) .replace(/]*)>/, (tag, attributes) => /\sfill=/.test(attributes) ? tag : `` ); return `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`; } async function font(name, file, weight) { return { name, data: await readFile(new URL(`assets/fonts/og/${file}`, projectRoot)), weight, style: 'normal', }; } const fonts = await Promise.all([ font('Manrope', 'Manrope-SemiBold.ttf', 600), font('Manrope', 'Manrope-ExtraBold.ttf', 800), font('Caveat', 'Caveat-Bold.ttf', 700), ]); const [logo, star5, star6, thinStar, shield, note, love, background] = await Promise.all([ readFile(new URL('assets/images/logo-alt.png', projectRoot)).then( (data) => `data:image/png;base64,${data.toString('base64')}` ), svgAsset('assets/images/thick-round-star-5.svg', '#9d7ba0'), svgAsset('assets/images/thick-round-star-6.svg', '#5780cc'), svgAsset('assets/images/thin-star-big.svg', '#0058ff'), svgAsset('assets/icons/shield.svg', '#1d4fac'), svgAsset('assets/icons/note.svg', '#715573'), svgAsset('assets/icons/love.svg', '#ff003d'), svgAsset('assets/images/og-background.svg', '#f7f9fd'), ]); const assets = { logo, star5, star6, thinStar, shield, note, love, background }; await mkdir(outputDirectory, { recursive: true }); for (const [id, page] of Object.entries(socialPages)) { for (const locale of socialLocales) { const response = new ImageResponse(createOgImage(page, locale, assets), { ...ogImageSize, fonts, }); const png = Buffer.from(await response.arrayBuffer()); const destination = new URL(`${id}-${locale}.png`, outputDirectory); const temporary = new URL(`${id}-${locale}.png.tmp`, outputDirectory); await writeFile(temporary, png); await rename(temporary, destination); console.log( `Generated ${fileURLToPath(destination)} (${png.length} bytes)` ); } }