import { createRequire } from 'node:module'; import { readFile } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; const require = createRequire(new URL('../apps/server/package.json', import.meta.url)); const sharp = require('sharp'); const asset = (name) => fileURLToPath(new URL(`../apps/web/public/${name}`, import.meta.url)); const source = await readFile(asset('icon.svg')); await Promise.all( [192, 512].map((size) => sharp(source, { density: (72 * size) / 64 }) .resize(size, size) .png() .toFile(asset(`icon-${size}.png`)), ), ); // Leave margin so the letter and dot remain inside Android's central safe zone. const padded = await sharp(source, { density: 432 }).resize(384, 384).png().toBuffer(); await sharp({ create: { width: 512, height: 512, channels: 4, background: '#111111' } }) .composite([{ input: padded, left: 64, top: 64 }]) .png() .toFile(asset('icon-maskable.png')); console.log('Generated icon-192.png, icon-512.png, icon-maskable.png from icon.svg');