mongoose 6.2.1 → 6.2.4

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 (65) hide show
  1. package/.eslintrc.json +5 -1
  2. package/.lgtm.yml +3 -0
  3. package/CHANGELOG.md +54 -0
  4. package/dist/browser.umd.js +156 -152
  5. package/index.js +5 -1
  6. package/lib/aggregate.js +22 -27
  7. package/lib/browserDocument.js +1 -1
  8. package/lib/cast/number.js +2 -3
  9. package/lib/cast.js +7 -4
  10. package/lib/connection.js +43 -21
  11. package/lib/cursor/AggregationCursor.js +12 -7
  12. package/lib/cursor/QueryCursor.js +11 -6
  13. package/lib/document.js +58 -72
  14. package/lib/drivers/node-mongodb-native/collection.js +12 -4
  15. package/lib/drivers/node-mongodb-native/connection.js +11 -0
  16. package/lib/error/cast.js +3 -2
  17. package/lib/helpers/clone.js +11 -2
  18. package/lib/helpers/cursor/eachAsync.js +18 -15
  19. package/lib/helpers/document/cleanModifiedSubpaths.js +1 -0
  20. package/lib/helpers/document/compile.js +7 -4
  21. package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
  22. package/lib/helpers/indexes/getRelatedIndexes.js +59 -0
  23. package/lib/helpers/isAsyncFunction.js +6 -7
  24. package/lib/helpers/populate/assignVals.js +4 -0
  25. package/lib/helpers/printJestWarning.js +2 -2
  26. package/lib/helpers/projection/applyProjection.js +77 -0
  27. package/lib/helpers/projection/hasIncludedChildren.js +36 -0
  28. package/lib/helpers/projection/isExclusive.js +5 -2
  29. package/lib/helpers/projection/isInclusive.js +5 -1
  30. package/lib/helpers/query/cast$expr.js +14 -19
  31. package/lib/helpers/query/hasDollarKeys.js +7 -3
  32. package/lib/helpers/query/isOperator.js +5 -2
  33. package/lib/helpers/schema/getIndexes.js +6 -2
  34. package/lib/index.js +14 -17
  35. package/lib/internal.js +9 -1
  36. package/lib/model.js +159 -153
  37. package/lib/options/SchemaTypeOptions.js +1 -1
  38. package/lib/plugins/trackTransaction.js +1 -1
  39. package/lib/query.js +159 -147
  40. package/lib/queryhelpers.js +8 -28
  41. package/lib/schema/SubdocumentPath.js +5 -4
  42. package/lib/schema/array.js +13 -6
  43. package/lib/schema/buffer.js +1 -1
  44. package/lib/schema/date.js +1 -1
  45. package/lib/schema/decimal128.js +1 -1
  46. package/lib/schema/documentarray.js +9 -7
  47. package/lib/schema/number.js +1 -1
  48. package/lib/schema/objectid.js +1 -1
  49. package/lib/schema/string.js +4 -4
  50. package/lib/schema.js +12 -8
  51. package/lib/schematype.js +12 -14
  52. package/lib/types/ArraySubdocument.js +1 -1
  53. package/lib/types/DocumentArray/index.js +1 -1
  54. package/lib/types/array/index.js +2 -2
  55. package/lib/types/array/methods/index.js +10 -11
  56. package/lib/types/buffer.js +3 -3
  57. package/lib/types/map.js +3 -4
  58. package/lib/utils.js +9 -3
  59. package/package.json +17 -21
  60. package/tsconfig.json +0 -2
  61. package/types/Connection.d.ts +212 -0
  62. package/types/Error.d.ts +129 -0
  63. package/types/PipelineStage.d.ts +272 -0
  64. package/types/index.d.ts +61 -602
  65. package/lib/types/array/ArrayWrapper.js +0 -981
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ function getRelatedSchemaIndexes(model, schemaIndexes) {
4
+ return getRelatedIndexes({
5
+ baseModelName: model.baseModelName,
6
+ discriminatorMapping: model.schema.discriminatorMapping,
7
+ indexes: schemaIndexes,
8
+ indexesType: 'schema'
9
+ });
10
+ }
11
+
12
+ function getRelatedDBIndexes(model, dbIndexes) {
13
+ return getRelatedIndexes({
14
+ baseModelName: model.baseModelName,
15
+ discriminatorMapping: model.schema.discriminatorMapping,
16
+ indexes: dbIndexes,
17
+ indexesType: 'db'
18
+ });
19
+ }
20
+
21
+ module.exports = {
22
+ getRelatedSchemaIndexes,
23
+ getRelatedDBIndexes
24
+ };
25
+
26
+ function getRelatedIndexes({
27
+ baseModelName,
28
+ discriminatorMapping,
29
+ indexes,
30
+ indexesType
31
+ }) {
32
+ const discriminatorKey = discriminatorMapping && discriminatorMapping.key;
33
+ const discriminatorValue = discriminatorMapping && discriminatorMapping.value;
34
+
35
+ if (!discriminatorKey) {
36
+ return indexes;
37
+ }
38
+
39
+ const isChildDiscriminatorModel = Boolean(baseModelName);
40
+ if (isChildDiscriminatorModel) {
41
+ return indexes.filter(index => {
42
+ const partialFilterExpression = getPartialFilterExpression(index, indexesType);
43
+ return partialFilterExpression && partialFilterExpression[discriminatorKey] === discriminatorValue;
44
+ });
45
+ }
46
+
47
+ return indexes.filter(index => {
48
+ const partialFilterExpression = getPartialFilterExpression(index, indexesType);
49
+ return !partialFilterExpression || !partialFilterExpression[discriminatorKey];
50
+ });
51
+ }
52
+
53
+ function getPartialFilterExpression(index, indexesType) {
54
+ if (indexesType === 'schema') {
55
+ const options = index[1];
56
+ return options && options.partialFilterExpression;
57
+ }
58
+ return index.partialFilterExpression;
59
+ }
@@ -1,11 +1,10 @@
1
1
  'use strict';
2
2
 
3
- const { inspect } = require('util');
3
+ const asyncFunctionPrototype = Object.getPrototypeOf(async function() {});
4
4
 
5
5
  module.exports = function isAsyncFunction(v) {
6
- if (typeof v !== 'function') {
7
- return;
8
- }
9
-
10
- return inspect(v).startsWith('[AsyncFunction:');
11
- };
6
+ return (
7
+ typeof v === 'function' &&
8
+ Object.getPrototypeOf(v) === asyncFunctionPrototype
9
+ );
10
+ };
@@ -172,6 +172,10 @@ module.exports = function assignVals(o) {
172
172
  o.allOptions.options[populateModelSymbol] = o.allOptions.model;
173
173
  docs[i].$populated(_path, o.unpopulatedValues[i], o.allOptions.options);
174
174
 
175
+ if (valueToSet != null && valueToSet.$__ != null) {
176
+ valueToSet.$__.wasPopulated = { value: o.unpopulatedValues[i] };
177
+ }
178
+
175
179
  if (valueToSet instanceof Map && !valueToSet.$isMongooseMap) {
176
180
  valueToSet = new MongooseMap(valueToSet, _path, docs[i], docs[i].schema.path(_path).$__schemaType);
177
181
  }
@@ -6,12 +6,12 @@ if (typeof jest !== 'undefined' && typeof window !== 'undefined') {
6
6
  utils.warn('Mongoose: looks like you\'re trying to test a Mongoose app ' +
7
7
  'with Jest\'s default jsdom test environment. Please make sure you read ' +
8
8
  'Mongoose\'s docs on configuring Jest to test Node.js apps: ' +
9
- 'http://mongoosejs.com/docs/jest.html');
9
+ 'https://mongoosejs.com/docs/jest.html');
10
10
  }
11
11
 
12
12
  if (typeof jest !== 'undefined' && process.nextTick.toString().indexOf('nextTick') === -1) {
13
13
  utils.warn('Mongoose: looks like you\'re trying to test a Mongoose app ' +
14
14
  'with Jest\'s mock timers enabled. Please make sure you read ' +
15
15
  'Mongoose\'s docs on configuring Jest to test Node.js apps: ' +
16
- 'http://mongoosejs.com/docs/jest.html');
16
+ 'https://mongoosejs.com/docs/jest.html');
17
17
  }
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ const hasIncludedChildren = require('./hasIncludedChildren');
4
+ const isExclusive = require('./isExclusive');
5
+ const isInclusive = require('./isInclusive');
6
+ const isPOJO = require('../../utils').isPOJO;
7
+
8
+ module.exports = function applyProjection(doc, projection, _hasIncludedChildren) {
9
+ if (projection == null) {
10
+ return doc;
11
+ }
12
+ if (doc == null) {
13
+ return doc;
14
+ }
15
+
16
+ let exclude = null;
17
+ if (isInclusive(projection)) {
18
+ exclude = false;
19
+ } else if (isExclusive(projection)) {
20
+ exclude = true;
21
+ }
22
+
23
+ if (exclude == null) {
24
+ return doc;
25
+ } else if (exclude) {
26
+ _hasIncludedChildren = _hasIncludedChildren || hasIncludedChildren(projection);
27
+ return applyExclusiveProjection(doc, projection, _hasIncludedChildren);
28
+ } else {
29
+ _hasIncludedChildren = _hasIncludedChildren || hasIncludedChildren(projection);
30
+ return applyInclusiveProjection(doc, projection, _hasIncludedChildren);
31
+ }
32
+ };
33
+
34
+ function applyExclusiveProjection(doc, projection, hasIncludedChildren, projectionLimb, prefix) {
35
+ if (doc == null || typeof doc !== 'object') {
36
+ return doc;
37
+ }
38
+ const ret = { ...doc };
39
+ projectionLimb = prefix ? (projectionLimb || {}) : projection;
40
+
41
+ for (const key of Object.keys(ret)) {
42
+ const fullPath = prefix ? prefix + '.' + key : key;
43
+ if (projection.hasOwnProperty(fullPath) || projectionLimb.hasOwnProperty(key)) {
44
+ if (isPOJO(projection[fullPath]) || isPOJO(projectionLimb[key])) {
45
+ ret[key] = applyExclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
46
+ } else {
47
+ delete ret[key];
48
+ }
49
+ } else if (hasIncludedChildren[fullPath]) {
50
+ ret[key] = applyExclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
51
+ }
52
+ }
53
+ return ret;
54
+ }
55
+
56
+ function applyInclusiveProjection(doc, projection, hasIncludedChildren, projectionLimb, prefix) {
57
+ if (doc == null || typeof doc !== 'object') {
58
+ return doc;
59
+ }
60
+ const ret = { ...doc };
61
+ projectionLimb = prefix ? (projectionLimb || {}) : projection;
62
+
63
+ for (const key of Object.keys(ret)) {
64
+ const fullPath = prefix ? prefix + '.' + key : key;
65
+ if (projection.hasOwnProperty(fullPath) || projectionLimb.hasOwnProperty(key)) {
66
+ if (isPOJO(projection[fullPath]) || isPOJO(projectionLimb[key])) {
67
+ ret[key] = applyInclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
68
+ }
69
+ continue;
70
+ } else if (hasIncludedChildren[fullPath]) {
71
+ ret[key] = applyInclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
72
+ } else {
73
+ delete ret[key];
74
+ }
75
+ }
76
+ return ret;
77
+ }
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ /*!
4
+ * Creates an object that precomputes whether a given path has child fields in
5
+ * the projection.
6
+ *
7
+ * ####Example:
8
+ * const res = hasIncludedChildren({ 'a.b.c': 0 });
9
+ * res.a; // 1
10
+ * res['a.b']; // 1
11
+ * res['a.b.c']; // 1
12
+ * res['a.c']; // undefined
13
+ */
14
+
15
+ module.exports = function hasIncludedChildren(fields) {
16
+ const hasIncludedChildren = {};
17
+ const keys = Object.keys(fields);
18
+
19
+ for (const key of keys) {
20
+ if (key.indexOf('.') === -1) {
21
+ hasIncludedChildren[key] = 1;
22
+ continue;
23
+ }
24
+ const parts = key.split('.');
25
+ let c = parts[0];
26
+
27
+ for (let i = 0; i < parts.length; ++i) {
28
+ hasIncludedChildren[c] = 1;
29
+ if (i + 1 < parts.length) {
30
+ c = c + '.' + parts[i + 1];
31
+ }
32
+ }
33
+ }
34
+
35
+ return hasIncludedChildren;
36
+ };
@@ -21,8 +21,11 @@ module.exports = function isExclusive(projection) {
21
21
  while (ki--) {
22
22
  // Does this projection explicitly define inclusion/exclusion?
23
23
  // Explicitly avoid `$meta` and `$slice`
24
- if (keys[ki] !== '_id' && isDefiningProjection(projection[keys[ki]])) {
25
- exclude = !projection[keys[ki]];
24
+ const key = keys[ki];
25
+ if (key !== '_id' && isDefiningProjection(projection[key])) {
26
+ exclude = (projection[key] != null && typeof projection[key] === 'object') ?
27
+ isExclusive(projection[key]) :
28
+ !projection[key];
26
29
  break;
27
30
  }
28
31
  }
@@ -26,7 +26,11 @@ module.exports = function isInclusive(projection) {
26
26
  // If field is truthy (1, true, etc.) and not an object, then this
27
27
  // projection must be inclusive. If object, assume its $meta, $slice, etc.
28
28
  if (isDefiningProjection(projection[prop]) && !!projection[prop]) {
29
- return true;
29
+ if (projection[prop] != null && typeof projection[prop] === 'object') {
30
+ return isInclusive(projection[prop]);
31
+ } else {
32
+ return !!projection[prop];
33
+ }
30
34
  }
31
35
  }
32
36
 
@@ -68,7 +68,7 @@ const dateOperators = new Set([
68
68
  ]);
69
69
 
70
70
  module.exports = function cast$expr(val, schema, strictQuery) {
71
- if (typeof val !== 'object' || val == null) {
71
+ if (typeof val !== 'object' || val === null) {
72
72
  throw new Error('`$expr` must be an object');
73
73
  }
74
74
 
@@ -123,10 +123,8 @@ function _castExpression(val, schema, strictQuery) {
123
123
 
124
124
  function _omitUndefined(val) {
125
125
  const keys = Object.keys(val);
126
- for (const key of keys) {
127
- if (val[key] === void 0) {
128
- delete val[key];
129
- }
126
+ for (let i = 0, len = keys.length; i < len; ++i) {
127
+ (val[keys[i]] === void 0) && delete val[keys[i]];
130
128
  }
131
129
  }
132
130
 
@@ -144,15 +142,14 @@ function castNumberOperator(val) {
144
142
  }
145
143
 
146
144
  function castIn(val, schema, strictQuery) {
147
- let search = val[0];
148
- let path = val[1];
145
+ const path = val[1];
149
146
  if (!isPath(path)) {
150
147
  return val;
151
148
  }
149
+ const search = val[0];
152
150
 
153
- path = path.slice(1);
154
- const schematype = schema.path(path);
155
- if (schematype == null) {
151
+ const schematype = schema.path(path.slice(1));
152
+ if (schematype === null) {
156
153
  if (strictQuery === false) {
157
154
  return val;
158
155
  } else if (strictQuery === 'throw') {
@@ -166,12 +163,10 @@ function castIn(val, schema, strictQuery) {
166
163
  throw new Error('Path must be an array for $in');
167
164
  }
168
165
 
169
- if (schematype.$isMongooseDocumentArray) {
170
- search = schematype.$embeddedSchemaType.cast(search);
171
- } else {
172
- search = schematype.caster.cast(search);
173
- }
174
- return [search, val[1]];
166
+ return [
167
+ schematype.$isMongooseDocumentArray ? schematype.$embeddedSchemaType.cast(search) : schematype.caster.cast(search),
168
+ path
169
+ ];
175
170
  }
176
171
 
177
172
  // { $op: [<number>, <number>] }
@@ -268,14 +263,14 @@ function castComparison(val, schema, strictQuery) {
268
263
  }
269
264
 
270
265
  function isPath(val) {
271
- return typeof val === 'string' && val.startsWith('$');
266
+ return typeof val === 'string' && val[0] === '$';
272
267
  }
273
268
 
274
269
  function isLiteral(val) {
275
- if (typeof val === 'string' && val.startsWith('$')) {
270
+ if (typeof val === 'string' && val[0] === '$') {
276
271
  return false;
277
272
  }
278
- if (typeof val === 'object' && val != null && Object.keys(val).find(key => key.startsWith('$'))) {
273
+ if (typeof val === 'object' && val !== null && Object.keys(val).find(key => key[0] === '$')) {
279
274
  // The `$literal` expression can make an object a literal
280
275
  // https://docs.mongodb.com/manual/reference/operator/aggregation/literal/#mongodb-expression-exp.-literal
281
276
  return val.$literal != null;
@@ -4,16 +4,20 @@
4
4
  * ignore
5
5
  */
6
6
 
7
- module.exports = function(obj) {
8
- if (obj == null || typeof obj !== 'object') {
7
+ module.exports = function hasDollarKeys(obj) {
8
+
9
+ if (typeof obj !== 'object' || obj === null) {
9
10
  return false;
10
11
  }
12
+
11
13
  const keys = Object.keys(obj);
12
14
  const len = keys.length;
15
+
13
16
  for (let i = 0; i < len; ++i) {
14
- if (keys[i].startsWith('$')) {
17
+ if (keys[i][0] === '$') {
15
18
  return true;
16
19
  }
17
20
  }
21
+
18
22
  return false;
19
23
  };
@@ -7,5 +7,8 @@ const specialKeys = new Set([
7
7
  ]);
8
8
 
9
9
  module.exports = function isOperator(path) {
10
- return path.startsWith('$') && !specialKeys.has(path);
11
- };
10
+ return (
11
+ path[0] === '$' &&
12
+ !specialKeys.has(path)
13
+ );
14
+ };
@@ -2,6 +2,7 @@
2
2
 
3
3
  const get = require('../get');
4
4
  const helperIsObject = require('../isObject');
5
+ const decorateDiscriminatorIndexOptions = require('../indexes/decorateDiscriminatorIndexOptions');
5
6
 
6
7
  /*!
7
8
  * Gather all indexes defined in the schema, including single nested,
@@ -88,6 +89,7 @@ module.exports = function getIndexes(schema) {
88
89
  }
89
90
 
90
91
  const indexName = options && options.name;
92
+
91
93
  if (typeof indexName === 'string') {
92
94
  if (indexByName.has(indexName)) {
93
95
  Object.assign(indexByName.get(indexName), field);
@@ -108,9 +110,11 @@ module.exports = function getIndexes(schema) {
108
110
  fixSubIndexPaths(schema, prefix);
109
111
  } else {
110
112
  schema._indexes.forEach(function(index) {
111
- if (!('background' in index[1])) {
112
- index[1].background = true;
113
+ const options = index[1];
114
+ if (!('background' in options)) {
115
+ options.background = true;
113
116
  }
117
+ decorateDiscriminatorIndexOptions(schema, options);
114
118
  });
115
119
  indexes = indexes.concat(schema._indexes);
116
120
  }
package/lib/index.js CHANGED
@@ -19,7 +19,6 @@ const Query = require('./query');
19
19
  const Model = require('./model');
20
20
  const applyPlugins = require('./helpers/schema/applyPlugins');
21
21
  const driver = require('./driver');
22
- const get = require('./helpers/get');
23
22
  const promiseOrCallback = require('./helpers/promiseOrCallback');
24
23
  const legacyPluralize = require('./helpers/pluralize');
25
24
  const utils = require('./utils');
@@ -252,17 +251,17 @@ Mongoose.prototype.get = Mongoose.prototype.set;
252
251
  * db.openUri('localhost', 'database', port, [opts]);
253
252
  *
254
253
  * @param {String} [uri] a mongodb:// URI
255
- * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
256
- * @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.
254
+ * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](https://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
255
+ * @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.
257
256
  * @param {String} [options.dbName] The name of the database you want to use. If not provided, Mongoose uses the database name from connection string.
258
257
  * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
259
258
  * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
260
259
  * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
261
260
  * @param {Number} [options.reconnectTries=30] If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect every `reconnectInterval` milliseconds for `reconnectTries` times, and give up afterward. When the driver gives up, the mongoose connection emits a `reconnectFailed` event. This option does nothing for replica set connections.
262
261
  * @param {Number} [options.reconnectInterval=1000] See `reconnectTries` option above.
263
- * @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](http://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
264
- * @param {Number} [options.maxPoolSize=5] 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).
265
- * @param {Number} [options.minPoolSize=1] 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).
262
+ * @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
263
+ * @param {Number} [options.maxPoolSize=5] 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).
264
+ * @param {Number} [options.minPoolSize=1] 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).
266
265
  * @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).
267
266
  * @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.
268
267
  * @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.
@@ -309,20 +308,20 @@ Mongoose.prototype.createConnection = function(uri, options, callback) {
309
308
  * })
310
309
  *
311
310
  * @param {String} uri(s)
312
- * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
313
- * @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.
311
+ * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](https://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
312
+ * @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.
314
313
  * @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.
315
314
  * @param {String} [options.dbName] The name of the database we want to use. If not provided, use database name from connection string.
316
315
  * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
317
316
  * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
318
- * @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).
317
+ * @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).
319
318
  * @param {Number} [options.minPoolSize=0] The minimum number of sockets the MongoDB driver will keep open for this connection.
320
319
  * @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).
321
320
  * @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.
322
321
  * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
323
322
  * @param {Number} [options.reconnectTries=30] If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect every `reconnectInterval` milliseconds for `reconnectTries` times, and give up afterward. When the driver gives up, the mongoose connection emits a `reconnectFailed` event. This option does nothing for replica set connections.
324
323
  * @param {Number} [options.reconnectInterval=1000] See `reconnectTries` option above.
325
- * @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](http://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
324
+ * @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
326
325
  * @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).
327
326
  * @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.
328
327
  * @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.
@@ -379,13 +378,13 @@ Mongoose.prototype.disconnect = function(callback) {
379
378
  /**
380
379
  * _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
381
380
  * for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
382
- * and [transactions](http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
381
+ * and [transactions](https://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
383
382
  *
384
383
  * Calling `mongoose.startSession()` is equivalent to calling `mongoose.connection.startSession()`.
385
384
  * Sessions are scoped to a connection, so calling `mongoose.startSession()`
386
385
  * starts a session on the [default mongoose connection](/docs/api.html#mongoose_Mongoose-connection).
387
386
  *
388
- * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
387
+ * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
389
388
  * @param {Boolean} [options.causalConsistency=true] set to false to disable causal consistency
390
389
  * @param {Function} [callback]
391
390
  * @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
@@ -632,10 +631,8 @@ Mongoose.prototype._applyPlugins = function(schema, options) {
632
631
  const _mongoose = this instanceof Mongoose ? this : mongoose;
633
632
 
634
633
  options = options || {};
635
- options.applyPluginsToDiscriminators = get(_mongoose,
636
- 'options.applyPluginsToDiscriminators', false);
637
- options.applyPluginsToChildSchemas = get(_mongoose,
638
- 'options.applyPluginsToChildSchemas', true);
634
+ options.applyPluginsToDiscriminators = _mongoose.options && _mongoose.options.applyPluginsToDiscriminators || false;
635
+ options.applyPluginsToChildSchemas = typeof (_mongoose.options && _mongoose.options.applyPluginsToDiscriminators) === 'boolean' ? _mongoose.options.applyPluginsToDiscriminators : true;
639
636
  applyPlugins(schema, _mongoose.plugins, options, '$globalPluginsApplied');
640
637
  };
641
638
 
@@ -977,7 +974,7 @@ Mongoose.prototype.syncIndexes = function(options) {
977
974
  /**
978
975
  * The Mongoose Decimal128 [SchemaType](/docs/schematypes.html). Used for
979
976
  * declaring paths in your schema that should be
980
- * [128-bit decimal floating points](http://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-decimal.html).
977
+ * [128-bit decimal floating points](https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-decimal.html).
981
978
  * Do not use this to create a new Decimal128 instance, use `mongoose.Types.Decimal128`
982
979
  * instead.
983
980
  *
package/lib/internal.js CHANGED
@@ -29,7 +29,15 @@ InternalCache.prototype._id = undefined;
29
29
  InternalCache.prototype.ownerDocument = undefined;
30
30
  InternalCache.prototype.populate = undefined; // what we want to populate in this doc
31
31
  InternalCache.prototype.populated = undefined;// the _ids that have been populated
32
- InternalCache.prototype.wasPopulated = false; // if this doc was the result of a population
32
+
33
+ /**
34
+ * If `false`, this document was not the result of population.
35
+ * If `true`, this document is a populated doc underneath another doc
36
+ * If an object, this document is a populated doc and the `value` property of the
37
+ * object contains the original depopulated value.
38
+ */
39
+ InternalCache.prototype.wasPopulated = false;
40
+
33
41
  InternalCache.prototype.scope = undefined;
34
42
 
35
43
  InternalCache.prototype.session = null;