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.
Files changed (76) hide show
  1. package/.eslintrc.json +154 -0
  2. package/CHANGELOG.md +59 -0
  3. package/dist/browser.umd.js +233 -222
  4. package/index.js +5 -1
  5. package/lib/aggregate.js +23 -28
  6. package/lib/browserDocument.js +1 -1
  7. package/lib/cast/number.js +2 -3
  8. package/lib/cast.js +9 -7
  9. package/lib/connection.js +76 -24
  10. package/lib/cursor/AggregationCursor.js +12 -7
  11. package/lib/cursor/QueryCursor.js +11 -6
  12. package/lib/document.js +107 -107
  13. package/lib/drivers/node-mongodb-native/collection.js +12 -4
  14. package/lib/drivers/node-mongodb-native/connection.js +11 -0
  15. package/lib/error/cast.js +3 -2
  16. package/lib/error/index.js +11 -0
  17. package/lib/error/syncIndexes.js +30 -0
  18. package/lib/helpers/clone.js +51 -29
  19. package/lib/helpers/common.js +2 -2
  20. package/lib/helpers/cursor/eachAsync.js +18 -15
  21. package/lib/helpers/document/compile.js +7 -4
  22. package/lib/helpers/getFunctionName.js +6 -4
  23. package/lib/helpers/isMongooseObject.js +9 -8
  24. package/lib/helpers/isObject.js +4 -4
  25. package/lib/helpers/model/discriminator.js +2 -1
  26. package/lib/helpers/path/parentPaths.js +10 -5
  27. package/lib/helpers/populate/assignRawDocsToIdStructure.js +4 -2
  28. package/lib/helpers/populate/assignVals.js +8 -4
  29. package/lib/helpers/populate/getModelsMapForPopulate.js +4 -4
  30. package/lib/helpers/populate/markArraySubdocsPopulated.js +3 -1
  31. package/lib/helpers/populate/modelNamesFromRefPath.js +4 -3
  32. package/lib/helpers/printJestWarning.js +2 -2
  33. package/lib/helpers/projection/applyProjection.js +77 -0
  34. package/lib/helpers/projection/hasIncludedChildren.js +36 -0
  35. package/lib/helpers/projection/isExclusive.js +5 -2
  36. package/lib/helpers/projection/isInclusive.js +5 -1
  37. package/lib/helpers/query/cast$expr.js +279 -0
  38. package/lib/helpers/query/castUpdate.js +6 -2
  39. package/lib/helpers/query/isOperator.js +5 -2
  40. package/lib/helpers/schema/applyPlugins.js +11 -0
  41. package/lib/helpers/schema/getPath.js +4 -2
  42. package/lib/helpers/timestamps/setupTimestamps.js +3 -8
  43. package/lib/index.js +28 -26
  44. package/lib/internal.js +1 -1
  45. package/lib/model.js +161 -122
  46. package/lib/options/SchemaTypeOptions.js +1 -1
  47. package/lib/plugins/trackTransaction.js +5 -4
  48. package/lib/query.js +159 -146
  49. package/lib/queryhelpers.js +10 -10
  50. package/lib/schema/SubdocumentPath.js +4 -3
  51. package/lib/schema/array.js +30 -21
  52. package/lib/schema/buffer.js +1 -1
  53. package/lib/schema/date.js +1 -1
  54. package/lib/schema/decimal128.js +1 -1
  55. package/lib/schema/documentarray.js +9 -11
  56. package/lib/schema/number.js +1 -1
  57. package/lib/schema/objectid.js +2 -2
  58. package/lib/schema/string.js +4 -4
  59. package/lib/schema.js +9 -8
  60. package/lib/schematype.js +77 -30
  61. package/lib/types/ArraySubdocument.js +2 -1
  62. package/lib/types/DocumentArray/index.js +10 -27
  63. package/lib/types/DocumentArray/isMongooseDocumentArray.js +5 -0
  64. package/lib/types/DocumentArray/methods/index.js +15 -3
  65. package/lib/types/array/index.js +22 -21
  66. package/lib/types/array/isMongooseArray.js +5 -0
  67. package/lib/types/array/methods/index.js +22 -23
  68. package/lib/types/buffer.js +3 -3
  69. package/lib/types/map.js +2 -3
  70. package/lib/utils.js +10 -7
  71. package/package.json +19 -151
  72. package/tools/repl.js +1 -1
  73. package/tsconfig.json +8 -0
  74. package/types/PipelineStage.d.ts +272 -0
  75. package/{index.d.ts → types/index.d.ts} +156 -357
  76. package/lib/types/array/ArrayWrapper.js +0 -981
package/index.js CHANGED
@@ -6,4 +6,8 @@
6
6
 
7
7
  'use strict';
8
8
 
9
- module.exports = require('./lib/');
9
+ const mongoose = require('./lib/');
10
+
11
+ module.exports = mongoose;
12
+ module.exports.default = mongoose;
13
+ module.exports.mongoose = mongoose;
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 http://docs.mongodb.org/manual/applications/aggregation/
46
- * @see driver http://mongodb.github.com/node-mongodb-native/api-generated/collection.html#aggregate
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
- const fields = {};
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: fields });
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 http://docs.mongodb.org/manual/reference/aggregation/project/
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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/reference/aggregation/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 http://docs.mongodb.org/manual/applications/replication/#read-preference
625
- * @see driver http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences
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 http://docs.mongodb.org/manual/reference/command/aggregate/
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 http://docs.mongodb.org/manual/reference/command/aggregate/
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 http://docs.mongodb.org/manual/reference/command/aggregate/
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 http://docs.mongodb.org/manual/reference/command/aggregate/
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 http://mongodb.github.io/node-mongodb-native/2.0/api/AggregationCursor.html
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 http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#aggregate
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.some(key => { return key[0] === '$'; });
1109
+ return k.length === 1 && k[0][0] === '$';
1115
1110
  }
1116
1111
 
1117
1112
  /*!
@@ -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 http://nodejs.org/api/events.html#events_class_events_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
@@ -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 a `CastError` if the value
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
- * @param {String} [path] optional the path to set on the CastError
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
- if (typeof val !== 'object' || val == null) {
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 = get(_schematype, 'schema.options.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
- get(_schematype, 'schema.discriminators') != null &&
113
- discriminatorKey != null &&
114
- pathLastHalf !== discriminatorKey) {
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 http://nodejs.org/api/events.html#events_class_events_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](http://mongodb.github.io/node-mongodb-native/2.2/api/Db.html#createCollection)
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](http://mongodb.github.io/node-mongodb-native/2.2/api/Db.html#createCollection)
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](http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
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](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
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()`](http://mongodb.github.io/node-mongodb-native/3.5/api/ClientSession.html#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 http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect
654
- * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
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](http://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
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](http://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
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](http://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
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
- 'http://mongoosejs.com/docs/connections.html for supported connection syntax');
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 = get(client, 's.options.hosts.0.host', void 0);
835
- conn.port = get(client, 's.options.hosts.0.port', void 0);
836
- conn.name = dbName != null ? dbName : get(client, 's.options.dbName', void 0);
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 = get(client, 'topology.description.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
- this.$wasForceClosed = !!force;
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`](http://mongodb.github.io/node-mongodb-native/3.5/api/MongoClient.html) instance
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`](http://mongodb.github.io/node-mongodb-native/3.5/api/MongoClient.html) instance
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, { useUnifiedTopology: client.s.options.useUnifiedTopology }, client.s.options.dbName);
1401
+ _setClient(this, client, {}, client.s.options.dbName);
1379
1402
 
1380
1403
  return this;
1381
1404
  };
1382
1405
 
1383
- Connection.prototype.syncIndexes = async function syncIndexes() {
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
- for (const model in this.models) {
1386
- result[model] = await this.model(model).syncIndexes();
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 http://bit.ly/mongoose-async-iterate-aggregation';
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.map = function(fn) {
141
- this._transforms.push(fn);
142
- return this;
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 http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#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](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag).
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.map = function(fn) {
145
- this._transforms.push(fn);
146
- return this;
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 http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#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](http://mongodb.github.io/node-mongodb-native/2.2/api/Cursor.html#addCursorFlag).
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