const w = new WrapFns()
w.on('call::https.request', console.log)
w.wrap('https.request', https, 'request');
w.wrap('https.request', https, 'request');
w.wrap('http.request', http, 'request');
w.wrap('globalThis.fetch', globalThis, 'fetch');
class WrapFns { | |
tokensOriginals = {} | |
wrap(label, target, fnName) { | |
const self = this; | |
const original = this.tokensOriginals[label] ?? Symbol('original'); | |
this.tokensOriginals[label] = original; | |
if (target[original] !== undefined) { | |
throw new Error(`${label} already wrapped`); | |
} | |
target[original] = target[fnName] | |
target[fnName] = function wrap(...args) { | |
try { | |
const res = target[original](...args); | |
self.emit(`call::${label}`, args, res); | |
return res; | |
} catch (e) { | |
self.emit(`call_error::${label}`, args, e); | |
throw e; | |
} | |
} | |
} | |
_events = {}; | |
on(name, listener) { | |
this._events[name] = this._events[name] || []; | |
this._events[name].push(listener); | |
} | |
off(name, listener) { | |
if (this._events[name]) { | |
this._events[name] = this._events[name].filter(l => l !== listener); | |
if (this._events[name].length === 0) { | |
const { [name]: _, ...events } = this._events; | |
this._events = events; | |
} | |
} | |
} | |
emit(name, ...args) { | |
if (this._events[name]) { | |
this._events[name].forEach(l => l(...args)); | |
} | |
} | |
} |