diff --git a/README.md b/README.md index 94e8fed..18584be 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ yarn add nestlogged ## More Info -[Github Wiki](https://github.com/Worplo/nestlogged/wiki) +[Wiki](https://nestlogged.worplo.com) \ No newline at end of file diff --git a/dist/README.md b/dist/README.md index 94e8fed..18584be 100644 --- a/dist/README.md +++ b/dist/README.md @@ -17,4 +17,4 @@ yarn add nestlogged ## More Info -[Github Wiki](https://github.com/Worplo/nestlogged/wiki) +[Wiki](https://nestlogged.worplo.com) \ No newline at end of file diff --git a/dist/lib/logged.d.ts b/dist/lib/logged.d.ts index 62ebff3..8fcf554 100644 --- a/dist/lib/logged.d.ts +++ b/dist/lib/logged.d.ts @@ -7,5 +7,11 @@ export declare function LoggedController(prefix: string | string[]): (target: an export declare function LoggedController(options: ControllerOptions & { verbose?: boolean; }): (target: any) => void; -export declare function LoggedFunction, R>(_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R | Promise>): void; -export declare function LoggedRoute, R>(route?: string): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R>) => void; +interface OverrideBuildOptions { + skipCallLog: boolean; + skipReturnLog: boolean; + skipErrorLog: boolean; +} +export declare function LoggedFunction, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R | Promise>) => void; +export declare function LoggedRoute, R>(route?: string, options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R>) => void; +export {}; diff --git a/dist/lib/logged.js b/dist/lib/logged.js index 1536596..dbcf95e 100644 --- a/dist/lib/logged.js +++ b/dist/lib/logged.js @@ -4,7 +4,6 @@ exports.LoggedRoute = exports.LoggedFunction = exports.LoggedController = export const common_1 = require("@nestjs/common"); const logger_1 = require("./logger"); const reflected_1 = require("./reflected"); -const reflected_2 = require("./reflected"); const functions_1 = require("./functions"); const RevRequestMethod = [ "GET", @@ -39,7 +38,7 @@ function LoggedInjectable(options) { typeof target.prototype[method] === "function") { if (options && options.verbose) logger.log(`LoggedFunction applied to ${method}`); - LoggedFunction(target.prototype, method, { + LoggedFunction()(target.prototype, method, { value: target.prototype[method], }); } @@ -73,7 +72,23 @@ function LoggedController(param) { }; } exports.LoggedController = LoggedController; -function overrideBuild(originalFunction, baseLogger, metadatas, key, returnsData, route) { +const defaultOverrideBuildOptions = { + skipCallLog: false, + skipReturnLog: false, + skipErrorLog: false, +}; +class LoggedMetadata { + constructor(options) { + this.options = options ?? defaultOverrideBuildOptions; + } + updateOption(options) { + this.options = { + ...this.options, + ...options + }; + } +} +function overrideBuild(originalFunction, baseLogger, metadatas, key, returnsData, logged, route) { return function (...args) { let injectedLogger = baseLogger; if (typeof metadatas.scopedLoggerInjectableParam !== "undefined") { @@ -86,20 +101,47 @@ function overrideBuild(originalFunction, baseLogger, metadatas, key, returnsData } injectedLogger = args[metadatas.scopedLoggerInjectableParam]; } - injectedLogger.log(`${route ? "HIT HTTP" : "CALL"} ${route ? `${route.fullRoute} (${key})` : key} ${metadatas.loggedParams && metadatas.loggedParams.length > 0 - ? "WITH " + - metadatas.loggedParams.map(({ name, index, include, exclude }) => name + - "=" + - (0, functions_1.imObjectContainedLogSync)(args[index], { - include, - exclude, - })).join(", ") - : ""}`); + if (!logged.options.skipCallLog) { + injectedLogger.log(`${route ? "HIT HTTP" : "CALL"} ${route ? `${route.fullRoute} (${key})` : key} ${metadatas.loggedParams && metadatas.loggedParams.length > 0 + ? "WITH " + + metadatas.loggedParams.map(({ name, index, include, exclude }) => name + + "=" + + (0, functions_1.imObjectContainedLogSync)(args[index], { + include, + exclude, + })).join(", ") + : ""}`); + } try { const r = originalFunction.call(this, ...args); - if (originalFunction.constructor.name === 'AsyncFunction' || - (r && typeof r === 'object' && typeof r['then'] === 'function')) { - return r['then']((r) => { + if (!logged.options.skipReturnLog) { + if (originalFunction.constructor.name === 'AsyncFunction' || + (r && typeof r === 'object' && typeof r['then'] === 'function')) { + return r['then']((r) => { + const resultLogged = Array.isArray(returnsData) + ? typeof r === "object" && r !== null + ? "WITH " + + returnsData.map(({ name, path }) => { + const value = (0, functions_1.getItemByPathSync)(r, path); + return value !== undefined ? `${name}=${value}` : ""; + }) + .filter((v) => v.length > 0) + .join(", ") + : "" + : typeof returnsData === 'string' + ? "WITH " + returnsData + "=" + typeof r === "object" ? JSON.stringify(r) : r + : returnsData + ? typeof r === "object" + ? "WITH " + JSON.stringify(r) + : "WITH " + r + : ""; + injectedLogger.log(route + ? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}` + : `RETURNED ${key} ${resultLogged}`); + return r; + }); + } + else { const resultLogged = Array.isArray(returnsData) ? typeof r === "object" && r !== null ? "WITH " + @@ -121,68 +163,60 @@ function overrideBuild(originalFunction, baseLogger, metadatas, key, returnsData ? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}` : `RETURNED ${key} ${resultLogged}`); return r; - }); + } } else { - const resultLogged = Array.isArray(returnsData) - ? typeof r === "object" && r !== null - ? "WITH " + - returnsData.map(({ name, path }) => { - const value = (0, functions_1.getItemByPathSync)(r, path); - return value !== undefined ? `${name}=${value}` : ""; - }) - .filter((v) => v.length > 0) - .join(", ") - : "" - : typeof returnsData === 'string' - ? "WITH " + returnsData + "=" + typeof r === "object" ? JSON.stringify(r) : r - : returnsData - ? typeof r === "object" - ? "WITH " + JSON.stringify(r) - : "WITH " + r - : ""; - injectedLogger.log(route - ? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}` - : `RETURNED ${key} ${resultLogged}`); return r; } } catch (e) { - injectedLogger.error(`WHILE ${route ? `HTTP ${route.fullRoute} (${key})` : key} ERROR ${e}`); + if (!logged.options.skipErrorLog) { + injectedLogger.error(`WHILE ${route ? `HTTP ${route.fullRoute} (${key})` : key} ERROR ${e}`); + } throw e; } }; } -function LoggedFunction(_target, key, descriptor) { - loggerInit(_target); - const logger = _target.logger; - const fn = descriptor.value; - if (!fn || typeof fn !== "function") { - logger.warn(`LoggedFunction decorator applied to non-function property: ${key}`); - return; - } - const all = Reflect.getMetadataKeys(fn).map((k) => [ - k, - Reflect.getMetadata(k, fn), - ]); - const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_2.scopedLogger, _target, key); - const loggedParams = Reflect.getOwnMetadata(reflected_2.loggedParam, _target, key); - const scopeKeys = Reflect.getOwnMetadata(reflected_1.scopeKey, _target, key); - const returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); - const overrideFunction = overrideBuild(fn, logger, { - scopedLoggerInjectableParam, - loggedParams, - scopeKeys, - }, key, returnsData); - _target[key] = overrideFunction; - descriptor.value = overrideFunction; - all.forEach(([k, v]) => { - Reflect.defineMetadata(k, v, _target[key]); - Reflect.defineMetadata(k, v, descriptor.value); - }); +function LoggedFunction(options) { + return (_target, key, descriptor) => { + loggerInit(_target); + const logger = _target.logger; + const fn = descriptor.value; + if (!fn || typeof fn !== "function") { + logger.warn(`LoggedFunction decorator applied to non-function property: ${key}`); + return; + } + const logMetadata = Reflect.getOwnMetadata(reflected_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new LoggedMetadata(options); + const all = Reflect.getMetadataKeys(fn).map((k) => [ + k, + Reflect.getMetadata(k, fn), + ]); + const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_1.scopedLogger, _target, key); + const loggedParams = Reflect.getOwnMetadata(reflected_1.loggedParam, _target, key); + const scopeKeys = Reflect.getOwnMetadata(reflected_1.scopeKey, _target, key); + const returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); + const overrideFunction = overrideBuild(fn, logger, { + scopedLoggerInjectableParam, + loggedParams, + scopeKeys, + }, key, returnsData, newMetadata, undefined); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(reflected_1.nestLoggedMetadata, newMetadata, _target, key); + all.forEach(([k, v]) => { + Reflect.defineMetadata(k, v, _target[key]); + Reflect.defineMetadata(k, v, descriptor.value); + }); + }; } exports.LoggedFunction = LoggedFunction; -function LoggedRoute(route) { +function LoggedRoute(route, options) { return (_target, key, descriptor) => { loggerInit(_target); const logger = _target.logger; @@ -191,6 +225,13 @@ function LoggedRoute(route) { logger.warn(`LoggedRoute decorator applied to non-function property: ${key}`); return; } + const logMetadata = Reflect.getOwnMetadata(reflected_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new LoggedMetadata(options); const all = Reflect.getMetadataKeys(fn).map((k) => [ k, Reflect.getMetadata(k, fn), @@ -198,19 +239,20 @@ function LoggedRoute(route) { const httpPath = Reflect.getMetadata("path", fn); const httpMethod = Reflect.getMetadata("method", fn); const fullRoute = `${_target.constructor.name}::${route ?? httpPath}[${RevRequestMethod[httpMethod]}]`; - const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_2.scopedLogger, _target, key); - const loggedParams = Reflect.getOwnMetadata(reflected_2.loggedParam, _target, key); + const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_1.scopedLogger, _target, key); + const loggedParams = Reflect.getOwnMetadata(reflected_1.loggedParam, _target, key); const scopeKeys = Reflect.getOwnMetadata(reflected_1.scopeKey, _target, key); const returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); const overrideFunction = overrideBuild(fn, logger, { scopedLoggerInjectableParam, loggedParams, scopeKeys, - }, key, returnsData, { + }, key, returnsData, newMetadata, { fullRoute, }); _target[key] = overrideFunction; descriptor.value = overrideFunction; + Reflect.defineMetadata(reflected_1.nestLoggedMetadata, newMetadata, _target, key); all.forEach(([k, v]) => { Reflect.defineMetadata(k, v, _target[key]); Reflect.defineMetadata(k, v, descriptor.value); diff --git a/dist/lib/reflected.d.ts b/dist/lib/reflected.d.ts index ea9ec17..4eb81f1 100644 --- a/dist/lib/reflected.d.ts +++ b/dist/lib/reflected.d.ts @@ -25,6 +25,7 @@ export declare const scopedLogger: unique symbol; export declare const loggedParam: unique symbol; export declare const scopeKey: unique symbol; export declare const returns: unique symbol; +export declare const nestLoggedMetadata: unique symbol; export declare function InjectLogger(target: any, propertyKey: string | symbol, parameterIndex: number): void; type ParameterDecoratorType = (target: any, propertyKey: string | symbol, parameterIndex: number) => void; type LoggedParamReturns = (name: string, options?: IncludeExcludePath) => ParameterDecoratorType; diff --git a/dist/lib/reflected.js b/dist/lib/reflected.js index 362423b..3730be2 100644 --- a/dist/lib/reflected.js +++ b/dist/lib/reflected.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.Returns = exports.LoggedHeaders = exports.LoggedBody = exports.LoggedQuery = exports.LoggedParam = exports.Logged = exports.InjectLogger = exports.returns = exports.scopeKey = exports.loggedParam = exports.scopedLogger = void 0; +exports.Returns = exports.LoggedHeaders = exports.LoggedBody = exports.LoggedQuery = exports.LoggedParam = exports.Logged = exports.InjectLogger = exports.nestLoggedMetadata = exports.returns = exports.scopeKey = exports.loggedParam = exports.scopedLogger = void 0; const route_paramtypes_enum_1 = require("@nestjs/common/enums/route-paramtypes.enum"); const common_1 = require("@nestjs/common"); const shared_utils_1 = require("@nestjs/common/utils/shared.utils"); @@ -22,6 +22,7 @@ exports.scopedLogger = Symbol("nlogdec-scopedLogger"); exports.loggedParam = Symbol("nlogdec-loggedParam"); exports.scopeKey = Symbol("nlogdec-scopeKey"); exports.returns = Symbol("nlogdec-returns"); +exports.nestLoggedMetadata = Symbol("nlogdec-metadata"); function InjectLogger(target, propertyKey, parameterIndex) { Reflect.defineMetadata(exports.scopedLogger, parameterIndex, target, propertyKey); } diff --git a/dist/package.json b/dist/package.json index a556732..86c2951 100644 --- a/dist/package.json +++ b/dist/package.json @@ -1,6 +1,6 @@ { "name": "nestlogged", - "version": "2.2.8", + "version": "3.0.0", "description": "A NestJS Logger Decorator Library", "main": "lib/index.js", "repository": "https://github.com/worplo/nestlogged",