/** * 校验 custom-brand 源:缺失文件对比 + 超大 SVG 抽查 */ 'use strict'; const vm = require('vm'); const fs = require('fs'); const https = require('https'); const src = fs.readFileSync('js/data/sources/custom-brand.js', 'utf8'); const sandbox = { window: {} }; vm.createContext(sandbox); vm.runInContext(src, sandbox); const icons = vm.runInContext("window['HGB_Source_custom-brand'].icons", sandbox); const local = new Set(icons.map(i => i.name)); function fetchRaw(url) { return new Promise((res, rej) => { https.get(url, { timeout: 25000 }, r => { if (r.statusCode >= 300 && r.statusCode < 400 && r.headers.location) { r.resume(); return res(fetchRaw(r.headers.location)); } if (r.statusCode !== 200) { rej(new Error('HTTP ' + r.statusCode)); r.resume(); return; } const c = []; r.on('data', x => c.push(x)); r.on('end', () => res(Buffer.concat(c).toString('utf8'))); }).on('error', rej); }); } (async () => { const raw = await fetchRaw('https://data.jsdelivr.com/v1/packages/gh/elax46/custom-brand-icons@main'); const j = JSON.parse(raw); const all = []; const walk = (files) => { for (const f of files || []) { if (f.type === 'file') all.push(f.name.replace(/\.svg$/i, '')); else walk(f.files || []); } }; walk(j.files.find(f => f.name === 'icon-svg').files || []); const missing = all.filter(n => !local.has(n)); console.log('缺失文件(' + missing.length + '):', missing.join(', ') || '(无)'); const big = [...icons].sort((a, b) => b.svg.length - a.svg.length).slice(0, 1)[0]; console.log('最大图标', big.name, '| 长度', big.svg.length, '| path 数', (big.svg.match(/ /[^\x20-\x7e]/.test(i.name)); console.log('非 ASCII 文件名数:', nonAscii.length, nonAscii.slice(0, 5).map(i => i.name).join(', ')); // 含 defs/渐变 的个数(wrap 类保留原色的检查) const defs = icons.filter(i => /<(defs|linearGradient|radialGradient|pattern)/.test(i.svg)); console.log('含 defs/渐变 图标数:', defs.length); // fill 颜色分布 const fills = {}; for (const i of icons) { const m = i.svg.match(/fill="#[0-9a-fA-F]{3,6}"/); const k = m ? m[0] : 'currentColor/无'; fills[k] = (fills[k] || 0) + 1; } console.log('fill 分布:', JSON.stringify(fills).slice(0, 300)); })().catch(e => { console.error('❌', e.message); process.exit(1); });