ejson2
Version:
Extended JSON Evolved
83 lines • 3.04 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.clone = void 0;
const utils_1 = require("../utils");
const index_1 = require("./index");
const clone = (rootVal) => {
const set = new WeakSet();
function internalClone(internalVal) {
let ret;
if (!(0, utils_1.isObject)(internalVal)) {
return internalVal;
}
if (internalVal === null) {
return null; // null has typeof "object"
}
if (internalVal instanceof Date) {
return new Date(internalVal.getTime());
}
// RegExps are not really EJSON elements (eg we don't define a serialization
// for them), but they're immutable anyway, so we can support them in clone.
if (internalVal instanceof RegExp) {
return internalVal;
}
if (internalVal?._bsontype === 'ObjectId' &&
(0, utils_1.isFunction)(internalVal.toString)) {
return internalVal.toString();
}
if (internalVal.constructor.name === 'model' &&
(0, utils_1.isObject)(internalVal._doc)) {
return internalClone(internalVal._doc);
}
if (index_1.EJSON.isBinary(internalVal)) {
ret = index_1.EJSON.newBinary(internalVal.length);
for (let i = 0; i < internalVal.length; i++) {
ret[i] = internalVal[i];
}
return ret;
}
function cloneArray(arr) {
set.add(arr);
return arr
.map(val => {
if ((0, utils_1.isObjectAndNotNull)(val)) {
if (set.has(val)) {
return undefined;
}
set.add(val);
}
return (0, exports.clone)(val);
})
.filter(val => val !== undefined);
}
if (Array.isArray(internalVal)) {
return cloneArray(internalVal);
}
if ((0, utils_1.isArguments)(internalVal)) {
set.add(internalVal);
return cloneArray(Array.from(internalVal));
}
// handle general user-defined typed Objects if they have a clone method
if ((0, utils_1.isFunction)(internalVal.clone)) {
return internalVal.clone();
}
// handle other custom types
if (index_1.EJSON._isCustomType(internalVal)) {
return index_1.EJSON.fromJSONValue(internalClone(index_1.EJSON.toJSONValue(internalVal)));
}
set.add(internalVal);
ret = {};
(0, utils_1.keysOf)(internalVal).forEach(key => {
if ((0, utils_1.isObjectAndNotNull)(internalVal[key])) {
if (set.has(internalVal[key]))
return;
set.add(internalVal[key]);
}
ret[key] = internalClone(internalVal[key]);
});
return ret;
}
return internalClone(rootVal);
};
exports.clone = clone;
//# sourceMappingURL=clone.js.map