UNPKG

class-logger

Version:

Boilerplate-free decorator-based class logging

118 lines (117 loc) 4.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const config_service_1 = require("./config.service"); const constants_1 = require("./constants"); class ClassWrapperService { constructor() { this.proxyTrapConstruct = (target, args, newTarget) => { const config = this.classGetConfigMerged(target.prototype); if (config.include.construct) { const messageStart = config.formatter.start({ args, className: target.name, include: config.include, propertyName: 'construct', }); config.log(messageStart); } const instance = Reflect.construct(target, args, newTarget); const instanceWrapped = this.wrapClassInstance(instance); return instanceWrapped; }; this.makeProxyTrapGet = (className) => (target, property, receiver) => { const prop = Reflect.get(target, property, receiver); if (typeof prop !== 'function') { return prop; } const configProp = Reflect.getMetadata(constants_1.CLASS_LOGGER_METADATA_KEY, target, property); if (!configProp) { return prop; } const configClass = this.classGetConfigMerged(target); const configFinal = config_service_1.ConfigService.configsMerge(configClass, configProp); const propWrapped = this.wrapFunction(configFinal, prop, className, property, target); return propWrapped; }; } wrap(targetWrap) { const get = this.makeProxyTrapGet(targetWrap.name); const proxied = new Proxy(targetWrap, { construct: this.proxyTrapConstruct, get, }); Reflect.getMetadataKeys(targetWrap).forEach((metadataKey) => { Reflect.defineMetadata(metadataKey, Reflect.getMetadata(metadataKey, targetWrap), proxied); }); return proxied; } wrapClassInstance(instance) { const get = this.makeProxyTrapGet(instance.constructor.name); return new Proxy(instance, { get, }); } wrapFunction(config, fn, className, propertyName, classInstance) { const classWrapper = this; const res = function (...args) { const messageStart = config.formatter.start({ args, classInstance, className, include: config.include, propertyName, }); config.log(messageStart); const logEnd = (result, error) => { const messageEnd = config.formatter.end({ args, classInstance, className, error: !!error, include: config.include, propertyName, result, }); let logFn = config.log; if (error) { logFn = config.logError; } logFn(messageEnd); }; try { let fnRes = fn.apply(this, args); if (classWrapper.isPromise(fnRes)) { fnRes = fnRes .then((result) => { logEnd(result); return result; }) .catch((error) => { logEnd(error, true); throw error; }); return fnRes; } logEnd(fnRes); return fnRes; } catch (error) { logEnd(error, true); throw error; } }; Object.keys(fn).forEach((prop) => { res[prop] = fn[prop]; }); return res; } isPromise(val) { return !!val && typeof val === 'object' && typeof val.then === 'function' && typeof val.catch === 'function'; } classGetConfigMerged(target) { const configClassMeta = Reflect.getMetadata(constants_1.CLASS_LOGGER_METADATA_KEY, target); const configRes = config_service_1.ConfigService.configsMerge(config_service_1.ConfigService.config, configClassMeta); return configRes; } } exports.ClassWrapperService = ClassWrapperService;