-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathutils.js
More file actions
69 lines (55 loc) · 2.49 KB
/
Copy pathutils.js
File metadata and controls
69 lines (55 loc) · 2.49 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
const zipObject = (props, values) => props.reduce((prev, prop, i) => Object.assign(prev, { [prop]: values[i] }), {});
const isObjectLike = (obj) => obj !== null && typeof obj === 'object';
const get = (obj, path, defaultValue) => path.split('.').reduce((a, c) => (a && a[c] ? a[c] : (defaultValue || null)), obj);
const set = (obj, path, value) => {
if (Object(obj) !== obj) return obj;
// If not yet an array, get the keys from the string-path
if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
// Split the path. Note: last index is the value key
path.slice(0,-1).reduce((a, c, i) =>
Object(a[c]) === a[c] // Does the key exist and is its value an object?
// Yes: then follow that path
? a[c]
// No: create the key. Is the next key a potential array-index?
: a[c] = Math.abs(path[i+1])>>0 === +path[i+1]
? [] // Yes: assign a new array object
: {}, // No: assign a new plain object
obj)[path[path.length-1]] = value; // Finally assign the value to the last key
return obj;
};
const isEmpty = (obj) => {
return !obj || (Object.entries(obj).length === 0 && obj.constructor === Object);
};
/**
* Recursively removes properties whose keys start with '$' from an object or array.
* This version preserves the original object's prototype chain and property descriptors
* (including getters and setters) for generic objects.
*
* It returns a new, sanitized object or array without modifying the original.
*
* @param {any} params - The object or array to clean.
* @returns {any} A new object/array with '$' properties removed, or the original primitive value/uncleanable object type.
*/
const sanitizeQueryParameters = (params) => {
if (params === null || typeof params !== 'object') {
return params;
}
if (Array.isArray(params)) {
return params.map(item => sanitizeQueryParameters(item));
}
const cleanedObject = Object.create(Object.getPrototypeOf(params));
for (const key in params) {
if (Object.hasOwn(params, key)) {
if (key.startsWith('$')) {
continue;
}
const descriptor = Object.getOwnPropertyDescriptor(params, key);
if ('value' in descriptor) {
descriptor.value = sanitizeQueryParameters(descriptor.value);
}
Object.defineProperty(cleanedObject, key, descriptor);
}
}
return cleanedObject;
};
module.exports = { zipObject, isObjectLike, isEmpty, get, set, sanitizeQueryParameters };