mongoose 6.0.13 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.umd.js +18 -14
- package/index.d.ts +310 -28
- package/lib/aggregate.js +17 -0
- package/lib/connection.js +12 -4
- package/lib/document.js +35 -11
- package/lib/drivers/node-mongodb-native/collection.js +3 -6
- package/lib/drivers/node-mongodb-native/connection.js +1 -0
- package/lib/helpers/populate/assignVals.js +4 -4
- package/lib/helpers/populate/getModelsMapForPopulate.js +31 -3
- package/lib/helpers/projection/isSubpath.js +13 -0
- package/lib/helpers/timestamps/setupTimestamps.js +1 -1
- package/lib/helpers/update/castArrayFilters.js +11 -1
- package/lib/index.js +6 -1
- package/lib/internal.js +1 -0
- package/lib/model.js +23 -12
- package/lib/options/SchemaTypeOptions.js +1 -1
- package/lib/plugins/clearValidating.js +2 -2
- package/lib/plugins/removeSubdocs.js +1 -1
- package/lib/plugins/saveSubdocs.js +2 -2
- package/lib/plugins/validateBeforeSave.js +1 -1
- package/lib/query.js +46 -7
- package/lib/schema.js +1 -3
- package/lib/schematype.js +2 -2
- package/lib/types/subdocument.js +1 -1
- package/lib/utils.js +12 -0
- package/lib/validoptions.js +1 -0
- package/package.json +2 -3
|
@@ -214,14 +214,11 @@ function iter(i) {
|
|
|
214
214
|
} catch (error) {
|
|
215
215
|
// Collection operation may throw because of max bson size, catch it here
|
|
216
216
|
// See gh-3906
|
|
217
|
-
if (typeof callback === 'function') {
|
|
218
|
-
callback(error);
|
|
219
|
-
} else {
|
|
220
|
-
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
|
|
221
|
-
}
|
|
222
217
|
if (typeof lastArg === 'function') {
|
|
223
|
-
lastArg(error);
|
|
218
|
+
return lastArg(error);
|
|
224
219
|
} else {
|
|
220
|
+
this.conn.emit('operation-end', { _id: opId, modelName: _this.modelName, collectionName: this.name, method: i, error: error });
|
|
221
|
+
|
|
225
222
|
throw error;
|
|
226
223
|
}
|
|
227
224
|
}
|
|
@@ -73,9 +73,6 @@ module.exports = function assignVals(o) {
|
|
|
73
73
|
|
|
74
74
|
return valueFilter(val[0], options, populateOptions, _allIds);
|
|
75
75
|
} else if (o.justOne === false && !Array.isArray(val)) {
|
|
76
|
-
if (val === null && o.isVirtual) {
|
|
77
|
-
return void 0;
|
|
78
|
-
}
|
|
79
76
|
return valueFilter([val], options, populateOptions, _allIds);
|
|
80
77
|
}
|
|
81
78
|
return valueFilter(val, options, populateOptions, _allIds);
|
|
@@ -133,6 +130,9 @@ module.exports = function assignVals(o) {
|
|
|
133
130
|
docs[i].$populated(_path, o.justOne ? originalIds[0] : originalIds, o.allOptions);
|
|
134
131
|
// If virtual populate and doc is already init-ed, need to walk through
|
|
135
132
|
// the actual doc to set rather than setting `_doc` directly
|
|
133
|
+
if (Array.isArray(valueToSet)) {
|
|
134
|
+
valueToSet = valueToSet.map(v => v == null ? void 0 : v);
|
|
135
|
+
}
|
|
136
136
|
mpath.set(_path, valueToSet, docs[i], void 0, setValue, false);
|
|
137
137
|
continue;
|
|
138
138
|
}
|
|
@@ -170,7 +170,7 @@ module.exports = function assignVals(o) {
|
|
|
170
170
|
}
|
|
171
171
|
if (docs[i].$__) {
|
|
172
172
|
o.allOptions.options[populateModelSymbol] = o.allOptions.model;
|
|
173
|
-
docs[i].$populated(_path, o.
|
|
173
|
+
docs[i].$populated(_path, o.unpopulatedValues[i], o.allOptions.options);
|
|
174
174
|
|
|
175
175
|
if (valueToSet instanceof Map && !valueToSet.$isMongooseMap) {
|
|
176
176
|
valueToSet = new MongooseMap(valueToSet, _path, docs[i], docs[i].schema.path(_path).$__schemaType);
|
|
@@ -75,6 +75,20 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
|
|
75
75
|
let normalizedRefPath = null;
|
|
76
76
|
let schemaOptions = null;
|
|
77
77
|
|
|
78
|
+
if (schema != null && schema.instance === 'Embedded' && schema.options.ref) {
|
|
79
|
+
const data = {
|
|
80
|
+
localField: options.path + '._id',
|
|
81
|
+
foreignField: '_id',
|
|
82
|
+
justOne: true
|
|
83
|
+
};
|
|
84
|
+
const res = _getModelNames(doc, schema, modelNameFromQuery, model);
|
|
85
|
+
|
|
86
|
+
const unpopulatedValue = mpath.get(options.path, doc);
|
|
87
|
+
const id = mpath.get('_id', unpopulatedValue);
|
|
88
|
+
addModelNamesToMap(model, map, available, res.modelNames, options, data, id, doc, schemaOptions, unpopulatedValue);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
|
|
78
92
|
if (Array.isArray(schema)) {
|
|
79
93
|
const schemasArray = schema;
|
|
80
94
|
for (const _schema of schemasArray) {
|
|
@@ -183,7 +197,7 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
|
|
183
197
|
let isRefPath = false;
|
|
184
198
|
let justOne = null;
|
|
185
199
|
|
|
186
|
-
if (schema && schema.
|
|
200
|
+
if (schema && schema.instance === 'Array') {
|
|
187
201
|
schema = schema.caster;
|
|
188
202
|
}
|
|
189
203
|
if (schema && schema.$isSchemaMap) {
|
|
@@ -305,7 +319,12 @@ module.exports = function getModelsMapForPopulate(model, docs, options) {
|
|
|
305
319
|
}
|
|
306
320
|
|
|
307
321
|
if (!modelNames) {
|
|
308
|
-
|
|
322
|
+
// `Model.populate()` on a POJO with no known local model. Default to using the `Model`
|
|
323
|
+
if (options._localModel == null) {
|
|
324
|
+
modelNames = [model.modelName];
|
|
325
|
+
} else {
|
|
326
|
+
return { modelNames: modelNames, justOne: justOne, isRefPath: isRefPath, refPath: refPath };
|
|
327
|
+
}
|
|
309
328
|
}
|
|
310
329
|
|
|
311
330
|
if (!Array.isArray(modelNames)) {
|
|
@@ -444,11 +463,16 @@ function _virtualPopulate(model, docs, options, _virtualRes) {
|
|
|
444
463
|
* ignore
|
|
445
464
|
*/
|
|
446
465
|
|
|
447
|
-
function addModelNamesToMap(model, map, available, modelNames, options, data, ret, doc, schemaOptions) {
|
|
466
|
+
function addModelNamesToMap(model, map, available, modelNames, options, data, ret, doc, schemaOptions, unpopulatedValue) {
|
|
448
467
|
// `PopulateOptions#connection`: if the model is passed as a string, the
|
|
449
468
|
// connection matters because different connections have different models.
|
|
450
469
|
const connection = options.connection != null ? options.connection : model.db;
|
|
451
470
|
|
|
471
|
+
unpopulatedValue = unpopulatedValue === void 0 ? ret : unpopulatedValue;
|
|
472
|
+
if (Array.isArray(unpopulatedValue)) {
|
|
473
|
+
unpopulatedValue = utils.cloneArrays(unpopulatedValue);
|
|
474
|
+
}
|
|
475
|
+
|
|
452
476
|
if (modelNames == null) {
|
|
453
477
|
return;
|
|
454
478
|
}
|
|
@@ -510,6 +534,7 @@ function addModelNamesToMap(model, map, available, modelNames, options, data, re
|
|
|
510
534
|
docs: [doc],
|
|
511
535
|
ids: [ids],
|
|
512
536
|
allIds: [ret],
|
|
537
|
+
unpopulatedValues: [unpopulatedValue],
|
|
513
538
|
localField: new Set([data.localField]),
|
|
514
539
|
foreignField: new Set([data.foreignField]),
|
|
515
540
|
justOne: data.justOne,
|
|
@@ -525,6 +550,7 @@ function addModelNamesToMap(model, map, available, modelNames, options, data, re
|
|
|
525
550
|
available[modelName].docs.push(doc);
|
|
526
551
|
available[modelName].ids.push(ids);
|
|
527
552
|
available[modelName].allIds.push(ret);
|
|
553
|
+
available[modelName].unpopulatedValues.push(unpopulatedValue);
|
|
528
554
|
if (data.hasMatchFunction) {
|
|
529
555
|
available[modelName].match.push(data.match);
|
|
530
556
|
}
|
|
@@ -556,6 +582,8 @@ function _getLocalFieldValues(doc, localField, model, options, virtual, schema)
|
|
|
556
582
|
const localFieldGetters = localFieldPath && localFieldPath.getters ?
|
|
557
583
|
localFieldPath.getters : [];
|
|
558
584
|
|
|
585
|
+
localField = localFieldPath != null && localFieldPath.instance === 'Embedded' ? localField + '._id' : localField;
|
|
586
|
+
|
|
559
587
|
const _populateOptions = get(options, 'options', {});
|
|
560
588
|
|
|
561
589
|
const getters = 'getters' in _populateOptions ?
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* Determines if `path2` is a subpath of or equal to `path1`
|
|
5
|
+
*
|
|
6
|
+
* @param {string} path1
|
|
7
|
+
* @param {string} path2
|
|
8
|
+
* @return {Boolean}
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
module.exports = function isSubpath(path1, path2) {
|
|
12
|
+
return path1 === path2 || path2.startsWith(path1 + '.');
|
|
13
|
+
};
|
|
@@ -46,7 +46,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
46
46
|
|
|
47
47
|
const defaultTimestamp = currentTime != null ?
|
|
48
48
|
currentTime() :
|
|
49
|
-
|
|
49
|
+
this.ownerDocument().constructor.base.now();
|
|
50
50
|
const auto_id = this._id && this._id.auto;
|
|
51
51
|
|
|
52
52
|
if (!skipCreatedAt && createdAt && !this.$__getValue(createdAt) && this.$__isSelected(createdAt)) {
|
|
@@ -10,7 +10,17 @@ module.exports = function castArrayFilters(query) {
|
|
|
10
10
|
const update = query.getUpdate();
|
|
11
11
|
const schema = query.schema;
|
|
12
12
|
const updatedPathsByFilter = updatedPathsByArrayFilter(update);
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
let strictQuery = schema.options.strict;
|
|
15
|
+
if (query._mongooseOptions.strict != null) {
|
|
16
|
+
strictQuery = query._mongooseOptions.strict;
|
|
17
|
+
}
|
|
18
|
+
if (schema._userProvidedOptions.strictQuery != null) {
|
|
19
|
+
strictQuery = schema._userProvidedOptions.strictQuery;
|
|
20
|
+
}
|
|
21
|
+
if (query._mongooseOptions.strictQuery != null) {
|
|
22
|
+
strictQuery = query._mongooseOptions.strictQuery;
|
|
23
|
+
}
|
|
14
24
|
|
|
15
25
|
_castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilter, query);
|
|
16
26
|
};
|
package/lib/index.js
CHANGED
|
@@ -156,7 +156,7 @@ Mongoose.prototype.driver = driver;
|
|
|
156
156
|
* - 'toObject': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toObject()`](/docs/api.html#document_Document-toObject)
|
|
157
157
|
* - 'toJSON': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toJSON()`](/docs/api.html#document_Document-toJSON), for determining how Mongoose documents get serialized by `JSON.stringify()`
|
|
158
158
|
* - 'strict': true by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
|
|
159
|
-
* - 'strictQuery':
|
|
159
|
+
* - 'strictQuery': same value as 'strict' by default (`true`), may be `false`, `true`, or `'throw'`. Sets the default [strictQuery](/docs/guide.html#strictQuery) mode for schemas.
|
|
160
160
|
* - 'selectPopulatedPaths': true by default. Set to false to opt out of Mongoose adding all fields that you `populate()` to your `select()`. The schema-level option `selectPopulatedPaths` overwrites this one.
|
|
161
161
|
* - 'maxTimeMS': If set, attaches [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/) to every query
|
|
162
162
|
* - 'autoIndex': true by default. Set to false to disable automatic index creation for all models associated with this Mongoose instance.
|
|
@@ -984,6 +984,11 @@ Mongoose.prototype.isValidObjectId = function(v) {
|
|
|
984
984
|
return false;
|
|
985
985
|
};
|
|
986
986
|
|
|
987
|
+
Mongoose.prototype.syncIndexes = function() {
|
|
988
|
+
const _mongoose = this instanceof Mongoose ? this : mongoose;
|
|
989
|
+
return _mongoose.connection.syncIndexes();
|
|
990
|
+
};
|
|
991
|
+
|
|
987
992
|
/**
|
|
988
993
|
* The Mongoose Decimal128 [SchemaType](/docs/schematypes.html). Used for
|
|
989
994
|
* declaring paths in your schema that should be
|
package/lib/internal.js
CHANGED
package/lib/model.js
CHANGED
|
@@ -343,15 +343,17 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
343
343
|
where[key] = val;
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
-
this.constructor.exists(where, optionsWithCustomValues)
|
|
347
|
-
|
|
346
|
+
this.constructor.exists(where, optionsWithCustomValues).
|
|
347
|
+
then((documentExists) => {
|
|
348
348
|
if (!documentExists) {
|
|
349
|
-
|
|
349
|
+
const matchedCount = 0;
|
|
350
|
+
return callback(null, { $where: where, matchedCount });
|
|
350
351
|
}
|
|
351
352
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
.
|
|
353
|
+
const matchedCount = 1;
|
|
354
|
+
callback(null, { $where: where, matchedCount });
|
|
355
|
+
}).
|
|
356
|
+
catch(callback);
|
|
355
357
|
return;
|
|
356
358
|
}
|
|
357
359
|
|
|
@@ -379,7 +381,7 @@ Model.prototype.$__save = function(options, callback) {
|
|
|
379
381
|
if (get(options, 'safe.w') !== 0 && get(options, 'w') !== 0) {
|
|
380
382
|
// Skip checking if write succeeded if writeConcern is set to
|
|
381
383
|
// unacknowledged writes, because otherwise `numAffected` will always be 0
|
|
382
|
-
if (result) {
|
|
384
|
+
if (result != null) {
|
|
383
385
|
if (Array.isArray(result)) {
|
|
384
386
|
numAffected = result.length;
|
|
385
387
|
} else if (result.matchedCount != null) {
|
|
@@ -916,7 +918,7 @@ Model.prototype.$__where = function _where(where) {
|
|
|
916
918
|
* })
|
|
917
919
|
*
|
|
918
920
|
*
|
|
919
|
-
* As an extra measure of flow control, remove will return a Promise (bound to `fn` if passed) so it could be chained, or hooked to
|
|
921
|
+
* As an extra measure of flow control, remove will return a Promise (bound to `fn` if passed) so it could be chained, or hooked to receive errors
|
|
920
922
|
*
|
|
921
923
|
* ####Example:
|
|
922
924
|
* product.remove().then(function (product) {
|
|
@@ -1336,14 +1338,18 @@ Model.createCollection = function createCollection(options, callback) {
|
|
|
1336
1338
|
options = void 0;
|
|
1337
1339
|
}
|
|
1338
1340
|
|
|
1339
|
-
const schemaCollation = get(this, 'schema
|
|
1341
|
+
const schemaCollation = get(this, ['schema', 'options', 'collation'], null);
|
|
1340
1342
|
if (schemaCollation != null) {
|
|
1341
1343
|
options = Object.assign({ collation: schemaCollation }, options);
|
|
1342
1344
|
}
|
|
1343
|
-
const capped = get(this, 'schema
|
|
1345
|
+
const capped = get(this, ['schema', 'options', 'capped']);
|
|
1344
1346
|
if (capped) {
|
|
1345
1347
|
options = Object.assign({ capped: true }, capped, options);
|
|
1346
1348
|
}
|
|
1349
|
+
const timeseries = get(this, ['schema', 'options', 'timeseries']);
|
|
1350
|
+
if (timeseries != null) {
|
|
1351
|
+
options = Object.assign({ timeseries }, options);
|
|
1352
|
+
}
|
|
1347
1353
|
|
|
1348
1354
|
callback = this.$handleCallbackError(callback);
|
|
1349
1355
|
|
|
@@ -4410,7 +4416,6 @@ function _populate(model, docs, paths, cache, callback) {
|
|
|
4410
4416
|
if (paths.length === 0) {
|
|
4411
4417
|
return callback(null, docs);
|
|
4412
4418
|
}
|
|
4413
|
-
|
|
4414
4419
|
// each path has its own query options and must be executed separately
|
|
4415
4420
|
for (const path of paths) {
|
|
4416
4421
|
populate(model, docs, path, next);
|
|
@@ -4434,6 +4439,11 @@ const excludeIdReg = /\s?-_id\s?/;
|
|
|
4434
4439
|
const excludeIdRegGlobal = /\s?-_id\s?/g;
|
|
4435
4440
|
|
|
4436
4441
|
function populate(model, docs, options, callback) {
|
|
4442
|
+
|
|
4443
|
+
const populateOptions = { ...options };
|
|
4444
|
+
if (model.base.options.strictPopulate != null && options.strictPopulate == null) {
|
|
4445
|
+
populateOptions.strictPopulate = model.base.options.strictPopulate;
|
|
4446
|
+
}
|
|
4437
4447
|
// normalize single / multiple docs passed
|
|
4438
4448
|
if (!Array.isArray(docs)) {
|
|
4439
4449
|
docs = [docs];
|
|
@@ -4442,7 +4452,7 @@ function populate(model, docs, options, callback) {
|
|
|
4442
4452
|
return callback();
|
|
4443
4453
|
}
|
|
4444
4454
|
|
|
4445
|
-
const modelsMap = getModelsMapForPopulate(model, docs,
|
|
4455
|
+
const modelsMap = getModelsMapForPopulate(model, docs, populateOptions);
|
|
4446
4456
|
if (modelsMap instanceof MongooseError) {
|
|
4447
4457
|
return immediate(function() {
|
|
4448
4458
|
callback(modelsMap);
|
|
@@ -4707,6 +4717,7 @@ function _assign(model, vals, mod, assignmentOpts) {
|
|
|
4707
4717
|
// If virtual, make sure to not mutate original field
|
|
4708
4718
|
rawIds: mod.isVirtual ? allIds : mod.allIds,
|
|
4709
4719
|
allIds: allIds,
|
|
4720
|
+
unpopulatedValues: mod.unpopulatedValues,
|
|
4710
4721
|
foreignField: mod.foreignField,
|
|
4711
4722
|
rawDocs: rawDocs,
|
|
4712
4723
|
rawOrder: rawOrder,
|
|
@@ -82,7 +82,7 @@ Object.defineProperty(SchemaTypeOptions.prototype, 'cast', opts);
|
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* If true, attach a required validator to this path, which ensures this path
|
|
85
|
-
*
|
|
85
|
+
* cannot be set to a nullish value. If a function, Mongoose calls the
|
|
86
86
|
* function and only checks for nullish values if the function returns a truthy value.
|
|
87
87
|
*
|
|
88
88
|
* @api public
|
|
@@ -9,7 +9,7 @@ module.exports = function(schema) {
|
|
|
9
9
|
// in parallel. We need to clear `this.$__.validating` before post hooks for gh-8597
|
|
10
10
|
const unshift = true;
|
|
11
11
|
schema.s.hooks.post('validate', false, function() {
|
|
12
|
-
if (this.
|
|
12
|
+
if (this.$__.isSubDocument) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ module.exports = function(schema) {
|
|
|
17
17
|
}, unshift);
|
|
18
18
|
|
|
19
19
|
schema.s.hooks.post('validate', false, function(error, res, next) {
|
|
20
|
-
if (this.
|
|
20
|
+
if (this.$__.isSubDocument) {
|
|
21
21
|
next();
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
@@ -9,7 +9,7 @@ const each = require('../helpers/each');
|
|
|
9
9
|
module.exports = function(schema) {
|
|
10
10
|
const unshift = true;
|
|
11
11
|
schema.s.hooks.pre('save', false, function(next) {
|
|
12
|
-
if (this.
|
|
12
|
+
if (this.$__.isSubDocument) {
|
|
13
13
|
next();
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
@@ -37,7 +37,7 @@ module.exports = function(schema) {
|
|
|
37
37
|
}, null, unshift);
|
|
38
38
|
|
|
39
39
|
schema.s.hooks.post('save', function(doc, next) {
|
|
40
|
-
if (this.
|
|
40
|
+
if (this.$__.isSubDocument) {
|
|
41
41
|
next();
|
|
42
42
|
return;
|
|
43
43
|
}
|
package/lib/query.js
CHANGED
|
@@ -25,6 +25,7 @@ const helpers = require('./queryhelpers');
|
|
|
25
25
|
const immediate = require('./helpers/immediate');
|
|
26
26
|
const isExclusive = require('./helpers/projection/isExclusive');
|
|
27
27
|
const isInclusive = require('./helpers/projection/isInclusive');
|
|
28
|
+
const isSubpath = require('./helpers/projection/isSubpath');
|
|
28
29
|
const mquery = require('mquery');
|
|
29
30
|
const parseProjection = require('./helpers/projection/parseProjection');
|
|
30
31
|
const removeUnusedArrayFilters = require('./helpers/update/removeUnusedArrayFilters');
|
|
@@ -995,6 +996,10 @@ Query.prototype.projection = function(arg) {
|
|
|
995
996
|
* query.select({ a: 1, b: 1 });
|
|
996
997
|
* query.select({ c: 0, d: 0 });
|
|
997
998
|
*
|
|
999
|
+
* Additional calls to select can override the previous selection:
|
|
1000
|
+
* query.select({ a: 1, b: 1 }).select({ b: 0 }); // selection is now { a: 1 }
|
|
1001
|
+
* query.select({ a: 0, b: 0 }).select({ b: 1 }); // selection is now { a: 0 }
|
|
1002
|
+
*
|
|
998
1003
|
*
|
|
999
1004
|
* @method select
|
|
1000
1005
|
* @memberOf Query
|
|
@@ -1026,17 +1031,50 @@ Query.prototype.select = function select() {
|
|
|
1026
1031
|
sanitizeProjection = this._mongooseOptions.sanitizeProjection;
|
|
1027
1032
|
}
|
|
1028
1033
|
|
|
1034
|
+
function sanitizeValue(value) {
|
|
1035
|
+
return typeof value === 'string' && sanitizeProjection ? value = 1 : value;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1029
1038
|
arg = parseProjection(arg);
|
|
1030
1039
|
|
|
1031
1040
|
if (utils.isObject(arg)) {
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1041
|
+
if (this.selectedInclusively()) {
|
|
1042
|
+
Object.entries(arg).forEach(([key, value]) => {
|
|
1043
|
+
if (value) {
|
|
1044
|
+
// Add the field to the projection
|
|
1045
|
+
fields[key] = userProvidedFields[key] = sanitizeValue(value);
|
|
1046
|
+
} else {
|
|
1047
|
+
// Remove the field from the projection
|
|
1048
|
+
Object.keys(userProvidedFields).forEach(field => {
|
|
1049
|
+
if (isSubpath(key, field)) {
|
|
1050
|
+
delete fields[field];
|
|
1051
|
+
delete userProvidedFields[field];
|
|
1052
|
+
}
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
});
|
|
1056
|
+
} else if (this.selectedExclusively()) {
|
|
1057
|
+
Object.entries(arg).forEach(([key, value]) => {
|
|
1058
|
+
if (!value) {
|
|
1059
|
+
// Add the field to the projection
|
|
1060
|
+
fields[key] = userProvidedFields[key] = sanitizeValue(value);
|
|
1061
|
+
} else {
|
|
1062
|
+
// Remove the field from the projection
|
|
1063
|
+
Object.keys(userProvidedFields).forEach(field => {
|
|
1064
|
+
if (isSubpath(key, field)) {
|
|
1065
|
+
delete fields[field];
|
|
1066
|
+
delete userProvidedFields[field];
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
});
|
|
1071
|
+
} else {
|
|
1072
|
+
const keys = Object.keys(arg);
|
|
1073
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
1074
|
+
const value = arg[keys[i]];
|
|
1075
|
+
fields[keys[i]] = sanitizeValue(value);
|
|
1076
|
+
userProvidedFields[keys[i]] = sanitizeValue(value);
|
|
1037
1077
|
}
|
|
1038
|
-
fields[keys[i]] = value;
|
|
1039
|
-
userProvidedFields[keys[i]] = value;
|
|
1040
1078
|
}
|
|
1041
1079
|
return this;
|
|
1042
1080
|
}
|
|
@@ -4470,6 +4508,7 @@ Query.prototype.orFail = function(err) {
|
|
|
4470
4508
|
throw _orFailError(err, this);
|
|
4471
4509
|
}
|
|
4472
4510
|
break;
|
|
4511
|
+
case 'replaceOne':
|
|
4473
4512
|
case 'update':
|
|
4474
4513
|
case 'updateMany':
|
|
4475
4514
|
case 'updateOne':
|
package/lib/schema.js
CHANGED
|
@@ -69,6 +69,7 @@ let id = 0;
|
|
|
69
69
|
* - [versionKey](/docs/guide.html#versionKey): string or object - defaults to "__v"
|
|
70
70
|
* - [optimisticConcurrency](/docs/guide.html#optimisticConcurrency): bool - defaults to false. Set to true to enable [optimistic concurrency](https://thecodebarbarian.com/whats-new-in-mongoose-5-10-optimistic-concurrency.html).
|
|
71
71
|
* - [collation](/docs/guide.html#collation): object - defaults to null (which means use no collation)
|
|
72
|
+
* - [timeseries](/docs/guide.html#timeseries): object - defaults to null (which means this schema's collection won't be a timeseries collection)
|
|
72
73
|
* - [selectPopulatedPaths](/docs/guide.html#selectPopulatedPaths): boolean - defaults to `true`
|
|
73
74
|
* - [skipVersioning](/docs/guide.html#skipVersioning): object - paths to exclude from versioning
|
|
74
75
|
* - [timestamps](/docs/guide.html#timestamps): object or boolean - defaults to `false`. If true, Mongoose adds `createdAt` and `updatedAt` properties to your schema and manages those properties for you.
|
|
@@ -116,7 +117,6 @@ function Schema(obj, options) {
|
|
|
116
117
|
this.s = {
|
|
117
118
|
hooks: new Kareem()
|
|
118
119
|
};
|
|
119
|
-
|
|
120
120
|
this.options = this.defaultOptions(options);
|
|
121
121
|
|
|
122
122
|
// build paths
|
|
@@ -416,11 +416,9 @@ Schema.prototype.pick = function(paths, options) {
|
|
|
416
416
|
|
|
417
417
|
Schema.prototype.defaultOptions = function(options) {
|
|
418
418
|
this._userProvidedOptions = options == null ? {} : utils.clone(options);
|
|
419
|
-
|
|
420
419
|
const baseOptions = get(this, 'base.options', {});
|
|
421
420
|
|
|
422
421
|
const strict = 'strict' in baseOptions ? baseOptions.strict : true;
|
|
423
|
-
|
|
424
422
|
options = utils.options({
|
|
425
423
|
strict: strict,
|
|
426
424
|
strictQuery: 'strict' in this._userProvidedOptions ?
|
package/lib/schematype.js
CHANGED
|
@@ -1398,7 +1398,7 @@ SchemaType._isRef = function(self, value, doc, init) {
|
|
|
1398
1398
|
// - setting / pushing values after population
|
|
1399
1399
|
const path = doc.$__fullPath(self.path, true);
|
|
1400
1400
|
|
|
1401
|
-
const owner = doc.ownerDocument
|
|
1401
|
+
const owner = doc.ownerDocument();
|
|
1402
1402
|
ref = (path != null && owner.$populated(path)) || doc.$populated(self.path);
|
|
1403
1403
|
}
|
|
1404
1404
|
|
|
@@ -1445,7 +1445,7 @@ SchemaType.prototype._castRef = function _castRef(value, doc, init) {
|
|
|
1445
1445
|
// path to a plain object; cast to the Model used in
|
|
1446
1446
|
// the population query.
|
|
1447
1447
|
const path = doc.$__fullPath(this.path, true);
|
|
1448
|
-
const owner = doc.ownerDocument
|
|
1448
|
+
const owner = doc.ownerDocument();
|
|
1449
1449
|
const pop = owner.$populated(path, true);
|
|
1450
1450
|
let ret = value;
|
|
1451
1451
|
if (!doc.$__.populated ||
|
package/lib/types/subdocument.js
CHANGED
|
@@ -26,6 +26,7 @@ function Subdocument(value, fields, parent, skipId, options) {
|
|
|
26
26
|
this.$basePath = options.path;
|
|
27
27
|
}
|
|
28
28
|
Document.call(this, value, fields, skipId, options);
|
|
29
|
+
this.$__.isSubDocument = true;
|
|
29
30
|
|
|
30
31
|
delete this.$__.priorDoc;
|
|
31
32
|
}
|
|
@@ -234,7 +235,6 @@ Subdocument.prototype.ownerDocument = function() {
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
let parent = this; // eslint-disable-line consistent-this
|
|
237
|
-
|
|
238
238
|
const paths = [];
|
|
239
239
|
const seenDocs = new Set([parent]);
|
|
240
240
|
|
package/lib/utils.js
CHANGED
|
@@ -178,6 +178,18 @@ exports.clone = clone;
|
|
|
178
178
|
|
|
179
179
|
exports.promiseOrCallback = promiseOrCallback;
|
|
180
180
|
|
|
181
|
+
/*!
|
|
182
|
+
* ignore
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
exports.cloneArrays = function cloneArrays(arr) {
|
|
186
|
+
if (!Array.isArray(arr)) {
|
|
187
|
+
return arr;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return arr.map(el => exports.cloneArrays(el));
|
|
191
|
+
};
|
|
192
|
+
|
|
181
193
|
/*!
|
|
182
194
|
* ignore
|
|
183
195
|
*/
|
package/lib/validoptions.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.1.1",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"bson": "^4.2.2",
|
|
23
23
|
"kareem": "2.3.2",
|
|
24
|
-
"mongodb": "4.1
|
|
24
|
+
"mongodb": "4.2.1",
|
|
25
25
|
"mpath": "0.8.4",
|
|
26
26
|
"mquery": "4.0.0",
|
|
27
27
|
"ms": "2.1.2",
|
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"typescript": "4.4.4",
|
|
62
62
|
"uuid": "2.0.3",
|
|
63
63
|
"uuid-parse": "1.0.0",
|
|
64
|
-
"validator": "10.8.0",
|
|
65
64
|
"webpack": "4.44.0"
|
|
66
65
|
},
|
|
67
66
|
"directories": {
|