cosmic-interchain-utils
Version:
Cosmic Interchain Utils
128 lines • 4.25 kB
JavaScript
import { cloneDeep, isEqual } from 'lodash-es';
import { stringify as yamlStringify } from 'yaml';
import { ethersBigNumberSerializer } from './logging.js';
import { assert } from './validation.js';
export function isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
}
export function deepEquals(v1, v2) {
return isEqual(v1, v2);
}
export function deepCopy(v) {
return cloneDeep(v);
}
// Useful for maintaining type safety when using Object.keys
export function objKeys(obj) {
return Object.keys(obj);
}
export function objLength(obj) {
return Object.keys(obj).length;
}
export function isObjEmpty(obj) {
return objLength(obj) === 0;
}
export function objMapEntries(obj, func) {
return Object.entries(obj).map(([k, v]) => [k, func(k, v)]);
}
// Map over the values of the object
export function objMap(obj, func) {
return Object.fromEntries(objMapEntries(obj, func));
}
export function objFilter(obj, func) {
return Object.fromEntries(Object.entries(obj).filter(([k, v]) => func(k, v)));
}
export function deepFind(obj, func, depth = 10) {
assert(depth > 0, 'deepFind max depth reached');
if (func(obj)) {
return obj;
}
const entries = isObject(obj)
? Object.values(obj)
: Array.isArray(obj)
? obj
: [];
return entries.map((e) => deepFind(e, func, depth - 1)).find((v) => v);
}
// promiseObjectAll :: {k: Promise a} -> Promise {k: a}
export function promiseObjAll(obj) {
const promiseList = Object.entries(obj).map(([name, promise]) => promise.then((result) => [name, result]));
return Promise.all(promiseList).then(Object.fromEntries);
}
// Get the subset of the object from key list
export function pick(obj, keys) {
const ret = {};
const objKeys = Object.keys(obj);
for (const key of keys) {
if (objKeys.includes(key)) {
ret[key] = obj[key];
}
}
return ret;
}
// Recursively merges b into a
// Where there are conflicts, b takes priority over a
export function objMerge(a, b, max_depth = 10) {
if (max_depth === 0) {
throw new Error('objMerge tried to go too deep');
}
if (isObject(a) && isObject(b)) {
const ret = {};
const aKeys = new Set(Object.keys(a));
const bKeys = new Set(Object.keys(b));
const allKeys = new Set([...aKeys, ...bKeys]);
for (const key of allKeys.values()) {
if (aKeys.has(key) && bKeys.has(key)) {
ret[key] = objMerge(a[key], b[key], max_depth - 1);
}
else if (aKeys.has(key)) {
ret[key] = a[key];
}
else {
ret[key] = b[key];
}
}
return ret;
}
else {
return b ? b : a;
}
}
export function invertKeysAndValues(data) {
return Object.fromEntries(Object.entries(data).map(([key, value]) => [value, key]));
}
// Returns an object with the keys as values from an array and value set to true
export function arrayToObject(keys, val = true) {
return keys.reduce((result, k) => {
result[k] = val;
return result;
}, {});
}
export function stringifyObject(object, format = 'yaml', space) {
// run through JSON first because ethersBigNumberSerializer does not play nice with yamlStringify
// so we fix up in JSON, then parse and if required return yaml on processed JSON after
const json = JSON.stringify(object, ethersBigNumberSerializer, space);
if (format === 'json') {
return json;
}
return yamlStringify(JSON.parse(json), null, space);
}
// Function to recursively remove 'address' properties and lowercase string properties
export function normalizeConfig(obj) {
if (Array.isArray(obj)) {
return obj.map(normalizeConfig);
}
else if (obj !== null && typeof obj === 'object') {
const newObj = {};
for (const key in obj) {
if (key !== 'address') {
newObj[key] = key === 'type' ? obj[key] : normalizeConfig(obj[key]);
}
}
return newObj;
}
else if (typeof obj === 'string') {
return obj.toLowerCase();
}
return obj;
}
//# sourceMappingURL=objects.js.map