import sharp from 'sharp'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); async function generateFaviconIco() { const sourceIcon = path.join(__dirname, '..', 'static', 'icon-source.png'); const outputIcon = path.join(__dirname, '..', 'static', 'favicon.ico'); console.log('Generating favicon.ico from icon-source.png...'); // Verify source file exists if (!fs.existsSync(sourceIcon)) { console.error('Error: icon-source.png not found at', sourceIcon); process.exit(1); } // Resize to 32x32 with transparent background await sharp(sourceIcon) .resize(32, 32, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } }) .ensureAlpha() .png() .toFile(outputIcon); // Verify output file const metadata = await sharp(outputIcon).metadata(); const stats = fs.statSync(outputIcon); console.log(`✓ favicon.ico generated successfully`); console.log(` Dimensions: ${metadata.width}x${metadata.height}`); console.log(` Format: ${metadata.format}`); console.log(` Size: ${(stats.size / 1024).toFixed(1)}KB`); // Validate success criteria if (metadata.width !== 32 || metadata.height !== 32) { console.error('Error: Invalid dimensions'); process.exit(1); } if (metadata.format !== 'png') { console.error('Error: Invalid format'); process.exit(1); } console.log('✓ All validation checks passed'); } generateFaviconIco().catch(err => { console.error('Error generating favicon.ico:', err); process.exit(1); });