tools/shots/cdp.mjs (1701 bytes)
1 // Minimal CDP client for the Brave instance on port 9334. 2 // Usage: node cdp.mjs <script.mjs> — the script default-exports async (page) => result. 3 const port = 9334; 4 const targets = await (await fetch(`http://127.0.0.1:${port}/json/list`)).json(); 5 let target = targets.find(t => t.type === 'page'); 6 if (!target) target = await (await fetch(`http://127.0.0.1:${port}/json/new?about:blank`, { method: 'PUT' })).json(); 7 const ws = new WebSocket(target.webSocketDebuggerUrl); 8 await new Promise(r => ws.addEventListener('open', r, { once: true })); 9 let id = 0; const pending = new Map(); const listeners = []; 10 ws.addEventListener('message', e => { 11 const m = JSON.parse(e.data); 12 if (m.id && pending.has(m.id)) { const { res, rej } = pending.get(m.id); pending.delete(m.id); m.error ? rej(new Error(JSON.stringify(m.error))) : res(m.result); } 13 else listeners.forEach(f => f(m)); 14 }); 15 const send = (method, params = {}) => new Promise((res, rej) => { const i = ++id; pending.set(i, { res, rej }); ws.send(JSON.stringify({ id: i, method, params })); }); 16 const sleep = ms => new Promise(r => setTimeout(r, ms)); 17 const evaluate = async (expr) => { const r = await send('Runtime.evaluate', { expression: expr, awaitPromise: true, returnByValue: true }); if (r.exceptionDetails) throw new Error(JSON.stringify(r.exceptionDetails)); return r.result.value; }; 18 const page = { send, sleep, evaluate, listeners }; 19 const mod = await import(new URL(process.argv[2], `file:///${process.cwd().replace(/\\/g, '/')}/`).href); 20 try { const out = await mod.default(page, process.argv.slice(3)); if (out !== undefined) console.log(typeof out === 'string' ? out : JSON.stringify(out, null, 1)); } 21 finally { ws.close(); }