SPB Git forge

spb/rareindex

Public
54commits 1branches 0releases
7.1 MBsize
maindefault branch
10 days agolast push
TypeScript 61.9% HTML 37.2% SQL 0.7%
2.1 KB · 51 lines javascript
Raw Blame History
1// Generates favicons / PWA icons / Apple touch icon / favicon.ico from public/brand/rareindex-mark.svg.2// Run from apps/web:  node scripts/brand-assets.mjs3import { readFileSync, writeFileSync, copyFileSync } from 'node:fs';4import sharp from 'sharp';56const svg = readFileSync('public/brand/rareindex-mark.svg');7const png = (size) => sharp(svg, { density: Math.ceil((size / 64) * 72) }).resize(size, size).png().toBuffer();89const out = {10  'src/app/icon.png': 32,11  'src/app/apple-icon.png': 180,12  'public/apple-touch-icon.png': 180,13  'public/icon-192.png': 192,14  'public/icon-512.png': 512,15};16for (const [path, size] of Object.entries(out)) writeFileSync(path, await png(size));1718// maskable: the mark on a full-bleed ink square with safe-zone padding (icon at 80 %)19const inner = await png(410);20const maskable = await sharp({ create: { width: 512, height: 512, channels: 4, background: '#0B0F19' } })21  .composite([{ input: inner, gravity: 'centre' }])22  .png()23  .toBuffer();24writeFileSync('public/icon-maskable-512.png', maskable);2526// favicon.ico = PNG-in-ICO container with 16, 32 and 48 px images27const sizes = [16, 32, 48];28const images = await Promise.all(sizes.map((s) => png(s)));29const header = Buffer.alloc(6);30header.writeUInt16LE(0, 0); // reserved31header.writeUInt16LE(1, 2); // type: icon32header.writeUInt16LE(images.length, 4);33const dir = Buffer.alloc(16 * images.length);34let offset = 6 + dir.length;35images.forEach((img, i) => {36  const s = sizes[i];37  dir.writeUInt8(s === 256 ? 0 : s, i * 16 + 0);38  dir.writeUInt8(s === 256 ? 0 : s, i * 16 + 1);39  dir.writeUInt8(0, i * 16 + 2); // palette40  dir.writeUInt8(0, i * 16 + 3); // reserved41  dir.writeUInt16LE(1, i * 16 + 4); // planes42  dir.writeUInt16LE(32, i * 16 + 6); // bpp43  dir.writeUInt32LE(img.length, i * 16 + 8);44  dir.writeUInt32LE(offset, i * 16 + 12);45  offset += img.length;46});47writeFileSync('src/app/favicon.ico', Buffer.concat([header, dir, ...images]));48copyFileSync('public/brand/rareindex-mark.svg', 'src/app/icon.svg');49copyFileSync('public/brand/rareindex-mark.svg', 'public/icon.svg');50console.log('brand assets written');51