Skip to content

Commit

Permalink
Dont manipulate original when masking (Fix #180), Possibility to over…
Browse files Browse the repository at this point in the history
…write LogObj for sub-logger (Fix #181), Fix #175
  • Loading branch information
terehov committed Nov 24, 2022
1 parent 0b8e697 commit f07cb87
Show file tree
Hide file tree
Showing 15 changed files with 335 additions and 248 deletions.
23 changes: 11 additions & 12 deletions build.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
const esbuild = require("esbuild");
import { build } from "esbuild";

esbuild
.build({
entryPoints: ["src/index.ts"],
outfile: "dist/browser/index.js",
platform: "browser",
bundle: true,
minify: true,
format: "iife",
globalName: "tslog",
loader: { ".ts": "ts" },
})
build({
entryPoints: ["src/index.ts"],
outfile: "dist/browser/index.js",
platform: "browser",
bundle: true,
minify: true,
format: "iife",
globalName: "tslog",
loader: { ".ts": "ts" },
})
.then(() => console.log("⚡ Done"))
.catch(() => process.exit(1));
5 changes: 5 additions & 0 deletions examples/nodejs/cjs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("../../../");
const log = new __1.Logger();
log.info("foo bar");
4 changes: 4 additions & 0 deletions examples/nodejs/esm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import "../../../dist";
import { Logger } from "../../../dist/server/index.js";
const log = new Logger();
log.info("foo bar");
2 changes: 1 addition & 1 deletion examples/nodejs/index2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Logger, BaseLogger } from "../../src";
import { Logger, BaseLogger } from "../../src/index.js";

const defaultLogObject: {
name: string;
Expand Down
370 changes: 185 additions & 185 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 14 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,35 @@
"bugs": {
"url": "https://github.com/fullstack-build/tslog/issues"
},
"type": "module",
"main": "./dist/nodejs/cjs/index.js",
"module": "./dist/nodejs/esm/index.js",
"types": "./dist/types/index.d.ts",
"browser": {
"tslog": "./dist/browser/index.js",
"util": false,
"./src/runtime/nodejs/index.ts": "./src/runtime/browser/index.ts"
"./dist/nodejs/esm/runtime/nodejs/index.js": "./dist/nodejs/esm/runtime/browser/index.js",
"./dist/nodejs/cjs/runtime/nodejs/index.js": "./dist/nodejs/cjs/runtime/browser/index.js",
"./src/runtime/nodejs/index.ts": "./src/runtime/browser/index.ts",
"util": false
},
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"require": "./dist/nodejs/cjs/index.js",
"import": "./dist/nodejs/esm/index.js"
"import": "./dist/nodejs/esm/index.js",
"default": "./dist/nodejs/esm/index.js"
}
},
"scripts": {
"build": "npm run build-types && npm run build-server && npm run build-browser",
"build-browser": "node build.js",
"build-types": "tsc -b tsconfig.types.json",
"build-server": "tsc -b tsconfig.esm.json tsconfig.cjs.json",
"start": "node --enable-source-maps --experimental-specifier-resolution=node examples/dist/examples/nodejs/index2.js",
"dev-ts": "nodemon --watch './**/*.ts' --exec 'node --enable-source-maps --experimental-specifier-resolution=node --no-warnings --loader ts-node/esm' examples/nodejs/index2.ts",
"dev-ts-old-example": "nodemon --watch './**/*.ts' --exec 'node --enable-source-maps --experimental-specifier-resolution=node --no-warnings --loader ts-node/esm' examples/nodejs/index.ts",
"dev-js": "tsc -b tsconfig.example.json && node --enable-source-maps --experimental-specifier-resolution=node examples/dist/examples/nodejs/index2.js",
"build-example": "tsc -b tsconfig.example.json",
"dev-ts": "nodemon --watch './**/*.ts' --exec 'node --experimental-specifier-resolution=node --enable-source-maps --no-warnings --loader ts-node/esm' examples/nodejs/index2.ts",
"start": "npm run build-example && node --experimental-specifier-resolution=node --enable-source-maps examples/dist/examples/nodejs/index2.js",
"dev-ts-old-example": "nodemon --watch './**/*.ts' --exec 'node --experimental-specifier-resolution=node --enable-source-maps --no-warnings --loader ts-node/esm' examples/nodejs/index.ts",
"dev-js": "npm run build-example && node --experimental-specifier-resolution=node --enable-source-maps examples/dist/examples/nodejs/index2.js",
"lint": "eslint --ext .js,.ts .",
"format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"",
"test": "JEST_PUPPETEER_CONFIG=jest-puppeteer.config.cjs jest",
Expand Down Expand Up @@ -80,7 +86,7 @@
"@typescript-eslint/eslint-plugin": "^5.36.1",
"@typescript-eslint/parser": "^5.36.1",
"docsify": "^4.11.4",
"esbuild": "^0.15.5",
"esbuild": "^0.15.15",
"eslint": "^8.23.0",
"eslint-config-prettier": "^8.5.0",
"husky": "^8.0.1",
Expand Down
71 changes: 41 additions & 30 deletions src/BaseLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ export class BaseLogger<LogObj> {
* Returns a child logger based on the current instance with inherited settings
*
* @param settings - Overwrite settings inherited from parent logger
* @param logObj - Overwrite logObj for sub-logger
*/
public getSubLogger(settings?: ISettingsParam<LogObj>): BaseLogger<LogObj> {
public getSubLogger(settings?: ISettingsParam<LogObj>, logObj?: LogObj): BaseLogger<LogObj> {
const subLoggerSettings: ISettings<LogObj> = {
...this.settings,
...settings,
Expand All @@ -175,7 +176,7 @@ export class BaseLogger<LogObj> {
childSettings?: ISettingsParam<LogObj>,
logObj?: LogObj,
stackDepthLevel?: number
) => this)(subLoggerSettings, this.logObj, this.stackDepthLevel);
) => this)(subLoggerSettings, logObj ?? this.logObj, this.stackDepthLevel);
//this.subLoggers.push(subLogger);
return subLogger;
}
Expand All @@ -184,48 +185,58 @@ export class BaseLogger<LogObj> {
const maskValuesOfKeys =
this.settings.maskValuesOfKeysCaseInsensitive !== true ? this.settings.maskValuesOfKeys : this.settings.maskValuesOfKeys.map((key) => key.toLowerCase());
return args?.map((arg) => {
return this._maskValuesOfKeysRecursive(arg, maskValuesOfKeys);
return this._recursiveCloneAndMaskValuesOfKeys(arg, maskValuesOfKeys);
});
}

private _maskValuesOfKeysRecursive<T>(obj: T, keys: (number | string)[], seen: unknown[] = []): T {
if (typeof obj !== "object" || obj == null) {
return obj;
private _recursiveCloneAndMaskValuesOfKeys<T>(source: T, keys: (number | string)[], seen: unknown[] = []): T {
if (seen.includes(source)) {
return { ...source };
}
if (seen.includes(obj)) {
return obj;
}
seen.push(obj);

Object.keys(obj).map((key) => {
const thisKey = this.settings?.maskValuesOfKeysCaseInsensitive !== true ? key : key.toLowerCase();

this.settings?.maskValuesRegEx?.forEach((regEx) => {
obj[key] = obj[key].replace(regEx, this.settings.maskPlaceholder);
});

if (keys.includes(thisKey)) {
obj[key] = this.settings.maskPlaceholder;
}

if (typeof obj[key] === "object" && obj[key] !== null) {
this._maskValuesOfKeysRecursive(obj[key], keys, seen);
}
});
seen.push(source);

return obj;
return isError(source)
? source // dont copy Error
: isBuffer(source)
? source // dont copy Buffer
: Array.isArray(source)
? source.map((item) => this._recursiveCloneAndMaskValuesOfKeys(item, keys, seen))
: source instanceof Date
? new Date(source.getTime())
: source && typeof source === "object"
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop)!);
// mask
o[prop] = keys.includes(this.settings?.maskValuesOfKeysCaseInsensitive !== true ? prop : prop.toLowerCase())
? this.settings.maskPlaceholder
: this._recursiveCloneAndMaskValuesOfKeys((source as { [key: string]: unknown })[prop], keys, seen);
return o;
}, Object.create(Object.getPrototypeOf(source)))
: ((source: T): T => {
// mask regEx
this.settings?.maskValuesRegEx?.forEach((regEx) => {
source = (source as string).replace(regEx, this.settings.maskPlaceholder) as T;
});
return source;
})(source);
}

private _recursiveCloneAndExecuteFunctions<T>(source: T): T {
private _recursiveCloneAndExecuteFunctions<T>(source: T, seen: unknown[] = []): T {
if (seen.includes(source)) {
return { ...source };
}
seen.push(source);

return Array.isArray(source)
? source.map((item) => this._recursiveCloneAndExecuteFunctions(item))
? source.map((item) => this._recursiveCloneAndExecuteFunctions(item, seen))
: source instanceof Date
? new Date(source.getTime())
: source && typeof source === "object"
? Object.getOwnPropertyNames(source).reduce((o, prop) => {
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop)!);
// execute functions or clone
o[prop] = typeof source[prop] === "function" ? source[prop]() : this._recursiveCloneAndExecuteFunctions((source as { [key: string]: unknown })[prop]);
o[prop] =
typeof source[prop] === "function" ? source[prop]() : this._recursiveCloneAndExecuteFunctions((source as { [key: string]: unknown })[prop], seen);
return o;
}, Object.create(Object.getPrototypeOf(source)))
: (source as T);
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class Logger<LogObj> extends BaseLogger<LogObj> {
*
* @param settings - Overwrite settings inherited from parent logger
*/
public getSubLogger(settings?: ISettingsParam<LogObj>): Logger<LogObj> {
return super.getSubLogger(settings) as Logger<LogObj>;
public getSubLogger(settings?: ISettingsParam<LogObj>, logObj?: LogObj): Logger<LogObj> {
return super.getSubLogger(settings, logObj) as Logger<LogObj>;
}
}
20 changes: 20 additions & 0 deletions tests/Nodejs/12_SubLoggers_and_Prefixes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,24 @@ describe("SubLoggers", () => {
expect(subLogMsg?.["1"]).toBe("sub");
expect(subLogMsg?.["2"]).toBe("test-sub");
});

test("sub logger overwriting LogObj", (): void => {
const mainLogObj = {
main: true,
sub: false,
};
const mainLogger = new Logger({ type: "hidden" }, mainLogObj);
const logMsg = mainLogger.info("main logger");
expect(logMsg?.main).toBe(true);
expect(logMsg?.sub).toBe(false);

const subLogObj = {
main: false,
sub: true,
};
const subLogger = mainLogger.getSubLogger({ type: "hidden" }, subLogObj);
const subLogMsg = subLogger.info("test-sub");
expect(subLogMsg?.main).toBe(false);
expect(subLogMsg?.sub).toBe(true);
});
});
25 changes: 22 additions & 3 deletions tests/Nodejs/13_Recursive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe("Recursive", () => {
beforeEach(() => {
mockConsoleLog(true, false);
});

test("hidden", (): void => {
const mainLogger = new Logger({ type: "hidden" });

Expand All @@ -22,7 +23,7 @@ describe("Recursive", () => {
const foo = new Foo();
const logMsg = mainLogger.info("circular", foo);
expect(logMsg?.["0"]).toBe("circular");
expect(logMsg?.["1"]["circular"]).toBe(logMsg?.["1"]);
expect(logMsg?.["1"]["circular"]).toEqual(logMsg?.["1"]);
});

test("json", (): void => {
Expand All @@ -41,7 +42,7 @@ describe("Recursive", () => {
const foo = new Foo();
const logMsg = mainLogger.info("circular", foo);
expect(logMsg?.["0"]).toBe("circular");
expect(logMsg?.["1"]["circular"]).toBe(logMsg?.["1"]);
expect(logMsg?.["1"]["circular"]).toEqual(logMsg?.["1"]);
});

test("pretty", (): void => {
Expand All @@ -60,6 +61,24 @@ describe("Recursive", () => {
const foo = new Foo();
const logMsg = mainLogger.info("circular", foo);
expect(logMsg?.["0"]).toBe("circular");
expect(logMsg?.["1"]["circular"]).toBe(logMsg?.["1"]);
expect(logMsg?.["1"]["circular"]).toEqual(logMsg?.["1"]);
});

test("pretty recursive LogObj function", (): void => {
/*
* Circular example
* */
function Foo() {
/* @ts-ignore */
this.abc = "Hello";
/* @ts-ignore */
this.circular = this;
}
/* @ts-ignore */
const foo = new Foo();
const mainLogger = new Logger({ type: "pretty" }, foo);

const logMsg = mainLogger.info("circular");
expect(logMsg?.["0"]).toBe("circular");
});
});
3 changes: 1 addition & 2 deletions tests/Nodejs/4_json_Log_Types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ describe("JSON: Log Types", () => {
const logger = new Logger({ type: "json" });
const date = new Date(0);
const log1 = logger.log(1234, "testLevel", date);
console.log("***" + log1?.["0"]);
expect(log1?.["0"]).toBe(date);
expect(log1?.["0"]).toStrictEqual(date);
expect(getConsoleLog()).toContain(`"1970-01-01T00:00:00.000Z"`);
});

Expand Down
20 changes: 20 additions & 0 deletions tests/Nodejs/7_pretty_Settings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,26 @@ describe("Pretty: Settings", () => {
expect(getConsoleLog()).not.toContain("otherKey456");
});

test("maskValuesOfKeys and don't manipulate original", (): void => {
const logger = new Logger({
type: "pretty",
maskValuesOfKeys: ["password", "otherkey"],
maskValuesOfKeysCaseInsensitive: true,
});
const obj = {
password: "pass123",
otherKey: "otherKey456",
};
logger.log(1234, "testLevel", obj);
expect(getConsoleLog()).toContain("password:");
expect(getConsoleLog()).toContain("[***]");
expect(getConsoleLog()).not.toContain("pass123");
expect(getConsoleLog()).toContain("otherKey:");
expect(getConsoleLog()).not.toContain("otherKey456");
expect(obj.password).toBe("pass123");
expect(obj.otherKey).toBe("otherKey456");
});

/* Additional pretty formatting tests */

test("stylePrettyLogs: false / prettyLogTemplate - shortcut: {{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}", (): void => {
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"compilerOptions": {
"declaration": false,
"declarationMap": false,
"outDir": "examples/dist"
"outDir": "examples/dist",
"moduleResolution": "node"
},
"include": ["examples/nodejs/*.ts"]
}
7 changes: 4 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
"compilerOptions": {
"lib": ["es2020", "dom"],
"target": "es2020",
"module": "esnext",
"moduleResolution": "Node",
"types": ["node", "jest", "puppeteer", "jest-environment-puppeteer", "expect-puppeteer"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"inlineSourceMap": true,
"inlineSourceMap": false,
"strict": true,
"skipLibCheck": true,
"suppressImplicitAnyIndexErrors": true,
"allowSyntheticDefaultImports": true,
"removeComments": true
"removeComments": true,
},
"exclude": ["node_modules", "**/node_modules", "**/dist", "**/tests", "*.test.ts", "examples"]
"exclude": ["node_modules", "**/node_modules", "**/dist", "**/tests", "*.test.ts"]
}
4 changes: 3 additions & 1 deletion tsconfig.types.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
"$schema": "http://json.schemastore.org/tsconfig",
"extends": "./tsconfig.json",
"compilerOptions": {
"removeComments": false,
"declaration": true,
"declarationMap": false,
"declarationDir": "dist/types",
"emitDeclarationOnly": true
}
},
"include": ["src/*.ts", "src/**/*.ts"]
}

0 comments on commit f07cb87

Please sign in to comment.