UNPKG

@creditkarma/dynamic-config

Version:

Dynamic Config for Node.js backed by Consul and Vault

259 lines 8.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.objectHasShape = exports.objectsAreEqual = exports.arraysAreEqual = exports.overlayObjects = exports.overlay = exports.overlayArrays = exports.setValueForKey = exports.getValueForKey = exports.deepMap = void 0; const basic_1 = require("./basic"); const json_1 = require("./json"); /** * Map over all keyed elements in an object, running over leafs first and recursing up. * * @param obj * @param mapping */ function deepMap(mapping, obj, path = '') { if ((0, basic_1.isNothing)(obj) || (0, basic_1.isPrimitive)(obj)) { return obj; } else if (Array.isArray(obj)) { const newObj = []; for (let i = 0; i < obj.length; i++) { const currentPath = path.length > 0 ? `${path}[${i}]` : `[${i}]`; const value = obj[i]; if ((0, basic_1.isNothing)(value)) { newObj[i] = value; } else if ((0, basic_1.isPrimitive)(value)) { newObj[i] = mapping(value, currentPath); } else { newObj[i] = mapping(value, currentPath); newObj[i] = deepMap(mapping, newObj[i], currentPath); newObj[i] = mapping(newObj[i], currentPath); } } return newObj; } else { const newObj = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { const currentPath = path.length > 0 ? `${path}.${key}` : `${key}`; const value = obj[key]; if ((0, basic_1.isNothing)(value)) { newObj[key] = value; } else if ((0, basic_1.isPrimitive)(value)) { newObj[key] = mapping(value, currentPath); } else { newObj[key] = mapping(value, currentPath); newObj[key] = deepMap(mapping, newObj[key], currentPath); newObj[key] = mapping(newObj[key], currentPath); } } } return newObj; } } exports.deepMap = deepMap; function getValueForKey(key, obj) { if ((0, basic_1.isPrimitive)(obj) || (0, basic_1.isNothing)(obj)) { return null; } else { const parts = (0, basic_1.splitKey)(key); if (parts.length > 1) { const [head, ...tail] = parts; const sub = obj[head]; if (!(0, basic_1.isPrimitive)(sub)) { return getValueForKey(tail.join('.'), sub); } else { return null; } } else if (obj[parts[0]] !== undefined) { return obj[parts[0]]; } else { return null; } } } exports.getValueForKey = getValueForKey; function setValueForKey(key, value, oldObj) { if (typeof key !== 'string') { throw new Error('Property to set must be a string'); } else if (oldObj === null) { throw new Error(`Cannot set value on null type at key: ${key}`); } else if (key === '') { return value; } else { const newObj = Array.isArray(oldObj) ? [] : {}; const [head, ...tail] = (0, basic_1.splitKey)(key); const props = Object.keys(oldObj); for (const prop of props) { if (prop === head) { if (tail.length > 0) { const nextObj = oldObj[prop] || {}; newObj[prop] = setValueForKey(tail.join('.'), value, nextObj); } else { newObj[prop] = value; } } else { newObj[prop] = oldObj[prop]; } } return newObj; } } exports.setValueForKey = setValueForKey; function max(...nums) { return nums.reduce((acc, next) => { if (next > acc) { return next; } else { return acc; } }); } function overlayArrays(base, update) { const newArray = []; const baseLen = base.length; const updateLen = update.length; const len = max(baseLen, updateLen); for (let i = 0; i < len; i++) { const baseValue = base[i]; const updateValue = update[i]; if (Array.isArray(baseValue) && Array.isArray(updateValue)) { newArray[i] = overlayArrays(baseValue, updateValue); } else if ((0, basic_1.isObject)(baseValue) && (0, basic_1.isObject)(updateValue)) { newArray[i] = overlay(baseValue, updateValue); } else if (updateValue !== undefined) { newArray[i] = updateValue; } else { newArray[i] = baseValue; } } return newArray; } exports.overlayArrays = overlayArrays; function overlay(base, update) { const newObj = {}; const baseKeys = Object.keys(base); const updateKeys = Object.keys(update); for (const key of updateKeys) { if (baseKeys.indexOf(key) === -1) { baseKeys.push(key); } } for (const key of baseKeys) { if (base.hasOwnProperty(key) || update.hasOwnProperty(key)) { const baseValue = base[key]; const updateValue = update[key]; if (Array.isArray(baseValue) && Array.isArray(updateValue)) { newObj[key] = overlayArrays(baseValue, updateValue); } else if ((0, basic_1.isObject)(baseValue) && (0, basic_1.isObject)(updateValue)) { newObj[key] = overlay(baseValue, updateValue); } else if (updateValue !== undefined) { newObj[key] = updateValue; } else { newObj[key] = baseValue; } } } return newObj; } exports.overlay = overlay; function overlayObjects(...configs) { return configs.reduce((acc, next) => { return overlay(acc, next); }, {}); } exports.overlayObjects = overlayObjects; function arraysAreEqual(arr1, arr2) { if (!Array.isArray(arr1) || !Array.isArray(arr2)) { return arr1 === arr2; } else if (arr1.length !== arr2.length) { return false; } else { for (let i = 0; i < arr1.length; i++) { const item1 = arr1[i]; const item2 = arr2[i]; if (Array.isArray(item1) && Array.isArray(item2)) { if (!arraysAreEqual(item1, item2)) { return false; } } else if ((0, basic_1.isObject)(item1) && (0, basic_1.isObject)(item2)) { if (!objectsAreEqual(item1, item2)) { return false; } } else if (item1 !== item2) { return false; } } return true; } } exports.arraysAreEqual = arraysAreEqual; function objectsAreEqual(obj1, obj2) { if (!(0, basic_1.isObject)(obj1) || !(0, basic_1.isObject)(obj2)) { return obj1 === obj2; } else { const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (!arraysAreEqual(keys1, keys2)) { return false; } else { for (const key of keys1) { const value1 = obj1[key]; const value2 = obj2[key]; if ((0, basic_1.isObject)(value1) && (0, basic_1.isObject)(value2)) { if (!objectsAreEqual(value1, value2)) { return false; } } else if (Array.isArray(value1) && Array.isArray(value2)) { if (!arraysAreEqual(value1, value2)) { return false; } } else if (value1 !== value2) { return false; } } return true; } } } exports.objectsAreEqual = objectsAreEqual; function objectHasShape(...args) { const targetSchema = (0, json_1.objectAsSimpleSchema)(args[0]); if (args.length === 2) { return (0, json_1.objectMatchesSchema)(targetSchema, args[1]); } else { return (obj) => { return (0, json_1.objectMatchesSchema)(targetSchema, obj); }; } } exports.objectHasShape = objectHasShape; //# sourceMappingURL=object.js.map