UNPKG

og-images-generator

Version:

Generate OG images from a static folder and / or a middleware. Extract metadata from HTML pages. No headless browser involved. Comes as a CLI, API or plugins.

66 lines (65 loc) 3.04 kB
import fs from 'node:fs'; import path from 'node:path'; import c from 'picocolors'; import { collectHtmlPages } from './collect.js'; import { renderAllPagesOg } from './render.js'; export const CONFIG_FILE_NAME = 'og-images.config.js'; export const CONFIG_FILE_PATH = path.join(process.cwd(), CONFIG_FILE_NAME); export async function loadUserConfig(configPath) { // eslint-disable-next-line no-console console.log(CONFIG_FILE_PATH); const config = await import(configPath || CONFIG_FILE_PATH).catch((error) => { // eslint-disable-next-line no-console console.error(error); throw new Error('Configuration not found.'); }); if (typeof config !== 'object' || !config) throw new Error('Configuration is invalid.'); if (!('template' in config)) throw new Error('No template found in configuration.'); if (typeof config.template !== 'function') throw new Error('Template should be a returning function.'); if (!('renderOptions' in config) || !config.renderOptions) throw new Error('No render options found in configuration.'); if (typeof config.renderOptions !== 'object') throw new Error('Return options should be an object.'); if (!('satori' in config.renderOptions)) throw new Error('Satori options are mandatory.'); // We assume the user has their config. properly typed from there, // further libs will throw in case of an invalid config. const resvg = ('resvg' in config.renderOptions ? config.renderOptions.resvg : {}); const satori = config.renderOptions.satori; return { template: config.template, renderOptions: { satori, resvg }, }; } export async function save(renderedImages, out) { await Promise.all(renderedImages.map(async (rendered) => { const fileDestination = rendered.path.replace(/\/index\.html$/, '').replace(/\.html$/, '') + '.png'; const destination = path.join(process.cwd(), out, fileDestination); await fs.promises .mkdir(path.dirname(destination), { recursive: true }) .catch(() => null); await fs.promises.writeFile(destination, rendered.data); })); // eslint-disable-next-line no-console console.log(c.bold(c.green(renderedImages.length + ' images generated.'))); } export async function generateOgImages(options) { const optionsOrDefaults = { base: options?.base || './dist', out: options?.out || './dist/og', json: options?.json || './dist/og/index.json', additionalPatterns: options?.additionalPatterns || [], globber: options?.globber || {}, }; const pages = await collectHtmlPages(optionsOrDefaults); const config = await loadUserConfig(); const renderedImages = await renderAllPagesOg(pages, config); await save(renderedImages, optionsOrDefaults.out); // eslint-disable-next-line no-console console.log(c.magenta('OG images generation completed successfully. ') + c.blue('Now exiting.')); }