helene
Version: 
Real-time Web Apps for Node.js
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