mongoose 8.10.0 → 8.10.2
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 +1 -1
- package/lib/connection.js +34 -23
- package/lib/document.js +5 -8
- package/lib/drivers/browser/index.js +1 -0
- package/lib/drivers/node-mongodb-native/bulkWriteResult.js +5 -0
- package/lib/drivers/node-mongodb-native/collection.js +5 -1
- package/lib/drivers/node-mongodb-native/index.js +1 -0
- package/lib/helpers/clone.js +1 -1
- package/lib/helpers/getDefaultBulkwriteResult.js +11 -20
- package/lib/helpers/model/decorateBulkWriteResult.js +8 -0
- package/lib/helpers/query/castUpdate.js +10 -0
- package/lib/model.js +33 -16
- package/lib/query.js +33 -23
- package/lib/schema/map.js +1 -8
- package/lib/schema.js +3 -0
- package/package.json +1 -1
- package/types/index.d.ts +57 -51
- package/types/inferschematype.d.ts +8 -4
- package/types/models.d.ts +1 -1
- package/types/schematypes.d.ts +12 -12
- package/types/validation.d.ts +6 -1
package/lib/connection.js
CHANGED
|
@@ -23,6 +23,7 @@ const CreateCollectionsError = require('./error/createCollectionsError');
|
|
|
23
23
|
const castBulkWrite = require('./helpers/model/castBulkWrite');
|
|
24
24
|
const { modelSymbol } = require('./helpers/symbols');
|
|
25
25
|
const isPromise = require('./helpers/isPromise');
|
|
26
|
+
const decorateBulkWriteResult = require('./helpers/model/decorateBulkWriteResult');
|
|
26
27
|
|
|
27
28
|
const arrayAtomicsSymbol = require('./helpers/symbols').arrayAtomicsSymbol;
|
|
28
29
|
const sessionNewDocuments = require('./helpers/symbols').sessionNewDocuments;
|
|
@@ -559,7 +560,9 @@ Connection.prototype.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
559
560
|
'bulkWrite'
|
|
560
561
|
);
|
|
561
562
|
}
|
|
562
|
-
|
|
563
|
+
const BulkWriteResult = this.base.driver.get().BulkWriteResult;
|
|
564
|
+
const res = new BulkWriteResult(getDefaultBulkwriteResult(), false);
|
|
565
|
+
return decorateBulkWriteResult(res, validationErrors, results);
|
|
563
566
|
}
|
|
564
567
|
|
|
565
568
|
let error;
|
|
@@ -567,16 +570,17 @@ Connection.prototype.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
567
570
|
then(res => ([res, null])).
|
|
568
571
|
catch(err => ([null, err]));
|
|
569
572
|
|
|
573
|
+
for (let i = 0; i < validOpIndexes.length; ++i) {
|
|
574
|
+
results[validOpIndexes[i]] = null;
|
|
575
|
+
}
|
|
570
576
|
if (error) {
|
|
571
577
|
if (validationErrors.length > 0) {
|
|
578
|
+
decorateBulkWriteResult(error, validationErrors, results);
|
|
572
579
|
error.mongoose = error.mongoose || {};
|
|
573
580
|
error.mongoose.validationErrors = validationErrors;
|
|
574
581
|
}
|
|
575
582
|
}
|
|
576
583
|
|
|
577
|
-
for (let i = 0; i < validOpIndexes.length; ++i) {
|
|
578
|
-
results[validOpIndexes[i]] = null;
|
|
579
|
-
}
|
|
580
584
|
if (validationErrors.length > 0) {
|
|
581
585
|
if (options.throwOnValidationError) {
|
|
582
586
|
throw new MongooseBulkWriteError(
|
|
@@ -586,9 +590,7 @@ Connection.prototype.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
586
590
|
'bulkWrite'
|
|
587
591
|
);
|
|
588
592
|
} else {
|
|
589
|
-
res
|
|
590
|
-
res.mongoose.validationErrors = validationErrors;
|
|
591
|
-
res.mongoose.results = results;
|
|
593
|
+
decorateBulkWriteResult(res, validationErrors, results);
|
|
592
594
|
}
|
|
593
595
|
}
|
|
594
596
|
}
|
|
@@ -818,32 +820,41 @@ Connection.prototype.dropCollection = async function dropCollection(collection)
|
|
|
818
820
|
/**
|
|
819
821
|
* Waits for connection to be established, so the connection has a `client`
|
|
820
822
|
*
|
|
823
|
+
* @param {Boolean} [noTimeout=false] if set, don't put a timeout on the operation. Used internally so `mongoose.model()` doesn't leave open handles.
|
|
821
824
|
* @return Promise
|
|
822
825
|
* @api private
|
|
823
826
|
*/
|
|
824
827
|
|
|
825
|
-
Connection.prototype._waitForConnect = async function _waitForConnect() {
|
|
828
|
+
Connection.prototype._waitForConnect = async function _waitForConnect(noTimeout) {
|
|
826
829
|
if ((this.readyState === STATES.connecting || this.readyState === STATES.disconnected) && this._shouldBufferCommands()) {
|
|
827
830
|
const bufferTimeoutMS = this._getBufferTimeoutMS();
|
|
828
831
|
let timeout = null;
|
|
829
832
|
let timedOut = false;
|
|
830
833
|
// The element that this function pushes onto `_queue`, stored to make it easy to remove later
|
|
831
834
|
const queueElement = {};
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
835
|
+
|
|
836
|
+
// Mongoose executes all elements in `_queue` when initial connection succeeds in `onOpen()`.
|
|
837
|
+
const waitForConnectPromise = new Promise(resolve => {
|
|
838
|
+
queueElement.fn = resolve;
|
|
839
|
+
this._queue.push(queueElement);
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
if (noTimeout) {
|
|
843
|
+
await waitForConnectPromise;
|
|
844
|
+
} else {
|
|
845
|
+
await Promise.race([
|
|
846
|
+
waitForConnectPromise,
|
|
847
|
+
new Promise(resolve => {
|
|
848
|
+
timeout = setTimeout(
|
|
849
|
+
() => {
|
|
850
|
+
timedOut = true;
|
|
851
|
+
resolve();
|
|
852
|
+
},
|
|
853
|
+
bufferTimeoutMS
|
|
854
|
+
);
|
|
855
|
+
})
|
|
856
|
+
]);
|
|
857
|
+
}
|
|
847
858
|
|
|
848
859
|
if (timedOut) {
|
|
849
860
|
const index = this._queue.indexOf(queueElement);
|
package/lib/document.js
CHANGED
|
@@ -741,15 +741,10 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
741
741
|
let schemaType;
|
|
742
742
|
let path;
|
|
743
743
|
let i;
|
|
744
|
-
let index = 0;
|
|
745
744
|
const strict = self.$__.strictMode;
|
|
746
745
|
const docSchema = self.$__schema;
|
|
747
746
|
|
|
748
|
-
|
|
749
|
-
_init(index++);
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
function _init(index) {
|
|
747
|
+
for (let index = 0; index < len; ++index) {
|
|
753
748
|
i = keys[index];
|
|
754
749
|
// avoid prototype pollution
|
|
755
750
|
if (i === '__proto__' || i === 'constructor') {
|
|
@@ -3558,8 +3553,10 @@ Document.prototype.$__undoReset = function $__undoReset() {
|
|
|
3558
3553
|
}
|
|
3559
3554
|
}
|
|
3560
3555
|
|
|
3561
|
-
|
|
3562
|
-
subdoc.$
|
|
3556
|
+
if (!this.$isSubdocument) {
|
|
3557
|
+
for (const subdoc of this.$getAllSubdocs()) {
|
|
3558
|
+
subdoc.$__undoReset();
|
|
3559
|
+
}
|
|
3563
3560
|
}
|
|
3564
3561
|
};
|
|
3565
3562
|
|
|
@@ -13,6 +13,8 @@ const internalToObjectOptions = require('../../options').internalToObjectOptions
|
|
|
13
13
|
const stream = require('stream');
|
|
14
14
|
const util = require('util');
|
|
15
15
|
|
|
16
|
+
const formatToObjectOptions = Object.freeze({ ...internalToObjectOptions, copyTrustedSymbol: false });
|
|
17
|
+
|
|
16
18
|
/**
|
|
17
19
|
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
|
|
18
20
|
*
|
|
@@ -384,7 +386,9 @@ function format(obj, sub, color, shell) {
|
|
|
384
386
|
}
|
|
385
387
|
|
|
386
388
|
const clone = require('../../helpers/clone');
|
|
387
|
-
|
|
389
|
+
// `sub` indicates `format()` was called recursively, so skip cloning because we already
|
|
390
|
+
// did a deep clone on the top-level object.
|
|
391
|
+
let x = sub ? obj : clone(obj, formatToObjectOptions);
|
|
388
392
|
const constructorName = getConstructorName(x);
|
|
389
393
|
|
|
390
394
|
if (constructorName === 'Binary') {
|
package/lib/helpers/clone.js
CHANGED
|
@@ -147,7 +147,7 @@ function cloneObject(obj, options, isArrayChild) {
|
|
|
147
147
|
} else if (seen) {
|
|
148
148
|
seen.set(obj, ret);
|
|
149
149
|
}
|
|
150
|
-
if (trustedSymbol in obj) {
|
|
150
|
+
if (trustedSymbol in obj && options?.copyTrustedSymbol !== false) {
|
|
151
151
|
ret[trustedSymbol] = obj[trustedSymbol];
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
|
|
2
3
|
function getDefaultBulkwriteResult() {
|
|
3
4
|
return {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
upserted: []
|
|
15
|
-
},
|
|
16
|
-
insertedCount: 0,
|
|
17
|
-
matchedCount: 0,
|
|
18
|
-
modifiedCount: 0,
|
|
19
|
-
deletedCount: 0,
|
|
20
|
-
upsertedCount: 0,
|
|
21
|
-
upsertedIds: {},
|
|
22
|
-
insertedIds: {},
|
|
23
|
-
n: 0
|
|
5
|
+
ok: 1,
|
|
6
|
+
nInserted: 0,
|
|
7
|
+
nUpserted: 0,
|
|
8
|
+
nMatched: 0,
|
|
9
|
+
nModified: 0,
|
|
10
|
+
nRemoved: 0,
|
|
11
|
+
upserted: [],
|
|
12
|
+
writeErrors: [],
|
|
13
|
+
insertedIds: [],
|
|
14
|
+
writeConcernErrors: []
|
|
24
15
|
};
|
|
25
16
|
}
|
|
26
17
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function decorateBulkWriteResult(resultOrError, validationErrors, results) {
|
|
4
|
+
resultOrError.mongoose = resultOrError.mongoose || {};
|
|
5
|
+
resultOrError.mongoose.validationErrors = validationErrors;
|
|
6
|
+
resultOrError.mongoose.results = results;
|
|
7
|
+
return resultOrError;
|
|
8
|
+
};
|
|
@@ -82,6 +82,16 @@ module.exports = function castUpdate(schema, obj, options, context, filter) {
|
|
|
82
82
|
schema = schema.discriminators[discriminatorValue] ||
|
|
83
83
|
(byValue && byValue.schema) ||
|
|
84
84
|
schema;
|
|
85
|
+
} else if (schema != null &&
|
|
86
|
+
options.overwriteDiscriminatorKey &&
|
|
87
|
+
obj.$set != null &&
|
|
88
|
+
utils.hasUserDefinedProperty(obj.$set, schema.options.discriminatorKey) &&
|
|
89
|
+
schema.discriminators != null) {
|
|
90
|
+
const discriminatorValue = obj.$set[schema.options.discriminatorKey];
|
|
91
|
+
const byValue = getDiscriminatorByValue(context.model.discriminators, discriminatorValue);
|
|
92
|
+
schema = schema.discriminators[discriminatorValue] ||
|
|
93
|
+
(byValue && byValue.schema) ||
|
|
94
|
+
schema;
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
if (options.upsert) {
|
package/lib/model.js
CHANGED
|
@@ -10,7 +10,6 @@ const Document = require('./document');
|
|
|
10
10
|
const DocumentNotFoundError = require('./error/notFound');
|
|
11
11
|
const EventEmitter = require('events').EventEmitter;
|
|
12
12
|
const Kareem = require('kareem');
|
|
13
|
-
const { MongoBulkWriteError } = require('mongodb');
|
|
14
13
|
const MongooseBulkWriteError = require('./error/bulkWriteError');
|
|
15
14
|
const MongooseError = require('./error/index');
|
|
16
15
|
const ObjectParameterError = require('./error/objectParameter');
|
|
@@ -69,6 +68,7 @@ const utils = require('./utils');
|
|
|
69
68
|
const minimize = require('./helpers/minimize');
|
|
70
69
|
const MongooseBulkSaveIncompleteError = require('./error/bulkSaveIncompleteError');
|
|
71
70
|
const ObjectExpectedError = require('./error/objectExpected');
|
|
71
|
+
const decorateBulkWriteResult = require('./helpers/model/decorateBulkWriteResult');
|
|
72
72
|
|
|
73
73
|
const modelCollectionSymbol = Symbol('mongoose#Model#collection');
|
|
74
74
|
const modelDbSymbol = Symbol('mongoose#Model#db');
|
|
@@ -1103,16 +1103,28 @@ Model.init = function init() {
|
|
|
1103
1103
|
return results;
|
|
1104
1104
|
};
|
|
1105
1105
|
const _createCollection = async() => {
|
|
1106
|
-
|
|
1107
|
-
const autoCreate = utils.getOption(
|
|
1106
|
+
let autoCreate = utils.getOption(
|
|
1108
1107
|
'autoCreate',
|
|
1109
1108
|
this.schema.options,
|
|
1110
|
-
conn.config
|
|
1111
|
-
|
|
1109
|
+
conn.config
|
|
1110
|
+
// No base.options here because we don't want to take the base value if the connection hasn't
|
|
1111
|
+
// set it yet
|
|
1112
1112
|
);
|
|
1113
|
+
if (autoCreate == null) {
|
|
1114
|
+
// `autoCreate` may later be set when the connection is opened, so wait for connect before checking
|
|
1115
|
+
await conn._waitForConnect(true);
|
|
1116
|
+
autoCreate = utils.getOption(
|
|
1117
|
+
'autoCreate',
|
|
1118
|
+
this.schema.options,
|
|
1119
|
+
conn.config,
|
|
1120
|
+
conn.base.options
|
|
1121
|
+
);
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1113
1124
|
if (!autoCreate) {
|
|
1114
1125
|
return;
|
|
1115
1126
|
}
|
|
1127
|
+
|
|
1116
1128
|
return await this.createCollection();
|
|
1117
1129
|
};
|
|
1118
1130
|
|
|
@@ -3387,7 +3399,11 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
3387
3399
|
const ordered = options.ordered == null ? true : options.ordered;
|
|
3388
3400
|
|
|
3389
3401
|
if (ops.length === 0) {
|
|
3390
|
-
|
|
3402
|
+
const BulkWriteResult = this.base.driver.get().BulkWriteResult;
|
|
3403
|
+
const bulkWriteResult = new BulkWriteResult(getDefaultBulkwriteResult(), false);
|
|
3404
|
+
bulkWriteResult.n = 0;
|
|
3405
|
+
decorateBulkWriteResult(bulkWriteResult, [], []);
|
|
3406
|
+
return bulkWriteResult;
|
|
3391
3407
|
}
|
|
3392
3408
|
|
|
3393
3409
|
const validations = ops.map(op => castBulkWrite(this, op, options));
|
|
@@ -3458,7 +3474,11 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
3458
3474
|
'bulkWrite'
|
|
3459
3475
|
);
|
|
3460
3476
|
}
|
|
3461
|
-
|
|
3477
|
+
const BulkWriteResult = this.base.driver.get().BulkWriteResult;
|
|
3478
|
+
const bulkWriteResult = new BulkWriteResult(getDefaultBulkwriteResult(), false);
|
|
3479
|
+
bulkWriteResult.result = getDefaultBulkwriteResult();
|
|
3480
|
+
decorateBulkWriteResult(bulkWriteResult, validationErrors, results);
|
|
3481
|
+
return bulkWriteResult;
|
|
3462
3482
|
}
|
|
3463
3483
|
|
|
3464
3484
|
let error;
|
|
@@ -3466,10 +3486,12 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
3466
3486
|
then(res => ([res, null])).
|
|
3467
3487
|
catch(error => ([null, error]));
|
|
3468
3488
|
|
|
3489
|
+
for (let i = 0; i < validOpIndexes.length; ++i) {
|
|
3490
|
+
results[validOpIndexes[i]] = null;
|
|
3491
|
+
}
|
|
3469
3492
|
if (error) {
|
|
3470
3493
|
if (validationErrors.length > 0) {
|
|
3471
|
-
error
|
|
3472
|
-
error.mongoose.validationErrors = validationErrors;
|
|
3494
|
+
decorateBulkWriteResult(error, validationErrors, results);
|
|
3473
3495
|
}
|
|
3474
3496
|
|
|
3475
3497
|
await new Promise((resolve, reject) => {
|
|
@@ -3483,9 +3505,6 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
3483
3505
|
});
|
|
3484
3506
|
}
|
|
3485
3507
|
|
|
3486
|
-
for (let i = 0; i < validOpIndexes.length; ++i) {
|
|
3487
|
-
results[validOpIndexes[i]] = null;
|
|
3488
|
-
}
|
|
3489
3508
|
if (validationErrors.length > 0) {
|
|
3490
3509
|
if (options.throwOnValidationError) {
|
|
3491
3510
|
throw new MongooseBulkWriteError(
|
|
@@ -3495,9 +3514,7 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
|
|
|
3495
3514
|
'bulkWrite'
|
|
3496
3515
|
);
|
|
3497
3516
|
} else {
|
|
3498
|
-
res
|
|
3499
|
-
res.mongoose.validationErrors = validationErrors;
|
|
3500
|
-
res.mongoose.results = results;
|
|
3517
|
+
decorateBulkWriteResult(res, validationErrors, results);
|
|
3501
3518
|
}
|
|
3502
3519
|
}
|
|
3503
3520
|
}
|
|
@@ -3563,7 +3580,7 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3563
3580
|
(err) => ({ bulkWriteResult: null, bulkWriteError: err })
|
|
3564
3581
|
);
|
|
3565
3582
|
// If not a MongoBulkWriteError, treat this as all documents failed to save.
|
|
3566
|
-
if (bulkWriteError != null &&
|
|
3583
|
+
if (bulkWriteError != null && bulkWriteError.name !== 'MongoBulkWriteError') {
|
|
3567
3584
|
throw bulkWriteError;
|
|
3568
3585
|
}
|
|
3569
3586
|
|
package/lib/query.js
CHANGED
|
@@ -65,6 +65,25 @@ const queryOptionMethods = new Set([
|
|
|
65
65
|
'wtimeout'
|
|
66
66
|
]);
|
|
67
67
|
|
|
68
|
+
// Map from operation name to the name of the function that executes the actual operation against MongoDB.
|
|
69
|
+
// Called a thunk for legacy reasons, "thunk" means function that takes exactly 1 param, a callback.
|
|
70
|
+
// Currently `_countDocuments()`, etc. are async functions that take no params.
|
|
71
|
+
const opToThunk = new Map([
|
|
72
|
+
['countDocuments', '_countDocuments'],
|
|
73
|
+
['distinct', '__distinct'],
|
|
74
|
+
['estimatedDocumentCount', '_estimatedDocumentCount'],
|
|
75
|
+
['find', '_find'],
|
|
76
|
+
['findOne', '_findOne'],
|
|
77
|
+
['findOneAndReplace', '_findOneAndReplace'],
|
|
78
|
+
['findOneAndUpdate', '_findOneAndUpdate'],
|
|
79
|
+
['replaceOne', '_replaceOne'],
|
|
80
|
+
['updateMany', '_updateMany'],
|
|
81
|
+
['updateOne', '_updateOne'],
|
|
82
|
+
['deleteMany', '_deleteMany'],
|
|
83
|
+
['deleteOne', '_deleteOne'],
|
|
84
|
+
['findOneAndDelete', '_findOneAndDelete']
|
|
85
|
+
]);
|
|
86
|
+
|
|
68
87
|
/**
|
|
69
88
|
* Query constructor used for building queries. You do not need
|
|
70
89
|
* to instantiate a `Query` directly. Instead use Model functions like
|
|
@@ -2337,18 +2356,17 @@ Query.prototype._find = async function _find() {
|
|
|
2337
2356
|
}
|
|
2338
2357
|
|
|
2339
2358
|
const mongooseOptions = this._mongooseOptions;
|
|
2340
|
-
const
|
|
2341
|
-
const userProvidedFields = _this._userProvidedFields || {};
|
|
2359
|
+
const userProvidedFields = this._userProvidedFields || {};
|
|
2342
2360
|
|
|
2343
2361
|
applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
|
|
2344
2362
|
applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
|
|
2345
2363
|
|
|
2346
2364
|
// Separate options to pass down to `completeMany()` in case we need to
|
|
2347
2365
|
// set a session on the document
|
|
2348
|
-
const completeManyOptions =
|
|
2366
|
+
const completeManyOptions = {
|
|
2349
2367
|
session: this && this.options && this.options.session || null,
|
|
2350
2368
|
lean: mongooseOptions.lean || null
|
|
2351
|
-
}
|
|
2369
|
+
};
|
|
2352
2370
|
|
|
2353
2371
|
const options = this._optionsForExec();
|
|
2354
2372
|
|
|
@@ -2366,7 +2384,7 @@ Query.prototype._find = async function _find() {
|
|
|
2366
2384
|
}
|
|
2367
2385
|
|
|
2368
2386
|
if (!mongooseOptions.populate) {
|
|
2369
|
-
const versionKey =
|
|
2387
|
+
const versionKey = this.schema.options.versionKey;
|
|
2370
2388
|
if (mongooseOptions.lean && mongooseOptions.lean.versionKey === false && versionKey) {
|
|
2371
2389
|
docs.forEach((doc) => {
|
|
2372
2390
|
if (versionKey in doc) {
|
|
@@ -2375,17 +2393,17 @@ Query.prototype._find = async function _find() {
|
|
|
2375
2393
|
});
|
|
2376
2394
|
}
|
|
2377
2395
|
return mongooseOptions.lean ?
|
|
2378
|
-
_completeManyLean(
|
|
2379
|
-
|
|
2396
|
+
_completeManyLean(this.model.schema, docs, null, completeManyOptions) :
|
|
2397
|
+
this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
|
|
2380
2398
|
}
|
|
2381
2399
|
|
|
2382
|
-
const pop = helpers.preparePopulationOptionsMQ(
|
|
2400
|
+
const pop = helpers.preparePopulationOptionsMQ(this, mongooseOptions);
|
|
2383
2401
|
|
|
2384
2402
|
if (mongooseOptions.lean) {
|
|
2385
|
-
return
|
|
2403
|
+
return this.model.populate(docs, pop);
|
|
2386
2404
|
}
|
|
2387
2405
|
|
|
2388
|
-
docs = await
|
|
2406
|
+
docs = await this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
|
|
2389
2407
|
await this.model.populate(docs, pop);
|
|
2390
2408
|
|
|
2391
2409
|
return docs;
|
|
@@ -4397,22 +4415,14 @@ Query.prototype.exec = async function exec(op) {
|
|
|
4397
4415
|
if (this.model == null) {
|
|
4398
4416
|
throw new MongooseError('Query must have an associated model before executing');
|
|
4399
4417
|
}
|
|
4400
|
-
this._validateOp();
|
|
4401
|
-
|
|
4402
|
-
if (!this.op) {
|
|
4403
|
-
return;
|
|
4404
|
-
}
|
|
4405
4418
|
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
throw new Error('Invalid field "" passed to sort()');
|
|
4410
|
-
}
|
|
4419
|
+
const thunk = opToThunk.get(this.op);
|
|
4420
|
+
if (!thunk) {
|
|
4421
|
+
throw new MongooseError('Query has invalid `op`: "' + this.op + '"');
|
|
4411
4422
|
}
|
|
4412
4423
|
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
thunk = '__distinct';
|
|
4424
|
+
if (this.options && this.options.sort && typeof this.options.sort === 'object' && this.options.sort.hasOwnProperty('')) {
|
|
4425
|
+
throw new Error('Invalid field "" passed to sort()');
|
|
4416
4426
|
}
|
|
4417
4427
|
|
|
4418
4428
|
if (this._executionStack != null) {
|
package/lib/schema/map.js
CHANGED
|
@@ -91,14 +91,7 @@ class SchemaMap extends SchemaType {
|
|
|
91
91
|
|
|
92
92
|
const isRequired = this.options.required && typeof this.options.required !== 'function';
|
|
93
93
|
const result = createJSONSchemaTypeDefinition('object', 'object', useBsonType, isRequired);
|
|
94
|
-
|
|
95
|
-
if (embeddedSchemaType.schema) {
|
|
96
|
-
result.additionalProperties = useBsonType
|
|
97
|
-
? { ...embeddedSchemaType.toJSONSchema(options) }
|
|
98
|
-
: { ...embeddedSchemaType.toJSONSchema(options) };
|
|
99
|
-
} else {
|
|
100
|
-
result.additionalProperties = embeddedSchemaType.toJSONSchema(options);
|
|
101
|
-
}
|
|
94
|
+
result.additionalProperties = embeddedSchemaType.toJSONSchema(options);
|
|
102
95
|
|
|
103
96
|
return result;
|
|
104
97
|
}
|
package/lib/schema.js
CHANGED
|
@@ -1118,6 +1118,9 @@ Schema.prototype.path = function(path, obj) {
|
|
|
1118
1118
|
this.paths[path] = this.interpretAsType(path, obj, this.options);
|
|
1119
1119
|
const schemaType = this.paths[path];
|
|
1120
1120
|
|
|
1121
|
+
// If overwriting an existing path, make sure to clear the childSchemas
|
|
1122
|
+
this.childSchemas = this.childSchemas.filter(childSchema => childSchema.path !== path);
|
|
1123
|
+
|
|
1121
1124
|
if (schemaType.$isSchemaMap) {
|
|
1122
1125
|
// Maps can have arbitrary keys, so `$*` is internal shorthand for "any key"
|
|
1123
1126
|
// The '$' is to imply this path should never be stored in MongoDB so we
|