/** * 运行时校验:字号档位、token 生效情况、面板宽度。 * 用法:node scripts/verify-tokens.mjs */ import { writeFile } from 'node:fs/promises' const port = Number(process.argv[2] ?? 9335) const outPng = process.argv[3] ?? null async function main() { const list = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json() const page = list.filter((t) => t.type === 'page')[0] if (!page) throw new Error('未找到页面') const ws = new WebSocket(page.webSocketDebuggerUrl) await new Promise((r, j) => { const t = setTimeout(() => j(new Error('连接超时')), 8000) ws.addEventListener('open', () => { clearTimeout(t) r() }) ws.addEventListener('error', () => { clearTimeout(t) j(new Error('连接失败')) }) }) const send = (method, params = {}) => new Promise((res, rej) => { const id = Math.floor(Math.random() * 1e9) const timer = setTimeout(() => rej(new Error(`超时 ${method}`)), 15000) const h = (ev) => { const m = JSON.parse(ev.data) if (m.id === id) { clearTimeout(timer) ws.removeEventListener('message', h) res(m.result) } } ws.addEventListener('message', h) ws.send(JSON.stringify({ id, method, params })) }) const expr = `(() => { const cs = getComputedStyle(document.documentElement); const read = (n) => cs.getPropertyValue(n).trim(); const body = getComputedStyle(document.body); const out = { level: document.documentElement.dataset.fontLevel, mdRoot: read('--yc-md-root'), offset: read('--yc-font-offset'), bodyFontSize: body.fontSize, bodyLineHeight: body.lineHeight, shellColumns: getComputedStyle(document.querySelector('.app-shell')).gridTemplateColumns, titlebarHeight: getComputedStyle(document.querySelector('.titlebar')).height, sidebarWidth: getComputedStyle(document.querySelector('.sidebar')).width, inputMaxWidth: read('--yc-input-max'), contentMax: read('--yc-content-max') }; // 逐档采样 const samples = {}; for (const lv of [1,2,3,4,5,6]) { document.documentElement.style.setProperty('--yc-font-offset-global', String([-1,0,1,2,2,2][lv-1])); document.documentElement.style.setProperty('--yc-md-root', ['16px','17.143px','18.286px','20.571px','22.857px','26.286px'][lv-1]); const c = getComputedStyle(document.body); samples[lv] = { body: c.fontSize, line: c.lineHeight }; } out.samples = samples; return JSON.stringify(out); })()` const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true }) const data = JSON.parse(r.result.value) console.log(JSON.stringify(data, null, 2)) if (outPng) { const shot = await send('Page.captureScreenshot', { format: 'png' }) if (shot?.data) { await writeFile(outPng, Buffer.from(shot.data, 'base64')) console.log('截图:', outPng) } } ws.close() } main().catch((e) => { console.error('失败:', e.message) process.exit(1) })