You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.4 KiB
JavaScript
82 lines
2.4 KiB
JavaScript
11 months ago
|
'use strict';
|
||
|
const schemaMerge = require('../schema/merge');
|
||
|
const specialProperties = require('../../helpers/specialProperties');
|
||
|
const isBsonType = require('../../helpers/isBsonType');
|
||
|
const ObjectId = require('../../types/objectid');
|
||
|
const isObject = require('../../helpers/isObject');
|
||
|
/**
|
||
|
* Merges `from` into `to` without overwriting existing properties.
|
||
|
*
|
||
|
* @param {Object} to
|
||
|
* @param {Object} from
|
||
|
* @param {String} [path]
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
module.exports = function mergeDiscriminatorSchema(to, from, path, seen) {
|
||
|
const keys = Object.keys(from);
|
||
|
let i = 0;
|
||
|
const len = keys.length;
|
||
|
let key;
|
||
|
|
||
|
path = path || '';
|
||
|
seen = seen || new WeakSet();
|
||
|
|
||
|
if (seen.has(from)) {
|
||
|
return;
|
||
|
}
|
||
|
seen.add(from);
|
||
|
|
||
|
while (i < len) {
|
||
|
key = keys[i++];
|
||
|
if (!path) {
|
||
|
if (key === 'discriminators' ||
|
||
|
key === 'base' ||
|
||
|
key === '_applyDiscriminators' ||
|
||
|
key === '_userProvidedOptions' ||
|
||
|
key === 'options' ||
|
||
|
key === 'tree') {
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
if (path === 'tree' && from != null && from.instanceOfSchema) {
|
||
|
continue;
|
||
|
}
|
||
|
if (specialProperties.has(key)) {
|
||
|
continue;
|
||
|
}
|
||
|
if (to[key] == null) {
|
||
|
to[key] = from[key];
|
||
|
} else if (isObject(from[key])) {
|
||
|
if (!isObject(to[key])) {
|
||
|
to[key] = {};
|
||
|
}
|
||
|
if (from[key] != null) {
|
||
|
// Skip merging schemas if we're creating a discriminator schema and
|
||
|
// base schema has a given path as a single nested but discriminator schema
|
||
|
// has the path as a document array, or vice versa (gh-9534)
|
||
|
if ((from[key].$isSingleNested && to[key].$isMongooseDocumentArray) ||
|
||
|
(from[key].$isMongooseDocumentArray && to[key].$isSingleNested) ||
|
||
|
(from[key].$isMongooseDocumentArrayElement && to[key].$isMongooseDocumentArrayElement)) {
|
||
|
continue;
|
||
|
} else if (from[key].instanceOfSchema) {
|
||
|
if (to[key].instanceOfSchema) {
|
||
|
schemaMerge(to[key], from[key].clone(), true);
|
||
|
} else {
|
||
|
to[key] = from[key].clone();
|
||
|
}
|
||
|
continue;
|
||
|
} else if (isBsonType(from[key], 'ObjectId')) {
|
||
|
to[key] = new ObjectId(from[key]);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
mergeDiscriminatorSchema(to[key], from[key], path ? path + '.' + key : key, seen);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (from != null && from.instanceOfSchema) {
|
||
|
to.tree = Object.assign({}, from.tree, to.tree);
|
||
|
}
|
||
|
};
|