You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
37 lines
1.1 KiB
37 lines
1.1 KiB
1 month ago
|
import { isArray, isPlainObject } from 'is-what';
|
||
|
|
||
|
function assignProp(carry, key, newVal, originalObject, includeNonenumerable) {
|
||
|
const propType = {}.propertyIsEnumerable.call(originalObject, key) ? "enumerable" : "nonenumerable";
|
||
|
if (propType === "enumerable")
|
||
|
carry[key] = newVal;
|
||
|
if (includeNonenumerable && propType === "nonenumerable") {
|
||
|
Object.defineProperty(carry, key, {
|
||
|
value: newVal,
|
||
|
enumerable: false,
|
||
|
writable: true,
|
||
|
configurable: true
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
function copy(target, options = {}) {
|
||
|
if (isArray(target)) {
|
||
|
return target.map((item) => copy(item, options));
|
||
|
}
|
||
|
if (!isPlainObject(target)) {
|
||
|
return target;
|
||
|
}
|
||
|
const props = Object.getOwnPropertyNames(target);
|
||
|
const symbols = Object.getOwnPropertySymbols(target);
|
||
|
return [...props, ...symbols].reduce((carry, key) => {
|
||
|
if (isArray(options.props) && !options.props.includes(key)) {
|
||
|
return carry;
|
||
|
}
|
||
|
const val = target[key];
|
||
|
const newVal = copy(val, options);
|
||
|
assignProp(carry, key, newVal, target, options.nonenumerable);
|
||
|
return carry;
|
||
|
}, {});
|
||
|
}
|
||
|
|
||
|
export { copy };
|