deno.land / x / mongoose@6.7.5 / lib / helpers / clone.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178'use strict';
const Decimal = require('../types/decimal128');const ObjectId = require('../types/objectid');const specialProperties = require('./specialProperties');const isMongooseObject = require('./isMongooseObject');const getFunctionName = require('./getFunctionName');const isBsonType = require('./isBsonType');const isObject = require('./isObject');const symbols = require('./symbols');const trustedSymbol = require('./query/trusted').trustedSymbol;const utils = require('../utils');
/** * Object clone with Mongoose natives support. * * If options.minimize is true, creates a minimal data object. Empty objects and undefined values will not be cloned. This makes the data payload sent to MongoDB as small as possible. * * Functions are never cloned. * * @param {Object} obj the object to clone * @param {Object} options * @param {Boolean} isArrayChild true if cloning immediately underneath an array. Special case for minimize. * @return {Object} the cloned object * @api private */
function clone(obj, options, isArrayChild) { if (obj == null) { return obj; }
if (Array.isArray(obj)) { return cloneArray(utils.isMongooseArray(obj) ? obj.__array : obj, options); }
if (isMongooseObject(obj)) { // Single nested subdocs should apply getters later in `applyGetters()` // when calling `toObject()`. See gh-7442, gh-8295 if (options && options._skipSingleNestedGetters && obj.$isSingleNested) { options = Object.assign({}, options, { getters: false }); } const isSingleNested = obj.$isSingleNested;
if (utils.isPOJO(obj) && obj.$__ != null && obj._doc != null) { return obj._doc; }
let ret; if (options && options.json && typeof obj.toJSON === 'function') { ret = obj.toJSON(options); } else { ret = obj.toObject(options); }
if (options && options.minimize && isSingleNested && Object.keys(ret).length === 0) { return undefined; }
return ret; }
const objConstructor = obj.constructor;
if (objConstructor) { switch (getFunctionName(objConstructor)) { case 'Object': return cloneObject(obj, options, isArrayChild); case 'Date': return new objConstructor(+obj); case 'RegExp': return cloneRegExp(obj); default: // ignore break; } }
if (isBsonType(obj, 'ObjectID')) { return new ObjectId(obj.id); }
if (isBsonType(obj, 'Decimal128')) { if (options && options.flattenDecimals) { return obj.toJSON(); } return Decimal.fromString(obj.toString()); }
// object created with Object.create(null) if (!objConstructor && isObject(obj)) { return cloneObject(obj, options, isArrayChild); }
if (typeof obj === 'object' && obj[symbols.schemaTypeSymbol]) { return obj.clone(); }
// If we're cloning this object to go into a MongoDB command, // and there's a `toBSON()` function, assume this object will be // stored as a primitive in MongoDB and doesn't need to be cloned. if (options && options.bson && typeof obj.toBSON === 'function') { return obj; }
if (typeof obj.valueOf === 'function') { return obj.valueOf(); }
return cloneObject(obj, options, isArrayChild);}module.exports = clone;
/*! * ignore */
function cloneObject(obj, options, isArrayChild) { const minimize = options && options.minimize; const omitUndefined = options && options.omitUndefined; const seen = options && options._seen; const ret = {}; let hasKeys;
if (seen && seen.has(obj)) { return seen.get(obj); } else if (seen) { seen.set(obj, ret); } if (trustedSymbol in obj) { ret[trustedSymbol] = obj[trustedSymbol]; }
let i = 0; let key = ''; const keys = Object.keys(obj); const len = keys.length;
for (i = 0; i < len; ++i) { if (specialProperties.has(key = keys[i])) { continue; }
// Don't pass `isArrayChild` down const val = clone(obj[key], options, false);
if ((minimize === false || omitUndefined) && typeof val === 'undefined') { delete ret[key]; } else if (minimize !== true || (typeof val !== 'undefined')) { hasKeys || (hasKeys = true); ret[key] = val; } }
return minimize && !isArrayChild ? hasKeys && ret : ret;}
function cloneArray(arr, options) { let i = 0; const len = arr.length; const ret = new Array(len); for (i = 0; i < len; ++i) { ret[i] = clone(arr[i], options, true); }
return ret;}
function cloneRegExp(regexp) { const ret = new RegExp(regexp.source, regexp.flags);
if (ret.lastIndex !== regexp.lastIndex) { ret.lastIndex = regexp.lastIndex; } return ret;}
Version Info