UNPKG

cumulocity-cypress

Version:
144 lines (143 loc) 5.02 kB
import _ from "lodash"; export function safeStringify(obj, indent = 2) { let cache = []; const retVal = JSON.stringify(obj, (key, value) => typeof value === "object" && value !== null ? cache.includes(value) ? undefined : cache.push(value) && value : value, indent); cache = []; return retVal; } export function sanitizeStringifiedObject(value) { if (!value || typeof value !== "string") { return value; } return value.replace(/("?)(password)("?):\s+("?).*?(")?(\s*,?[\s\n}]+)/gi, "$1$2$3: $4***$5$6"); } /** * Gets the case-sensitive path for a given case-insensitive path. The path is * assumed to be a dot-separated string. If the path is an array, it is assumed * to be a list of keys. * * The function will go over all keys and return the actual case-sensitive path * up to the first mismatch. * * @param obj The object to query * @param path The case-insensitive path to find * @returns The actual case-sensitive path if found, undefined otherwise */ export function toSensitiveObjectKeyPath(obj, path) { if (!obj) return undefined; const keys = _.isArray(path) ? path : path.split(/[.[\]]/g); let current = obj; const actualPath = []; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (_.isEmpty(key)) continue; if (current === null || current === undefined) { return undefined; } if (_.isArray(current)) { const index = parseInt(key); if (!isNaN(index)) { if (index >= 0 && index < current.length) { current = current[index]; actualPath.push(key); continue; } } actualPath.push(...keys.slice(i)); return actualPath.join("."); } // Handle object case with case-insensitive matching if (_.isObjectLike(current)) { const matchingKey = Object.keys(current).find((k) => k.toLowerCase() === key.toLowerCase()); if (matchingKey !== undefined) { current = current[matchingKey]; actualPath.push(matchingKey); } else { actualPath.push(...keys.slice(i)); break; } } else { actualPath.push(...keys.slice(i)); break; } } return actualPath.join("."); } /** * Gets the value of a case-insensitive key path from an object. The path is * assumed to be a dot-separated string. If the path is an array, it is assumed * to be a list of keys. * * @example * geti(obj, "obj.key.token") * geti(obj, ["obj", "key", "token"]) * geti(obj, "obj.key[0].token") * geti(obj, "obj.key.0.token") * * @param obj The object to query * @param keyPath The case-insensitive key path to find * @returns The value of the key path if found, undefined otherwise */ export function get_i(obj, keyPath) { if (obj == null || keyPath == null) return undefined; const sensitivePath = toSensitiveObjectKeyPath(obj, keyPath); if (sensitivePath == null) return undefined; return _.get(obj, sensitivePath); } /** * Converts a value to an array. If the value is an array, it is returned as is. * @param value The value to convert to an array * @returns The value as an array if it is not already an array */ export function to_array(value) { if (value == null) return undefined; if (_.isArray(value)) return value; return [value]; } /** * Converts a string value to a boolean. Supported values are "true", "false", "1", and "0". * @param input The input string to convert to a boolean * @param defaultValue The default value to return if the input is not a valid boolean string * @returns The boolean value of the input string or the default value if the input is not a valid boolean string */ export function to_boolean(input, defaultValue) { if (input == null || !_.isString(input)) return defaultValue; const booleanString = input.toString().toLowerCase(); if (booleanString == "true" || booleanString === "1") return true; if (booleanString == "false" || booleanString === "0") return false; return defaultValue; } export function buildTestHierarchy(objects, hierarchyfn) { const tree = {}; objects.forEach((item) => { const titles = hierarchyfn(item); if (titles) { let currentNode = tree; const protectedKeys = ["__proto__", "constructor", "prototype"]; titles?.forEach((title, index) => { if (!protectedKeys.includes(title)) { if (!currentNode[title]) { currentNode[title] = index === titles.length - 1 ? item : {}; } currentNode = currentNode[title]; } }); } }); return tree; }