'use strict'; // const wrap = (f, before, after) => (...args) => after(f(...before(...args))); // const wrapAsync = (f, before, after, beforeCb, afterCb) => // (...args) => { // const callback = args[args.length - 1]; // if (typeof callback === 'function') { // args[args.length - 1] = (...pars) => // afterCb(callback(...beforeCb(...pars))); // } // return after(f(...before(...args))); // }; const wrapFunction = (f) => { console.log('Wrap function:', f.name); return (...args) => { console.log('Called wrapper for:', f.name); console.dir({ args }); if (args.length > 0) { const callback = args[args.length - 1]; if (typeof callback === 'function') { args[args.length - 1] = (...args) => { console.log('Callback:', f.name); const cbRes = callback(...args); console.log('Callback results:', cbRes); return cbRes; }; } } console.log('Call:', f.name); console.dir(args); const result = f(...args); console.log('Ended wrapper for:', f.name); console.dir({ result }); return result; }; }; const cloneInterface = (anInterface) => { const clone = {}; const keys = Object.keys(anInterface); for (const key of keys) { const fn = anInterface[key]; clone[key] = wrapFunction(fn); } return clone; }; // Usage const interfaceName = { methodName(par1, par2, callback) { console.dir({ par1, par2 }); callback(null, { field: 'value' }); return par1; }, }; const cloned = cloneInterface(interfaceName); cloned.methodName('Uno', 'Due', (err, data) => { console.log({ err, data }); return true; });