|
export const logAccessTo = (() => { |
|
const pad = (value) => String(value).padStart(2, '0'); |
|
const getTime = (date = new Date()) => `${ |
|
pad(date.getHours())}:${ |
|
pad(date.getMinutes())}:${ |
|
pad(date.getSeconds())}.${ |
|
pad(date.getMilliseconds())}`; |
|
|
|
return (obj, props = []) => { |
|
const filtered = props && props.length; |
|
|
|
return new Proxy(obj, { |
|
get: (target, name, receiver) => { |
|
const value = target[name]; |
|
|
|
if (!filtered || props.includes(name)) { |
|
if (typeof value === 'function') { |
|
return new Proxy(value, { |
|
apply: (fn, thisArg, args) => { |
|
try { |
|
console.log(getTime(), 'CALL:', name, '(', ...args, ')'); |
|
if (receiver !== thisArg && target !== thisArg) { |
|
console.log(' - applied to', thisArg); |
|
} |
|
} catch (error) { |
|
console.log(`Could not log "${String(name)}" method call`); |
|
} |
|
return target[name](...args); |
|
}, |
|
}); |
|
} else { |
|
try { |
|
console.log(getTime(), '<GET:', name, '=', value); |
|
} catch (error) { |
|
console.log(`Could not log accessing "${String(name)}"`); |
|
} |
|
} |
|
} |
|
|
|
return value; |
|
}, |
|
set: (target, name, value) => { |
|
if (!filtered || props.includes(name)) { |
|
try { |
|
console.log(getTime(), '>SET:', name, '=', value); |
|
} catch (error) { |
|
console.log(`Could not log setting "${String(name)}"`); |
|
} |
|
} |
|
|
|
return (target[name] = value); |
|
}, |
|
}); |
|
}; |
|
})(); |