From 9c729a5997b462629e9e1bb856a4f03eb01a0184 Mon Sep 17 00:00:00 2001 From: Shinwoo PARK Date: Thu, 20 Mar 2025 17:48:23 +0900 Subject: [PATCH] feat: 3.2.0 beta.2 release --- dist/lib/logged.d.ts | 1 + dist/lib/logged.js | 108 ++++++++++++++++++++++++++++++++++++---- dist/lib/logger.d.ts | 3 +- dist/lib/logger.js | 7 ++- dist/lib/reflected.d.ts | 4 +- dist/lib/reflected.js | 3 +- dist/package.json | 2 +- package.json | 2 +- 8 files changed, 112 insertions(+), 18 deletions(-) diff --git a/dist/lib/logged.d.ts b/dist/lib/logged.d.ts index 08910d0..c3ccb29 100644 --- a/dist/lib/logged.d.ts +++ b/dist/lib/logged.d.ts @@ -22,4 +22,5 @@ export declare function LoggedFunction, R>(options?: Partia export declare function LoggedRoute, R>(route?: string, options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R>) => void; export declare function LoggedGuard, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>) => void; export declare function LoggedInterceptor, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>) => void; +export declare function LoggedMiddleware, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>) => void; export {}; diff --git a/dist/lib/logged.js b/dist/lib/logged.js index 053447a..955bdd1 100644 --- a/dist/lib/logged.js +++ b/dist/lib/logged.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.LoggedInterceptor = exports.LoggedGuard = exports.LoggedRoute = exports.LoggedFunction = exports.LoggedController = exports.LoggedInjectable = void 0; +exports.LoggedMiddleware = exports.LoggedInterceptor = exports.LoggedGuard = exports.LoggedRoute = exports.LoggedFunction = exports.LoggedController = exports.LoggedInjectable = void 0; const common_1 = require("@nestjs/common"); const logger_1 = require("./logger"); const reflected_1 = require("./reflected"); @@ -98,27 +98,69 @@ const callLogIdentifyMessageDictionary = { route: 'HIT HTTP', function: 'CALL', guard: 'HIT GUARD', - interceptor: 'HIT INTERCEPTOR' + interceptor: 'HIT INTERCEPTOR', + middleware: 'HIT MIDDLEWARE', }; function createCallLogIdentifyMessage(type, key, route) { - return `${callLogIdentifyMessageDictionary[type]} ${type === 'route' ? `${route} (${key})` : type === 'guard' ? `${route}` : key}`; + if (type === 'route') + return `${callLogIdentifyMessageDictionary[type]} ${route} (${key})`; + if (type === 'guard' || type === 'interceptor' || type === 'middleware') + return `${callLogIdentifyMessageDictionary[type]} ${route}`; + if (type === 'function') + return `${callLogIdentifyMessageDictionary[type]} ${key}`; + return callLogIdentifyMessageDictionary[type]; } +const REQUEST_LOG_ID = '__nestlogged_request_log_id__'; function overrideBuild(type, originalFunction, baseLogger, metadatas, key, returnsData, logged, route) { return function (...args) { // Creating ScopedLogger let injectedLogger = baseLogger; if (typeof metadatas.scopedLoggerInjectableParam !== "undefined") { - if (args.length <= metadatas.scopedLoggerInjectableParam || - !(args[metadatas.scopedLoggerInjectableParam] instanceof logger_1.ScopedLogger)) { - args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key); + if (type === 'function') { + if (args.length <= metadatas.scopedLoggerInjectableParam || + !(args[metadatas.scopedLoggerInjectableParam] instanceof logger_1.ScopedLogger)) { + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key); + } + else { + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromSuper(baseLogger, args[metadatas.scopedLoggerInjectableParam], key); + } } else { - args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromSuper(baseLogger, args[metadatas.scopedLoggerInjectableParam], key); + // special, can access to request object + if (type === 'guard' || type === 'interceptor') { + // args[0] == ExecutionContext + const ctx = args[0]; + if (ctx.getType() !== 'http') { + injectedLogger.error('Cannot inject logger: Request type is not http'); + } + else { + let req = ctx.switchToHttp().getRequest(); + if (req[REQUEST_LOG_ID] === undefined) { + req[REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[REQUEST_LOG_ID]); + } + } + else if (type === 'middleware') { + let req = args[0]; + if (req[REQUEST_LOG_ID] === undefined) { + req[REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[REQUEST_LOG_ID]); + } + else if (type === 'route') { + // args[metadatas.scopedLoggerInjectableParam] is now Request object, thanks to code in @LoggedRoute!!!! + let req = args[metadatas.scopedLoggerInjectableParam]; + if (req[REQUEST_LOG_ID] === undefined) { + req[REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[REQUEST_LOG_ID]); + } } injectedLogger = args[metadatas.scopedLoggerInjectableParam]; } // If this is ExecutionContext based function (e.g. Guard, Interceptor) get Request from Context - if (type === 'guard') { + if (type === 'guard' || type === 'interceptor') { const context = args[0]; if (context.getType() === 'http') { const req = context.switchToHttp().getRequest(); @@ -127,7 +169,11 @@ function overrideBuild(type, originalFunction, baseLogger, metadatas, key, retur } // Start Log if (logged.options.callLogLevel !== 'skip') { - const callLogIdentifyMessage = type === 'route' || type === 'guard' || type === 'interceptor' ? createCallLogIdentifyMessage(type, key, route) : createCallLogIdentifyMessage(type, key); + const callLogIdentifyMessage = type === 'middleware' || type === 'guard' || type === 'interceptor' + ? createCallLogIdentifyMessage(type, route) + : type === 'route' + ? createCallLogIdentifyMessage(type, key, route) + : createCallLogIdentifyMessage(type, key); injectedLogger[logged.options.callLogLevel](`${callLogIdentifyMessage} ${metadatas.loggedParams && metadatas.loggedParams.length > 0 ? "WITH " + metadatas.loggedParams.map(({ name, index, include, exclude }) => name + @@ -266,6 +312,10 @@ function LoggedRoute(route, options) { const httpMethod = Reflect.getMetadata("method", fn); const fullRoute = `${_target.constructor.name}::${route ?? httpPath}[${RevRequestMethod[httpMethod]}]`; const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_1.scopedLogger, _target, key); + // if @InjectLogger exists, fake nestjs as it is @Req() + if (scopedLoggerInjectableParam !== undefined) { + (0, reflected_1.createRouteParamDecorator)(0)()(_target, key, scopedLoggerInjectableParam); + } const loggedParams = Reflect.getOwnMetadata(reflected_1.loggedParam, _target, key); const returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); const overrideFunction = overrideBuild('route', fn, logger, { @@ -307,7 +357,7 @@ function LoggedGuard(options) { const overrideFunction = overrideBuild('guard', fn, logger, { scopedLoggerInjectableParam, loggedParams: [], - }, key, returnsData, newMetadata); + }, _target.constructor.name, returnsData, newMetadata); _target[key] = overrideFunction; descriptor.value = overrideFunction; Reflect.defineMetadata(reflected_1.nestLoggedMetadata, newMetadata, _target, key); @@ -343,7 +393,7 @@ function LoggedInterceptor(options) { const overrideFunction = overrideBuild('interceptor', fn, logger, { scopedLoggerInjectableParam, loggedParams: [], - }, key, returnsData, newMetadata); + }, _target.constructor.name, returnsData, newMetadata); _target[key] = overrideFunction; descriptor.value = overrideFunction; Reflect.defineMetadata(reflected_1.nestLoggedMetadata, newMetadata, _target, key); @@ -354,3 +404,39 @@ function LoggedInterceptor(options) { }; } exports.LoggedInterceptor = LoggedInterceptor; +function LoggedMiddleware(options) { + return (_target, key, descriptor) => { + loggerInit(_target); + const logger = _target.logger; + const fn = descriptor.value; + if (!fn || typeof fn !== "function") { + logger.warn(`LoggedMiddleware 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 returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); + const overrideFunction = overrideBuild('middleware', fn, logger, { + scopedLoggerInjectableParam, + loggedParams: [], + }, _target.constructor.name, returnsData, newMetadata); + _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.LoggedMiddleware = LoggedMiddleware; diff --git a/dist/lib/logger.d.ts b/dist/lib/logger.d.ts index e92ed3f..bfe25c3 100644 --- a/dist/lib/logger.d.ts +++ b/dist/lib/logger.d.ts @@ -12,5 +12,6 @@ export declare class ScopedLogger extends Logger { error: (message: string) => void; fatal: (message: string) => void; static fromSuper(baseLogger: Logger, logger: ScopedLogger, scope: string): ScopedLogger; - static fromRoot(logger: Logger, scope: string): ScopedLogger; + static fromRoot(logger: Logger, scope: string, scopeId?: string): ScopedLogger; + static createScopeId(): string; } diff --git a/dist/lib/logger.js b/dist/lib/logger.js index b385f73..2783c05 100644 --- a/dist/lib/logger.js +++ b/dist/lib/logger.js @@ -26,9 +26,12 @@ class ScopedLogger extends common_1.Logger { return new ScopedLogger(baseLogger, [...logger.scope, scope], logger.scopeId); } ; - static fromRoot(logger, scope) { - return new ScopedLogger(logger, [scope]); + static fromRoot(logger, scope, scopeId) { + return new ScopedLogger(logger, [scope], scopeId); } ; + static createScopeId() { + return createId(); + } } exports.ScopedLogger = ScopedLogger; diff --git a/dist/lib/reflected.d.ts b/dist/lib/reflected.d.ts index ed6208e..63f7826 100644 --- a/dist/lib/reflected.d.ts +++ b/dist/lib/reflected.d.ts @@ -1,4 +1,6 @@ -import { PipeTransform, Type } from "@nestjs/common"; +import { RouteParamtypes } from '@nestjs/common/enums/route-paramtypes.enum'; +import { ParamData, PipeTransform, Type } from "@nestjs/common"; +export declare function createRouteParamDecorator(paramtype: RouteParamtypes): (data?: ParamData) => ParameterDecorator; export type Path = string | string[]; export type Paths = Path[]; export interface IncludeExcludePath { diff --git a/dist/lib/reflected.js b/dist/lib/reflected.js index a17e470..ccea5e4 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.nestLoggedMetadata = exports.returns = 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.loggedParam = exports.scopedLogger = exports.createRouteParamDecorator = 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"); @@ -11,6 +11,7 @@ function createRouteParamDecorator(paramtype) { Reflect.defineMetadata(ROUTE_ARGS_METADATA, (0, common_1.assignMetadata)(args, paramtype, index, data), target.constructor, key); }; } +exports.createRouteParamDecorator = createRouteParamDecorator; const createPipesRouteParamDecorator = (paramtype) => (data, ...pipes) => (target, key, index) => { const args = Reflect.getMetadata(ROUTE_ARGS_METADATA, target.constructor, key) || {}; const hasParamData = (0, shared_utils_1.isNil)(data) || (0, shared_utils_1.isString)(data); diff --git a/dist/package.json b/dist/package.json index d5fd17b..d3dcc84 100644 --- a/dist/package.json +++ b/dist/package.json @@ -1,6 +1,6 @@ { "name": "nestlogged", - "version": "3.2.0-beta.1", + "version": "3.2.0-beta.2", "description": "A NestJS Logger Decorator Library", "main": "lib/index.js", "repository": "https://git.psw.kr/p-sw/nestlogged", diff --git a/package.json b/package.json index a5e0f77..99c2617 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nestlogged", - "version": "3.2.0-beta.1", + "version": "3.2.0-beta.2", "description": "A NestJS Logger Decorator Library", "main": "./dist/lib/index.js", "repository": "https://git.psw.kr/p-sw/nestlogged",