#!/usr/bin/env node import { mkdir, readFile, readdir, writeFile } from "node:fs/promises"; import { existsSync } from "node:fs"; import path from "node:path"; import vm from "node:vm"; const root = path.resolve(new URL("..", import.meta.url).pathname); const catalogPath = path.join(root, "platformCatalog.js"); const assetsManifestPath = path.join(root, "platformAssets.js"); const outputDir = path.join(root, "assets", "platforms"); const cdnBase = "https://cdn.simpleicons.org"; function loadCatalog(source) { const sandbox = { window: {}, globalThis: {} }; sandbox.globalThis = sandbox.window; vm.runInNewContext(source, sandbox, { filename: catalogPath }); return sandbox.window.BindVaultPlatformCatalog || []; } function iconFile(entry) { return entry.file || `${entry.simpleIcon || entry.key}.svg`; } async function downloadIcon(entry, options) { const slug = entry.simpleIcon || entry.key; const target = path.join(outputDir, iconFile(entry)); if (!options.force && existsSync(target)) { return { key: entry.key, status: "skipped", file: path.relative(root, target) }; } const response = await fetch(`${cdnBase}/${encodeURIComponent(slug)}`); if (!response.ok) { throw new Error(`${entry.key}: ${response.status} ${response.statusText}`); } const svg = await response.text(); if (!svg.trim().startsWith(" entry.simpleIcon); await mkdir(outputDir, { recursive: true }); const results = []; const failures = []; for (const entry of entries) { try { const result = await downloadIcon(entry, options); results.push(result); console.log(`${result.status.padEnd(10)} ${result.file}`); } catch (error) { failures.push(error); console.error(`failed ${entry.key}: ${error.message}`); } } const files = (await readdir(outputDir)) .filter((file) => file.toLowerCase().endsWith(".svg")) .sort(); const manifest = [ "window.BindVaultPlatformAssets = {", ...files.map((file) => ` ${JSON.stringify(file)}: true,`), "};", "", ].join("\n"); await writeFile(assetsManifestPath, manifest, "utf8"); console.log(`\nSimple Icons: ${results.length} ok, ${failures.length} failed`); console.log(`Manifest: ${path.relative(root, assetsManifestPath)}`); if (failures.length && options.strict) process.exitCode = 1; } main().catch((error) => { console.error(error); process.exit(1); });