Changes
This commit is contained in:
6
node_modules/mongoose/lib/helpers/arrayDepth.js
generated
vendored
6
node_modules/mongoose/lib/helpers/arrayDepth.js
generated
vendored
@@ -4,13 +4,14 @@ module.exports = arrayDepth;
|
||||
|
||||
function arrayDepth(arr) {
|
||||
if (!Array.isArray(arr)) {
|
||||
return { min: 0, max: 0 };
|
||||
return { min: 0, max: 0, containsNonArrayItem: true };
|
||||
}
|
||||
if (arr.length === 0) {
|
||||
return { min: 1, max: 1 };
|
||||
return { min: 1, max: 1, containsNonArrayItem: false };
|
||||
}
|
||||
|
||||
const res = arrayDepth(arr[0]);
|
||||
|
||||
for (let i = 1; i < arr.length; ++i) {
|
||||
const _res = arrayDepth(arr[i]);
|
||||
if (_res.min < res.min) {
|
||||
@@ -19,6 +20,7 @@ function arrayDepth(arr) {
|
||||
if (_res.max > res.max) {
|
||||
res.max = _res.max;
|
||||
}
|
||||
res.containsNonArrayItem = res.containsNonArrayItem || _res.containsNonArrayItem;
|
||||
}
|
||||
|
||||
res.min = res.min + 1;
|
||||
|
||||
13
node_modules/mongoose/lib/helpers/document/compile.js
generated
vendored
13
node_modules/mongoose/lib/helpers/document/compile.js
generated
vendored
@@ -124,6 +124,13 @@ function defineKey(prop, subprops, prototype, prefix, keys, options) {
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(nested, '$__parent', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: false,
|
||||
value: this
|
||||
});
|
||||
|
||||
compile(subprops, nested, path, options);
|
||||
this.$__.getters[path] = nested;
|
||||
}
|
||||
@@ -131,8 +138,10 @@ function defineKey(prop, subprops, prototype, prefix, keys, options) {
|
||||
return this.$__.getters[path];
|
||||
},
|
||||
set: function(v) {
|
||||
if (v instanceof Document) {
|
||||
v = v.toObject({ transform: false });
|
||||
if (v != null && v.$__isNested) {
|
||||
// Convert top-level to POJO, but leave subdocs hydrated so `$set`
|
||||
// can handle them. See gh-9293.
|
||||
v = v.$__parent.get(path);
|
||||
}
|
||||
const doc = this.$__[scopeSymbol] || this;
|
||||
doc.$set(path, v);
|
||||
|
||||
51
node_modules/mongoose/lib/helpers/indexes/isIndexEqual.js
generated
vendored
51
node_modules/mongoose/lib/helpers/indexes/isIndexEqual.js
generated
vendored
@@ -3,8 +3,52 @@
|
||||
const get = require('../get');
|
||||
const utils = require('../../utils');
|
||||
|
||||
/**
|
||||
* Given a Mongoose index definition (key + options objects) and a MongoDB server
|
||||
* index definition, determine if the two indexes are equal.
|
||||
*
|
||||
* @param {Object} key the Mongoose index spec
|
||||
* @param {Object} options the Mongoose index definition's options
|
||||
* @param {Object} dbIndex the index in MongoDB as returned by `listIndexes()`
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function isIndexEqual(key, options, dbIndex) {
|
||||
// If these options are different, need to rebuild the index
|
||||
// Special case: text indexes have a special format in the db. For example,
|
||||
// `{ name: 'text' }` becomes:
|
||||
// {
|
||||
// v: 2,
|
||||
// key: { _fts: 'text', _ftsx: 1 },
|
||||
// name: 'name_text',
|
||||
// ns: 'test.tests',
|
||||
// background: true,
|
||||
// weights: { name: 1 },
|
||||
// default_language: 'english',
|
||||
// language_override: 'language',
|
||||
// textIndexVersion: 3
|
||||
// }
|
||||
if (dbIndex.textIndexVersion != null) {
|
||||
const weights = dbIndex.weights;
|
||||
if (Object.keys(weights).length !== Object.keys(key).length) {
|
||||
return false;
|
||||
}
|
||||
for (const prop of Object.keys(weights)) {
|
||||
if (!(prop in key)) {
|
||||
return false;
|
||||
}
|
||||
const weight = weights[prop];
|
||||
if (weight !== get(options, 'weights.' + prop) && !(weight === 1 && get(options, 'weights.' + prop) == null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (options['default_language'] !== dbIndex['default_language']) {
|
||||
return dbIndex['default_language'] === 'english' && options['default_language'] == null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const optionKeys = [
|
||||
'unique',
|
||||
'partialFilterExpression',
|
||||
@@ -17,6 +61,9 @@ module.exports = function isIndexEqual(key, options, dbIndex) {
|
||||
continue;
|
||||
}
|
||||
if (key === 'collation') {
|
||||
if (options[key] == null || dbIndex[key] == null) {
|
||||
return options[key] == null && dbIndex[key] == null;
|
||||
}
|
||||
const definedKeys = Object.keys(options.collation);
|
||||
const schemaCollation = options.collation;
|
||||
const dbCollation = dbIndex.collation;
|
||||
@@ -45,4 +92,4 @@ module.exports = function isIndexEqual(key, options, dbIndex) {
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
23
node_modules/mongoose/lib/helpers/model/castBulkWrite.js
generated
vendored
23
node_modules/mongoose/lib/helpers/model/castBulkWrite.js
generated
vendored
@@ -37,8 +37,12 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
} else if (op['updateOne']) {
|
||||
return (callback) => {
|
||||
try {
|
||||
if (!op['updateOne']['filter']) throw new Error('Must provide a filter object.');
|
||||
if (!op['updateOne']['update']) throw new Error('Must provide an update object.');
|
||||
if (!op['updateOne']['filter']) {
|
||||
throw new Error('Must provide a filter object.');
|
||||
}
|
||||
if (!op['updateOne']['update']) {
|
||||
throw new Error('Must provide an update object.');
|
||||
}
|
||||
|
||||
const model = decideModelByObject(originalModel, op['updateOne']['filter']);
|
||||
const schema = model.schema;
|
||||
@@ -54,7 +58,6 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
|
||||
applyTimestampsToChildren(now, op['updateOne']['update'], model.schema);
|
||||
|
||||
|
||||
if (op['updateOne'].setDefaultsOnInsert) {
|
||||
setDefaultsOnInsert(op['updateOne']['filter'], model.schema, op['updateOne']['update'], {
|
||||
setDefaultsOnInsert: true,
|
||||
@@ -71,8 +74,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
strict: strict,
|
||||
overwrite: false,
|
||||
upsert: op['updateOne'].upsert
|
||||
});
|
||||
|
||||
}, model, op['updateOne']['filter']);
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
@@ -82,8 +84,12 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
} else if (op['updateMany']) {
|
||||
return (callback) => {
|
||||
try {
|
||||
if (!op['updateMany']['filter']) throw new Error('Must provide a filter object.');
|
||||
if (!op['updateMany']['update']) throw new Error('Must provide an update object.');
|
||||
if (!op['updateMany']['filter']) {
|
||||
throw new Error('Must provide a filter object.');
|
||||
}
|
||||
if (!op['updateMany']['update']) {
|
||||
throw new Error('Must provide an update object.');
|
||||
}
|
||||
|
||||
const model = decideModelByObject(originalModel, op['updateMany']['filter']);
|
||||
const schema = model.schema;
|
||||
@@ -115,7 +121,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
strict: strict,
|
||||
overwrite: false,
|
||||
upsert: op['updateMany'].upsert
|
||||
});
|
||||
}, model, op['updateMany']['filter']);
|
||||
|
||||
} catch (error) {
|
||||
return callback(error, null);
|
||||
@@ -153,6 +159,7 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
||||
if (error) {
|
||||
return callback(error, null);
|
||||
}
|
||||
op['replaceOne']['replacement'] = op['replaceOne']['replacement'].toBSON();
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
|
||||
12
node_modules/mongoose/lib/helpers/model/discriminator.js
generated
vendored
12
node_modules/mongoose/lib/helpers/model/discriminator.js
generated
vendored
@@ -149,11 +149,17 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
|
||||
|
||||
for (const _key of keys) {
|
||||
if (!CUSTOMIZABLE_DISCRIMINATOR_OPTIONS[_key]) {
|
||||
// Special case: compiling a model sets `pluralization = true` by default. Avoid throwing an error
|
||||
// for that case. See gh-9238
|
||||
if (_key === 'pluralization' && schema.options[_key] == true && baseSchema.options[_key] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!utils.deepEqual(schema.options[_key], baseSchema.options[_key])) {
|
||||
throw new Error('Can\'t customize discriminator option ' + _key +
|
||||
' (can only modify ' +
|
||||
Object.keys(CUSTOMIZABLE_DISCRIMINATOR_OPTIONS).join(', ') +
|
||||
')');
|
||||
' (can only modify ' +
|
||||
Object.keys(CUSTOMIZABLE_DISCRIMINATOR_OPTIONS).join(', ') +
|
||||
')');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
36
node_modules/mongoose/lib/helpers/populate/assignVals.js
generated
vendored
36
node_modules/mongoose/lib/helpers/populate/assignVals.js
generated
vendored
@@ -18,6 +18,7 @@ module.exports = function assignVals(o) {
|
||||
justOne: o.justOne
|
||||
});
|
||||
populateOptions.$nullIfNotFound = o.isVirtual;
|
||||
const populatedModel = o.populatedModel;
|
||||
|
||||
const originalIds = [].concat(o.rawIds);
|
||||
|
||||
@@ -39,12 +40,31 @@ module.exports = function assignVals(o) {
|
||||
if (val instanceof SkipPopulateValue) {
|
||||
return val.val;
|
||||
}
|
||||
|
||||
if (o.justOne === true && Array.isArray(val)) {
|
||||
return valueFilter(val[0], options, populateOptions);
|
||||
// Might be an embedded discriminator (re: gh-9244) with multiple models, so make sure to pick the right
|
||||
// model before assigning.
|
||||
const ret = [];
|
||||
for (const doc of val) {
|
||||
const _docPopulatedModel = leanPopulateMap.get(doc);
|
||||
if (_docPopulatedModel == null || _docPopulatedModel === populatedModel) {
|
||||
ret.push(doc);
|
||||
}
|
||||
}
|
||||
// Since we don't want to have to create a new mongoosearray, make sure to
|
||||
// modify the array in place
|
||||
while (val.length > ret.length) {
|
||||
Array.prototype.pop.apply(val, []);
|
||||
}
|
||||
for (let i = 0; i < ret.length; ++i) {
|
||||
val[i] = ret[i];
|
||||
}
|
||||
|
||||
return valueFilter(val[0], options, populateOptions, populatedModel);
|
||||
} else if (o.justOne === false && !Array.isArray(val)) {
|
||||
return valueFilter([val], options, populateOptions);
|
||||
return valueFilter([val], options, populateOptions, populatedModel);
|
||||
}
|
||||
return valueFilter(val, options, populateOptions);
|
||||
return valueFilter(val, options, populateOptions, populatedModel);
|
||||
}
|
||||
|
||||
for (let i = 0; i < docs.length; ++i) {
|
||||
@@ -84,6 +104,16 @@ module.exports = function assignVals(o) {
|
||||
}, new Map());
|
||||
}
|
||||
|
||||
if (isDoc && Array.isArray(valueToSet)) {
|
||||
for (const val of valueToSet) {
|
||||
if (val != null && val.$__ != null) {
|
||||
val.$__.parent = docs[i];
|
||||
}
|
||||
}
|
||||
} else if (isDoc && valueToSet != null && valueToSet.$__ != null) {
|
||||
valueToSet.$__.parent = docs[i];
|
||||
}
|
||||
|
||||
if (o.isVirtual && isDoc) {
|
||||
docs[i].populated(o.path, o.justOne ? originalIds[0] : originalIds, o.allOptions);
|
||||
// If virtual populate and doc is already init-ed, need to walk through
|
||||
|
||||
13
node_modules/mongoose/lib/helpers/populate/getModelsMapForPopulate.js
generated
vendored
13
node_modules/mongoose/lib/helpers/populate/getModelsMapForPopulate.js
generated
vendored
@@ -40,6 +40,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
doc = docs[i];
|
||||
let justOne = null;
|
||||
|
||||
schema = getSchemaTypes(modelSchema, doc, options.path);
|
||||
// Special case: populating a path that's a DocumentArray unless
|
||||
@@ -76,6 +77,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
isRefPath = isRefPath || res.isRefPath;
|
||||
normalizedRefPath = normalizeRefPath(normalizedRefPath, doc, options.path) ||
|
||||
res.refPath;
|
||||
justOne = res.justOne;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
@@ -99,6 +101,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
modelNames = res.modelNames;
|
||||
isRefPath = res.isRefPath;
|
||||
normalizedRefPath = res.refPath;
|
||||
justOne = res.justOne;
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
@@ -142,7 +145,6 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
// `justOne = null` means we don't know from the schema whether the end
|
||||
// result should be an array or a single doc. This can result from
|
||||
// populating a POJO using `Model.populate()`
|
||||
let justOne = null;
|
||||
if ('justOne' in options && options.justOne !== void 0) {
|
||||
justOne = options.justOne;
|
||||
} else if (virtual && virtual.options && virtual.options.refPath) {
|
||||
@@ -339,6 +341,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
let modelNames;
|
||||
let discriminatorKey;
|
||||
let isRefPath = false;
|
||||
let justOne = null;
|
||||
|
||||
if (schema && schema.caster) {
|
||||
schema = schema.caster;
|
||||
@@ -407,6 +410,10 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
const _virtualRes = getVirtual(modelForCurrentDoc.schema, options.path);
|
||||
const virtual = _virtualRes == null ? null : _virtualRes.virtual;
|
||||
|
||||
if (schemaForCurrentDoc != null) {
|
||||
justOne = !schemaForCurrentDoc.$isMongooseArray && !schemaForCurrentDoc._arrayPath;
|
||||
}
|
||||
|
||||
let ref;
|
||||
let refPath;
|
||||
|
||||
@@ -440,14 +447,14 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
||||
}
|
||||
|
||||
if (!modelNames) {
|
||||
return { modelNames: modelNames, isRefPath: isRefPath, refPath: normalizedRefPath };
|
||||
return { modelNames: modelNames, isRefPath: isRefPath, refPath: normalizedRefPath, justOne: justOne };
|
||||
}
|
||||
|
||||
if (!Array.isArray(modelNames)) {
|
||||
modelNames = [modelNames];
|
||||
}
|
||||
|
||||
return { modelNames: modelNames, isRefPath: isRefPath, refPath: normalizedRefPath };
|
||||
return { modelNames: modelNames, isRefPath: isRefPath, refPath: normalizedRefPath, justOne: justOne };
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
8
node_modules/mongoose/lib/helpers/query/castUpdate.js
generated
vendored
8
node_modules/mongoose/lib/helpers/query/castUpdate.js
generated
vendored
@@ -105,6 +105,14 @@ module.exports = function castUpdate(schema, obj, options, context, filter) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(ret).length === 0 &&
|
||||
options.upsert &&
|
||||
Object.keys(filter).length > 0) {
|
||||
// Trick the driver into allowing empty upserts to work around
|
||||
// https://github.com/mongodb/node-mongodb-native/pull/2490
|
||||
return { $setOnInsert: filter };
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
6
node_modules/mongoose/lib/helpers/schematype/handleImmutable.js
generated
vendored
6
node_modules/mongoose/lib/helpers/schematype/handleImmutable.js
generated
vendored
@@ -33,11 +33,13 @@ function createImmutableSetter(path, immutable) {
|
||||
if (!_immutable) {
|
||||
return v;
|
||||
}
|
||||
if (this.$__.strictMode === 'throw' && v !== this[path]) {
|
||||
|
||||
const _value = this.$__getValue(path);
|
||||
if (this.$__.strictMode === 'throw' && v !== _value) {
|
||||
throw new StrictModeError(path, 'Path `' + path + '` is immutable ' +
|
||||
'and strict mode is set to throw.', true);
|
||||
}
|
||||
|
||||
return this[path];
|
||||
return _value;
|
||||
};
|
||||
}
|
||||
|
||||
17
node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js
generated
vendored
17
node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js
generated
vendored
@@ -14,6 +14,17 @@ const get = require('./get');
|
||||
*/
|
||||
|
||||
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 = {};
|
||||
@@ -22,12 +33,6 @@ module.exports = function(filter, schema, castedDoc, options) {
|
||||
|
||||
let hasDollarUpdate = false;
|
||||
|
||||
options = options || {};
|
||||
|
||||
if (!options.upsert || !options.setDefaultsOnInsert) {
|
||||
return castedDoc;
|
||||
}
|
||||
|
||||
for (let i = 0; i < numKeys; ++i) {
|
||||
if (keys[i].startsWith('$')) {
|
||||
modifiedPaths(castedDoc[keys[i]], '', modified);
|
||||
|
||||
1
node_modules/mongoose/lib/helpers/symbols.js
generated
vendored
1
node_modules/mongoose/lib/helpers/symbols.js
generated
vendored
@@ -11,5 +11,6 @@ exports.modelSymbol = Symbol('mongoose#Model');
|
||||
exports.objectIdSymbol = Symbol('mongoose#ObjectId');
|
||||
exports.populateModelSymbol = Symbol('mongoose.PopulateOptions#Model');
|
||||
exports.schemaTypeSymbol = Symbol('mongoose#schemaType');
|
||||
exports.sessionNewDocuments = Symbol('mongoose:ClientSession#newDocuments');
|
||||
exports.scopeSymbol = Symbol('mongoose#Document#scope');
|
||||
exports.validatorErrorSymbol = Symbol('mongoose:validatorError');
|
||||
169
node_modules/mongoose/lib/helpers/update/applyTimestampsToChildren.js
generated
vendored
169
node_modules/mongoose/lib/helpers/update/applyTimestampsToChildren.js
generated
vendored
@@ -15,25 +15,19 @@ function applyTimestampsToChildren(now, update, schema) {
|
||||
}
|
||||
|
||||
const keys = Object.keys(update);
|
||||
let key;
|
||||
let createdAt;
|
||||
let updatedAt;
|
||||
let timestamps;
|
||||
let path;
|
||||
|
||||
const hasDollarKey = keys.length && keys[0].startsWith('$');
|
||||
|
||||
if (hasDollarKey) {
|
||||
if (update.$push) {
|
||||
for (key in update.$push) {
|
||||
for (const key of Object.keys(update.$push)) {
|
||||
const $path = schema.path(key);
|
||||
if (update.$push[key] &&
|
||||
$path &&
|
||||
$path.$isMongooseDocumentArray &&
|
||||
$path.schema.options.timestamps) {
|
||||
timestamps = $path.schema.options.timestamps;
|
||||
createdAt = handleTimestampOption(timestamps, 'createdAt');
|
||||
updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
const timestamps = $path.schema.options.timestamps;
|
||||
const createdAt = handleTimestampOption(timestamps, 'createdAt');
|
||||
const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
if (update.$push[key].$each) {
|
||||
update.$push[key].$each.forEach(function(subdoc) {
|
||||
if (updatedAt != null) {
|
||||
@@ -56,93 +50,14 @@ function applyTimestampsToChildren(now, update, schema) {
|
||||
}
|
||||
if (update.$set != null) {
|
||||
const keys = Object.keys(update.$set);
|
||||
for (key of keys) {
|
||||
// Replace positional operator `$` and array filters `$[]` and `$[.*]`
|
||||
const keyToSearch = cleanPositionalOperators(key);
|
||||
path = schema.path(keyToSearch);
|
||||
if (!path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const parentSchemaTypes = [];
|
||||
const pieces = keyToSearch.split('.');
|
||||
for (let i = pieces.length - 1; i > 0; --i) {
|
||||
const s = schema.path(pieces.slice(0, i).join('.'));
|
||||
if (s != null &&
|
||||
(s.$isMongooseDocumentArray || s.$isSingleNested)) {
|
||||
parentSchemaTypes.push({ parentPath: key.split('.').slice(0, i).join('.'), parentSchemaType: s });
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(update.$set[key]) && path.$isMongooseDocumentArray) {
|
||||
applyTimestampsToDocumentArray(update.$set[key], path, now);
|
||||
} else if (update.$set[key] && path.$isSingleNested) {
|
||||
applyTimestampsToSingleNested(update.$set[key], path, now);
|
||||
} else if (parentSchemaTypes.length > 0) {
|
||||
for (const item of parentSchemaTypes) {
|
||||
const parentPath = item.parentPath;
|
||||
const parentSchemaType = item.parentSchemaType;
|
||||
timestamps = parentSchemaType.schema.options.timestamps;
|
||||
createdAt = handleTimestampOption(timestamps, 'createdAt');
|
||||
updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
|
||||
if (!timestamps || updatedAt == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parentSchemaType.$isSingleNested) {
|
||||
// Single nested is easy
|
||||
update.$set[parentPath + '.' + updatedAt] = now;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parentSchemaType.$isMongooseDocumentArray) {
|
||||
let childPath = key.substr(parentPath.length + 1);
|
||||
|
||||
if (/^\d+$/.test(childPath)) {
|
||||
update.$set[parentPath + '.' + childPath][updatedAt] = now;
|
||||
continue;
|
||||
}
|
||||
|
||||
const firstDot = childPath.indexOf('.');
|
||||
childPath = firstDot !== -1 ? childPath.substr(0, firstDot) : childPath;
|
||||
|
||||
update.$set[parentPath + '.' + childPath + '.' + updatedAt] = now;
|
||||
}
|
||||
}
|
||||
} else if (path.schema != null && path.schema != schema && update.$set[key]) {
|
||||
timestamps = path.schema.options.timestamps;
|
||||
createdAt = handleTimestampOption(timestamps, 'createdAt');
|
||||
updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
|
||||
if (!timestamps) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (updatedAt != null) {
|
||||
update.$set[key][updatedAt] = now;
|
||||
}
|
||||
if (createdAt != null) {
|
||||
update.$set[key][createdAt] = now;
|
||||
}
|
||||
}
|
||||
for (const key of keys) {
|
||||
applyTimestampsToUpdateKey(schema, key, update.$set, now);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const keys = Object.keys(update).filter(key => !key.startsWith('$'));
|
||||
for (key of keys) {
|
||||
// Replace positional operator `$` and array filters `$[]` and `$[.*]`
|
||||
const keyToSearch = cleanPositionalOperators(key);
|
||||
path = schema.path(keyToSearch);
|
||||
if (!path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Array.isArray(update[key]) && path.$isMongooseDocumentArray) {
|
||||
applyTimestampsToDocumentArray(update[key], path, now);
|
||||
} else if (update[key] != null && path.$isSingleNested) {
|
||||
applyTimestampsToSingleNested(update[key], path, now);
|
||||
}
|
||||
for (const key of keys) {
|
||||
applyTimestampsToUpdateKey(schema, key, update, now);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,3 +102,71 @@ function applyTimestampsToSingleNested(subdoc, schematype, now) {
|
||||
|
||||
applyTimestampsToChildren(now, subdoc, schematype.schema);
|
||||
}
|
||||
|
||||
function applyTimestampsToUpdateKey(schema, key, update, now) {
|
||||
// Replace positional operator `$` and array filters `$[]` and `$[.*]`
|
||||
const keyToSearch = cleanPositionalOperators(key);
|
||||
const path = schema.path(keyToSearch);
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentSchemaTypes = [];
|
||||
const pieces = keyToSearch.split('.');
|
||||
for (let i = pieces.length - 1; i > 0; --i) {
|
||||
const s = schema.path(pieces.slice(0, i).join('.'));
|
||||
if (s != null &&
|
||||
(s.$isMongooseDocumentArray || s.$isSingleNested)) {
|
||||
parentSchemaTypes.push({ parentPath: key.split('.').slice(0, i).join('.'), parentSchemaType: s });
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(update[key]) && path.$isMongooseDocumentArray) {
|
||||
applyTimestampsToDocumentArray(update[key], path, now);
|
||||
} else if (update[key] && path.$isSingleNested) {
|
||||
applyTimestampsToSingleNested(update[key], path, now);
|
||||
} else if (parentSchemaTypes.length > 0) {
|
||||
for (const item of parentSchemaTypes) {
|
||||
const parentPath = item.parentPath;
|
||||
const parentSchemaType = item.parentSchemaType;
|
||||
const timestamps = parentSchemaType.schema.options.timestamps;
|
||||
const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
|
||||
if (!timestamps || updatedAt == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parentSchemaType.$isSingleNested) {
|
||||
// Single nested is easy
|
||||
update[parentPath + '.' + updatedAt] = now;
|
||||
} else if (parentSchemaType.$isMongooseDocumentArray) {
|
||||
let childPath = key.substr(parentPath.length + 1);
|
||||
|
||||
if (/^\d+$/.test(childPath)) {
|
||||
update[parentPath + '.' + childPath][updatedAt] = now;
|
||||
continue;
|
||||
}
|
||||
|
||||
const firstDot = childPath.indexOf('.');
|
||||
childPath = firstDot !== -1 ? childPath.substr(0, firstDot) : childPath;
|
||||
|
||||
update[parentPath + '.' + childPath + '.' + updatedAt] = now;
|
||||
}
|
||||
}
|
||||
} else if (path.schema != null && path.schema != schema && update[key]) {
|
||||
const timestamps = path.schema.options.timestamps;
|
||||
const createdAt = handleTimestampOption(timestamps, 'createdAt');
|
||||
const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
|
||||
|
||||
if (!timestamps) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updatedAt != null) {
|
||||
update[key][updatedAt] = now;
|
||||
}
|
||||
if (createdAt != null) {
|
||||
update[key][createdAt] = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user