From ea26a46ee167ca333114c3f044202653e7a07988 Mon Sep 17 00:00:00 2001 From: p-sw Date: Wed, 10 Jan 2024 02:01:45 +0900 Subject: [PATCH] fix: allow non-promise returning --- src/functions.ts | 81 +++++++++++++++++++++++++++++++++- src/logged.ts | 110 ++++++++++++++++++++++++++++------------------ src/test/index.ts | 23 +++++++++- 3 files changed, 169 insertions(+), 45 deletions(-) diff --git a/src/functions.ts b/src/functions.ts index 103d45c..6faa258 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -51,6 +51,51 @@ export async function includeOrExcludeObject( : ocv; } +export function includeOrExcludeObjectSync( + ocv: any, + paths: string[], + currentPath: string[] = [], + include: boolean // or exclude +) { + if (Array.isArray(ocv)) { + return ( + ocv.map( + (v, i) => + includeOrExcludeObjectSync( + v, + paths, + [...currentPath, i.toString()], + include + ) + ) + ).filter((e) => e !== notIncludedSymbol); + } + + if (typeof ocv === "object") { + return Object.fromEntries( + Object.entries(ocv).map(([key, value]) => [ + key, + includeOrExcludeObject( + value, + paths, + [...currentPath, key], + include + ), + ]).filter((e) => e[1] !== notIncludedSymbol) + ); + } + + const isIncluded = paths.includes(currentPath.join(".")); + + return include + ? isIncluded // include mode, path is in list + ? ocv + : notIncludedSymbol + : isIncluded // exclude mode, path is in list + ? notIncludedSymbol + : ocv; +} + export default async function objectContainedLogged( ocv: any, options?: { include?: string[]; exclude: string[] } @@ -75,12 +120,46 @@ export default async function objectContainedLogged( } } +export function objectContainedLoggedSync( + ocv: any, + options?: { include?: string[]; exclude: string[] } +): string { + if (options && typeof ocv === "object") { + if (options.include && options.include.length > 0) { + return JSON.stringify( + includeOrExcludeObjectSync(ocv, options.include, [], true) + ); + } + if (options.exclude && options.exclude.length > 0) { + return JSON.stringify( + includeOrExcludeObjectSync(ocv, options.exclude, [], false) + ); + } + } + + if (typeof ocv === "object") { + return JSON.stringify(ocv); + } else { + return `${ocv}`; + } +} + export async function getItemByPath(obj: object, path: string | string[]) { const paths = Array.isArray(path) ? path : path.split("."); + return Object.keys(obj).includes(paths[0]) + ? typeof obj[paths[0]] === "object" + ? await getItemByPath(obj[paths[0]], paths.slice(1)) + : obj[paths[0]] + : undefined; +} + +export function getItemByPathSync(obj: object, path: string | string[]) { + const paths = Array.isArray(path) ? path : path.split("."); + return Object.keys(obj).includes(paths[0]) ? typeof obj[paths[0]] === "object" ? getItemByPath(obj[paths[0]], paths.slice(1)) : obj[paths[0]] : undefined; -} +} \ No newline at end of file diff --git a/src/logged.ts b/src/logged.ts index e4fc79b..7723294 100644 --- a/src/logged.ts +++ b/src/logged.ts @@ -14,7 +14,7 @@ import { scopeKey, } from "./reflected"; import { loggedParam, scopedLogger } from "./reflected"; -import objectContainedLogged, { getItemByPath } from "./functions"; +import { objectContainedLoggedSync, getItemByPathSync } from "./functions"; import { RequestMethod } from "@nestjs/common"; const RevRequestMethod = [ @@ -122,7 +122,7 @@ interface FunctionMetadata { } function overrideBuild, R>( - originalFunction: (...args: F) => Promise | R, + originalFunction: (...args: F) => R, baseLogger: Logger, metadatas: FunctionMetadata, key: string, @@ -130,8 +130,8 @@ function overrideBuild, R>( route?: { fullRoute: string; } -) { - return async function (...args: F) { +): (...args: F) => R { + return function (...args: F): R { let injectedLogger: Logger = baseLogger; if (typeof metadatas.scopedLoggerInjectableParam !== "undefined") { if ( @@ -161,55 +161,79 @@ function overrideBuild, R>( } ${ metadatas.loggedParams && metadatas.loggedParams.length > 0 ? "WITH " + - ( - await Promise.all( - metadatas.loggedParams.map( - async ({ name, index, include, exclude }) => - name + - "=" + - (await objectContainedLogged(args[index], { - include, - exclude, - })) - ) - ) + metadatas.loggedParams.map( + ({ name, index, include, exclude }) => + name + + "=" + + objectContainedLoggedSync(args[index], { + include, + exclude, + }) ).join(", ") : "" }` ); try { - const r: R = await originalFunction.call(this, ...args); - - const resultLogged = Array.isArray(returnsData) - ? typeof r === "object" - ? "WITH " + - ( - await Promise.all( - returnsData.map(async ({ name, path }) => { - const value = await getItemByPath(r, path); + const r: R = originalFunction.call(this, ...args); + if ( + originalFunction.constructor.name === 'AsyncFunction' || + (typeof r === 'object' && typeof r['then'] === 'function') + ) { + return r['then']((r: any) => { + const resultLogged = Array.isArray(returnsData) + ? typeof r === "object" + ? "WITH " + + returnsData.map(({ name, path }) => { + const value = 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 - : ""; + .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; + injectedLogger.log( + route + ? `RETURNED HTTP ${route.fullRoute} (${key}) ${resultLogged}` + : `RETURNED ${key} ${resultLogged}` + ); + return r; + }) + } else { + const resultLogged = Array.isArray(returnsData) + ? typeof r === "object" + ? "WITH " + + returnsData.map(({ name, path }) => { + const value = 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}` diff --git a/src/test/index.ts b/src/test/index.ts index 6c9f5ba..8b96fe7 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -163,6 +163,15 @@ class LoggedClass { await this.testLoggerRootLogging2(logger); } + testSyncLoggerRootLogging2(@InjectLogger logger?: ScopedLogger) { + logger.log('2') + return 2 + } + + testSyncLoggerRootLogging(@InjectLogger logger?: ScopedLogger) { + logger.log(this.testSyncLoggerRootLogging2(logger).toString()) + } + testSyncLogging(@InjectLogger logger?: ScopedLogger) { logger.log("synced yay"); } @@ -325,6 +334,17 @@ class LoggedMethodsClass { await this.testLoggerRootLogging2(logger); } + @LoggedFunction + testSyncLoggerRootLogging2(@InjectLogger logger?: ScopedLogger) { + logger.log('2') + return 2 + } + + @LoggedFunction + testSyncLoggerRootLogging(@InjectLogger logger?: ScopedLogger) { + logger.log(this.testSyncLoggerRootLogging2(logger).toString()) + } + @LoggedFunction testSyncLogging(@InjectLogger logger?: ScopedLogger) { logger.log("synced yay"); @@ -353,7 +373,8 @@ const tester = new LoggedClass(); // void tester.testMissingReturnLogging("asdf"); // void tester.testRawObjectReturnLogging("asdf"); // void tester.testRawValueReturnLogging("asdf"); -// void tester.testLoggerRootLogging(); +void tester.testLoggerRootLogging(); +// tester.testSyncLoggerRootLogging(); // tester.testSyncLogging(); /**