@creditkarma/dynamic-config
Version:
Dynamic Config for Node.js backed by Consul and Vault
259 lines • 8.46 kB
JavaScript
;
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