diff --git a/package.json b/package.json index fcfe087..fb094ae 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "typescript": "^5.2.2" }, "scripts": { - "build": "rimraf packages/nestlogged/dist && yarn workspace nestlogged tsc", - "fastify:build": "rimraf packages/nestlogged-fastify/dist && yarn workspace nestlogged-fastify tsc", + "build": "rimraf packages/nestlogged/lib && yarn workspace nestlogged tsc", + "fastify:build": "rimraf packages/nestlogged-fastify/lib && yarn workspace nestlogged-fastify tsc", "format": "prettier --write \"./packages/**/*.ts\"" }, "packageManager": "yarn@4.7.0+sha512.5a0afa1d4c1d844b3447ee3319633797bcd6385d9a44be07993ae52ff4facabccafb4af5dcd1c2f9a94ac113e5e9ff56f6130431905884414229e284e37bb7c9" diff --git a/packages/nestlogged/lib/index.d.ts b/packages/nestlogged/lib/index.d.ts new file mode 100644 index 0000000..e42cc6f --- /dev/null +++ b/packages/nestlogged/lib/index.d.ts @@ -0,0 +1,4 @@ +export { LoggedRoute, LoggedFunction, LoggedController, LoggedInjectable, LoggedGuard, LoggedInterceptor, LoggedMiddleware, } from './logged'; +export { ScopedLogger } from './logger'; +export { InjectLogger, LoggedParam, LoggedHeaders, LoggedBody, LoggedQuery, Logged, Returns, } from './reflected'; +export { getRequestLogger } from './utils'; diff --git a/packages/nestlogged/lib/index.js b/packages/nestlogged/lib/index.js new file mode 100644 index 0000000..fdbe9cc --- /dev/null +++ b/packages/nestlogged/lib/index.js @@ -0,0 +1,23 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getRequestLogger = exports.Returns = exports.Logged = exports.LoggedQuery = exports.LoggedBody = exports.LoggedHeaders = exports.LoggedParam = exports.InjectLogger = exports.ScopedLogger = exports.LoggedMiddleware = exports.LoggedInterceptor = exports.LoggedGuard = exports.LoggedInjectable = exports.LoggedController = exports.LoggedFunction = exports.LoggedRoute = void 0; +var logged_1 = require("./logged"); +Object.defineProperty(exports, "LoggedRoute", { enumerable: true, get: function () { return logged_1.LoggedRoute; } }); +Object.defineProperty(exports, "LoggedFunction", { enumerable: true, get: function () { return logged_1.LoggedFunction; } }); +Object.defineProperty(exports, "LoggedController", { enumerable: true, get: function () { return logged_1.LoggedController; } }); +Object.defineProperty(exports, "LoggedInjectable", { enumerable: true, get: function () { return logged_1.LoggedInjectable; } }); +Object.defineProperty(exports, "LoggedGuard", { enumerable: true, get: function () { return logged_1.LoggedGuard; } }); +Object.defineProperty(exports, "LoggedInterceptor", { enumerable: true, get: function () { return logged_1.LoggedInterceptor; } }); +Object.defineProperty(exports, "LoggedMiddleware", { enumerable: true, get: function () { return logged_1.LoggedMiddleware; } }); +var logger_1 = require("./logger"); +Object.defineProperty(exports, "ScopedLogger", { enumerable: true, get: function () { return logger_1.ScopedLogger; } }); +var reflected_1 = require("./reflected"); +Object.defineProperty(exports, "InjectLogger", { enumerable: true, get: function () { return reflected_1.InjectLogger; } }); +Object.defineProperty(exports, "LoggedParam", { enumerable: true, get: function () { return reflected_1.LoggedParam; } }); +Object.defineProperty(exports, "LoggedHeaders", { enumerable: true, get: function () { return reflected_1.LoggedHeaders; } }); +Object.defineProperty(exports, "LoggedBody", { enumerable: true, get: function () { return reflected_1.LoggedBody; } }); +Object.defineProperty(exports, "LoggedQuery", { enumerable: true, get: function () { return reflected_1.LoggedQuery; } }); +Object.defineProperty(exports, "Logged", { enumerable: true, get: function () { return reflected_1.Logged; } }); +Object.defineProperty(exports, "Returns", { enumerable: true, get: function () { return reflected_1.Returns; } }); +var utils_1 = require("./utils"); +Object.defineProperty(exports, "getRequestLogger", { enumerable: true, get: function () { return utils_1.getRequestLogger; } }); diff --git a/packages/nestlogged/lib/internals/nest.d.ts b/packages/nestlogged/lib/internals/nest.d.ts new file mode 100644 index 0000000..3d0a16d --- /dev/null +++ b/packages/nestlogged/lib/internals/nest.d.ts @@ -0,0 +1,6 @@ +import { RouteParamtypes } from '@nestjs/common/enums/route-paramtypes.enum'; +import { ParamData, PipeTransform, Type } from '@nestjs/common'; +import { ROUTE_ARGS_METADATA } from '@nestjs/common/constants'; +export { RouteParamtypes, PipeTransform, Type, ROUTE_ARGS_METADATA }; +export declare function createRouteParamDecorator(paramtype: RouteParamtypes): (data?: ParamData) => ParameterDecorator; +export declare const createPipesRouteParamDecorator: (paramtype: RouteParamtypes) => (data?: any, ...pipes: (Type | PipeTransform)[]) => ParameterDecorator; diff --git a/packages/nestlogged/lib/internals/nest.js b/packages/nestlogged/lib/internals/nest.js new file mode 100644 index 0000000..04ca6e6 --- /dev/null +++ b/packages/nestlogged/lib/internals/nest.js @@ -0,0 +1,24 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createPipesRouteParamDecorator = exports.createRouteParamDecorator = exports.ROUTE_ARGS_METADATA = exports.RouteParamtypes = void 0; +const route_paramtypes_enum_1 = require("@nestjs/common/enums/route-paramtypes.enum"); +Object.defineProperty(exports, "RouteParamtypes", { enumerable: true, get: function () { return route_paramtypes_enum_1.RouteParamtypes; } }); +const common_1 = require("@nestjs/common"); +const constants_1 = require("@nestjs/common/constants"); +Object.defineProperty(exports, "ROUTE_ARGS_METADATA", { enumerable: true, get: function () { return constants_1.ROUTE_ARGS_METADATA; } }); +const shared_utils_1 = require("@nestjs/common/utils/shared.utils"); +function createRouteParamDecorator(paramtype) { + return (data) => (target, key, index) => { + const args = Reflect.getMetadata(constants_1.ROUTE_ARGS_METADATA, target.constructor, key) || {}; + Reflect.defineMetadata(constants_1.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(constants_1.ROUTE_ARGS_METADATA, target.constructor, key) || {}; + const hasParamData = (0, shared_utils_1.isNil)(data) || (0, shared_utils_1.isString)(data); + const paramData = hasParamData ? data : undefined; + const paramPipes = hasParamData ? pipes : [data, ...pipes]; + Reflect.defineMetadata(constants_1.ROUTE_ARGS_METADATA, (0, common_1.assignMetadata)(args, paramtype, index, paramData, ...paramPipes), target.constructor, key); +}; +exports.createPipesRouteParamDecorator = createPipesRouteParamDecorator; diff --git a/packages/nestlogged/lib/internals/utils.d.ts b/packages/nestlogged/lib/internals/utils.d.ts new file mode 100644 index 0000000..4df622b --- /dev/null +++ b/packages/nestlogged/lib/internals/utils.d.ts @@ -0,0 +1,12 @@ +export declare const notIncludedSymbol: unique symbol; +export declare function includeObjectSync(ocv: any, opt: { + paths: string[]; +}): any; +export declare function excludeObjectSync(ocv: any, opt: { + paths: string[]; +}): any; +export declare function objectContainedLogSync(ocv: any, options?: { + include?: string[]; + exclude?: string[]; +}): string; +export declare function getItemByPathSync(obj: object, path: string | string[]): any; diff --git a/packages/nestlogged/lib/internals/utils.js b/packages/nestlogged/lib/internals/utils.js new file mode 100644 index 0000000..048f3cc --- /dev/null +++ b/packages/nestlogged/lib/internals/utils.js @@ -0,0 +1,82 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getItemByPathSync = exports.objectContainedLogSync = exports.excludeObjectSync = exports.includeObjectSync = exports.notIncludedSymbol = void 0; +exports.notIncludedSymbol = Symbol('notIncluded'); +function includeObjectSync(ocv, opt) { + let current = Array.isArray(ocv) ? [] : typeof ocv === 'object' ? {} : ocv; + opt.paths.forEach((dotpath) => { + let query = ocv; + let objRef = current; + const path = dotpath.split('.'); + for (const [index, key] of Object.entries(path)) { + query = query[key]; + if (query !== undefined && objRef[key] === undefined) { + if (typeof query === 'object') { + if (Array.isArray(query)) { + objRef[key] = []; + } + else { + objRef[key] = {}; + } + } + } + if (typeof query !== 'object' || index === (path.length - 1).toString()) { + objRef[key] = query; + break; + } + objRef = objRef[key]; + } + }); + return current; +} +exports.includeObjectSync = includeObjectSync; +function excludeObjectSync(ocv, opt) { + const copied = typeof ocv === 'object' + ? Array.isArray(ocv) + ? [...ocv] + : { ...ocv } + : ocv; + opt.paths.forEach((dotpath) => { + let objRef = copied; + const path = dotpath.split('.'); + const lastIndex = (path.length - 1).toString(); + for (const [index, key] of Object.entries(path)) { + if (index === lastIndex) { + delete objRef[key]; + break; + } + objRef = objRef[key]; + if (typeof objRef !== 'object') { + break; + } + } + }); + return copied; +} +exports.excludeObjectSync = excludeObjectSync; +function objectContainedLogSync(ocv, options) { + if (options && typeof ocv === 'object' && ocv !== null) { + if (options.include && options.include.length > 0) { + return JSON.stringify(includeObjectSync(ocv, { paths: options.include })); + } + if (options.exclude && options.exclude.length > 0) { + return JSON.stringify(excludeObjectSync(ocv, { paths: options.exclude })); + } + } + if (typeof ocv === 'object' && ocv !== null) { + return JSON.stringify(ocv); + } + else { + return `${ocv}`; + } +} +exports.objectContainedLogSync = objectContainedLogSync; +function getItemByPathSync(obj, path) { + const paths = Array.isArray(path) ? path : path.split('.'); + return Object.keys(obj).includes(paths[0]) + ? typeof obj[paths[0]] === 'object' + ? getItemByPathSync(obj[paths[0]], paths.slice(1)) + : obj[paths[0]] + : undefined; +} +exports.getItemByPathSync = getItemByPathSync; diff --git a/packages/nestlogged/lib/logged/class.d.ts b/packages/nestlogged/lib/logged/class.d.ts new file mode 100644 index 0000000..35a92b2 --- /dev/null +++ b/packages/nestlogged/lib/logged/class.d.ts @@ -0,0 +1,9 @@ +import { ControllerOptions, ScopeOptions } from '@nestjs/common'; +export declare function LoggedInjectable(options?: ScopeOptions & { + verbose?: boolean; +}): (target: any) => void; +export declare function LoggedController(): (target: any) => void; +export declare function LoggedController(prefix: string | string[]): (target: any) => void; +export declare function LoggedController(options: ControllerOptions & { + verbose?: boolean; +}): (target: any) => void; diff --git a/packages/nestlogged/lib/logged/class.js b/packages/nestlogged/lib/logged/class.js new file mode 100644 index 0000000..386fc1a --- /dev/null +++ b/packages/nestlogged/lib/logged/class.js @@ -0,0 +1,50 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedController = exports.LoggedInjectable = void 0; +const common_1 = require("@nestjs/common"); +const utils_1 = require("./utils"); +const methods_1 = require("./methods"); +function LoggedInjectable(options) { + return (target) => { + (0, utils_1.loggerInit)(target.prototype); + const logger = target.prototype.logger; + const methods = Object.getOwnPropertyNames(target.prototype); + methods.forEach((method) => { + if (method !== 'constructor' && + typeof target.prototype[method] === 'function') { + if (options && options.verbose) + logger.log(`LoggedFunction applied to ${method}`); + (0, methods_1.LoggedFunction)()(target.prototype, method, { + value: target.prototype[method], + }); + } + }); + (0, common_1.Injectable)(options)(target); + }; +} +exports.LoggedInjectable = LoggedInjectable; +function LoggedController(param) { + return (target) => { + (0, utils_1.loggerInit)(target.prototype); + const logger = target.prototype.logger; + const methods = Object.getOwnPropertyNames(target.prototype); + let verbose = typeof param === 'object' && Object.keys(param).includes('verbose') + ? param.verbose + : false; + methods.forEach((method) => { + if (method !== 'constructor' && + typeof target.prototype[method] === 'function') { + if (verbose) { + const path = Reflect.getMetadata('path', target.prototype[method]); + const httpMethod = Reflect.getMetadata('method', target.prototype[method]); + logger.log(`LoggedRoute applied to ${method} (${utils_1.RevRequestMethod[httpMethod]} ${path})`); + } + (0, methods_1.LoggedRoute)()(target.prototype, method, { + value: target.prototype[method], + }); + } + }); + (0, common_1.Controller)(param)(target); + }; +} +exports.LoggedController = LoggedController; diff --git a/packages/nestlogged/lib/logged/index.d.ts b/packages/nestlogged/lib/logged/index.d.ts new file mode 100644 index 0000000..67b66e2 --- /dev/null +++ b/packages/nestlogged/lib/logged/index.d.ts @@ -0,0 +1,2 @@ +export * from './methods'; +export { LoggedController, LoggedInjectable } from './class'; diff --git a/packages/nestlogged/lib/logged/index.js b/packages/nestlogged/lib/logged/index.js new file mode 100644 index 0000000..0b7e383 --- /dev/null +++ b/packages/nestlogged/lib/logged/index.js @@ -0,0 +1,21 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedInjectable = exports.LoggedController = void 0; +__exportStar(require("./methods"), exports); +var class_1 = require("./class"); +Object.defineProperty(exports, "LoggedController", { enumerable: true, get: function () { return class_1.LoggedController; } }); +Object.defineProperty(exports, "LoggedInjectable", { enumerable: true, get: function () { return class_1.LoggedInjectable; } }); diff --git a/packages/nestlogged/lib/logged/metadata.d.ts b/packages/nestlogged/lib/logged/metadata.d.ts new file mode 100644 index 0000000..971377d --- /dev/null +++ b/packages/nestlogged/lib/logged/metadata.d.ts @@ -0,0 +1,7 @@ +import { OverrideBuildOptions } from './utils'; +export declare const nestLoggedMetadata: unique symbol; +export declare class LoggedMetadata { + options: OverrideBuildOptions; + constructor(options?: Partial); + updateOption(options: Partial): void; +} diff --git a/packages/nestlogged/lib/logged/metadata.js b/packages/nestlogged/lib/logged/metadata.js new file mode 100644 index 0000000..600ae52 --- /dev/null +++ b/packages/nestlogged/lib/logged/metadata.js @@ -0,0 +1,20 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedMetadata = exports.nestLoggedMetadata = void 0; +const utils_1 = require("./utils"); +exports.nestLoggedMetadata = Symbol('nlogdec-metadata'); +class LoggedMetadata { + constructor(options) { + this.options = { + ...utils_1.defaultOverrideBuildOptions, + ...(options ?? {}), + }; + } + updateOption(options) { + this.options = { + ...this.options, + ...options, + }; + } +} +exports.LoggedMetadata = LoggedMetadata; diff --git a/packages/nestlogged/lib/logged/methods/function.d.ts b/packages/nestlogged/lib/logged/methods/function.d.ts new file mode 100644 index 0000000..c7ac515 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/function.d.ts @@ -0,0 +1,2 @@ +import { OverrideBuildOptions } from '../utils'; +export declare function LoggedFunction, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R | Promise>) => void; diff --git a/packages/nestlogged/lib/logged/methods/function.js b/packages/nestlogged/lib/logged/methods/function.js new file mode 100644 index 0000000..7807c86 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/function.js @@ -0,0 +1,44 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedFunction = void 0; +const utils_1 = require("../utils"); +const metadata_1 = require("../metadata"); +const reflected_1 = require("../../reflected"); +const override_1 = require("../override"); +function LoggedFunction(options) { + return (_target, key, descriptor) => { + (0, utils_1.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(metadata_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new metadata_1.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 returnsData = Reflect.getOwnMetadata(reflected_1.returns, fn); + const overrideFunction = (0, override_1.overrideBuild)('function', fn, logger, { + scopedLoggerInjectableParam, + loggedParams, + }, key, returnsData, newMetadata); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(metadata_1.nestLoggedMetadata, newMetadata, _target, key); + all.forEach(([k, v]) => { + Reflect.defineMetadata(k, v, _target[key]); + Reflect.defineMetadata(k, v, descriptor.value); + }); + }; +} +exports.LoggedFunction = LoggedFunction; diff --git a/packages/nestlogged/lib/logged/methods/guard.d.ts b/packages/nestlogged/lib/logged/methods/guard.d.ts new file mode 100644 index 0000000..97fa480 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/guard.d.ts @@ -0,0 +1,3 @@ +import { ExecutionContext } from '@nestjs/common'; +import { OverrideBuildOptions } from '../utils'; +export declare function LoggedGuard, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>) => void; diff --git a/packages/nestlogged/lib/logged/methods/guard.js b/packages/nestlogged/lib/logged/methods/guard.js new file mode 100644 index 0000000..360c586 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/guard.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedGuard = void 0; +const utils_1 = require("../utils"); +const metadata_1 = require("../metadata"); +const reflected_1 = require("../../reflected"); +const override_1 = require("../override"); +function LoggedGuard(options) { + return (_target, key, descriptor) => { + (0, utils_1.loggerInit)(_target); + const logger = _target.logger; + const fn = descriptor.value; + if (!fn || typeof fn !== 'function') { + logger.warn(`LoggedGuard decorator applied to non-function property: ${key}`); + return; + } + const logMetadata = Reflect.getOwnMetadata(metadata_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new metadata_1.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 = (0, override_1.overrideBuild)('guard', fn, logger, { + scopedLoggerInjectableParam, + loggedParams: [], + }, _target.constructor.name, returnsData, newMetadata); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(metadata_1.nestLoggedMetadata, newMetadata, _target, key); + all.forEach(([k, v]) => { + Reflect.defineMetadata(k, v, _target[key]); + Reflect.defineMetadata(k, v, descriptor.value); + }); + }; +} +exports.LoggedGuard = LoggedGuard; diff --git a/packages/nestlogged/lib/logged/methods/index.d.ts b/packages/nestlogged/lib/logged/methods/index.d.ts new file mode 100644 index 0000000..9aeedf1 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/index.d.ts @@ -0,0 +1,5 @@ +export { LoggedFunction } from './function'; +export { LoggedRoute } from './route'; +export { LoggedGuard } from './guard'; +export { LoggedInterceptor } from './interceptor'; +export { LoggedMiddleware } from './middleware'; diff --git a/packages/nestlogged/lib/logged/methods/index.js b/packages/nestlogged/lib/logged/methods/index.js new file mode 100644 index 0000000..d2f4aba --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/index.js @@ -0,0 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedMiddleware = exports.LoggedInterceptor = exports.LoggedGuard = exports.LoggedRoute = exports.LoggedFunction = void 0; +var function_1 = require("./function"); +Object.defineProperty(exports, "LoggedFunction", { enumerable: true, get: function () { return function_1.LoggedFunction; } }); +var route_1 = require("./route"); +Object.defineProperty(exports, "LoggedRoute", { enumerable: true, get: function () { return route_1.LoggedRoute; } }); +var guard_1 = require("./guard"); +Object.defineProperty(exports, "LoggedGuard", { enumerable: true, get: function () { return guard_1.LoggedGuard; } }); +var interceptor_1 = require("./interceptor"); +Object.defineProperty(exports, "LoggedInterceptor", { enumerable: true, get: function () { return interceptor_1.LoggedInterceptor; } }); +var middleware_1 = require("./middleware"); +Object.defineProperty(exports, "LoggedMiddleware", { enumerable: true, get: function () { return middleware_1.LoggedMiddleware; } }); diff --git a/packages/nestlogged/lib/logged/methods/interceptor.d.ts b/packages/nestlogged/lib/logged/methods/interceptor.d.ts new file mode 100644 index 0000000..53f7a61 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/interceptor.d.ts @@ -0,0 +1,3 @@ +import { OverrideBuildOptions } from '../utils'; +import { ExecutionContext } from '@nestjs/common'; +export declare function LoggedInterceptor, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(context: ExecutionContext, ...args: F) => R>) => void; diff --git a/packages/nestlogged/lib/logged/methods/interceptor.js b/packages/nestlogged/lib/logged/methods/interceptor.js new file mode 100644 index 0000000..e4beaba --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/interceptor.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedInterceptor = void 0; +const utils_1 = require("../utils"); +const metadata_1 = require("../metadata"); +const reflected_1 = require("../../reflected"); +const override_1 = require("../override"); +function LoggedInterceptor(options) { + return (_target, key, descriptor) => { + (0, utils_1.loggerInit)(_target); + const logger = _target.logger; + const fn = descriptor.value; + if (!fn || typeof fn !== 'function') { + logger.warn(`LoggedInterceptor decorator applied to non-function property: ${key}`); + return; + } + const logMetadata = Reflect.getOwnMetadata(metadata_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new metadata_1.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 = (0, override_1.overrideBuild)('interceptor', fn, logger, { + scopedLoggerInjectableParam, + loggedParams: [], + }, _target.constructor.name, returnsData, newMetadata); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(metadata_1.nestLoggedMetadata, newMetadata, _target, key); + all.forEach(([k, v]) => { + Reflect.defineMetadata(k, v, _target[key]); + Reflect.defineMetadata(k, v, descriptor.value); + }); + }; +} +exports.LoggedInterceptor = LoggedInterceptor; diff --git a/packages/nestlogged/lib/logged/methods/middleware.d.ts b/packages/nestlogged/lib/logged/methods/middleware.d.ts new file mode 100644 index 0000000..66a698b --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/middleware.d.ts @@ -0,0 +1,2 @@ +import { OverrideBuildOptions } from '../utils'; +export declare function LoggedMiddleware, R>(options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R>) => void; diff --git a/packages/nestlogged/lib/logged/methods/middleware.js b/packages/nestlogged/lib/logged/methods/middleware.js new file mode 100644 index 0000000..61b713d --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/middleware.js @@ -0,0 +1,43 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedMiddleware = void 0; +const utils_1 = require("../utils"); +const metadata_1 = require("../metadata"); +const reflected_1 = require("../../reflected"); +const override_1 = require("../override"); +function LoggedMiddleware(options) { + return (_target, key, descriptor) => { + (0, utils_1.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(metadata_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new metadata_1.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 = (0, override_1.overrideBuild)('middleware', fn, logger, { + scopedLoggerInjectableParam, + loggedParams: [], + }, _target.constructor.name, returnsData, newMetadata); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(metadata_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/packages/nestlogged/lib/logged/methods/route.d.ts b/packages/nestlogged/lib/logged/methods/route.d.ts new file mode 100644 index 0000000..b8e0538 --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/route.d.ts @@ -0,0 +1,2 @@ +import { OverrideBuildOptions } from '../utils'; +export declare function LoggedRoute, R>(route?: string, options?: Partial): (_target: any, key: string, descriptor: TypedPropertyDescriptor<(...args: F) => R>) => void; diff --git a/packages/nestlogged/lib/logged/methods/route.js b/packages/nestlogged/lib/logged/methods/route.js new file mode 100644 index 0000000..462d3fc --- /dev/null +++ b/packages/nestlogged/lib/logged/methods/route.js @@ -0,0 +1,52 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoggedRoute = void 0; +const utils_1 = require("../utils"); +const metadata_1 = require("../metadata"); +const reflected_1 = require("../../reflected"); +const override_1 = require("../override"); +const nest_1 = require("../../internals/nest"); +function LoggedRoute(route, options) { + return (_target, key, descriptor) => { + (0, utils_1.loggerInit)(_target); + const logger = _target.logger; + const fn = descriptor.value; + if (!fn || typeof fn !== 'function') { + logger.warn(`LoggedRoute decorator applied to non-function property: ${key}`); + return; + } + const logMetadata = Reflect.getOwnMetadata(metadata_1.nestLoggedMetadata, _target, key); + if (logMetadata) { + // already applied, override instead + logMetadata.updateOption(options); + return; + } + const newMetadata = new metadata_1.LoggedMetadata(options); + const all = Reflect.getMetadataKeys(fn).map((k) => [ + k, + Reflect.getMetadata(k, fn), + ]); + const httpPath = Reflect.getMetadata('path', fn); + const httpMethod = Reflect.getMetadata('method', fn); + const fullRoute = `${_target.constructor.name}::${route ?? httpPath}[${utils_1.RevRequestMethod[httpMethod]}]`; + const scopedLoggerInjectableParam = Reflect.getOwnMetadata(reflected_1.scopedLogger, _target, key); + // if @InjectLogger exists, fake nestjs as it is @Req() + if (scopedLoggerInjectableParam !== undefined) { + (0, nest_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 = (0, override_1.overrideBuild)('route', fn, logger, { + scopedLoggerInjectableParam, + loggedParams, + }, key, returnsData, newMetadata, fullRoute); + _target[key] = overrideFunction; + descriptor.value = overrideFunction; + Reflect.defineMetadata(metadata_1.nestLoggedMetadata, newMetadata, _target, key); + all.forEach(([k, v]) => { + Reflect.defineMetadata(k, v, _target[key]); + Reflect.defineMetadata(k, v, descriptor.value); + }); + }; +} +exports.LoggedRoute = LoggedRoute; diff --git a/packages/nestlogged/lib/logged/override.d.ts b/packages/nestlogged/lib/logged/override.d.ts new file mode 100644 index 0000000..a7d3f82 --- /dev/null +++ b/packages/nestlogged/lib/logged/override.d.ts @@ -0,0 +1,10 @@ +import { Logger } from '@nestjs/common'; +import { LoggedParamReflectData, ReturnsReflectData } from '../reflected'; +import { LoggedMetadata } from './metadata'; +interface FunctionMetadata { + scopedLoggerInjectableParam?: number; + loggedParams?: LoggedParamReflectData[]; +} +export declare function overrideBuild, R>(type: 'route', originalFunction: (...args: F) => R, baseLogger: Logger, metadatas: FunctionMetadata, key: string, returnsData: ReturnsReflectData[] | string | true, logged: LoggedMetadata, route: string): (...args: F) => R; +export declare function overrideBuild, R>(type: 'function' | 'guard' | 'interceptor' | 'middleware', originalFunction: (...args: F) => R, baseLogger: Logger, metadatas: FunctionMetadata, key: string, returnsData: ReturnsReflectData[] | string | true, logged: LoggedMetadata): (...args: F) => R; +export {}; diff --git a/packages/nestlogged/lib/logged/override.js b/packages/nestlogged/lib/logged/override.js new file mode 100644 index 0000000..ae9f77f --- /dev/null +++ b/packages/nestlogged/lib/logged/override.js @@ -0,0 +1,152 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.overrideBuild = void 0; +const utils_1 = require("./utils"); +const utils_2 = require("../internals/utils"); +const logger_1 = require("../logger"); +function overrideBuild(type, originalFunction, baseLogger, metadatas, key, returnsData, logged, route) { + return function (...args) { + // Creating ScopedLogger + let injectedLogger = baseLogger; + if (typeof metadatas.scopedLoggerInjectableParam !== 'undefined') { + 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 { + // 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[utils_1.REQUEST_LOG_ID] === undefined) { + req[utils_1.REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[utils_1.REQUEST_LOG_ID]); + } + } + else if (type === 'middleware') { + let req = args[0]; + if (req[utils_1.REQUEST_LOG_ID] === undefined) { + req[utils_1.REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[utils_1.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[utils_1.REQUEST_LOG_ID] === undefined) { + req[utils_1.REQUEST_LOG_ID] = logger_1.ScopedLogger.createScopeId(); + } + args[metadatas.scopedLoggerInjectableParam] = logger_1.ScopedLogger.fromRoot(baseLogger, key, req[utils_1.REQUEST_LOG_ID]); + } + } + injectedLogger = args[metadatas.scopedLoggerInjectableParam]; + } + // If this is ExecutionContext based function (e.g. Guard, Interceptor) get Request from Context + if (type === 'guard' || type === 'interceptor') { + const context = args[0]; + if (context.getType() === 'http') { + const req = context.switchToHttp().getRequest(); + route = /* supporting FastifyRequest */ req.raw ? req.raw.url : req.url; + } + } + // Start Log + if (logged.options.callLogLevel !== 'skip') { + const callLogIdentifyMessage = type === 'middleware' || + type === 'guard' || + type === 'interceptor' || + type === 'route' + ? (0, utils_1.createCallLogIdentifyMessage)('HIT', type, key, route) + : (0, utils_1.createCallLogIdentifyMessage)('HIT', type, key); + injectedLogger[logged.options.callLogLevel](`${callLogIdentifyMessage} ${metadatas.loggedParams && metadatas.loggedParams.length > 0 + ? 'WITH ' + + metadatas.loggedParams + .map(({ name, index, include, exclude }) => name + + '=' + + (0, utils_2.objectContainedLogSync)(args[index], { + include, + exclude, + })) + .join(', ') + : ''}`); + } + try { + const r = originalFunction.call(this, ...args); // Try to call original function + // Return Log + if (logged.options.returnLogLevel !== 'skip') { + 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, utils_2.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[logged.options.returnLogLevel](`${(0, utils_1.createCallLogIdentifyMessage)('RETURNED', type, key, route)} ${resultLogged}`); + return r; + }); + } + else { + const resultLogged = Array.isArray(returnsData) + ? typeof r === 'object' && r !== null + ? 'WITH ' + + returnsData + .map(({ name, path }) => { + const value = (0, utils_2.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[logged.options.returnLogLevel](`${(0, utils_1.createCallLogIdentifyMessage)('RETURNED', type, key, route)} ${resultLogged}`); + return r; + } + } + else { + return r; + } + } + catch (e) { + // Error Log + if (logged.options.errorLogLevel !== 'skip') { + injectedLogger[logged.options.errorLogLevel](`${(0, utils_1.createCallLogIdentifyMessage)('ERROR', type, key, route)} ${e}`); + } + throw e; + } + }; +} +exports.overrideBuild = overrideBuild; diff --git a/packages/nestlogged/lib/logged/utils.d.ts b/packages/nestlogged/lib/logged/utils.d.ts new file mode 100644 index 0000000..f89a9e3 --- /dev/null +++ b/packages/nestlogged/lib/logged/utils.d.ts @@ -0,0 +1,18 @@ +import { LogLevel } from '@nestjs/common'; +export declare const RevRequestMethod: string[]; +export declare function loggerInit(_target: any): void; +export type BuildType = 'route' | 'function' | 'guard' | 'interceptor' | 'middleware'; +export declare function createCallLogIdentifyMessage(message: 'HIT' | 'RETURNED' | 'ERROR', type: BuildType, key?: string, route?: string): string; +export declare const REQUEST_LOG_ID = "__nestlogged_request_log_id__"; +export interface OverrideBuildOptions { + callLogLevel: LogLevel | 'skip'; + returnLogLevel: LogLevel | 'skip'; + errorLogLevel: LogLevel | 'skip'; + /** @deprecated use `callLogLevel: 'skip'` instead */ + skipCallLog: boolean; + /** @deprecated use `returnLogLevel: 'skip'` instead */ + skipReturnLog: boolean; + /** @deprecated use `errorLogLevel: 'skip'` instead */ + skipErrorLog: boolean; +} +export declare const defaultOverrideBuildOptions: OverrideBuildOptions; diff --git a/packages/nestlogged/lib/logged/utils.js b/packages/nestlogged/lib/logged/utils.js new file mode 100644 index 0000000..7d4177c --- /dev/null +++ b/packages/nestlogged/lib/logged/utils.js @@ -0,0 +1,57 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.defaultOverrideBuildOptions = exports.REQUEST_LOG_ID = exports.createCallLogIdentifyMessage = exports.loggerInit = exports.RevRequestMethod = void 0; +const common_1 = require("@nestjs/common"); +exports.RevRequestMethod = [ + 'GET', + 'POST', + 'PUT', + 'DELETE', + 'PATCH', + 'ALL', + 'OPTIONS', + 'HEAD', + 'SEARCH', +]; +function loggerInit(_target) { + if (!Object.getOwnPropertyNames(_target).includes('logger')) { + const newTargetLogger = new common_1.Logger(_target.constructor.name); + newTargetLogger.log('Logger Initialized.'); + Object.defineProperty(_target, 'logger', { + writable: false, + enumerable: false, + configurable: false, + value: newTargetLogger, + }); + } +} +exports.loggerInit = loggerInit; +const callLogIdentifyMessageDictionary = { + route: 'ENDPOINT', + function: 'FUNCTION', + guard: 'GUARD', + interceptor: 'INTERCEPTOR', + middleware: 'MIDDLEWARE', +}; +function createCallLogIdentifyMessage(message, type, key, route) { + if (message === 'ERROR') + return `ERROR WHILE ${callLogIdentifyMessageDictionary[type]} ${key} (${route}): `; + if (type === 'guard' || + type === 'interceptor' || + type === 'middleware' || + type === 'route') + return `${message} ${callLogIdentifyMessageDictionary[type]} ${key} (${route})`; + if (type === 'function') + return `${message} ${callLogIdentifyMessageDictionary[type]} ${key}`; + return `${message} ${callLogIdentifyMessageDictionary[type]}`; +} +exports.createCallLogIdentifyMessage = createCallLogIdentifyMessage; +exports.REQUEST_LOG_ID = '__nestlogged_request_log_id__'; +exports.defaultOverrideBuildOptions = { + callLogLevel: 'log', + returnLogLevel: 'log', + errorLogLevel: 'error', + skipCallLog: false, + skipReturnLog: false, + skipErrorLog: false, +}; diff --git a/packages/nestlogged/lib/logger.d.ts b/packages/nestlogged/lib/logger.d.ts new file mode 100644 index 0000000..6fc7757 --- /dev/null +++ b/packages/nestlogged/lib/logger.d.ts @@ -0,0 +1,17 @@ +import { Logger } from '@nestjs/common'; +export declare class ScopedLogger extends Logger { + private logger; + private scope; + private scopeId; + constructor(logger: Logger, scope: string[], scopeId?: string); + private scopedLog; + debug: (message: string) => void; + log: (message: string) => void; + warn: (message: string) => void; + verbose: (message: string) => void; + error: (message: string) => void; + fatal: (message: string) => void; + static fromSuper(baseLogger: Logger, logger: ScopedLogger, scope: string): ScopedLogger; + static fromRoot(logger: Logger, scope: string, scopeId?: string): ScopedLogger; + static createScopeId(): string; +} diff --git a/packages/nestlogged/lib/logger.js b/packages/nestlogged/lib/logger.js new file mode 100644 index 0000000..305d6d7 --- /dev/null +++ b/packages/nestlogged/lib/logger.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ScopedLogger = void 0; +const common_1 = require("@nestjs/common"); +const hyperid = require("hyperid"); +const createId = hyperid({ fixedLength: true }); +class ScopedLogger extends common_1.Logger { + constructor(logger, scope, scopeId = createId()) { + super(); + this.logger = logger; + this.scope = scope; + this.scopeId = scopeId; + this.debug = this.scopedLog('debug'); + this.log = this.scopedLog('log'); + this.warn = this.scopedLog('warn'); + this.verbose = this.scopedLog('verbose'); + this.error = this.scopedLog('error'); + this.fatal = this.scopedLog('fatal'); + } + scopedLog(method) { + return (message) => { + this.logger[method](`${this.scopeId ? `(ID ${this.scopeId}) | ` : ''}${this.scope.join(' -> ')}: ${message}`); + }; + } + static fromSuper(baseLogger, logger, scope) { + return new ScopedLogger(baseLogger, [...logger.scope, scope], logger.scopeId); + } + static fromRoot(logger, scope, scopeId) { + return new ScopedLogger(logger, [scope], scopeId); + } + static createScopeId() { + return createId(); + } +} +exports.ScopedLogger = ScopedLogger; diff --git a/packages/nestlogged/lib/reflected.d.ts b/packages/nestlogged/lib/reflected.d.ts new file mode 100644 index 0000000..24bf15c --- /dev/null +++ b/packages/nestlogged/lib/reflected.d.ts @@ -0,0 +1,45 @@ +import { Type, PipeTransform } from './internals/nest'; +export type Path = string | string[]; +export type Paths = Path[]; +export interface IncludeExcludePath { + includePath?: Paths; + excludePath?: Paths; +} +export interface LoggedParamReflectData { + name: string; + index: number; + include?: string[]; + exclude?: string[]; +} +export interface ScopeKeyReflectData { + name: string; + index: number; + path?: string[]; + priority?: number; +} +export interface ReturnsReflectData { + name: string; + path: string; +} +export declare const scopedLogger: unique symbol; +export declare const loggedParam: unique symbol; +export declare const returns: 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; +export declare const Logged: LoggedParamReturns; +type Pipe = Type | PipeTransform; +export declare function LoggedParam(): LoggedParamReturns; +export declare function LoggedParam(...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedParam(property: string, ...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedQuery(): LoggedParamReturns; +export declare function LoggedQuery(...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedQuery(property: string, ...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedBody(): LoggedParamReturns; +export declare function LoggedBody(...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedBody(property: string, ...pipes: Pipe[]): LoggedParamReturns; +export declare function LoggedHeaders(property?: string): LoggedParamReturns; +export declare function Returns, R>(namePaths?: { + [name: string]: string; +} | string): (_target: any, _key: string | symbol, descriptor: TypedPropertyDescriptor<(...args: F) => Promise | R>) => void; +export {}; diff --git a/packages/nestlogged/lib/reflected.js b/packages/nestlogged/lib/reflected.js new file mode 100644 index 0000000..b78c3d4 --- /dev/null +++ b/packages/nestlogged/lib/reflected.js @@ -0,0 +1,76 @@ +"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.loggedParam = exports.scopedLogger = void 0; +const nest_1 = require("./internals/nest"); +exports.scopedLogger = Symbol('nlogdec-scopedLogger'); +exports.loggedParam = Symbol('nlogdec-loggedParam'); +exports.returns = Symbol('nlogdec-returns'); +function InjectLogger(target, propertyKey, parameterIndex) { + Reflect.defineMetadata(exports.scopedLogger, parameterIndex, target, propertyKey); +} +exports.InjectLogger = InjectLogger; +function createLoggedFunctionParam(name, options) { + return (target, propertyKey, parameterIndex) => { + const existingLoggedParams = Reflect.getOwnMetadata(exports.loggedParam, target, propertyKey) || []; + existingLoggedParams.push({ + name, + index: parameterIndex, + // If path is provided in string[] type, convert it to string path because it is used in string type + include: options && + options.includePath && + options.includePath.map((v) => (Array.isArray(v) ? v.join('.') : v)), + exclude: options && + options.excludePath && + options.excludePath.map((v) => (Array.isArray(v) ? v.join('.') : v)), + }); + Reflect.defineMetadata(exports.loggedParam, existingLoggedParams, target, propertyKey); + }; +} +const Logged = (name, options) => createLoggedFunctionParam(name, options); +exports.Logged = Logged; +function LoggedParam(property, ...pipes) { + return (name, options) => { + return (target, propertyKey, parameterIndex) => { + (0, nest_1.createPipesRouteParamDecorator)(nest_1.RouteParamtypes.PARAM)(property, ...pipes)(target, propertyKey, parameterIndex); + createLoggedFunctionParam(name, options)(target, propertyKey, parameterIndex); + }; + }; +} +exports.LoggedParam = LoggedParam; +function LoggedQuery(property, ...pipes) { + return (name, options) => { + return (target, propertyKey, parameterIndex) => { + (0, nest_1.createPipesRouteParamDecorator)(nest_1.RouteParamtypes.QUERY)(property, ...pipes)(target, propertyKey, parameterIndex); + createLoggedFunctionParam(name, options)(target, propertyKey, parameterIndex); + }; + }; +} +exports.LoggedQuery = LoggedQuery; +function LoggedBody(property, ...pipes) { + return (name, options) => { + return (target, propertyKey, parameterIndex) => { + (0, nest_1.createPipesRouteParamDecorator)(nest_1.RouteParamtypes.BODY)(property, ...pipes)(target, propertyKey, parameterIndex); + createLoggedFunctionParam(name, options)(target, propertyKey, parameterIndex); + }; + }; +} +exports.LoggedBody = LoggedBody; +function LoggedHeaders(property) { + return (name, options) => { + return (target, propertyKey, parameterIndex) => { + (0, nest_1.createRouteParamDecorator)(nest_1.RouteParamtypes.HEADERS)(property)(target, propertyKey, parameterIndex); + createLoggedFunctionParam(name, options)(target, propertyKey, parameterIndex); + }; + }; +} +exports.LoggedHeaders = LoggedHeaders; +function Returns(namePaths) { + return (_target, _key, descriptor) => { + Reflect.defineMetadata(exports.returns, namePaths + ? typeof namePaths === 'string' + ? namePaths + : Object.entries(namePaths).reduce((prev, curr) => [...prev, { name: curr[0], path: curr[1] }], []) + : true, descriptor.value); + }; +} +exports.Returns = Returns; diff --git a/packages/nestlogged/lib/utils.d.ts b/packages/nestlogged/lib/utils.d.ts new file mode 100644 index 0000000..1a27448 --- /dev/null +++ b/packages/nestlogged/lib/utils.d.ts @@ -0,0 +1,2 @@ +import { ScopedLogger } from './logger'; +export declare function getRequestLogger(functionName: string, req: any): ScopedLogger; diff --git a/packages/nestlogged/lib/utils.js b/packages/nestlogged/lib/utils.js new file mode 100644 index 0000000..a8ba580 --- /dev/null +++ b/packages/nestlogged/lib/utils.js @@ -0,0 +1,11 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getRequestLogger = void 0; +const common_1 = require("@nestjs/common"); +const logger_1 = require("./logger"); +const utils_1 = require("./logged/utils"); +const logger = new common_1.Logger(); +function getRequestLogger(functionName, req) { + return new logger_1.ScopedLogger(logger, [functionName], req[utils_1.REQUEST_LOG_ID]); +} +exports.getRequestLogger = getRequestLogger; diff --git a/packages/nestlogged/tsconfig.build.json b/packages/nestlogged/tsconfig.build.json index 1ab50dd..786db75 100644 --- a/packages/nestlogged/tsconfig.build.json +++ b/packages/nestlogged/tsconfig.build.json @@ -2,7 +2,7 @@ "extends": "./tsconfig.json", "exclude": [ "node_modules", - "dist", + "lib", "src/test", ], "compilerOptions": { diff --git a/packages/nestlogged/tsconfig.json b/packages/nestlogged/tsconfig.json index 3546de1..96b36a8 100644 --- a/packages/nestlogged/tsconfig.json +++ b/packages/nestlogged/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "ES2021", "sourceMap": false, - "outDir": "./dist/lib", + "outDir": "./lib", "rootDir": "./src", "declaration": true, "declarationMap": false, @@ -12,6 +12,6 @@ }, "exclude": [ "node_modules", - "dist", + "lib", ], }