49 lines
2 KiB
JavaScript
49 lines
2 KiB
JavaScript
|
|
// One-shot script: render site-theseus-x/assets/favicon.svg to the icon
|
||
|
|
// files electron-builder wants — a 512x512 PNG (main icon) and a multi-
|
||
|
|
// resolution .ico (Windows taskbar / installer / shortcut icon).
|
||
|
|
//
|
||
|
|
// Not in the runtime app bundle; run manually when the brand changes:
|
||
|
|
// node nsis/make-icons.mjs
|
||
|
|
// Outputs build/icon.png and build/icon.ico (both gitignored regenerated).
|
||
|
|
import fs from "node:fs";
|
||
|
|
import path from "node:path";
|
||
|
|
import { fileURLToPath } from "node:url";
|
||
|
|
import sharp from "sharp";
|
||
|
|
import pngToIco from "png-to-ico";
|
||
|
|
|
||
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||
|
|
// SVG source lives in the theseus.x standalone site so the browser icon
|
||
|
|
// and the site brand stay in lockstep.
|
||
|
|
const SVG = path.join(__dirname, "..", "..", "site-theseus-x", "assets", "favicon.svg");
|
||
|
|
// Icons drop into build/, which is gitignored (regenerated artifacts).
|
||
|
|
// electron-builder picks them up from there via package.json.
|
||
|
|
const OUT_DIR = path.join(__dirname, "..", "build");
|
||
|
|
const PNG_512 = path.join(OUT_DIR, "icon.png");
|
||
|
|
const ICO = path.join(OUT_DIR, "icon.ico");
|
||
|
|
const TMP_DIR = path.join(OUT_DIR, ".icon-tmp");
|
||
|
|
const ICO_SIZES = [16, 24, 32, 48, 64, 128, 256];
|
||
|
|
|
||
|
|
if (!fs.existsSync(SVG)) throw new Error("SVG not found at " + SVG);
|
||
|
|
console.log("source:", SVG);
|
||
|
|
|
||
|
|
// Main 512x512 PNG for macOS / linux / electron-builder auto-derived Windows.
|
||
|
|
await sharp(SVG).resize(512, 512).png().toFile(PNG_512);
|
||
|
|
console.log("wrote", PNG_512);
|
||
|
|
|
||
|
|
// Write individual sized PNGs to a temp dir, then feed their paths to
|
||
|
|
// png-to-ico so it preserves each as a distinct image inside the .ico.
|
||
|
|
fs.mkdirSync(TMP_DIR, { recursive: true });
|
||
|
|
const paths = [];
|
||
|
|
for (const size of ICO_SIZES) {
|
||
|
|
const p = path.join(TMP_DIR, `icon-${size}.png`);
|
||
|
|
await sharp(SVG).resize(size, size).png().toFile(p);
|
||
|
|
paths.push(p);
|
||
|
|
}
|
||
|
|
const ico = await pngToIco(paths);
|
||
|
|
fs.writeFileSync(ICO, ico);
|
||
|
|
console.log("wrote", ICO, `(${ICO_SIZES.length} sizes)`);
|
||
|
|
|
||
|
|
// Clean up the temp PNGs.
|
||
|
|
for (const p of paths) fs.unlinkSync(p);
|
||
|
|
fs.rmdirSync(TMP_DIR);
|