UNPKG

@dyihoon90/glogging

Version:

HTTP request logging middleware & transaction function decorator for express, using winston

99 lines 3.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.traverseAndMutateObject = traverseAndMutateObject; exports.redactProperties = redactProperties; exports.isPlainObject = isPlainObject; var lodash_1 = require("lodash"); /** * Traverse the object deeply, calling callback on all properties that are not object * Arrays and objects are both considered object * Removes circular references * Limits the traversal depth to prevent excessive recursion * Note: Mutates the obj passed in * @param obj The object to traverse and mutate * @param callback Function to call on each non-object property * @param maxDepth Maximum depth to traverse (default: 100) * @param currentDepth Current depth of traversal (used internally) * @param seen Set of already seen objects (used for circular reference detection) * @returns The mutated object */ function traverseAndMutateObject(obj, callback, maxDepth, currentDepth, seen) { if (maxDepth === void 0) { maxDepth = 5; } if (currentDepth === void 0) { currentDepth = 0; } if (seen === void 0) { seen = new Set(); } if (!obj || typeof obj !== 'object') { return obj; } // If we've reached the maximum depth, stop traversing if (currentDepth >= maxDepth) { return {}; } // If we've seen this object before, it's a circular reference if (seen.has(obj)) { return '[Circular]'; } // Add this object to the set of seen objects seen.add(obj); (0, lodash_1.forIn)(obj, function (value, key) { if (isPlainObject(value)) { obj[key] = traverseAndMutateObject(value, callback, maxDepth, currentDepth + 1, seen); } else { obj[key] = callback(key, value); } }); // Remove this object from the set of seen objects seen.delete(obj); return obj; } /** * Remove from obj, all properties list redactedProperties. * Recursively remove from nested properties as well * @param redactedProperties * @param clonedObj */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function redactProperties(redactedProperties, obj) { var clonedObj = (0, lodash_1.clone)(obj); if (!redactedProperties || redactProperties.length === 0 || !obj) { return clonedObj; } if (Array.isArray(clonedObj)) { clonedObj.forEach(function (_value, index) { if (redactedProperties.includes(index)) { clonedObj.splice(index, 1); } if (typeof clonedObj[index] === 'object') { clonedObj[index] = redactProperties(redactedProperties, clonedObj[index]); } }); } else { Object.keys(clonedObj).forEach(function (key) { if (redactedProperties.includes(key)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any clonedObj[key] = '[REDACTED]'; } else if (typeof clonedObj[key] === 'object' && clonedObj[key] !== null) { // eslint-disable-next-line @typescript-eslint/no-explicit-any clonedObj[key] = redactProperties(redactedProperties, clonedObj[key]); } }); } return clonedObj; } /** * Checks if the given value is a plain object. * A plain object is an object created by the Object constructor or one with a [[Prototype]] of null. * * @param value - The value to check * @returns True if the value is a plain object, false otherwise */ function isPlainObject(value) { if (typeof value !== 'object' || value === null) { return false; } var prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; } //# sourceMappingURL=ObjUtils.js.map