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/lib/document.js CHANGED
@@ -16,6 +16,7 @@ const StrictModeError = require('./error/strict');
16
16
  const ValidationError = require('./error/validation');
17
17
  const ValidatorError = require('./error/validator');
18
18
  const VirtualType = require('./virtualtype');
19
+ const $__hasIncludedChildren = require('./helpers/projection/hasIncludedChildren');
19
20
  const promiseOrCallback = require('./helpers/promiseOrCallback');
20
21
  const cleanModifiedSubpaths = require('./helpers/document/cleanModifiedSubpaths');
21
22
  const compile = require('./helpers/document/compile').compile;
@@ -66,7 +67,7 @@ const specialProperties = utils.specialProperties;
66
67
  * @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
67
68
  * @param {Object} [options] various configuration options for the document
68
69
  * @param {Boolean} [options.defaults=true] if `false`, skip applying default values to this document.
69
- * @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
70
+ * @inherits NodeJS EventEmitter https://nodejs.org/api/events.html#events_class_events_eventemitter
70
71
  * @event `init`: Emitted on a document after it has been retrieved from the db and fully hydrated by Mongoose.
71
72
  * @event `save`: Emitted when the document is successfully saved
72
73
  * @api private
@@ -90,7 +91,7 @@ function Document(obj, fields, skipId, options) {
90
91
  options = arguments[4] || {};
91
92
  }
92
93
 
93
- this.$__ = new InternalCache;
94
+ this.$__ = new InternalCache();
94
95
  this.$isNew = 'isNew' in options ? options.isNew : true;
95
96
 
96
97
  if ('priorDoc' in options) {
@@ -417,33 +418,6 @@ Object.defineProperty(Document.prototype, '$op', {
417
418
  }
418
419
  });
419
420
 
420
- /*!
421
- * ignore
422
- */
423
-
424
- function $__hasIncludedChildren(fields) {
425
- const hasIncludedChildren = {};
426
- const keys = Object.keys(fields);
427
-
428
- for (const key of keys) {
429
- if (key.indexOf('.') === -1) {
430
- hasIncludedChildren[key] = 1;
431
- continue;
432
- }
433
- const parts = key.split('.');
434
- let c = parts[0];
435
-
436
- for (let i = 0; i < parts.length; ++i) {
437
- hasIncludedChildren[c] = 1;
438
- if (i + 1 < parts.length) {
439
- c = c + '.' + parts[i + 1];
440
- }
441
- }
442
- }
443
-
444
- return hasIncludedChildren;
445
- }
446
-
447
421
  /*!
448
422
  * ignore
449
423
  */
@@ -479,7 +453,7 @@ function $__applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSet
479
453
  break;
480
454
  }
481
455
  } else if (exclude === false && fields && !included) {
482
- if (curPath in fields) {
456
+ if (curPath in fields || type.$isSingleNested && hasIncludedChildren[curPath]) {
483
457
  included = true;
484
458
  } else if (!hasIncludedChildren[curPath]) {
485
459
  break;
@@ -795,11 +769,12 @@ function init(self, obj, doc, opts, prefix) {
795
769
 
796
770
  const keys = Object.keys(obj);
797
771
  const len = keys.length;
798
- let schema;
772
+ let schemaType;
799
773
  let path;
800
774
  let i;
801
775
  let index = 0;
802
776
  const strict = self.$__.strictMode;
777
+ const docSchema = self.$__schema;
803
778
 
804
779
  while (index < len) {
805
780
  _init(index++);
@@ -808,25 +783,27 @@ function init(self, obj, doc, opts, prefix) {
808
783
  function _init(index) {
809
784
  i = keys[index];
810
785
  path = prefix + i;
811
- schema = self.$__schema.path(path);
786
+ schemaType = docSchema.path(path);
812
787
 
813
788
  // Should still work if not a model-level discriminator, but should not be
814
789
  // necessary. This is *only* to catch the case where we queried using the
815
790
  // base model and the discriminated model has a projection
816
- if (self.$__schema.$isRootDiscriminator && !self.$__isSelected(path)) {
791
+ if (docSchema.$isRootDiscriminator && !self.$__isSelected(path)) {
817
792
  return;
818
793
  }
819
794
 
820
- if (!schema && utils.isPOJO(obj[i])) {
795
+ if (!schemaType && utils.isPOJO(obj[i])) {
821
796
  // assume nested object
822
797
  if (!doc[i]) {
823
798
  doc[i] = {};
799
+ if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
800
+ self[i] = doc[i];
801
+ }
824
802
  }
825
803
  init(self, obj[i], doc[i], opts, path + '.');
826
- } else if (!schema) {
804
+ } else if (!schemaType) {
827
805
  doc[i] = obj[i];
828
- if (!strict && !prefix) {
829
- // Set top-level properties that aren't in the schema if strict is false
806
+ if (!strict) {
830
807
  self[i] = obj[i];
831
808
  }
832
809
  } else {
@@ -835,13 +812,13 @@ function init(self, obj, doc, opts, prefix) {
835
812
  delete doc[i];
836
813
  }
837
814
  if (obj[i] === null) {
838
- doc[i] = schema._castNullish(null);
815
+ doc[i] = schemaType._castNullish(null);
839
816
  } else if (obj[i] !== undefined) {
840
817
  const wasPopulated = obj[i].$__ == null ? null : obj[i].$__.wasPopulated;
841
818
 
842
- if (schema && !wasPopulated) {
819
+ if (schemaType && !wasPopulated) {
843
820
  try {
844
- doc[i] = schema.cast(obj[i], self, true);
821
+ doc[i] = schemaType.cast(obj[i], self, true);
845
822
  } catch (e) {
846
823
  self.invalidate(e.path, new ValidatorError({
847
824
  path: e.path,
@@ -911,9 +888,9 @@ Document.prototype.update = function update() {
911
888
  *
912
889
  * @see Model.updateOne #model_Model.updateOne
913
890
  * @param {Object} doc
914
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
891
+ * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api.html#query_Query-setOptions)
915
892
  * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](/docs/api.html#query_Query-lean) and the [Mongoose lean tutorial](/docs/tutorials/lean.html).
916
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](http://mongoosejs.com/docs/guide.html#strict)
893
+ * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
917
894
  * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
918
895
  * @param {Function} callback
919
896
  * @return {Query}
@@ -1116,7 +1093,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1116
1093
 
1117
1094
  // `_skipMinimizeTopLevel` is because we may have deleted the top-level
1118
1095
  // nested key to ensure key order.
1119
- const _skipMinimizeTopLevel = get(options, '_skipMinimizeTopLevel', false);
1096
+ const _skipMinimizeTopLevel = options._skipMinimizeTopLevel || false;
1120
1097
  if (len === 0 && _skipMinimizeTopLevel) {
1121
1098
  delete options._skipMinimizeTopLevel;
1122
1099
  if (val) {
@@ -1135,7 +1112,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1135
1112
  // them to ensure we keep the user's key order.
1136
1113
  if (type === true &&
1137
1114
  !prefix &&
1138
- path[key] != null &&
1115
+ valForKey != null &&
1139
1116
  pathtype === 'nested' &&
1140
1117
  this._doc[key] != null) {
1141
1118
  delete this._doc[key];
@@ -1260,7 +1237,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1260
1237
  const parts = path.indexOf('.') === -1 ? [path] : path.split('.');
1261
1238
 
1262
1239
  // Might need to change path for top-level alias
1263
- if (typeof this.$__schema.aliases[parts[0]] == 'string') {
1240
+ if (typeof this.$__schema.aliases[parts[0]] === 'string') {
1264
1241
  parts[0] = this.$__schema.aliases[parts[0]];
1265
1242
  }
1266
1243
 
@@ -1313,7 +1290,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1313
1290
  let curPath = '';
1314
1291
  for (i = 0; i < parts.length - 1; ++i) {
1315
1292
  cur = cur[parts[i]];
1316
- curPath += (curPath.length > 0 ? '.' : '') + parts[i];
1293
+ curPath += (curPath.length !== 0 ? '.' : '') + parts[i];
1317
1294
  if (!cur) {
1318
1295
  this.$set(curPath, {});
1319
1296
  // Hack re: gh-5800. If nested field is not selected, it probably exists
@@ -1336,7 +1313,8 @@ Document.prototype.$set = function $set(path, val, type, options) {
1336
1313
  if (parts.length <= 1) {
1337
1314
  pathToMark = path;
1338
1315
  } else {
1339
- for (i = 0; i < parts.length; ++i) {
1316
+ const len = parts.length;
1317
+ for (i = 0; i < len; ++i) {
1340
1318
  const subpath = parts.slice(0, i + 1).join('.');
1341
1319
  if (this.$get(subpath, null, { getters: false }) === null) {
1342
1320
  pathToMark = subpath;
@@ -1361,7 +1339,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1361
1339
  _markValidSubpaths(this, path);
1362
1340
  }
1363
1341
 
1364
- if (schema.$isSingleNested && val != null && merge) {
1342
+ if (val != null && merge && schema.$isSingleNested) {
1365
1343
  if (val instanceof Document) {
1366
1344
  val = val.toObject({ virtuals: false, transform: false });
1367
1345
  }
@@ -1431,9 +1409,10 @@ Document.prototype.$set = function $set(path, val, type, options) {
1431
1409
  val = schema.applySetters(val, this, false, priorVal);
1432
1410
  }
1433
1411
 
1434
- if (schema.$isMongooseDocumentArray &&
1435
- Array.isArray(val) &&
1436
- val.length > 0 &&
1412
+ if (Array.isArray(val) &&
1413
+ !Array.isArray(schema) &&
1414
+ schema.$isMongooseDocumentArray &&
1415
+ val.length !== 0 &&
1437
1416
  val[0] != null &&
1438
1417
  val[0].$__ != null &&
1439
1418
  val[0].$__.populated != null) {
@@ -1459,7 +1438,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1459
1438
  delete this.$__.populated[path];
1460
1439
  }
1461
1440
 
1462
- if (schema.$isSingleNested && val != null) {
1441
+ if (val != null && schema.$isSingleNested) {
1463
1442
  _checkImmutableSubpaths(val, schema, priorVal);
1464
1443
  }
1465
1444
 
@@ -1652,11 +1631,11 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
1652
1631
 
1653
1632
  // handle directly setting arrays (gh-1126)
1654
1633
  MongooseArray || (MongooseArray = require('./types/array'));
1655
- if (val && val.isMongooseArray) {
1634
+ if (val && utils.isMongooseArray(val)) {
1656
1635
  val._registerAtomic('$set', val);
1657
1636
 
1658
1637
  // Update embedded document parent references (gh-5189)
1659
- if (val.isMongooseDocumentArray) {
1638
+ if (utils.isMongooseDocumentArray(val)) {
1660
1639
  val.forEach(function(item) {
1661
1640
  item && item.__parentArray && (item.__parentArray = val);
1662
1641
  });
@@ -1670,10 +1649,10 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
1670
1649
  }
1671
1650
  });
1672
1651
  }
1673
- } else if (Array.isArray(val) && val.isMongooseArray && Array.isArray(priorVal) && priorVal.isMongooseArray) {
1652
+ } else if (Array.isArray(val) && Array.isArray(priorVal) && utils.isMongooseArray(val) && utils.isMongooseArray(priorVal)) {
1674
1653
  val[arrayAtomicsSymbol] = priorVal[arrayAtomicsSymbol];
1675
1654
  val[arrayAtomicsBackupSymbol] = priorVal[arrayAtomicsBackupSymbol];
1676
- if (val.isMongooseDocumentArray) {
1655
+ if (utils.isMongooseDocumentArray(val)) {
1677
1656
  val.forEach(doc => { doc.isNew = false; });
1678
1657
  }
1679
1658
  }
@@ -1702,7 +1681,7 @@ Document.prototype.$__set = function(pathToMark, path, options, constructing, pa
1702
1681
  obj = obj[parts[i]];
1703
1682
  } else if (obj[parts[i]] && obj[parts[i]] instanceof Embedded) {
1704
1683
  obj = obj[parts[i]];
1705
- } else if (obj[parts[i]] && obj[parts[i]].$isSingleNested) {
1684
+ } else if (obj[parts[i]] && !Array.isArray(obj[parts[i]]) && obj[parts[i]].$isSingleNested) {
1706
1685
  obj = obj[parts[i]];
1707
1686
  } else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
1708
1687
  obj = obj[parts[i]];
@@ -1782,7 +1761,7 @@ Document.prototype.get = function(path, type, options) {
1782
1761
  }
1783
1762
 
1784
1763
  // Might need to change path for top-level alias
1785
- if (typeof this.$__schema.aliases[pieces[0]] == 'string') {
1764
+ if (typeof this.$__schema.aliases[pieces[0]] === 'string') {
1786
1765
  pieces[0] = this.$__schema.aliases[pieces[0]];
1787
1766
  }
1788
1767
 
@@ -1963,7 +1942,7 @@ Document.prototype.$isEmpty = function(path) {
1963
1942
  transform: false
1964
1943
  };
1965
1944
 
1966
- if (arguments.length > 0) {
1945
+ if (arguments.length !== 0) {
1967
1946
  const v = this.$get(path);
1968
1947
  if (v == null) {
1969
1948
  return true;
@@ -2006,51 +1985,60 @@ function _isEmpty(v) {
2006
1985
 
2007
1986
  Document.prototype.modifiedPaths = function(options) {
2008
1987
  options = options || {};
1988
+
2009
1989
  const directModifiedPaths = Object.keys(this.$__.activePaths.states.modify);
2010
- const _this = this;
2011
- return directModifiedPaths.reduce(function(list, path) {
2012
- const parts = path.split('.');
2013
- list = list.concat(parts.reduce(function(chains, part, i) {
2014
- return chains.concat(parts.slice(0, i).concat(part).join('.'));
2015
- }, []).filter(function(chain) {
2016
- return (list.indexOf(chain) === -1);
2017
- }));
1990
+ const result = new Set();
1991
+
1992
+ let i = 0;
1993
+ let j = 0;
1994
+ const len = directModifiedPaths.length;
1995
+
1996
+ for (i = 0; i < len; ++i) {
1997
+ const path = directModifiedPaths[i];
1998
+ const parts = parentPaths(path);
1999
+ const pLen = parts.length;
2000
+
2001
+ for (j = 0; j < pLen; ++j) {
2002
+ result.add(parts[j]);
2003
+ }
2018
2004
 
2019
2005
  if (!options.includeChildren) {
2020
- return list;
2006
+ continue;
2021
2007
  }
2022
2008
 
2023
- let cur = _this.$get(path);
2024
- if (cur != null && typeof cur === 'object') {
2009
+ let ii = 0;
2010
+ let cur = this.$get(path);
2011
+ if (typeof cur === 'object' && cur !== null) {
2025
2012
  if (cur._doc) {
2026
2013
  cur = cur._doc;
2027
2014
  }
2015
+ const len = cur.length;
2028
2016
  if (Array.isArray(cur)) {
2029
- const len = cur.length;
2030
- for (let i = 0; i < len; ++i) {
2031
- if (list.indexOf(path + '.' + i) === -1) {
2032
- list.push(path + '.' + i);
2033
- if (cur[i] != null && cur[i].$__) {
2034
- const modified = cur[i].modifiedPaths();
2035
- for (const childPath of modified) {
2036
- list.push(path + '.' + i + '.' + childPath);
2017
+ for (ii = 0; ii < len; ++ii) {
2018
+ const subPath = path + '.' + ii;
2019
+ if (!result.has(subPath)) {
2020
+ result.add(subPath);
2021
+ if (cur[ii] != null && cur[ii].$__) {
2022
+ const modified = cur[ii].modifiedPaths();
2023
+ let iii = 0;
2024
+ const iiiLen = modified.length;
2025
+ for (iii = 0; iii < iiiLen; ++iii) {
2026
+ result.add(subPath + '.' + modified[iii]);
2037
2027
  }
2038
2028
  }
2039
2029
  }
2040
2030
  }
2041
2031
  } else {
2042
- Object.keys(cur).
2043
- filter(function(key) {
2044
- return list.indexOf(path + '.' + key) === -1;
2045
- }).
2046
- forEach(function(key) {
2047
- list.push(path + '.' + key);
2048
- });
2032
+ const keys = Object.keys(cur);
2033
+ let ii = 0;
2034
+ const len = keys.length;
2035
+ for (ii = 0; ii < len; ++ii) {
2036
+ result.add(path + '.' + keys[ii]);
2037
+ }
2049
2038
  }
2050
2039
  }
2051
-
2052
- return list;
2053
- }, []);
2040
+ }
2041
+ return Array.from(result);
2054
2042
  };
2055
2043
 
2056
2044
  Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
@@ -2448,7 +2436,12 @@ Document.prototype.$validate = Document.prototype.validate;
2448
2436
  */
2449
2437
 
2450
2438
  function _evaluateRequiredFunctions(doc) {
2451
- Object.keys(doc.$__.activePaths.states.require).forEach(path => {
2439
+ const requiredFields = Object.keys(doc.$__.activePaths.states.require);
2440
+ let i = 0;
2441
+ const len = requiredFields.length;
2442
+ for (i = 0; i < len; ++i) {
2443
+ const path = requiredFields[i];
2444
+
2452
2445
  const p = doc.$__schema.path(path);
2453
2446
 
2454
2447
  if (p != null && typeof p.originalRequiredValue === 'function') {
@@ -2459,7 +2452,7 @@ function _evaluateRequiredFunctions(doc) {
2459
2452
  doc.invalidate(path, err);
2460
2453
  }
2461
2454
  }
2462
- });
2455
+ }
2463
2456
  }
2464
2457
 
2465
2458
  /*!
@@ -2520,7 +2513,9 @@ function _getPathsToValidate(doc) {
2520
2513
  // To avoid potential performance issues, skip doc arrays whose children
2521
2514
  // are not required. `getPositionalPathType()` may be slow, so avoid
2522
2515
  // it unless we have a case of #6364
2523
- (_pathType.$isMongooseDocumentArray && !get(_pathType, 'schemaOptions.required'))) {
2516
+ (!Array.isArray(_pathType) &&
2517
+ _pathType.$isMongooseDocumentArray &&
2518
+ !(_pathType && _pathType.schemaOptions && _pathType.schemaOptions.required))) {
2524
2519
  continue;
2525
2520
  }
2526
2521
 
@@ -2597,7 +2592,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2597
2592
  (typeof options === 'object') &&
2598
2593
  ('validateModifiedOnly' in options);
2599
2594
 
2600
- const pathsToSkip = get(options, 'pathsToSkip', null);
2595
+ const pathsToSkip = (options && options.pathsToSkip) || null;
2601
2596
 
2602
2597
  let shouldValidateModifiedOnly;
2603
2598
  if (hasValidateModifiedOnlyOption) {
@@ -3047,7 +3042,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
3047
3042
  *
3048
3043
  * @param {Object} [options] options optional options
3049
3044
  * @param {Session} [options.session=null] the [session](https://docs.mongodb.com/manual/reference/server-sessions/) associated with this save operation. If not specified, defaults to the [document's associated session](api.html#document_Document-$session).
3050
- * @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](http://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
3045
+ * @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](https://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
3051
3046
  * @param {Boolean} [options.validateBeforeSave] set to false to save without validating.
3052
3047
  * @param {Boolean} [options.validateModifiedOnly=false] If `true`, Mongoose will only validate modified paths, as opposed to modified paths and `required` paths.
3053
3048
  * @param {Number|String} [options.w] set the [write concern](https://docs.mongodb.com/manual/reference/write-concern/#w-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
@@ -3062,7 +3057,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
3062
3057
  * @throws {DocumentNotFoundError} if this [save updates an existing document](api.html#document_Document-isNew) but the document doesn't exist in the database. For example, you will get this error if the document is [deleted between when you retrieved the document and when you saved it](documents.html#updating).
3063
3058
  * @return {Promise|undefined} Returns undefined if used with callback or a Promise otherwise.
3064
3059
  * @api public
3065
- * @see middleware http://mongoosejs.com/docs/middleware.html
3060
+ * @see middleware https://mongoosejs.com/docs/middleware.html
3066
3061
  */
3067
3062
 
3068
3063
  /**
@@ -3112,7 +3107,7 @@ Document.prototype.$__reset = function reset() {
3112
3107
  return _this.$__getValue(i);
3113
3108
  })
3114
3109
  .filter(function(val) {
3115
- return val && val instanceof Array && val.isMongooseDocumentArray && val.length;
3110
+ return val && Array.isArray(val) && utils.isMongooseDocumentArray(val) && val.length;
3116
3111
  })
3117
3112
  .forEach(function(array) {
3118
3113
  let i = array.length;
@@ -3135,7 +3130,7 @@ Document.prototype.$__reset = function reset() {
3135
3130
  return _this.$__getValue(i);
3136
3131
  }).
3137
3132
  filter(function(val) {
3138
- return val && val.$isSingleNested;
3133
+ return val && !Array.isArray(val) && val.$isSingleNested;
3139
3134
  }).
3140
3135
  forEach(function(doc) {
3141
3136
  doc.$__reset();
@@ -3315,7 +3310,7 @@ Document.prototype.$__getArrayPathsToValidate = function() {
3315
3310
  return this.$__getValue(i);
3316
3311
  }.bind(this))
3317
3312
  .filter(function(val) {
3318
- return val && val instanceof Array && val.isMongooseDocumentArray && val.length;
3313
+ return val && Array.isArray(val) && utils.isMongooseDocumentArray(val) && val.length;
3319
3314
  }).reduce(function(seed, array) {
3320
3315
  return seed.concat(array);
3321
3316
  }, [])
@@ -3357,12 +3352,12 @@ Document.prototype.$getAllSubdocs = function() {
3357
3352
  seed = Array.from(val.keys()).reduce(function(seed, path) {
3358
3353
  return docReducer(val.get(path), seed, null);
3359
3354
  }, seed);
3360
- } else if (val && val.$isSingleNested) {
3355
+ } else if (val && !Array.isArray(val) && val.$isSingleNested) {
3361
3356
  seed = Object.keys(val._doc).reduce(function(seed, path) {
3362
3357
  return docReducer(val._doc, seed, path);
3363
3358
  }, seed);
3364
3359
  seed.push(val);
3365
- } else if (val && val.isMongooseDocumentArray) {
3360
+ } else if (val && utils.isMongooseDocumentArray(val)) {
3366
3361
  val.forEach(function _docReduce(doc) {
3367
3362
  if (!doc || !doc._doc) {
3368
3363
  return;
@@ -3436,8 +3431,11 @@ Document.prototype.$toObject = function(options, json) {
3436
3431
  };
3437
3432
 
3438
3433
  const path = json ? 'toJSON' : 'toObject';
3439
- const baseOptions = get(this, 'constructor.base.options.' + path, {});
3440
- const schemaOptions = get(this, '$__schema.options', {});
3434
+ const baseOptions = this.constructor &&
3435
+ this.constructor.base &&
3436
+ this.constructor.base.options &&
3437
+ get(this.constructor.base.options, path) || {};
3438
+ const schemaOptions = this.$__schema && this.$__schema.options || {};
3441
3439
  // merge base default options with Schema's set default options if available.
3442
3440
  // `clone` is necessary here because `utils.options` directly modifies the second input.
3443
3441
  defaultOptions = utils.options(defaultOptions, clone(baseOptions));
@@ -3484,7 +3482,7 @@ Document.prototype.$toObject = function(options, json) {
3484
3482
  }
3485
3483
 
3486
3484
  const depopulate = options.depopulate ||
3487
- get(options, '_parentOptions.depopulate', false);
3485
+ (options._parentOptions && options._parentOptions.depopulate || false);
3488
3486
  // _isNested will only be true if this is not the top level document, we
3489
3487
  // should never depopulate
3490
3488
  if (depopulate && options._isNested && this.$__.wasPopulated) {
@@ -3564,7 +3562,7 @@ Document.prototype.$toObject = function(options, json) {
3564
3562
  /**
3565
3563
  * Converts this document into a plain-old JavaScript object ([POJO](https://masteringjs.io/tutorials/fundamentals/pojo)).
3566
3564
  *
3567
- * Buffers are converted to instances of [mongodb.Binary](http://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html) for proper storage.
3565
+ * Buffers are converted to instances of [mongodb.Binary](https://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html) for proper storage.
3568
3566
  *
3569
3567
  * ####Options:
3570
3568
  *
@@ -3703,7 +3701,7 @@ Document.prototype.$toObject = function(options, json) {
3703
3701
  * @param {Boolean} [options.flattenMaps=false] if true, convert Maps to POJOs. Useful if you want to `JSON.stringify()` the result of `toObject()`.
3704
3702
  * @param {Boolean} [options.useProjection=false] - If true, omits fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
3705
3703
  * @return {Object} js object
3706
- * @see mongodb.Binary http://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html
3704
+ * @see mongodb.Binary https://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html
3707
3705
  * @api public
3708
3706
  * @memberOf Document
3709
3707
  * @instance
@@ -3761,7 +3759,9 @@ function applyVirtuals(self, json, options, toObjectOptions) {
3761
3759
  let assignPath;
3762
3760
  let cur = self._doc;
3763
3761
  let v;
3764
- const aliases = get(toObjectOptions, 'aliases', true);
3762
+ const aliases = typeof (toObjectOptions && toObjectOptions.aliases) === 'boolean'
3763
+ ? toObjectOptions.aliases
3764
+ : true;
3765
3765
 
3766
3766
  let virtualsToApply = null;
3767
3767
  if (Array.isArray(options.virtuals)) {
@@ -4139,7 +4139,7 @@ Document.prototype.populate = function populate() {
4139
4139
  const args = [...arguments];
4140
4140
  let fn;
4141
4141
 
4142
- if (args.length > 0) {
4142
+ if (args.length !== 0) {
4143
4143
  if (typeof args[args.length - 1] === 'function') {
4144
4144
  fn = args.pop();
4145
4145
  }
@@ -4298,7 +4298,7 @@ Document.prototype.depopulate = function(path) {
4298
4298
 
4299
4299
  let populatedIds;
4300
4300
  const virtualKeys = this.$$populatedVirtuals ? Object.keys(this.$$populatedVirtuals) : [];
4301
- const populated = get(this, '$__.populated', {});
4301
+ const populated = this.$__ && this.$__.populated || {};
4302
4302
 
4303
4303
  if (arguments.length === 0) {
4304
4304
  // Depopulate all
@@ -8,7 +8,6 @@ const MongooseCollection = require('../../collection');
8
8
  const MongooseError = require('../../error/mongooseError');
9
9
  const Collection = require('mongodb').Collection;
10
10
  const ObjectId = require('./objectid');
11
- const get = require('../../helpers/get');
12
11
  const getConstructorName = require('../../helpers/getConstructorName');
13
12
  const stream = require('stream');
14
13
  const util = require('util');
@@ -76,7 +75,11 @@ function iter(i) {
76
75
  const collection = this.collection;
77
76
  const args = Array.from(arguments);
78
77
  const _this = this;
79
- const debug = get(_this, 'conn.base.options.debug');
78
+ const debug = _this &&
79
+ _this.conn &&
80
+ _this.conn.base &&
81
+ _this.conn.base.options &&
82
+ _this.conn.base.options.debug;
80
83
  const lastArg = arguments[arguments.length - 1];
81
84
  const opId = new ObjectId();
82
85
 
@@ -84,7 +87,7 @@ function iter(i) {
84
87
  if (this.conn.$wasForceClosed) {
85
88
  const error = new MongooseError('Connection was force closed');
86
89
  if (args.length > 0 &&
87
- typeof args[args.length - 1] === 'function') {
90
+ typeof args[args.length - 1] === 'function') {
88
91
  args[args.length - 1](error);
89
92
  return;
90
93
  } else {
@@ -368,7 +371,12 @@ function format(obj, sub, color, shell) {
368
371
  formatDate(x, key, shell);
369
372
  } else if (_constructorName === 'ClientSession') {
370
373
  x[key] = inspectable('ClientSession("' +
371
- get(x[key], 'id.id.buffer', '').toString('hex') + '")');
374
+ (
375
+ x[key] &&
376
+ x[key].id &&
377
+ x[key].id.id &&
378
+ x[key].id.id.buffer || ''
379
+ ).toString('hex') + '")');
372
380
  } else if (Array.isArray(x[key])) {
373
381
  x[key] = x[key].map(map);
374
382
  } else if (error != null) {
@@ -137,6 +137,17 @@ NativeConnection.prototype.doClose = function(force, fn) {
137
137
  return this;
138
138
  }
139
139
 
140
+ let skipCloseClient = false;
141
+ if (force != null && typeof force === 'object') {
142
+ skipCloseClient = force.skipCloseClient;
143
+ force = force.force;
144
+ }
145
+
146
+ if (skipCloseClient) {
147
+ immediate(() => fn());
148
+ return this;
149
+ }
150
+
140
151
  this.client.close(force, (err, res) => {
141
152
  // Defer because the driver will wait at least 1ms before finishing closing
142
153
  // the pool, see https://github.com/mongodb-js/mongodb-core/blob/a8f8e4ce41936babc3b9112bf42d609779f03b39/lib/connection/pool.js#L1026-L1030.
package/lib/error/cast.js CHANGED
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  const MongooseError = require('./mongooseError');
8
- const get = require('../helpers/get');
9
8
  const util = require('util');
10
9
 
11
10
  /**
@@ -111,7 +110,9 @@ function getValueType(value) {
111
110
  }
112
111
 
113
112
  function getMessageFormat(schemaType) {
114
- const messageFormat = get(schemaType, 'options.cast', null);
113
+ const messageFormat = schemaType &&
114
+ schemaType.options &&
115
+ schemaType.options.cast || null;
115
116
  if (typeof messageFormat === 'string') {
116
117
  return messageFormat;
117
118
  }
@@ -181,6 +181,17 @@ MongooseError.OverwriteModelError = require('./overwriteModel');
181
181
 
182
182
  MongooseError.MissingSchemaError = require('./missingSchema');
183
183
 
184
+ /**
185
+ * Thrown when the MongoDB Node driver can't connect to a valid server
186
+ * to send an operation to.
187
+ *
188
+ * @api public
189
+ * @memberOf Error
190
+ * @static MongooseServerSelectionError
191
+ */
192
+
193
+ MongooseError.MongooseServerSelectionError = require('./serverSelection');
194
+
184
195
  /**
185
196
  * An instance of this error will be returned if you used an array projection
186
197
  * and then modified the array in an unsafe way.
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ /*!
4
+ * Module dependencies.
5
+ */
6
+
7
+ const MongooseError = require('./mongooseError');
8
+
9
+ /**
10
+ * SyncIndexes Error constructor.
11
+ *
12
+ * @param {String} message
13
+ * @param {String} errorsMap
14
+ * @inherits MongooseError
15
+ * @api private
16
+ */
17
+
18
+ class SyncIndexesError extends MongooseError {
19
+ constructor(message, errorsMap) {
20
+ super(message);
21
+ this.errors = errorsMap;
22
+ }
23
+ }
24
+
25
+ Object.defineProperty(SyncIndexesError.prototype, 'name', {
26
+ value: 'SyncIndexesError'
27
+ });
28
+
29
+
30
+ module.exports = SyncIndexesError;