|
@ -1,6 +1,8 @@ |
|
|
import { Big } from 'big.js'; |
|
|
import { Big } from 'big.js'; |
|
|
import { cloneDeep, isArray, isObject } from 'lodash'; |
|
|
import { cloneDeep, isArray, isObject } from 'lodash'; |
|
|
|
|
|
|
|
|
|
|
|
import { RedactylNullSupported } from './redactyle.helper'; |
|
|
|
|
|
|
|
|
export function hasNotDefinedValuesInObject(aObject: Object): boolean { |
|
|
export function hasNotDefinedValuesInObject(aObject: Object): boolean { |
|
|
for (const key in aObject) { |
|
|
for (const key in aObject) { |
|
|
if (aObject[key] === null || aObject[key] === undefined) { |
|
|
if (aObject[key] === null || aObject[key] === undefined) { |
|
@ -44,47 +46,67 @@ export function redactAttributes({ |
|
|
return object; |
|
|
return object; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Create deep clone
|
|
|
let redactedObject = isFirstRun ? cloneDeep(object) : object; |
|
|
const redactedObject = isFirstRun |
|
|
|
|
|
? JSON.parse(JSON.stringify(object)) |
|
|
|
|
|
: object; |
|
|
|
|
|
|
|
|
|
|
|
for (const option of options) { |
|
|
for (const option of options) { |
|
|
if (redactedObject.hasOwnProperty(option.attribute)) { |
|
|
const { attribute, valueMap } = option; |
|
|
if (option.valueMap['*'] || option.valueMap['*'] === null) { |
|
|
|
|
|
redactedObject[option.attribute] = option.valueMap['*']; |
|
|
const redactyl = new RedactylNullSupported({ properties: [] }); |
|
|
} else if (option.valueMap[redactedObject[option.attribute]]) { |
|
|
redactyl.addProperties([attribute]); |
|
|
redactedObject[option.attribute] = |
|
|
|
|
|
option.valueMap[redactedObject[option.attribute]]; |
|
|
// Handle different value mapping scenarios
|
|
|
} |
|
|
if ('*' in valueMap) { |
|
|
|
|
|
// Wildcard replacement - replace all instances of this attribute
|
|
|
|
|
|
redactyl.setText(valueMap['*']); |
|
|
|
|
|
redactedObject = redactyl.redact(redactedObject); |
|
|
} else { |
|
|
} else { |
|
|
// If the attribute is not present on the current object,
|
|
|
// Specific value mapping - need to handle this differently
|
|
|
// check if it exists on any nested objects
|
|
|
// We'll use a custom approach for specific value mappings
|
|
|
for (const property in redactedObject) { |
|
|
redactedObject = redactSpecificValues( |
|
|
if (isArray(redactedObject[property])) { |
|
|
redactedObject, |
|
|
redactedObject[property] = redactedObject[property].map( |
|
|
attribute, |
|
|
(currentObject) => { |
|
|
valueMap |
|
|
return redactAttributes({ |
|
|
); |
|
|
options, |
|
|
|
|
|
isFirstRun: false, |
|
|
|
|
|
object: currentObject |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
); |
|
|
|
|
|
} else if ( |
|
|
|
|
|
isObject(redactedObject[property]) && |
|
|
|
|
|
!(redactedObject[property] instanceof Big) |
|
|
|
|
|
) { |
|
|
|
|
|
// Recursively call the function on the nested object
|
|
|
|
|
|
redactedObject[property] = redactAttributes({ |
|
|
|
|
|
options, |
|
|
|
|
|
isFirstRun: false, |
|
|
|
|
|
object: redactedObject[property] |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return redactedObject; |
|
|
return redactedObject; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Helper function to handle specific value mappings (non-wildcard)
|
|
|
|
|
|
function redactSpecificValues( |
|
|
|
|
|
obj: any, |
|
|
|
|
|
attribute: string, |
|
|
|
|
|
valueMap: { [key: string]: any } |
|
|
|
|
|
): any { |
|
|
|
|
|
if (!obj || typeof obj !== 'object') { |
|
|
|
|
|
return obj; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (isArray(obj)) { |
|
|
|
|
|
return obj.map((item) => redactSpecificValues(item, attribute, valueMap)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const result = { ...obj }; |
|
|
|
|
|
|
|
|
|
|
|
// Check if current level has the attribute and if its value should be replaced
|
|
|
|
|
|
if (attribute in result) { |
|
|
|
|
|
const currentValue = result[attribute]; |
|
|
|
|
|
if (currentValue in valueMap) { |
|
|
|
|
|
result[attribute] = valueMap[currentValue]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Recursively process nested objects
|
|
|
|
|
|
for (const key in result) { |
|
|
|
|
|
if (isObject(result[key]) && !(result[key] instanceof Big)) { |
|
|
|
|
|
result[key] = redactSpecificValues(result[key], attribute, valueMap); |
|
|
|
|
|
} else if (isArray(result[key])) { |
|
|
|
|
|
result[key] = result[key].map((item: any) => |
|
|
|
|
|
isObject(item) ? redactSpecificValues(item, attribute, valueMap) : item |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|