mongoose 6.1.9 → 6.2.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/.eslintrc.json +154 -0
- package/CHANGELOG.md +59 -0
- package/dist/browser.umd.js +233 -222
- package/index.js +5 -1
- package/lib/aggregate.js +23 -28
- package/lib/browserDocument.js +1 -1
- package/lib/cast/number.js +2 -3
- package/lib/cast.js +9 -7
- package/lib/connection.js +76 -24
- package/lib/cursor/AggregationCursor.js +12 -7
- package/lib/cursor/QueryCursor.js +11 -6
- package/lib/document.js +107 -107
- package/lib/drivers/node-mongodb-native/collection.js +12 -4
- package/lib/drivers/node-mongodb-native/connection.js +11 -0
- package/lib/error/cast.js +3 -2
- package/lib/error/index.js +11 -0
- package/lib/error/syncIndexes.js +30 -0
- package/lib/helpers/clone.js +51 -29
- package/lib/helpers/common.js +2 -2
- package/lib/helpers/cursor/eachAsync.js +18 -15
- package/lib/helpers/document/compile.js +7 -4
- package/lib/helpers/getFunctionName.js +6 -4
- package/lib/helpers/isMongooseObject.js +9 -8
- package/lib/helpers/isObject.js +4 -4
- package/lib/helpers/model/discriminator.js +2 -1
- package/lib/helpers/path/parentPaths.js +10 -5
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +4 -2
- package/lib/helpers/populate/assignVals.js +8 -4
- package/lib/helpers/populate/getModelsMapForPopulate.js +4 -4
- package/lib/helpers/populate/markArraySubdocsPopulated.js +3 -1
- package/lib/helpers/populate/modelNamesFromRefPath.js +4 -3
- package/lib/helpers/printJestWarning.js +2 -2
- package/lib/helpers/projection/applyProjection.js +77 -0
- package/lib/helpers/projection/hasIncludedChildren.js +36 -0
- package/lib/helpers/projection/isExclusive.js +5 -2
- package/lib/helpers/projection/isInclusive.js +5 -1
- package/lib/helpers/query/cast$expr.js +279 -0
- package/lib/helpers/query/castUpdate.js +6 -2
- package/lib/helpers/query/isOperator.js +5 -2
- package/lib/helpers/schema/applyPlugins.js +11 -0
- package/lib/helpers/schema/getPath.js +4 -2
- package/lib/helpers/timestamps/setupTimestamps.js +3 -8
- package/lib/index.js +28 -26
- package/lib/internal.js +1 -1
- package/lib/model.js +161 -122
- package/lib/options/SchemaTypeOptions.js +1 -1
- package/lib/plugins/trackTransaction.js +5 -4
- package/lib/query.js +159 -146
- package/lib/queryhelpers.js +10 -10
- package/lib/schema/SubdocumentPath.js +4 -3
- package/lib/schema/array.js +30 -21
- package/lib/schema/buffer.js +1 -1
- package/lib/schema/date.js +1 -1
- package/lib/schema/decimal128.js +1 -1
- package/lib/schema/documentarray.js +9 -11
- package/lib/schema/number.js +1 -1
- package/lib/schema/objectid.js +2 -2
- package/lib/schema/string.js +4 -4
- package/lib/schema.js +9 -8
- package/lib/schematype.js +77 -30
- package/lib/types/ArraySubdocument.js +2 -1
- package/lib/types/DocumentArray/index.js +10 -27
- package/lib/types/DocumentArray/isMongooseDocumentArray.js +5 -0
- package/lib/types/DocumentArray/methods/index.js +15 -3
- package/lib/types/array/index.js +22 -21
- package/lib/types/array/isMongooseArray.js +5 -0
- package/lib/types/array/methods/index.js +22 -23
- package/lib/types/buffer.js +3 -3
- package/lib/types/map.js +2 -3
- package/lib/utils.js +10 -7
- package/package.json +19 -151
- package/tools/repl.js +1 -1
- package/tsconfig.json +8 -0
- package/types/PipelineStage.d.ts +272 -0
- package/{index.d.ts → types/index.d.ts} +156 -357
- package/lib/types/array/ArrayWrapper.js +0 -981
package/index.js
CHANGED
package/lib/aggregate.js
CHANGED
|
@@ -39,11 +39,11 @@ const readConcern = Query.prototype.readConcern;
|
|
|
39
39
|
* ```javascript
|
|
40
40
|
* new Aggregate([{ $match: { _id: '00000000000000000000000a' } }]);
|
|
41
41
|
* // Do this instead to cast to an ObjectId
|
|
42
|
-
* new Aggregate([{ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } }]);
|
|
42
|
+
* new Aggregate([{ $match: { _id: new mongoose.Types.ObjectId('00000000000000000000000a') } }]);
|
|
43
43
|
* ```
|
|
44
44
|
*
|
|
45
|
-
* @see MongoDB
|
|
46
|
-
* @see driver
|
|
45
|
+
* @see MongoDB https://docs.mongodb.org/manual/applications/aggregation/
|
|
46
|
+
* @see driver https://mongodb.github.com/node-mongodb-native/api-generated/collection.html#aggregate
|
|
47
47
|
* @param {Array} [pipeline] aggregation pipeline as an array of objects
|
|
48
48
|
* @param {Model} [model] the model to use with this aggregate.
|
|
49
49
|
* @api public
|
|
@@ -174,15 +174,10 @@ Aggregate.prototype.append = function() {
|
|
|
174
174
|
* @api public
|
|
175
175
|
*/
|
|
176
176
|
Aggregate.prototype.addFields = function(arg) {
|
|
177
|
-
|
|
178
|
-
if (typeof arg === 'object' && !Array.isArray(arg)) {
|
|
179
|
-
Object.keys(arg).forEach(function(field) {
|
|
180
|
-
fields[field] = arg[field];
|
|
181
|
-
});
|
|
182
|
-
} else {
|
|
177
|
+
if (typeof arg !== 'object' || arg === null || Array.isArray(arg)) {
|
|
183
178
|
throw new Error('Invalid addFields() argument. Must be an object');
|
|
184
179
|
}
|
|
185
|
-
return this.append({ $addFields:
|
|
180
|
+
return this.append({ $addFields: Object.assign({}, arg) });
|
|
186
181
|
};
|
|
187
182
|
|
|
188
183
|
/**
|
|
@@ -212,7 +207,7 @@ Aggregate.prototype.addFields = function(arg) {
|
|
|
212
207
|
* aggregate.project({ salary_k: { $divide: [ "$salary", 1000 ] } });
|
|
213
208
|
*
|
|
214
209
|
* @param {Object|String} arg field specification
|
|
215
|
-
* @see projection
|
|
210
|
+
* @see projection https://docs.mongodb.org/manual/reference/aggregation/project/
|
|
216
211
|
* @return {Aggregate}
|
|
217
212
|
* @api public
|
|
218
213
|
*/
|
|
@@ -249,7 +244,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
249
244
|
*
|
|
250
245
|
* aggregate.group({ _id: "$department" });
|
|
251
246
|
*
|
|
252
|
-
* @see $group
|
|
247
|
+
* @see $group https://docs.mongodb.org/manual/reference/aggregation/group/
|
|
253
248
|
* @method group
|
|
254
249
|
* @memberOf Aggregate
|
|
255
250
|
* @instance
|
|
@@ -265,7 +260,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
265
260
|
*
|
|
266
261
|
* aggregate.match({ department: { $in: [ "sales", "engineering" ] } });
|
|
267
262
|
*
|
|
268
|
-
* @see $match
|
|
263
|
+
* @see $match https://docs.mongodb.org/manual/reference/aggregation/match/
|
|
269
264
|
* @method match
|
|
270
265
|
* @memberOf Aggregate
|
|
271
266
|
* @instance
|
|
@@ -281,7 +276,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
281
276
|
*
|
|
282
277
|
* aggregate.skip(10);
|
|
283
278
|
*
|
|
284
|
-
* @see $skip
|
|
279
|
+
* @see $skip https://docs.mongodb.org/manual/reference/aggregation/skip/
|
|
285
280
|
* @method skip
|
|
286
281
|
* @memberOf Aggregate
|
|
287
282
|
* @instance
|
|
@@ -297,7 +292,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
297
292
|
*
|
|
298
293
|
* aggregate.limit(10);
|
|
299
294
|
*
|
|
300
|
-
* @see $limit
|
|
295
|
+
* @see $limit https://docs.mongodb.org/manual/reference/aggregation/limit/
|
|
301
296
|
* @method limit
|
|
302
297
|
* @memberOf Aggregate
|
|
303
298
|
* @instance
|
|
@@ -325,7 +320,7 @@ Aggregate.prototype.project = function(arg) {
|
|
|
325
320
|
* num: 5
|
|
326
321
|
* });
|
|
327
322
|
*
|
|
328
|
-
* @see $geoNear
|
|
323
|
+
* @see $geoNear https://docs.mongodb.org/manual/reference/aggregation/geoNear/
|
|
329
324
|
* @method near
|
|
330
325
|
* @memberOf Aggregate
|
|
331
326
|
* @instance
|
|
@@ -364,7 +359,7 @@ Aggregate.prototype.near = function(arg) {
|
|
|
364
359
|
* aggregate.unwind("a", "b", "c");
|
|
365
360
|
* aggregate.unwind({ path: '$tags', preserveNullAndEmptyArrays: true });
|
|
366
361
|
*
|
|
367
|
-
* @see $unwind
|
|
362
|
+
* @see $unwind https://docs.mongodb.org/manual/reference/aggregation/unwind/
|
|
368
363
|
* @param {String|Object} fields the field(s) to unwind, either as field names or as [objects with options](https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/#document-operand-with-options). If passing a string, prefixing the field name with '$' is optional. If passing an object, `path` must start with '$'.
|
|
369
364
|
* @return {Aggregate}
|
|
370
365
|
* @api public
|
|
@@ -554,7 +549,7 @@ Aggregate.prototype.sample = function(size) {
|
|
|
554
549
|
* aggregate.sort({ field: 'asc', test: -1 });
|
|
555
550
|
* aggregate.sort('field -test');
|
|
556
551
|
*
|
|
557
|
-
* @see $sort
|
|
552
|
+
* @see $sort https://docs.mongodb.org/manual/reference/aggregation/sort/
|
|
558
553
|
* @param {Object|String} arg
|
|
559
554
|
* @return {Aggregate} this
|
|
560
555
|
* @api public
|
|
@@ -621,8 +616,8 @@ Aggregate.prototype.unionWith = function(options) {
|
|
|
621
616
|
* @param {Array} [tags] optional tags for this query
|
|
622
617
|
* @return {Aggregate} this
|
|
623
618
|
* @api public
|
|
624
|
-
* @see mongodb
|
|
625
|
-
* @see driver
|
|
619
|
+
* @see mongodb https://docs.mongodb.org/manual/applications/replication/#read-preference
|
|
620
|
+
* @see driver https://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences
|
|
626
621
|
*/
|
|
627
622
|
|
|
628
623
|
Aggregate.prototype.read = function(pref, tags) {
|
|
@@ -779,7 +774,7 @@ Aggregate.prototype.explain = function(verbosity, callback) {
|
|
|
779
774
|
*
|
|
780
775
|
* @param {Boolean} value Should tell server it can use hard drive to store data during aggregation.
|
|
781
776
|
* @param {Array} [tags] optional tags for this query
|
|
782
|
-
* @see mongodb
|
|
777
|
+
* @see mongodb https://docs.mongodb.org/manual/reference/command/aggregate/
|
|
783
778
|
*/
|
|
784
779
|
|
|
785
780
|
Aggregate.prototype.allowDiskUse = function(value) {
|
|
@@ -795,7 +790,7 @@ Aggregate.prototype.allowDiskUse = function(value) {
|
|
|
795
790
|
* Model.aggregate(..).hint({ qty: 1, category: 1 }).exec(callback)
|
|
796
791
|
*
|
|
797
792
|
* @param {Object|String} value a hint object or the index name
|
|
798
|
-
* @see mongodb
|
|
793
|
+
* @see mongodb https://docs.mongodb.org/manual/reference/command/aggregate/
|
|
799
794
|
*/
|
|
800
795
|
|
|
801
796
|
Aggregate.prototype.hint = function(value) {
|
|
@@ -812,7 +807,7 @@ Aggregate.prototype.hint = function(value) {
|
|
|
812
807
|
* await Model.aggregate(..).session(session);
|
|
813
808
|
*
|
|
814
809
|
* @param {ClientSession} session
|
|
815
|
-
* @see mongodb
|
|
810
|
+
* @see mongodb https://docs.mongodb.org/manual/reference/command/aggregate/
|
|
816
811
|
*/
|
|
817
812
|
|
|
818
813
|
Aggregate.prototype.session = function(session) {
|
|
@@ -837,7 +832,7 @@ Aggregate.prototype.session = function(session) {
|
|
|
837
832
|
* @param [options.allowDiskUse] boolean if true, the MongoDB server will use the hard drive to store data during this aggregation
|
|
838
833
|
* @param [options.collation] object see [`Aggregate.prototype.collation()`](./docs/api.html#aggregate_Aggregate-collation)
|
|
839
834
|
* @param [options.session] ClientSession see [`Aggregate.prototype.session()`](./docs/api.html#aggregate_Aggregate-session)
|
|
840
|
-
* @see mongodb
|
|
835
|
+
* @see mongodb https://docs.mongodb.org/manual/reference/command/aggregate/
|
|
841
836
|
* @return {Aggregate} this
|
|
842
837
|
* @api public
|
|
843
838
|
*/
|
|
@@ -866,7 +861,7 @@ Aggregate.prototype.option = function(value) {
|
|
|
866
861
|
* @param {Boolean} [options.useMongooseAggCursor] use experimental mongoose-specific aggregation cursor (for `eachAsync()` and other query cursor semantics)
|
|
867
862
|
* @return {AggregationCursor} cursor representing this aggregation
|
|
868
863
|
* @api public
|
|
869
|
-
* @see mongodb
|
|
864
|
+
* @see mongodb https://mongodb.github.io/node-mongodb-native/2.0/api/AggregationCursor.html
|
|
870
865
|
*/
|
|
871
866
|
|
|
872
867
|
Aggregate.prototype.cursor = function(options) {
|
|
@@ -887,7 +882,7 @@ Aggregate.prototype.cursor = function(options) {
|
|
|
887
882
|
* @param {Object} collation options
|
|
888
883
|
* @return {Aggregate} this
|
|
889
884
|
* @api public
|
|
890
|
-
* @see mongodb
|
|
885
|
+
* @see mongodb https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#aggregate
|
|
891
886
|
*/
|
|
892
887
|
|
|
893
888
|
Aggregate.prototype.collation = function(collation) {
|
|
@@ -1105,13 +1100,13 @@ if (Symbol.asyncIterator != null) {
|
|
|
1105
1100
|
*/
|
|
1106
1101
|
|
|
1107
1102
|
function isOperator(obj) {
|
|
1108
|
-
if (typeof obj !== 'object') {
|
|
1103
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
1109
1104
|
return false;
|
|
1110
1105
|
}
|
|
1111
1106
|
|
|
1112
1107
|
const k = Object.keys(obj);
|
|
1113
1108
|
|
|
1114
|
-
return k.length === 1 && k
|
|
1109
|
+
return k.length === 1 && k[0][0] === '$';
|
|
1115
1110
|
}
|
|
1116
1111
|
|
|
1117
1112
|
/*!
|
package/lib/browserDocument.js
CHANGED
|
@@ -19,7 +19,7 @@ const isObject = require('./helpers/isObject');
|
|
|
19
19
|
* @param {Object} obj the values to set
|
|
20
20
|
* @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
|
|
21
21
|
* @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
|
|
22
|
-
* @inherits NodeJS EventEmitter
|
|
22
|
+
* @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#events_class_events_eventemitter
|
|
23
23
|
* @event `init`: Emitted on a document after it has was retrieved from the db and fully hydrated by Mongoose.
|
|
24
24
|
* @event `save`: Emitted when the document is successfully saved
|
|
25
25
|
* @api private
|
package/lib/cast/number.js
CHANGED
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
const assert = require('assert');
|
|
4
4
|
|
|
5
5
|
/*!
|
|
6
|
-
* Given a value, cast it to a number, or throw
|
|
6
|
+
* Given a value, cast it to a number, or throw an `Error` if the value
|
|
7
7
|
* cannot be casted. `null` and `undefined` are considered valid.
|
|
8
8
|
*
|
|
9
9
|
* @param {Any} value
|
|
10
|
-
* @
|
|
11
|
-
* @return {Boolean|null|undefined}
|
|
10
|
+
* @return {Number}
|
|
12
11
|
* @throws {Error} if `value` is not one of the allowed values
|
|
13
12
|
* @api private
|
|
14
13
|
*/
|
package/lib/cast.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const CastError = require('./error/cast');
|
|
8
8
|
const StrictModeError = require('./error/strict');
|
|
9
9
|
const Types = require('./schema/index');
|
|
10
|
+
const cast$expr = require('./helpers/query/cast$expr');
|
|
10
11
|
const castTextSearch = require('./schema/operators/text');
|
|
11
12
|
const get = require('./helpers/get');
|
|
12
13
|
const getConstructorName = require('./helpers/getConstructorName');
|
|
@@ -79,9 +80,7 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
79
80
|
|
|
80
81
|
continue;
|
|
81
82
|
} else if (path === '$expr') {
|
|
82
|
-
|
|
83
|
-
throw new Error('`$expr` must be an object');
|
|
84
|
-
}
|
|
83
|
+
val = cast$expr(val, schema);
|
|
85
84
|
continue;
|
|
86
85
|
} else if (path === '$elemMatch') {
|
|
87
86
|
val = cast(schema, val, options, context);
|
|
@@ -103,15 +102,18 @@ module.exports = function cast(schema, obj, options, context) {
|
|
|
103
102
|
const pathFirstHalf = split.slice(0, j).join('.');
|
|
104
103
|
const pathLastHalf = split.slice(j).join('.');
|
|
105
104
|
const _schematype = schema.path(pathFirstHalf);
|
|
106
|
-
const discriminatorKey =
|
|
105
|
+
const discriminatorKey = _schematype &&
|
|
106
|
+
_schematype.schema &&
|
|
107
|
+
_schematype.schema.options &&
|
|
108
|
+
_schematype.schema.options.discriminatorKey;
|
|
107
109
|
|
|
108
110
|
// gh-6027: if we haven't found the schematype but this path is
|
|
109
111
|
// underneath an embedded discriminator and the embedded discriminator
|
|
110
112
|
// key is in the query, use the embedded discriminator schema
|
|
111
113
|
if (_schematype != null &&
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
(_schematype.schema && _schematype.schema.discriminators) != null &&
|
|
115
|
+
discriminatorKey != null &&
|
|
116
|
+
pathLastHalf !== discriminatorKey) {
|
|
115
117
|
const discriminatorVal = get(obj, pathFirstHalf + '.' + discriminatorKey);
|
|
116
118
|
if (discriminatorVal != null) {
|
|
117
119
|
schematype = _schematype.schema.discriminators[discriminatorVal].
|
package/lib/connection.js
CHANGED
|
@@ -10,6 +10,7 @@ const Schema = require('./schema');
|
|
|
10
10
|
const Collection = require('./driver').get().Collection;
|
|
11
11
|
const STATES = require('./connectionstate');
|
|
12
12
|
const MongooseError = require('./error/index');
|
|
13
|
+
const SyncIndexesError = require('./error/syncIndexes');
|
|
13
14
|
const PromiseProvider = require('./promise_provider');
|
|
14
15
|
const ServerSelectionError = require('./error/serverSelection');
|
|
15
16
|
const applyPlugins = require('./helpers/schema/applyPlugins');
|
|
@@ -40,7 +41,7 @@ const noPasswordAuthMechanisms = [
|
|
|
40
41
|
* For practical reasons, a Connection equals a Db.
|
|
41
42
|
*
|
|
42
43
|
* @param {Mongoose} base a mongoose instance
|
|
43
|
-
* @inherits NodeJS EventEmitter
|
|
44
|
+
* @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#events_class_events_eventemitter
|
|
44
45
|
* @event `connecting`: Emitted when `connection.openUri()` is executed on this connection.
|
|
45
46
|
* @event `connected`: Emitted when this connection successfully connects to the db. May be emitted _multiple_ times in `reconnected` scenarios.
|
|
46
47
|
* @event `open`: Emitted after we `connected` and `onOpen` is executed on all of this connection's models.
|
|
@@ -385,11 +386,11 @@ Connection.prototype.config;
|
|
|
385
386
|
* with specified options. Used to create [capped collections](https://docs.mongodb.com/manual/core/capped-collections/)
|
|
386
387
|
* and [views](https://docs.mongodb.com/manual/core/views/) from mongoose.
|
|
387
388
|
*
|
|
388
|
-
* Options are passed down without modification to the [MongoDB driver's `createCollection()` function](
|
|
389
|
+
* Options are passed down without modification to the [MongoDB driver's `createCollection()` function](https://mongodb.github.io/node-mongodb-native/2.2/api/Db.html#createCollection)
|
|
389
390
|
*
|
|
390
391
|
* @method createCollection
|
|
391
392
|
* @param {string} collection The collection to create
|
|
392
|
-
* @param {Object} [options] see [MongoDB driver docs](
|
|
393
|
+
* @param {Object} [options] see [MongoDB driver docs](https://mongodb.github.io/node-mongodb-native/2.2/api/Db.html#createCollection)
|
|
393
394
|
* @param {Function} [callback]
|
|
394
395
|
* @return {Promise}
|
|
395
396
|
* @api public
|
|
@@ -406,7 +407,7 @@ Connection.prototype.createCollection = _wrapConnHelper(function createCollectio
|
|
|
406
407
|
/**
|
|
407
408
|
* _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
|
|
408
409
|
* for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
|
|
409
|
-
* and [transactions](
|
|
410
|
+
* and [transactions](https://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
|
|
410
411
|
*
|
|
411
412
|
* ####Example:
|
|
412
413
|
*
|
|
@@ -421,7 +422,7 @@ Connection.prototype.createCollection = _wrapConnHelper(function createCollectio
|
|
|
421
422
|
*
|
|
422
423
|
*
|
|
423
424
|
* @method startSession
|
|
424
|
-
* @param {Object} [options] see the [mongodb driver options](
|
|
425
|
+
* @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
|
|
425
426
|
* @param {Boolean} [options.causalConsistency=true] set to false to disable causal consistency
|
|
426
427
|
* @param {Function} [callback]
|
|
427
428
|
* @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
|
|
@@ -443,7 +444,7 @@ Connection.prototype.startSession = _wrapConnHelper(function startSession(option
|
|
|
443
444
|
* async function executes successfully and attempt to retry if
|
|
444
445
|
* there was a retriable error.
|
|
445
446
|
*
|
|
446
|
-
* Calls the MongoDB driver's [`session.withTransaction()`](
|
|
447
|
+
* Calls the MongoDB driver's [`session.withTransaction()`](https://mongodb.github.io/node-mongodb-native/3.5/api/ClientSession.html#withTransaction),
|
|
447
448
|
* but also handles resetting Mongoose document state as shown below.
|
|
448
449
|
*
|
|
449
450
|
* ####Example:
|
|
@@ -650,18 +651,18 @@ Connection.prototype.onOpen = function() {
|
|
|
650
651
|
* Opens the connection with a URI using `MongoClient.connect()`.
|
|
651
652
|
*
|
|
652
653
|
* @param {String} uri The URI to connect with.
|
|
653
|
-
* @param {Object} [options] Passed on to
|
|
654
|
-
* @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](
|
|
654
|
+
* @param {Object} [options] Passed on to https://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect
|
|
655
|
+
* @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](https://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
|
|
655
656
|
* @param {Number} [options.bufferTimeoutMS=10000] Mongoose specific option. If `bufferCommands` is true, Mongoose will throw an error after `bufferTimeoutMS` if the operation is still buffered.
|
|
656
657
|
* @param {String} [options.dbName] The name of the database we want to use. If not provided, use database name from connection string.
|
|
657
658
|
* @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
|
|
658
659
|
* @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
|
|
659
|
-
* @param {Number} [options.maxPoolSize=100] The maximum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](
|
|
660
|
-
* @param {Number} [options.minPoolSize=0] The minimum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](
|
|
660
|
+
* @param {Number} [options.maxPoolSize=100] The maximum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](https://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
|
|
661
|
+
* @param {Number} [options.minPoolSize=0] The minimum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](https://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
|
|
661
662
|
* @param {Number} [options.serverSelectionTimeoutMS] If `useUnifiedTopology = true`, the MongoDB driver will try to find a server to send any given operation to, and keep retrying for `serverSelectionTimeoutMS` milliseconds before erroring out. If not set, the MongoDB driver defaults to using `30000` (30 seconds).
|
|
662
663
|
* @param {Number} [options.heartbeatFrequencyMS] If `useUnifiedTopology = true`, the MongoDB driver sends a heartbeat every `heartbeatFrequencyMS` to check on the status of the connection. A heartbeat is subject to `serverSelectionTimeoutMS`, so the MongoDB driver will retry failed heartbeats for up to 30 seconds by default. Mongoose only emits a `'disconnected'` event after a heartbeat has failed, so you may want to decrease this setting to reduce the time between when your server goes down and when Mongoose emits `'disconnected'`. We recommend you do **not** set this setting below 1000, too many heartbeats can lead to performance degradation.
|
|
663
664
|
* @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
|
|
664
|
-
* @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](
|
|
665
|
+
* @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
|
|
665
666
|
* @param {Number} [options.connectTimeoutMS=30000] How long the MongoDB driver will wait before killing a socket due to inactivity _during initial connection_. Defaults to 30000. This option is passed transparently to [Node.js' `socket#setTimeout()` function](https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback).
|
|
666
667
|
* @param {Number} [options.socketTimeoutMS=30000] How long the MongoDB driver will wait before killing a socket due to inactivity _after initial connection_. A socket may be inactive because of either no activity or a long-running operation. This is set to `30000` by default, you should set this to 2-3x your longest running operation if you expect some of your database operations to run longer than 20 seconds. This option is passed to [Node.js `socket#setTimeout()` function](https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback) after the MongoDB driver successfully completes.
|
|
667
668
|
* @param {Number} [options.family=0] Passed transparently to [Node.js' `dns.lookup()`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback) function. May be either `0, `4`, or `6`. `4` means use IPv4 only, `6` means use IPv6 only, `0` means try both.
|
|
@@ -681,7 +682,7 @@ Connection.prototype.openUri = function(uri, options, callback) {
|
|
|
681
682
|
throw new MongooseError('Mongoose 5.x no longer supports ' +
|
|
682
683
|
'`mongoose.connect(host, dbname, port)` or ' +
|
|
683
684
|
'`mongoose.createConnection(host, dbname, port)`. See ' +
|
|
684
|
-
'
|
|
685
|
+
'https://mongoosejs.com/docs/connections.html for supported connection syntax');
|
|
685
686
|
}
|
|
686
687
|
|
|
687
688
|
if (typeof uri !== 'string') {
|
|
@@ -786,6 +787,11 @@ Connection.prototype.openUri = function(uri, options, callback) {
|
|
|
786
787
|
return reject(error);
|
|
787
788
|
}
|
|
788
789
|
_this.client = client;
|
|
790
|
+
|
|
791
|
+
for (const db of this.otherDbs) {
|
|
792
|
+
_setClient(db, client, {}, db.name);
|
|
793
|
+
}
|
|
794
|
+
|
|
789
795
|
client.setMaxListeners(0);
|
|
790
796
|
client.connect((error) => {
|
|
791
797
|
if (error) {
|
|
@@ -831,9 +837,19 @@ function _setClient(conn, client, options, dbName) {
|
|
|
831
837
|
const db = dbName != null ? client.db(dbName) : client.db();
|
|
832
838
|
conn.db = db;
|
|
833
839
|
conn.client = client;
|
|
834
|
-
conn.host =
|
|
835
|
-
|
|
836
|
-
|
|
840
|
+
conn.host = client &&
|
|
841
|
+
client.s &&
|
|
842
|
+
client.s.options &&
|
|
843
|
+
client.s.options.hosts &&
|
|
844
|
+
client.s.options.hosts[0] &&
|
|
845
|
+
client.s.options.hosts[0].host || void 0;
|
|
846
|
+
conn.port = client &&
|
|
847
|
+
client.s &&
|
|
848
|
+
client.s.options &&
|
|
849
|
+
client.s.options.hosts &&
|
|
850
|
+
client.s.options.hosts[0] &&
|
|
851
|
+
client.s.options.hosts[0].port || void 0;
|
|
852
|
+
conn.name = dbName != null ? dbName : client && client.s && client.s.options && client.s.options.dbName || void 0;
|
|
837
853
|
conn._closeCalled = client._closeCalled;
|
|
838
854
|
|
|
839
855
|
const _handleReconnect = () => {
|
|
@@ -849,7 +865,10 @@ function _setClient(conn, client, options, dbName) {
|
|
|
849
865
|
}
|
|
850
866
|
};
|
|
851
867
|
|
|
852
|
-
const type =
|
|
868
|
+
const type = client &&
|
|
869
|
+
client.topology &&
|
|
870
|
+
client.topology.description &&
|
|
871
|
+
client.topology.description.type || '';
|
|
853
872
|
|
|
854
873
|
if (type === 'Single') {
|
|
855
874
|
client.on('serverDescriptionChanged', ev => {
|
|
@@ -897,7 +916,11 @@ Connection.prototype.close = function(force, callback) {
|
|
|
897
916
|
force = false;
|
|
898
917
|
}
|
|
899
918
|
|
|
900
|
-
|
|
919
|
+
if (force != null && typeof force === 'object') {
|
|
920
|
+
this.$wasForceClosed = !!force.force;
|
|
921
|
+
} else {
|
|
922
|
+
this.$wasForceClosed = !!force;
|
|
923
|
+
}
|
|
901
924
|
|
|
902
925
|
return promiseOrCallback(callback, cb => {
|
|
903
926
|
this._close(force, cb);
|
|
@@ -981,7 +1004,7 @@ Connection.prototype.onClose = function(force) {
|
|
|
981
1004
|
this.emit('close', force);
|
|
982
1005
|
|
|
983
1006
|
for (const db of this.otherDbs) {
|
|
984
|
-
db.close(force);
|
|
1007
|
+
db.close({ force: force, skipCloseClient: true });
|
|
985
1008
|
}
|
|
986
1009
|
};
|
|
987
1010
|
|
|
@@ -1330,7 +1353,7 @@ Connection.prototype.optionsProvideAuthenticationData = function(options) {
|
|
|
1330
1353
|
};
|
|
1331
1354
|
|
|
1332
1355
|
/**
|
|
1333
|
-
* Returns the [MongoDB driver `MongoClient`](
|
|
1356
|
+
* Returns the [MongoDB driver `MongoClient`](https://mongodb.github.io/node-mongodb-native/3.5/api/MongoClient.html) instance
|
|
1334
1357
|
* that this connection uses to talk to MongoDB.
|
|
1335
1358
|
*
|
|
1336
1359
|
* ####Example:
|
|
@@ -1347,7 +1370,7 @@ Connection.prototype.getClient = function getClient() {
|
|
|
1347
1370
|
};
|
|
1348
1371
|
|
|
1349
1372
|
/**
|
|
1350
|
-
* Set the [MongoDB driver `MongoClient`](
|
|
1373
|
+
* Set the [MongoDB driver `MongoClient`](https://mongodb.github.io/node-mongodb-native/3.5/api/MongoClient.html) instance
|
|
1351
1374
|
* that this connection uses to talk to MongoDB. This is useful if you already have a MongoClient instance, and want to
|
|
1352
1375
|
* reuse it.
|
|
1353
1376
|
*
|
|
@@ -1375,16 +1398,45 @@ Connection.prototype.setClient = function setClient(client) {
|
|
|
1375
1398
|
}
|
|
1376
1399
|
|
|
1377
1400
|
this._connectionString = client.s.url;
|
|
1378
|
-
_setClient(this, client, {
|
|
1401
|
+
_setClient(this, client, {}, client.s.options.dbName);
|
|
1379
1402
|
|
|
1380
1403
|
return this;
|
|
1381
1404
|
};
|
|
1382
1405
|
|
|
1383
|
-
|
|
1406
|
+
/**
|
|
1407
|
+
*
|
|
1408
|
+
* Syncs all the indexes for the models registered with this connection.
|
|
1409
|
+
*
|
|
1410
|
+
* @param {Object} options
|
|
1411
|
+
* @param {Boolean} options.continueOnError `false` by default. If set to `true`, mongoose will not throw an error if one model syncing failed, and will return an object where the keys are the names of the models, and the values are the results/errors for each model.
|
|
1412
|
+
* @returns
|
|
1413
|
+
*/
|
|
1414
|
+
Connection.prototype.syncIndexes = async function syncIndexes(options = {}) {
|
|
1384
1415
|
const result = {};
|
|
1385
|
-
|
|
1386
|
-
|
|
1416
|
+
const errorsMap = { };
|
|
1417
|
+
|
|
1418
|
+
const { continueOnError } = options;
|
|
1419
|
+
delete options.continueOnError;
|
|
1420
|
+
|
|
1421
|
+
for (const model of Object.values(this.models)) {
|
|
1422
|
+
try {
|
|
1423
|
+
result[model.modelName] = await model.syncIndexes(options);
|
|
1424
|
+
} catch (err) {
|
|
1425
|
+
if (!continueOnError) {
|
|
1426
|
+
errorsMap[model.modelName] = err;
|
|
1427
|
+
break;
|
|
1428
|
+
} else {
|
|
1429
|
+
result[model.modelName] = err;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
if (!continueOnError && Object.keys(errorsMap).length) {
|
|
1435
|
+
const message = Object.entries(errorsMap).map(([modelName, err]) => `${modelName}: ${err.message}`).join(', ');
|
|
1436
|
+
const syncIndexesError = new SyncIndexesError(message, errorsMap);
|
|
1437
|
+
throw syncIndexesError;
|
|
1387
1438
|
}
|
|
1439
|
+
|
|
1388
1440
|
return result;
|
|
1389
1441
|
};
|
|
1390
1442
|
|
|
@@ -97,7 +97,7 @@ AggregationCursor.prototype._read = function() {
|
|
|
97
97
|
|
|
98
98
|
if (Symbol.asyncIterator != null) {
|
|
99
99
|
const msg = 'Mongoose does not support using async iterators with an ' +
|
|
100
|
-
'existing aggregation cursor. See
|
|
100
|
+
'existing aggregation cursor. See https://bit.ly/mongoose-async-iterate-aggregation';
|
|
101
101
|
|
|
102
102
|
AggregationCursor.prototype[Symbol.asyncIterator] = function() {
|
|
103
103
|
throw new MongooseError(msg);
|
|
@@ -137,10 +137,15 @@ if (Symbol.asyncIterator != null) {
|
|
|
137
137
|
* @method map
|
|
138
138
|
*/
|
|
139
139
|
|
|
140
|
-
AggregationCursor.prototype
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
140
|
+
Object.defineProperty(AggregationCursor.prototype, 'map', {
|
|
141
|
+
value: function(fn) {
|
|
142
|
+
this._transforms.push(fn);
|
|
143
|
+
return this;
|
|
144
|
+
},
|
|
145
|
+
enumerable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
writable: true
|
|
148
|
+
});
|
|
144
149
|
|
|
145
150
|
/*!
|
|
146
151
|
* Marks this cursor as errored
|
|
@@ -160,7 +165,7 @@ AggregationCursor.prototype._markError = function(error) {
|
|
|
160
165
|
* @api public
|
|
161
166
|
* @method close
|
|
162
167
|
* @emits close
|
|
163
|
-
* @see MongoDB driver cursor#close
|
|
168
|
+
* @see MongoDB driver cursor#close https://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#close
|
|
164
169
|
*/
|
|
165
170
|
|
|
166
171
|
AggregationCursor.prototype.close = function(callback) {
|
|
@@ -288,7 +293,7 @@ function _transformForAsyncIterator(doc) {
|
|
|
288
293
|
}
|
|
289
294
|
|
|
290
295
|
/**
|
|
291
|
-
* Adds a [cursor flag](
|
|
296
|
+
* Adds a [cursor flag](https://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag).
|
|
292
297
|
* Useful for setting the `noCursorTimeout` and `tailable` flags.
|
|
293
298
|
*
|
|
294
299
|
* @param {String} flag
|
|
@@ -141,10 +141,15 @@ QueryCursor.prototype._read = function() {
|
|
|
141
141
|
* @method map
|
|
142
142
|
*/
|
|
143
143
|
|
|
144
|
-
QueryCursor.prototype
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
Object.defineProperty(QueryCursor.prototype, 'map', {
|
|
145
|
+
value: function(fn) {
|
|
146
|
+
this._transforms.push(fn);
|
|
147
|
+
return this;
|
|
148
|
+
},
|
|
149
|
+
enumerable: true,
|
|
150
|
+
configurable: true,
|
|
151
|
+
writable: true
|
|
152
|
+
});
|
|
148
153
|
|
|
149
154
|
/*!
|
|
150
155
|
* Marks this cursor as errored
|
|
@@ -164,7 +169,7 @@ QueryCursor.prototype._markError = function(error) {
|
|
|
164
169
|
* @api public
|
|
165
170
|
* @method close
|
|
166
171
|
* @emits close
|
|
167
|
-
* @see MongoDB driver cursor#close
|
|
172
|
+
* @see MongoDB driver cursor#close https://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#close
|
|
168
173
|
*/
|
|
169
174
|
|
|
170
175
|
QueryCursor.prototype.close = function(callback) {
|
|
@@ -247,7 +252,7 @@ QueryCursor.prototype.eachAsync = function(fn, opts, callback) {
|
|
|
247
252
|
QueryCursor.prototype.options;
|
|
248
253
|
|
|
249
254
|
/**
|
|
250
|
-
* Adds a [cursor flag](
|
|
255
|
+
* Adds a [cursor flag](https://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag).
|
|
251
256
|
* Useful for setting the `noCursorTimeout` and `tailable` flags.
|
|
252
257
|
*
|
|
253
258
|
* @param {String} flag
|