import sharp from 'sharp'; async function generate() { const canvasW = 1280; const canvasH = 800; // Rounded icon badge for top-left const iconRx = 8; const iconMask = Buffer.from(` `); const logoBuf = await sharp('public/icons/icon-48.png') .resize(40, 40) .composite([{ input: iconMask, blend: 'dest-in' }]) .png() .toBuffer(); const screenshots = [ ['public/screenshot1.png', 'public/store-screenshot-1280x800.png'], ['public/scripts.png', 'public/store-scripts-1280x800.png'], ['public/secrets.png', 'public/store-secrets-1280x800.png'] ]; for (const [popupSrc, output] of screenshots) { const { width, height } = await sharp(popupSrc).metadata(); const targetH = 690; const targetW = Math.round((width / height) * targetH); const rx = 14; const x = Math.round((canvasW - targetW) / 2); const y = Math.round((canvasH - targetH) / 2); const maskSvg = Buffer.from(` `); const roundedPopup = await sharp(popupSrc) .resize(targetW, targetH, { fit: 'fill' }) .composite([{ input: maskSvg, blend: 'dest-in' }]) .png() .toBuffer(); const bgSvg = Buffer.from(` OpenScript Lightweight MV3 User Script Manager Manifest V3 Sync Secrets `); const borderSvg = Buffer.from(` `); await sharp(bgSvg) .composite([ { input: logoBuf, top: 40, left: 56 }, { input: roundedPopup, top: y, left: x }, { input: borderSvg, top: y, left: x } ]) .png() .toFile(output); console.log(`✓ Generated ${output} (1280x800)`); } } generate();