From d510305c1bcc46eecc2bf1d319001109c3717ef3 Mon Sep 17 00:00:00 2001 From: Viktor Date: Tue, 22 Aug 2023 20:11:03 +0300 Subject: [PATCH 1/9] fix undefined check, add null test for browser --- src/runtime/browser/util.inspect.polyfil.ts | 2 +- tests/Browser/1_json.test.ts | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/runtime/browser/util.inspect.polyfil.ts b/src/runtime/browser/util.inspect.polyfil.ts index 26a3649..6bb0847 100644 --- a/src/runtime/browser/util.inspect.polyfil.ts +++ b/src/runtime/browser/util.inspect.polyfil.ts @@ -63,7 +63,7 @@ function isBoolean(arg: unknown) { } function isUndefined(arg: unknown) { - return arg == null; + return arg === undefined; } function stylizeNoColor(str: string) { diff --git a/tests/Browser/1_json.test.ts b/tests/Browser/1_json.test.ts index ffb77e2..e232f73 100644 --- a/tests/Browser/1_json.test.ts +++ b/tests/Browser/1_json.test.ts @@ -75,4 +75,14 @@ describe("Browser: JSON: Log level", () => { expect(consoleOutput).toContain("Foo bar"); }); + + it("pretty nullish", async () => { + await page.evaluate(() => { + // @ts-ignore + const logger = new tslog.Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info({ foo: null, bar: undefined }); + }); + expect(consoleOutput).toContain("null"); + expect(consoleOutput).toContain("undefined"); + }); }); From be1e549cce7d1b660e77684d6e827bc16bc511a6 Mon Sep 17 00:00:00 2001 From: Viktor Date: Tue, 22 Aug 2023 20:24:01 +0300 Subject: [PATCH 2/9] add null test for node --- tests/Nodejs/5_pretty_Log_Types.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/Nodejs/5_pretty_Log_Types.test.ts b/tests/Nodejs/5_pretty_Log_Types.test.ts index fd7564b..b8ec513 100644 --- a/tests/Nodejs/5_pretty_Log_Types.test.ts +++ b/tests/Nodejs/5_pretty_Log_Types.test.ts @@ -45,6 +45,12 @@ describe("Pretty: Log Types", () => { expect(getConsoleLog()).toContain("555"); }); + test("null", (): void => { + const logger = new Logger({ type: "pretty" }); + logger.log(1234, "testLevel", null); + expect(getConsoleLog()).toContain("null"); + }); + test("Array, stylePrettyLogs: false", (): void => { const logger = new Logger({ type: "pretty", stylePrettyLogs: false }); logger.log(1234, "testLevel", [1, 2, 3, "test"]); From 1e93accd4bc3cedb0e0ac8b510ae673deac46151 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Wed, 23 Aug 2023 15:41:49 +0200 Subject: [PATCH 3/9] Add more tests for some types --- examples/nodejs/index2.ts | 11 +++++++ src/runtime/nodejs/index.ts | 3 ++ tests/Browser/1_json.test.ts | 18 +++++++++++ tests/Nodejs/4_json_Log_Types.test.ts | 20 ++++++++++++ tests/Nodejs/5_pretty_Log_Types.test.ts | 43 +++++++++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/examples/nodejs/index2.ts b/examples/nodejs/index2.ts index 436268c..a712fe7 100644 --- a/examples/nodejs/index2.ts +++ b/examples/nodejs/index2.ts @@ -119,3 +119,14 @@ class CustomError extends Error { const err = new CustomError("a", "b"); logger.error(err); + +console.log("***********"); +logger.debug(null); +logger.debug(undefined); +logger.debug("*", undefined); +console.log("###############"); +//jsonLogger.debug(null); +jsonLogger.debug(undefined); +//jsonLogger.debug('*', undefined); +console.log("###############"); +logger.debug(new URL("https://www.test.de")); diff --git a/src/runtime/nodejs/index.ts b/src/runtime/nodejs/index.ts index 3ec8373..28080d0 100644 --- a/src/runtime/nodejs/index.ts +++ b/src/runtime/nodejs/index.ts @@ -165,6 +165,9 @@ export function transportJSON(json: LogObj & ILogObjMeta): void { // Store value in our collection cache.add(value); } + if (typeof value === "undefined") { + return "[undefined]"; + } return value; }); } diff --git a/tests/Browser/1_json.test.ts b/tests/Browser/1_json.test.ts index e232f73..dcac704 100644 --- a/tests/Browser/1_json.test.ts +++ b/tests/Browser/1_json.test.ts @@ -76,6 +76,24 @@ describe("Browser: JSON: Log level", () => { expect(consoleOutput).toContain("Foo bar"); }); + it("pretty undefined", async () => { + await page.evaluate(() => { + // @ts-ignore + const logger = new tslog.Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info(undefined); + }); + expect(consoleOutput).toContain("undefined"); + }); + + it("pretty null", async () => { + await page.evaluate(() => { + // @ts-ignore + const logger = new tslog.Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info(null); + }); + expect(consoleOutput).toContain("null"); + }); + it("pretty nullish", async () => { await page.evaluate(() => { // @ts-ignore diff --git a/tests/Nodejs/4_json_Log_Types.test.ts b/tests/Nodejs/4_json_Log_Types.test.ts index c750e4c..81396cc 100644 --- a/tests/Nodejs/4_json_Log_Types.test.ts +++ b/tests/Nodejs/4_json_Log_Types.test.ts @@ -20,6 +20,26 @@ describe("JSON: Log Types", () => { expect(getConsoleLog()).toContain('"1":"Test2"'); }); + it("pretty undefined", async () => { + const logger = new Logger({ type: "json" }); + logger.info(undefined); + expect(getConsoleLog()).toContain('"0":"[undefined]"'); + }); + + it("pretty null", async () => { + const logger = new Logger({ type: "json" }); + logger.info(null); + expect(getConsoleLog()).toContain('"0":null'); + }); + + it("pretty nullish", async () => { + const logger = new Logger({ type: "json" }); + logger.info({ foo: null, bar: undefined }); + + expect(getConsoleLog()).toContain('"foo":null'); + expect(getConsoleLog()).toContain('"bar":"[undefined]"'); + }); + test("boolean", (): void => { const logger = new Logger({ type: "json" }); logger.log(1234, "testLevel", true); diff --git a/tests/Nodejs/5_pretty_Log_Types.test.ts b/tests/Nodejs/5_pretty_Log_Types.test.ts index b8ec513..c1ee44f 100644 --- a/tests/Nodejs/5_pretty_Log_Types.test.ts +++ b/tests/Nodejs/5_pretty_Log_Types.test.ts @@ -33,6 +33,28 @@ describe("Pretty: Log Types", () => { expect(getConsoleLog()).toContain("Test1 Test2"); }); + it("pretty undefined", async () => { + const logger = new Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info(undefined); + + expect(getConsoleLog()).toContain("undefined"); + }); + + it("pretty null", async () => { + const logger = new Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info(null); + + expect(getConsoleLog()).toContain("null"); + }); + + it("pretty nullish", async () => { + const logger = new Logger({ type: "pretty", stylePrettyLogs: false }); + logger.info({ foo: null, bar: undefined }); + + expect(getConsoleLog()).toContain("null"); + expect(getConsoleLog()).toContain("undefined"); + }); + test("boolean", (): void => { const logger = new Logger({ type: "pretty" }); logger.log(1234, "testLevel", true); @@ -100,6 +122,27 @@ describe("Pretty: Log Types", () => { expect(getConsoleLog()).toContain("https://example2.com/"); }); + test("Date", (): void => { + const logger = new Logger({ type: "pretty" }); + const date = new Date(0); + logger.log(1234, "testLevel", date); + expect(getConsoleLog()).toContain("1970-01-01T00:00:00.000Z"); + }); + + test("Map", (): void => { + const logger = new Logger({ type: "pretty" }); + const map = new Map(); + logger.log(1234, "testLevel", map); + expect(getConsoleLog()).toContain("Map(0) {}"); + }); + + test("Set", (): void => { + const logger = new Logger({ type: "pretty" }); + const set = new Set(); + logger.log(1234, "testLevel", set); + expect(getConsoleLog()).toContain("Set(0) {}"); + }); + test("String, Object", (): void => { const logger = new Logger({ type: "pretty" }); logger.log(1234, "testLevel", "test", { test: true, nested: { 1: false } }); From ad6556fa880e788677e248a253d7e3cda6f74670 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Wed, 23 Aug 2023 15:42:40 +0200 Subject: [PATCH 4/9] 4.9.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5395b70..abf6219 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "tslog", - "version": "4.9.1", + "version": "4.9.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tslog", - "version": "4.9.1", + "version": "4.9.2", "license": "MIT", "devDependencies": { "@jest/types": "^28.1.3", diff --git a/package.json b/package.json index 560a934..367049d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tslog", - "version": "4.9.1", + "version": "4.9.2", "description": "Extensible TypeScript Logger for Node.js and Browser.", "author": "Eugene (https://fullstack.build)", "license": "MIT", From 6428cef35367de2512d345c6e7cd7bb4622c9dbd Mon Sep 17 00:00:00 2001 From: Olaf Buitelaar Date: Tue, 17 Oct 2023 15:22:30 +0200 Subject: [PATCH 5/9] in case an object is passed for logging, but contains properties from a different security context (e.g. an iframe which is loaded from another domain), handle these fields gracefully --- src/BaseLogger.ts | 8 +++++++- src/runtime/browser/index.ts | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/BaseLogger.ts b/src/BaseLogger.ts index 6406101..65673a0 100644 --- a/src/BaseLogger.ts +++ b/src/BaseLogger.ts @@ -213,7 +213,13 @@ export class BaseLogger { return Object.getOwnPropertyNames(source).reduce((o, prop) => { o[prop] = keys.includes(this.settings?.maskValuesOfKeysCaseInsensitive !== true ? prop : prop.toLowerCase()) ? this.settings.maskPlaceholder - : this._recursiveCloneAndMaskValuesOfKeys((source as Record)[prop], keys, seen); + : (()=>{ + try{ + return this._recursiveCloneAndMaskValuesOfKeys((source as Record)[prop], keys, seen); + }catch(e){ + return null; + } + })(); return o; }, baseObject) as T; } else { diff --git a/src/runtime/browser/index.ts b/src/runtime/browser/index.ts index bbd7854..36acb0c 100644 --- a/src/runtime/browser/index.ts +++ b/src/runtime/browser/index.ts @@ -62,8 +62,8 @@ export function getCallerStackFrame(stackDepthLevel: number, error: Error = Erro } export function getErrorTrace(error: Error): IStackFrame[] { - return (error as Error)?.stack - ?.split("\n") + return ((error as Error)?.stack + ?.split("\n") ?? []) ?.filter((line: string) => !line.includes("Error: ")) ?.reduce((result: IStackFrame[], line: string) => { result.push(stackLineToStackFrame(line)); From 135ee61d490b6910b15a14d725c1375d1ef58445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Hrub=C3=BD?= Date: Thu, 6 Jun 2024 12:48:35 +0200 Subject: [PATCH 6/9] Fix _extend fn - alter provided object --- src/runtime/browser/util.inspect.polyfil.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/runtime/browser/util.inspect.polyfil.ts b/src/runtime/browser/util.inspect.polyfil.ts index 26a3649..ebf79c8 100644 --- a/src/runtime/browser/util.inspect.polyfil.ts +++ b/src/runtime/browser/util.inspect.polyfil.ts @@ -381,13 +381,12 @@ function _extend(origin: object, add: object) { // Don't do anything if add isn't an object if (!add || !isObject(add)) return origin; - const clonedOrigin = { ...origin } as { [key: string]: unknown }; const clonedAdd = { ...add } as { [key: string]: unknown }; const keys = Object.keys(add); let i = keys.length; while (i--) { - clonedOrigin[keys[i]] = clonedAdd[keys[i]]; + origin[keys[i]] = clonedAdd[keys[i]]; } return origin; } From 8190017def691c739096fddad91c8a7b678212a5 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Sat, 8 Jun 2024 14:54:02 +0300 Subject: [PATCH 7/9] Format source --- docs/README.md | 2 +- src/BaseLogger.ts | 14 +++++++------- src/runtime/browser/index.ts | 3 +-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3949d1f..8630092 100644 --- a/docs/README.md +++ b/docs/README.md @@ -686,7 +686,7 @@ For `pretty` logs: For `JSON` logs (no formatting happens here): ```typescript const logger = new Logger({ - type: "pretty", + type: "json", overwrite: { transportJSON: (logObjWithMeta: any) => { // transport the LogObj to console, StdOut, a file or an external service diff --git a/src/BaseLogger.ts b/src/BaseLogger.ts index 65673a0..c5cc026 100644 --- a/src/BaseLogger.ts +++ b/src/BaseLogger.ts @@ -213,13 +213,13 @@ export class BaseLogger { return Object.getOwnPropertyNames(source).reduce((o, prop) => { o[prop] = keys.includes(this.settings?.maskValuesOfKeysCaseInsensitive !== true ? prop : prop.toLowerCase()) ? this.settings.maskPlaceholder - : (()=>{ - try{ - return this._recursiveCloneAndMaskValuesOfKeys((source as Record)[prop], keys, seen); - }catch(e){ - return null; - } - })(); + : (() => { + try { + return this._recursiveCloneAndMaskValuesOfKeys((source as Record)[prop], keys, seen); + } catch (e) { + return null; + } + })(); return o; }, baseObject) as T; } else { diff --git a/src/runtime/browser/index.ts b/src/runtime/browser/index.ts index 36acb0c..d1e58d8 100644 --- a/src/runtime/browser/index.ts +++ b/src/runtime/browser/index.ts @@ -62,8 +62,7 @@ export function getCallerStackFrame(stackDepthLevel: number, error: Error = Erro } export function getErrorTrace(error: Error): IStackFrame[] { - return ((error as Error)?.stack - ?.split("\n") ?? []) + return ((error as Error)?.stack?.split("\n") ?? []) ?.filter((line: string) => !line.includes("Error: ")) ?.reduce((result: IStackFrame[], line: string) => { result.push(stackLineToStackFrame(line)); From 21821bdb8fdbdcc287fe6f03f79b0d2adea0a051 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Sat, 8 Jun 2024 15:02:00 +0300 Subject: [PATCH 8/9] Update README to reflect the lower test coverage --- README.md | 2 +- src/runtime/browser/util.inspect.polyfil.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8630092..c63af52 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ logger.fatal(new Error("I am a pretty Error with a stacktrace.")); ## All Features - **Universal:** Works in browsers and Node.js -- **Tested:** 100% code coverage, CI +- **Tested:** Great code coverage, CI - **Super customizable:** Every aspect can be overwritten - **Fully typed:** Written in TypeScript, with native TypeScript support - **Default log level:** `silly`, `trace`, `debug`, `info`, `warn`, `error`, `fatal` (different colors) diff --git a/src/runtime/browser/util.inspect.polyfil.ts b/src/runtime/browser/util.inspect.polyfil.ts index c85de7b..9f15b1f 100644 --- a/src/runtime/browser/util.inspect.polyfil.ts +++ b/src/runtime/browser/util.inspect.polyfil.ts @@ -377,7 +377,8 @@ function reduceToSingleString(output: string[], base: string, braces: string[]): return braces[0] + (base === "" ? "" : base + "\n") + " " + output.join(",\n ") + " " + braces[1]; } -function _extend(origin: object, add: object) { +function _extend(origin: object, add: object): object { + const typedOrigin = { ...origin } as { [key: string]: unknown }; // Don't do anything if add isn't an object if (!add || !isObject(add)) return origin; @@ -386,9 +387,9 @@ function _extend(origin: object, add: object) { const keys = Object.keys(add); let i = keys.length; while (i--) { - origin[keys[i]] = clonedAdd[keys[i]]; + typedOrigin[keys[i]] = clonedAdd[keys[i]]; } - return origin; + return typedOrigin; } export function formatWithOptions(inspectOptions: InspectOptions, ...args: unknown[]) { From c7fd9123c8be02e5794b7e867b4accc1b546d8d5 Mon Sep 17 00:00:00 2001 From: Eugene Terehov Date: Sat, 8 Jun 2024 15:03:50 +0300 Subject: [PATCH 9/9] Update README --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 8630092..c63af52 100644 --- a/docs/README.md +++ b/docs/README.md @@ -167,7 +167,7 @@ logger.fatal(new Error("I am a pretty Error with a stacktrace.")); ## All Features - **Universal:** Works in browsers and Node.js -- **Tested:** 100% code coverage, CI +- **Tested:** Great code coverage, CI - **Super customizable:** Every aspect can be overwritten - **Fully typed:** Written in TypeScript, with native TypeScript support - **Default log level:** `silly`, `trace`, `debug`, `info`, `warn`, `error`, `fatal` (different colors)