diff options
author | 2020-11-16 00:10:28 +0100 | |
---|---|---|
committer | 2020-11-16 00:10:28 +0100 | |
commit | e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d (patch) | |
tree | 55713f725f77b44ebfec86e4eec3ce33e71458ca /node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js | |
download | website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.gz website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.tar.bz2 website_creator-e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d.zip |
api, login, auth
Diffstat (limited to 'node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js')
-rw-r--r-- | node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js b/node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js new file mode 100644 index 0000000..14e3f1b --- /dev/null +++ b/node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js @@ -0,0 +1,127 @@ +'use strict'; +const modifiedPaths = require('./common').modifiedPaths; +const get = require('./get'); + +/** + * Applies defaults to update and findOneAndUpdate operations. + * + * @param {Object} filter + * @param {Schema} schema + * @param {Object} castedDoc + * @param {Object} options + * @method setDefaultsOnInsert + * @api private + */ + +module.exports = function(filter, schema, castedDoc, options) { + options = options || {}; + + const shouldSetDefaultsOnInsert = + options.setDefaultsOnInsert != null ? + options.setDefaultsOnInsert : + schema.base.options.setDefaultsOnInsert; + + if (!options.upsert || !shouldSetDefaultsOnInsert) { + return castedDoc; + } + + const keys = Object.keys(castedDoc || {}); + const updatedKeys = {}; + const updatedValues = {}; + const numKeys = keys.length; + const modified = {}; + + let hasDollarUpdate = false; + + for (let i = 0; i < numKeys; ++i) { + if (keys[i].startsWith('$')) { + modifiedPaths(castedDoc[keys[i]], '', modified); + hasDollarUpdate = true; + } + } + + if (!hasDollarUpdate) { + modifiedPaths(castedDoc, '', modified); + } + + const paths = Object.keys(filter); + const numPaths = paths.length; + for (let i = 0; i < numPaths; ++i) { + const path = paths[i]; + const condition = filter[path]; + if (condition && typeof condition === 'object') { + const conditionKeys = Object.keys(condition); + const numConditionKeys = conditionKeys.length; + let hasDollarKey = false; + for (let j = 0; j < numConditionKeys; ++j) { + if (conditionKeys[j].startsWith('$')) { + hasDollarKey = true; + break; + } + } + if (hasDollarKey) { + continue; + } + } + updatedKeys[path] = true; + modified[path] = true; + } + + if (options && options.overwrite && !hasDollarUpdate) { + // Defaults will be set later, since we're overwriting we'll cast + // the whole update to a document + return castedDoc; + } + + schema.eachPath(function(path, schemaType) { + // Skip single nested paths if underneath a map + const isUnderneathMap = schemaType.path.endsWith('.$*') || + schemaType.path.indexOf('.$*.') !== -1; + if (schemaType.$isSingleNested && !isUnderneathMap) { + // Only handle nested schemas 1-level deep to avoid infinite + // recursion re: https://github.com/mongodb-js/mongoose-autopopulate/issues/11 + schemaType.schema.eachPath(function(_path, _schemaType) { + if (_path === '_id' && _schemaType.auto) { + // Ignore _id if auto id so we don't create subdocs + return; + } + + const def = _schemaType.getDefault(null, true); + if (!isModified(modified, path + '.' + _path) && + typeof def !== 'undefined') { + castedDoc = castedDoc || {}; + castedDoc.$setOnInsert = castedDoc.$setOnInsert || {}; + castedDoc.$setOnInsert[path + '.' + _path] = def; + updatedValues[path + '.' + _path] = def; + } + }); + } else { + const def = schemaType.getDefault(null, true); + if (!isModified(modified, path) && typeof def !== 'undefined') { + castedDoc = castedDoc || {}; + castedDoc.$setOnInsert = castedDoc.$setOnInsert || {}; + if (get(castedDoc, path) == null) { + castedDoc.$setOnInsert[path] = def; + } + updatedValues[path] = def; + } + } + }); + + return castedDoc; +}; + +function isModified(modified, path) { + if (modified[path]) { + return true; + } + const sp = path.split('.'); + let cur = sp[0]; + for (let i = 1; i < sp.length; ++i) { + if (modified[cur]) { + return true; + } + cur += '.' + sp[i]; + } + return false; +} |