import { mkdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; let cacheDir = process.env.ICON_CACHE || '/var/lib/void/icons'; let fetcher = defaultFetcher; export function _setCacheDir(d) { cacheDir = d; } export function _setFetcher(fn) { fetcher = fn || defaultFetcher; } const VALID = /^[a-z0-9-]+$/; export function validSlug(slug) { return VALID.test(slug); } async function defaultFetcher(slug) { const url = `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${slug}.png`; const res = await fetch(url, { signal: AbortSignal.timeout(8000) }); if (!res.ok) return null; return Buffer.from(await res.arrayBuffer()); } function isPng(buf) { return buf && buf.length > 8 && buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47; } // Returns a Buffer (cached or freshly fetched) or null if upstream has no icon. export async function getIcon(slug) { if (!validSlug(slug)) throw new Error('invalid slug'); const file = path.join(cacheDir, `${slug}.png`); try { return await readFile(file); } catch { /* miss → fetch */ } const buf = await fetcher(slug); if (!isPng(buf)) return null; await mkdir(cacheDir, { recursive: true }); await writeFile(file, buf); return buf; }