// scripts/generate-pwa-icons.js // Generates the full PWA icon set from public/favicon.svg // Run: node scripts/generate-pwa-icons.js const fs = require("fs"); const path = require("path"); const sharp = require("sharp"); const SIZES = [72, 96, 128, 144, 152, 192, 384, 512]; const OUT_DIR = path.join(__dirname, "..", "public", "icons"); const SVG_PATH = path.join(__dirname, "..", "public", "favicon.svg"); const svg = fs.readFileSync(SVG_PATH); async function main() { fs.mkdirSync(OUT_DIR, { recursive: true }); for (const size of SIZES) { await sharp(svg).resize(size, size).png().toFile(path.join(OUT_DIR, `icon-${size}x${size}.png`)); console.log(`✓ icon-${size}x${size}.png`); } // Maskable: same icon, with 20% safe-area padding baked in await sharp(svg).resize(410, 410).extend({ top: 51, bottom: 51, left: 51, right: 51, background: { r: 22, g: 77, b: 46, alpha: 1 }, }).png().toFile(path.join(OUT_DIR, "icon-maskable-512x512.png")); console.log("✓ icon-maskable-512x512.png"); // Badge await sharp(svg).resize(72, 72).png().toFile(path.join(OUT_DIR, "badge-72x72.png")); console.log("✓ badge-72x72.png"); // Shortcuts (same icon, 96x96) for (const name of ["orders-shortcut", "products-shortcut", "stops-shortcut"]) { await sharp(svg).resize(96, 96).png().toFile(path.join(OUT_DIR, `${name}.png`)); console.log(`✓ ${name}.png`); } } main().catch((err) => { console.error(err); process.exit(1); });