-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathobject-utils.ts
More file actions
101 lines (93 loc) · 2.47 KB
/
Copy pathobject-utils.ts
File metadata and controls
101 lines (93 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*!
* Convert JS SDK
* Version 1.0.0
* Copyright(c) 2020 Convert Insights, Inc
* License Apache-2.0
*/
/**
* Returns the value at path of object
* TODO: get this utility to work with the optional mapper() helper from config
* @param {Record<string, any>} object
* @param {string} path
* @param {any=} defaultValue
* @param {boolean=} truthy Should Number 0 number and Boolean false be considered as normal value
* @return {any}
*/
export function objectDeepValue(
object: Record<string, any>,
path: string,
defaultValue?: any,
truthy = false
): any {
try {
if (typeof object === 'object') {
const v = path.split('.').reduce((a, v) => a[v], object);
if (v || (truthy && (v === false || v === 0))) {
return v;
}
}
// eslint-disable-next-line no-empty
} catch (e) {}
if (typeof defaultValue !== 'undefined') {
return defaultValue;
} else {
return null;
}
}
/**
* Deep merge objects and their keys and nested objects
* Accepts arrays
*
* @param {...Record<any, any>} objects Objects to merge
* @return {Record<any, any>}
*/
export function objectDeepMerge(...objects) {
const isObject = (obj) => obj && typeof obj === 'object';
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach((key) => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = [...new Set([...oVal, ...pVal])];
} else if (isObject(pVal) && isObject(oVal)) {
prev[key] = objectDeepMerge(pVal, oVal);
} else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
/**
* Validates variable is object and not empty
* @param object
*/
export function objectNotEmpty(object: any): boolean {
return (
typeof object === 'object' &&
object !== null &&
Object.keys(object).length > 0
);
}
/**
* Compare two objects
* @param a
* @param b
*/
export const objectDeepEqual = (a, b) => {
if (a === b) return true;
if (typeof a != 'object' || typeof b != 'object' || a == null || b == null)
return false;
const keysA = Object.keys(a),
keysB = Object.keys(b);
if (keysA.length != keysB.length) return false;
for (const key of keysA) {
if (!keysB.includes(key)) return false;
if (typeof a[key] === 'function' || typeof b[key] === 'function') {
if (a[key].toString() != b[key].toString()) return false;
} else {
if (!objectDeepEqual(a[key], b[key])) return false;
}
}
return true;
};