mongoose 7.2.0 → 7.2.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/README.md +11 -22
- package/dist/browser.umd.js +1 -1
- package/lib/cursor/QueryCursor.js +26 -1
- package/lib/helpers/model/castBulkWrite.js +4 -1
- package/lib/helpers/update/applyTimestampsToUpdate.js +3 -2
- package/lib/query.js +7 -20
- package/lib/schema/array.js +5 -1
- package/lib/schematype.js +6 -4
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@ const MongooseError = require('../error/mongooseError');
|
|
|
8
8
|
const Readable = require('stream').Readable;
|
|
9
9
|
const eachAsync = require('../helpers/cursor/eachAsync');
|
|
10
10
|
const helpers = require('../queryhelpers');
|
|
11
|
+
const kareem = require('kareem');
|
|
11
12
|
const immediate = require('../helpers/immediate');
|
|
12
13
|
const util = require('util');
|
|
13
14
|
|
|
@@ -39,6 +40,7 @@ function QueryCursor(query, options) {
|
|
|
39
40
|
Readable.call(this, { autoDestroy: true, objectMode: true });
|
|
40
41
|
|
|
41
42
|
this.cursor = null;
|
|
43
|
+
this.skipped = false;
|
|
42
44
|
this.query = query;
|
|
43
45
|
const _this = this;
|
|
44
46
|
const model = query.model;
|
|
@@ -46,9 +48,25 @@ function QueryCursor(query, options) {
|
|
|
46
48
|
this._transforms = [];
|
|
47
49
|
this.model = model;
|
|
48
50
|
this.options = options || {};
|
|
49
|
-
|
|
50
51
|
model.hooks.execPre('find', query, (err) => {
|
|
51
52
|
if (err != null) {
|
|
53
|
+
if (err instanceof kareem.skipWrappedFunction) {
|
|
54
|
+
const resultValue = err.args[0];
|
|
55
|
+
if (resultValue != null && (!Array.isArray(resultValue) || resultValue.length)) {
|
|
56
|
+
const err = new MongooseError(
|
|
57
|
+
'Cannot `skipMiddlewareFunction()` with a value when using ' +
|
|
58
|
+
'`.find().cursor()`, value must be nullish or empty array, got "' +
|
|
59
|
+
util.inspect(resultValue) +
|
|
60
|
+
'".'
|
|
61
|
+
);
|
|
62
|
+
_this._markError(err);
|
|
63
|
+
_this.listeners('error').length > 0 && _this.emit('error', err);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.skipped = true;
|
|
67
|
+
_this.emit('cursor', null);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
52
70
|
_this._markError(err);
|
|
53
71
|
_this.listeners('error').length > 0 && _this.emit('error', err);
|
|
54
72
|
return;
|
|
@@ -66,6 +84,7 @@ function QueryCursor(query, options) {
|
|
|
66
84
|
// Max out the number of documents we'll populate in parallel at 5000.
|
|
67
85
|
this.options._populateBatchSize = Math.min(this.options.batchSize, 5000);
|
|
68
86
|
}
|
|
87
|
+
Object.assign(this.options, query._optionsForExec());
|
|
69
88
|
model.collection.find(query._conditions, this.options, (err, cursor) => {
|
|
70
89
|
if (err != null) {
|
|
71
90
|
_this._markError(err);
|
|
@@ -393,6 +412,9 @@ function _next(ctx, cb) {
|
|
|
393
412
|
callback(ctx._error);
|
|
394
413
|
});
|
|
395
414
|
}
|
|
415
|
+
if (ctx.skipped) {
|
|
416
|
+
return immediate(() => callback(null, null));
|
|
417
|
+
}
|
|
396
418
|
|
|
397
419
|
if (ctx.cursor) {
|
|
398
420
|
if (ctx.query._mongooseOptions.populate && !ctx._pop) {
|
|
@@ -448,6 +470,9 @@ function _next(ctx, cb) {
|
|
|
448
470
|
ctx.once('cursor', function(cursor) {
|
|
449
471
|
ctx.removeListener('error', cb);
|
|
450
472
|
if (cursor == null) {
|
|
473
|
+
if (ctx.skipped) {
|
|
474
|
+
return cb(null, null);
|
|
475
|
+
}
|
|
451
476
|
return;
|
|
452
477
|
}
|
|
453
478
|
_next(ctx, cb);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const MongooseError = require('../../error/mongooseError');
|
|
3
4
|
const getDiscriminatorByValue = require('../../helpers/discriminator/getDiscriminatorByValue');
|
|
4
5
|
const applyTimestampsToChildren = require('../update/applyTimestampsToChildren');
|
|
5
6
|
const applyTimestampsToUpdate = require('../update/applyTimestampsToUpdate');
|
|
6
7
|
const cast = require('../../cast');
|
|
7
8
|
const castUpdate = require('../query/castUpdate');
|
|
9
|
+
const { inspect } = require('util');
|
|
8
10
|
const setDefaultsOnInsert = require('../setDefaultsOnInsert');
|
|
9
11
|
|
|
10
12
|
/**
|
|
@@ -212,7 +214,8 @@ module.exports = function castBulkWrite(originalModel, op, options) {
|
|
|
212
214
|
};
|
|
213
215
|
} else {
|
|
214
216
|
return (callback) => {
|
|
215
|
-
|
|
217
|
+
const error = new MongooseError(`Invalid op passed to \`bulkWrite()\`: ${inspect(op)}`);
|
|
218
|
+
callback(error, null);
|
|
216
219
|
};
|
|
217
220
|
}
|
|
218
221
|
};
|
|
@@ -44,11 +44,12 @@ function applyTimestampsToUpdate(now, createdAt, updatedAt, currentUpdate, optio
|
|
|
44
44
|
|
|
45
45
|
if (Array.isArray(updates)) {
|
|
46
46
|
// Update with aggregation pipeline
|
|
47
|
+
if (updatedAt == null) {
|
|
48
|
+
return updates;
|
|
49
|
+
}
|
|
47
50
|
updates.push({ $set: { [updatedAt]: now } });
|
|
48
|
-
|
|
49
51
|
return updates;
|
|
50
52
|
}
|
|
51
|
-
|
|
52
53
|
updates.$set = updates.$set || {};
|
|
53
54
|
if (!skipUpdatedAt && updatedAt &&
|
|
54
55
|
(!currentUpdate.$currentDate || !currentUpdate.$currentDate[updatedAt])) {
|
package/lib/query.js
CHANGED
|
@@ -3289,19 +3289,15 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3289
3289
|
throw this.error();
|
|
3290
3290
|
}
|
|
3291
3291
|
|
|
3292
|
-
this._applyPaths();
|
|
3293
|
-
this._fields = this._castFields(this._fields);
|
|
3294
3292
|
applyGlobalMaxTimeMS(this.options, this.model);
|
|
3295
3293
|
applyGlobalDiskUse(this.options, this.model);
|
|
3296
3294
|
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
if ('strict' in opts) {
|
|
3301
|
-
this._mongooseOptions.strict = opts.strict;
|
|
3295
|
+
if ('strict' in this.options) {
|
|
3296
|
+
this._mongooseOptions.strict = this.options.strict;
|
|
3302
3297
|
}
|
|
3303
|
-
const options =
|
|
3298
|
+
const options = this._optionsForExec(this.model);
|
|
3304
3299
|
convertNewToReturnDocument(options);
|
|
3300
|
+
this._applyTranslateAliases(options);
|
|
3305
3301
|
|
|
3306
3302
|
this._update = this._castUpdate(this._update, false);
|
|
3307
3303
|
|
|
@@ -3312,7 +3308,7 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3312
3308
|
this._update, _opts);
|
|
3313
3309
|
|
|
3314
3310
|
if (!this._update || Object.keys(this._update).length === 0) {
|
|
3315
|
-
if (
|
|
3311
|
+
if (options.upsert) {
|
|
3316
3312
|
// still need to do the upsert to empty doc
|
|
3317
3313
|
const doc = clone(this._update);
|
|
3318
3314
|
delete doc._id;
|
|
@@ -3488,18 +3484,8 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
|
|
|
3488
3484
|
}
|
|
3489
3485
|
|
|
3490
3486
|
const filter = this._conditions;
|
|
3491
|
-
const options = this._optionsForExec();
|
|
3487
|
+
const options = this._optionsForExec(this.model);
|
|
3492
3488
|
this._applyTranslateAliases(options);
|
|
3493
|
-
let fields = null;
|
|
3494
|
-
|
|
3495
|
-
this._applyPaths();
|
|
3496
|
-
if (this._fields != null) {
|
|
3497
|
-
options.projection = this._castFields(clone(this._fields));
|
|
3498
|
-
fields = options.projection;
|
|
3499
|
-
if (fields instanceof Error) {
|
|
3500
|
-
throw fields;
|
|
3501
|
-
}
|
|
3502
|
-
}
|
|
3503
3489
|
|
|
3504
3490
|
let res = await this._collection.collection.findOneAndDelete(filter, options);
|
|
3505
3491
|
for (const fn of this._transforms) {
|
|
@@ -5021,6 +5007,7 @@ Query.prototype.cursor = function cursor(opts) {
|
|
|
5021
5007
|
}
|
|
5022
5008
|
|
|
5023
5009
|
const options = this._optionsForExec();
|
|
5010
|
+
|
|
5024
5011
|
try {
|
|
5025
5012
|
this.cast(this.model);
|
|
5026
5013
|
} catch (err) {
|
package/lib/schema/array.js
CHANGED
|
@@ -359,7 +359,11 @@ SchemaArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
359
359
|
options = options || emptyOpts;
|
|
360
360
|
|
|
361
361
|
let rawValue = utils.isMongooseArray(value) ? value.__array : value;
|
|
362
|
-
|
|
362
|
+
let path = options.path || this.path;
|
|
363
|
+
if (options.arrayPathIndex != null) {
|
|
364
|
+
path += '.' + options.arrayPathIndex;
|
|
365
|
+
}
|
|
366
|
+
value = MongooseArray(rawValue, path, doc, this);
|
|
363
367
|
rawValue = value.__array;
|
|
364
368
|
|
|
365
369
|
if (init && doc != null && doc.$__ != null && doc.$populated(this.path)) {
|
package/lib/schematype.js
CHANGED
|
@@ -822,10 +822,12 @@ SchemaType.prototype.get = function(fn) {
|
|
|
822
822
|
*
|
|
823
823
|
* #### Error message templates:
|
|
824
824
|
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
825
|
+
* Below is a list of supported template keywords:
|
|
826
|
+
*
|
|
827
|
+
* - PATH: The schema path where the error is being triggered.
|
|
828
|
+
* - VALUE: The value assigned to the PATH that is triggering the error.
|
|
829
|
+
* - KIND: The validation property that triggered the error i.e. required.
|
|
830
|
+
* - REASON: The error object that caused this error if there was one.
|
|
829
831
|
*
|
|
830
832
|
* If Mongoose's built-in error message templating isn't enough, Mongoose
|
|
831
833
|
* supports setting the `message` property to a function.
|