mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-08-23 18:31:43 +02:00
[ADD] objectDeepMerge
function
Recursively merges properties from source objects into a target object. If a property at the current level is an object, and both target and source have it, the property is merged. Otherwise, the source property overwrites the target property. This function does not modify the source objects and prevents prototype pollution by not allowing `__proto__`, `constructor`, and `prototype` property names.
This commit is contained in:
parent
c1cd7ca64f
commit
099a39a2a2
@ -217,3 +217,53 @@ const fetchPost = async ({
|
||||
responseIsJson: responseIsJson
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively merges properties from source objects into a target object. If a property at the current level is an object,
|
||||
* and both target and source have it, the property is merged. Otherwise, the source property overwrites the target property.
|
||||
* This function does not modify the source objects and prevents prototype pollution by not allowing __proto__, constructor,
|
||||
* and prototype property names.
|
||||
*
|
||||
* @usage
|
||||
* ```javascript
|
||||
* const target = {a: 1, b: {c: 2}};
|
||||
* const source1 = {b: {d: 3}, e: 4 };
|
||||
* const source2 = {a: 5, b: {c: 6}};
|
||||
*
|
||||
* const merged = objectDeepMerge(target, source1, source2);
|
||||
*
|
||||
* console.log(merged); // {a: 5, b: {c: 6, d: 3}, e: 4}
|
||||
* ```
|
||||
*
|
||||
* @param {Object} target The target object to merge properties into.
|
||||
* @param {...Object} sources One or more source objects from which to merge properties.
|
||||
* @returns {Object} The target object after merging properties from sources.
|
||||
*/
|
||||
function objectDeepMerge (target, ...sources) {
|
||||
if (!sources.length) {
|
||||
return target;
|
||||
}
|
||||
|
||||
// Iterate through each source object without modifying the `sources` array.
|
||||
sources.forEach(source => {
|
||||
if (isObject(target) && isObject(source)) {
|
||||
for (const key in source) {
|
||||
if (isObject(source[key])) {
|
||||
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
|
||||
continue; // Skip potentially dangerous keys to prevent prototype pollution.
|
||||
}
|
||||
|
||||
if (!target[key] || !isObject(target[key])) {
|
||||
target[key] = {};
|
||||
}
|
||||
|
||||
objectDeepMerge(target[key], source[key]);
|
||||
} else {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return target;
|
||||
}
|
||||
|
@ -100,3 +100,25 @@ fetchPost({
|
||||
- `csrfToken`: The CSRF token to include in the request headers.
|
||||
- `payload`: The data as JS object to send with the request.
|
||||
- `responseIsJson`: Optional boolean indicating if the response should be parsed as JSON (default is `true`).
|
||||
|
||||
### objectDeepMerge()
|
||||
|
||||
Recursively merges properties from source objects into a target object. If a property at the current level is an object,
|
||||
and both target and source have it, the property is merged. Otherwise, the source property overwrites the target property.
|
||||
|
||||
This function does not modify the source objects and prevents prototype pollution by not allowing `__proto__`, `constructor`,
|
||||
and `prototype` property names.
|
||||
|
||||
Usage:
|
||||
|
||||
```javascript
|
||||
/* global objectDeepMerge */
|
||||
|
||||
const target = {a: 1, b: {c: 2}};
|
||||
const source1 = {b: {d: 3}, e: 4 };
|
||||
const source2 = {a: 5, b: {c: 6}};
|
||||
|
||||
const merged = objectDeepMerge(target, source1, source2);
|
||||
|
||||
console.log(merged); // {a: 5, b: {c: 6, d: 3}, e: 4}
|
||||
```
|
||||
|
Loading…
x
Reference in New Issue
Block a user