mongoose 6.3.4 → 6.3.7

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 (53) hide show
  1. package/.eslintrc.json +1 -1
  2. package/dist/browser.umd.js +1 -1
  3. package/lgtm.yml +12 -0
  4. package/lib/cast/objectid.js +3 -2
  5. package/lib/connection.js +3 -2
  6. package/lib/document.js +37 -24
  7. package/lib/error/index.js +2 -2
  8. package/lib/helpers/clone.js +7 -1
  9. package/lib/helpers/common.js +3 -4
  10. package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +2 -2
  11. package/lib/helpers/isBsonType.js +5 -3
  12. package/lib/helpers/path/setDottedPath.js +14 -1
  13. package/lib/helpers/schematype/handleImmutable.js +2 -1
  14. package/lib/helpers/topology/isAtlas.js +15 -2
  15. package/lib/helpers/update/applyTimestampsToChildren.js +4 -0
  16. package/lib/helpers/update/castArrayFilters.js +3 -0
  17. package/lib/index.js +4 -3
  18. package/lib/options/SchemaTypeOptions.js +13 -0
  19. package/lib/query.js +4 -1
  20. package/lib/schema/SubdocumentPath.js +8 -1
  21. package/lib/schema/decimal128.js +4 -4
  22. package/lib/schema/documentarray.js +2 -4
  23. package/lib/schema/map.js +8 -0
  24. package/lib/schema/objectid.js +4 -3
  25. package/lib/schema/string.js +2 -2
  26. package/lib/schema.js +33 -2
  27. package/lib/schematype.js +1 -0
  28. package/lib/types/DocumentArray/methods/index.js +3 -3
  29. package/lib/types/array/methods/index.js +3 -3
  30. package/lib/types/map.js +4 -4
  31. package/lib/utils.js +3 -4
  32. package/package.json +17 -15
  33. package/types/aggregate.d.ts +3 -4
  34. package/types/callback.d.ts +8 -0
  35. package/types/collection.d.ts +46 -0
  36. package/types/connection.d.ts +91 -71
  37. package/types/document.d.ts +1 -1
  38. package/types/error.d.ts +5 -1
  39. package/types/helpers.d.ts +32 -0
  40. package/types/index.d.ts +32 -1859
  41. package/types/indizes.d.ts +98 -0
  42. package/types/middlewares.d.ts +14 -0
  43. package/types/models.d.ts +419 -0
  44. package/types/populate.d.ts +40 -0
  45. package/types/query.d.ts +637 -0
  46. package/types/schematypes.d.ts +427 -0
  47. package/types/session.d.ts +36 -0
  48. package/types/types.d.ts +102 -0
  49. package/types/utility.d.ts +13 -0
  50. package/types/validation.d.ts +32 -0
  51. package/.lgtm.yml +0 -3
  52. package/CHANGELOG.md +0 -7300
  53. package/History.md +0 -1
package/lgtm.yml ADDED
@@ -0,0 +1,12 @@
1
+ path_classifiers:
2
+ src:
3
+ - lib
4
+ types:
5
+ - types
6
+ test:
7
+ - test
8
+ docs:
9
+ - docs
10
+ queries:
11
+ - exclude: "*"
12
+ - include: lib
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ const isBsonType = require('../helpers/isBsonType');
3
4
  const ObjectId = require('../driver').get().ObjectId;
4
5
 
5
6
  module.exports = function castObjectId(value) {
@@ -7,12 +8,12 @@ module.exports = function castObjectId(value) {
7
8
  return value;
8
9
  }
9
10
 
10
- if (value instanceof ObjectId) {
11
+ if (isBsonType(value, 'ObjectID')) {
11
12
  return value;
12
13
  }
13
14
 
14
15
  if (value._id) {
15
- if (value._id instanceof ObjectId) {
16
+ if (isBsonType(value._id, 'ObjectID')) {
16
17
  return value._id;
17
18
  }
18
19
  if (value._id.toString instanceof Function) {
package/lib/connection.js CHANGED
@@ -7,13 +7,13 @@
7
7
  const ChangeStream = require('./cursor/ChangeStream');
8
8
  const EventEmitter = require('events').EventEmitter;
9
9
  const Schema = require('./schema');
10
- const Collection = require('./driver').get().Collection;
11
10
  const STATES = require('./connectionstate');
12
11
  const MongooseError = require('./error/index');
13
12
  const SyncIndexesError = require('./error/syncIndexes');
14
13
  const PromiseProvider = require('./promise_provider');
15
14
  const ServerSelectionError = require('./error/serverSelection');
16
15
  const applyPlugins = require('./helpers/schema/applyPlugins');
16
+ const driver = require('./driver');
17
17
  const promiseOrCallback = require('./helpers/promiseOrCallback');
18
18
  const get = require('./helpers/get');
19
19
  const immediate = require('./helpers/immediate');
@@ -548,7 +548,7 @@ Connection.prototype.dropDatabase = _wrapConnHelper(function dropDatabase(cb) {
548
548
  // If `dropDatabase()` is called, this model's collection will not be
549
549
  // init-ed. It is sufficiently common to call `dropDatabase()` after
550
550
  // `mongoose.connect()` but before creating models that we want to
551
- // support this. See gh-6967
551
+ // support this. See gh-6796
552
552
  for (const name of Object.keys(this.models)) {
553
553
  delete this.models[name].$init;
554
554
  }
@@ -1026,6 +1026,7 @@ Connection.prototype.collection = function(name, options) {
1026
1026
  };
1027
1027
  options = Object.assign({}, defaultOptions, options ? utils.clone(options) : {});
1028
1028
  options.$wasForceClosed = this.$wasForceClosed;
1029
+ const Collection = driver.get().Collection;
1029
1030
  if (!(name in this.collections)) {
1030
1031
  this.collections[name] = new Collection(name, this, options);
1031
1032
  }
package/lib/document.js CHANGED
@@ -79,7 +79,6 @@ function Document(obj, fields, skipId, options) {
79
79
  options = skipId;
80
80
  skipId = options.skipId;
81
81
  }
82
- options = Object.assign({}, options);
83
82
 
84
83
  // Support `browserDocument.js` syntax
85
84
  if (this.$__schema == null) {
@@ -93,9 +92,9 @@ function Document(obj, fields, skipId, options) {
93
92
  }
94
93
 
95
94
  this.$__ = new InternalCache();
96
- this.$isNew = 'isNew' in options ? options.isNew : true;
95
+ this.$isNew = options && options.isNew != null ? options.isNew : true;
97
96
 
98
- if (options.priorDoc != null) {
97
+ if (options && options.priorDoc != null) {
99
98
  this.$__.priorDoc = options.priorDoc;
100
99
  }
101
100
 
@@ -108,18 +107,20 @@ function Document(obj, fields, skipId, options) {
108
107
  }
109
108
 
110
109
  let defaults = true;
111
- if (options.defaults !== undefined) {
110
+ if (options && options.defaults !== undefined) {
112
111
  this.$__.defaults = options.defaults;
113
112
  defaults = options.defaults;
114
113
  }
115
114
 
116
115
  const schema = this.$__schema;
117
116
 
117
+ let strict;
118
118
  if (typeof fields === 'boolean' || fields === 'throw') {
119
119
  this.$__.strictMode = fields;
120
+ strict = fields;
120
121
  fields = undefined;
121
122
  } else {
122
- this.$__.strictMode = schema.options.strict;
123
+ strict = schema.options.strict;
123
124
  if (fields != null) {
124
125
  this.$__.selected = fields;
125
126
  }
@@ -136,7 +137,6 @@ function Document(obj, fields, skipId, options) {
136
137
  // excluded fields
137
138
  if (utils.isPOJO(fields)) {
138
139
  exclude = isExclusive(fields);
139
-
140
140
  this.$__.fields = fields;
141
141
  this.$__.exclude = exclude;
142
142
  }
@@ -170,15 +170,15 @@ function Document(obj, fields, skipId, options) {
170
170
  // Function defaults get applied **after** setting initial values so they
171
171
  // see the full doc rather than an empty one, unless they opt out.
172
172
  // Re: gh-3781, gh-6155
173
- if (options.willInit && defaults) {
173
+ if (options && options.willInit && defaults) {
174
174
  if (options.skipDefaults) {
175
175
  this.$__.skipDefaults = options.skipDefaults;
176
176
  }
177
177
  } else if (defaults) {
178
- $__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options.skipDefaults);
178
+ $__applyDefaults(this, fields, exclude, hasIncludedChildren, false, options && options.skipDefaults);
179
179
  }
180
180
 
181
- if (!this.$__.strictMode && obj) {
181
+ if (!strict && obj) {
182
182
  const _this = this;
183
183
  const keys = Object.keys(this._doc);
184
184
 
@@ -641,7 +641,11 @@ Document.prototype.$__buildDoc = function(obj, fields, skipId, exclude, hasInclu
641
641
  for (let i = 0; i < len; ++i) {
642
642
  const piece = path[i];
643
643
 
644
- curPath += (!curPath.length ? '' : '.') + piece;
644
+ if (!curPath.length) {
645
+ curPath = piece;
646
+ } else {
647
+ curPath += '.' + piece;
648
+ }
645
649
 
646
650
  // support excluding intermediary levels
647
651
  if (exclude === true) {
@@ -1045,8 +1049,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1045
1049
  type = undefined;
1046
1050
  }
1047
1051
 
1048
- options = options || {};
1049
- const merge = options.merge;
1052
+ const merge = options && options.merge;
1050
1053
  const adhoc = type && type !== true;
1051
1054
  const constructing = type === true;
1052
1055
  let adhocs;
@@ -1056,7 +1059,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1056
1059
  let key;
1057
1060
  let prefix;
1058
1061
 
1059
- const strict = 'strict' in options
1062
+ const strict = options && 'strict' in options
1060
1063
  ? options.strict
1061
1064
  : this.$__.strictMode;
1062
1065
 
@@ -1087,7 +1090,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1087
1090
 
1088
1091
  // `_skipMinimizeTopLevel` is because we may have deleted the top-level
1089
1092
  // nested key to ensure key order.
1090
- const _skipMinimizeTopLevel = options._skipMinimizeTopLevel || false;
1093
+ const _skipMinimizeTopLevel = options && options._skipMinimizeTopLevel || false;
1091
1094
  if (len === 0 && _skipMinimizeTopLevel) {
1092
1095
  delete options._skipMinimizeTopLevel;
1093
1096
  if (val) {
@@ -1378,7 +1381,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
1378
1381
  })();
1379
1382
 
1380
1383
  let didPopulate = false;
1381
- if (refMatches && val instanceof Document) {
1384
+ if (refMatches && val instanceof Document && (!val.$__.wasPopulated || utils.deepEqual(val.$__.wasPopulated.value, val._id))) {
1382
1385
  const unpopulatedValue = (schema && schema.$isSingleNested) ? schema.cast(val, this) : val._id;
1383
1386
  this.$populated(path, unpopulatedValue, { [populateModelSymbol]: val.constructor });
1384
1387
  val.$__.wasPopulated = { value: unpopulatedValue };
@@ -1565,7 +1568,7 @@ Document.prototype.set = Document.prototype.$set;
1565
1568
  */
1566
1569
 
1567
1570
  Document.prototype.$__shouldModify = function(pathToMark, path, options, constructing, parts, schema, val, priorVal) {
1568
- if (options._skipMarkModified) {
1571
+ if (options && options._skipMarkModified) {
1569
1572
  return false;
1570
1573
  }
1571
1574
  if (this.$isNew) {
@@ -3464,9 +3467,9 @@ Document.prototype.$toObject = function(options, json) {
3464
3467
 
3465
3468
  const path = json ? 'toJSON' : 'toObject';
3466
3469
  const baseOptions = this.constructor &&
3467
- this.constructor.base &&
3468
- this.constructor.base.options &&
3469
- get(this.constructor.base.options, path) || {};
3470
+ this.constructor.base &&
3471
+ this.constructor.base.options &&
3472
+ get(this.constructor.base.options, path) || {};
3470
3473
  const schemaOptions = this.$__schema && this.$__schema.options || {};
3471
3474
  // merge base default options with Schema's set default options if available.
3472
3475
  // `clone` is necessary here because `utils.options` directly modifies the second input.
@@ -3474,8 +3477,8 @@ Document.prototype.$toObject = function(options, json) {
3474
3477
  defaultOptions = utils.options(defaultOptions, clone(schemaOptions[path] || {}));
3475
3478
 
3476
3479
  // If options do not exist or is not an object, set it to empty object
3477
- options = utils.isPOJO(options) ? clone(options) : {};
3478
- options._calledWithOptions = options._calledWithOptions || clone(options);
3480
+ options = utils.isPOJO(options) ? { ...options } : {};
3481
+ options._calledWithOptions = options._calledWithOptions || { ...options };
3479
3482
 
3480
3483
  let _minimize;
3481
3484
  if (options._calledWithOptions.minimize != null) {
@@ -3499,11 +3502,12 @@ Document.prototype.$toObject = function(options, json) {
3499
3502
  // `clone()` will recursively call `$toObject()` on embedded docs, so we
3500
3503
  // need the original options the user passed in, plus `_isNested` and
3501
3504
  // `_parentOptions` for checking whether we need to depopulate.
3502
- const cloneOptions = Object.assign(utils.clone(options), {
3505
+ const cloneOptions = Object.assign({}, options, {
3503
3506
  _isNested: true,
3504
3507
  json: json,
3505
3508
  minimize: _minimize,
3506
- flattenMaps: flattenMaps
3509
+ flattenMaps: flattenMaps,
3510
+ _seen: (options && options._seen) || new Map()
3507
3511
  });
3508
3512
 
3509
3513
  if (utils.hasUserDefinedProperty(options, 'getters')) {
@@ -3928,12 +3932,19 @@ function applySchemaTypeTransforms(self, json) {
3928
3932
  const schematype = schema.paths[path];
3929
3933
  if (typeof schematype.options.transform === 'function') {
3930
3934
  const val = self.$get(path);
3935
+ if (val === undefined) {
3936
+ continue;
3937
+ }
3931
3938
  const transformedValue = schematype.options.transform.call(self, val);
3932
3939
  throwErrorIfPromise(path, transformedValue);
3933
3940
  utils.setValue(path, transformedValue, json);
3934
3941
  } else if (schematype.$embeddedSchemaType != null &&
3935
3942
  typeof schematype.$embeddedSchemaType.options.transform === 'function') {
3936
- const vals = [].concat(self.$get(path));
3943
+ const val = self.$get(path);
3944
+ if (val === undefined) {
3945
+ continue;
3946
+ }
3947
+ const vals = [].concat(val);
3937
3948
  const transform = schematype.$embeddedSchemaType.options.transform;
3938
3949
  for (let i = 0; i < vals.length; ++i) {
3939
3950
  const transformedValue = transform.call(self, vals[i]);
@@ -4226,8 +4237,10 @@ Document.prototype.populate = function populate() {
4226
4237
  * @api public
4227
4238
  * @return {Array<Document>} array of populated documents. Empty array if there are no populated documents associated with this document.
4228
4239
  * @memberOf Document
4240
+ * @method $getPopulatedDocs
4229
4241
  * @instance
4230
4242
  */
4243
+
4231
4244
  Document.prototype.$getPopulatedDocs = function $getPopulatedDocs() {
4232
4245
  let keys = [];
4233
4246
  if (this.$__.populated != null) {
@@ -5,11 +5,11 @@
5
5
  * Mongoose-specific errors.
6
6
  *
7
7
  * #### Example:
8
- * const Model = mongoose.model('Test', new Schema({ answer: Number }));
8
+ * const Model = mongoose.model('Test', new mongoose.Schema({ answer: Number }));
9
9
  * const doc = new Model({ answer: 'not a number' });
10
10
  * const err = doc.validateSync();
11
11
  *
12
- * err instanceof mongoose.Error; // true
12
+ * err instanceof mongoose.Error.ValidationError; // true
13
13
  *
14
14
  * @constructor Error
15
15
  * @param {String} msg Error message
@@ -77,7 +77,7 @@ function clone(obj, options, isArrayChild) {
77
77
  }
78
78
  }
79
79
 
80
- if (obj instanceof ObjectId) {
80
+ if (isBsonType(obj, 'ObjectID')) {
81
81
  return new ObjectId(obj.id);
82
82
  }
83
83
 
@@ -119,9 +119,15 @@ module.exports = clone;
119
119
  function cloneObject(obj, options, isArrayChild) {
120
120
  const minimize = options && options.minimize;
121
121
  const omitUndefined = options && options.omitUndefined;
122
+ const seen = options && options._seen;
122
123
  const ret = {};
123
124
  let hasKeys;
124
125
 
126
+ if (seen && seen.has(obj)) {
127
+ return seen.get(obj);
128
+ } else if (seen) {
129
+ seen.set(obj, ret);
130
+ }
125
131
  if (trustedSymbol in obj) {
126
132
  ret[trustedSymbol] = obj[trustedSymbol];
127
133
  }
@@ -5,8 +5,7 @@
5
5
  */
6
6
 
7
7
  const Binary = require('../driver').get().Binary;
8
- const Decimal128 = require('../types/decimal128');
9
- const ObjectId = require('../types/objectid');
8
+ const isBsonType = require('./isBsonType');
10
9
  const isMongooseObject = require('./isMongooseObject');
11
10
 
12
11
  exports.flatten = flatten;
@@ -99,9 +98,9 @@ function shouldFlatten(val) {
99
98
  return val &&
100
99
  typeof val === 'object' &&
101
100
  !(val instanceof Date) &&
102
- !(val instanceof ObjectId) &&
101
+ !isBsonType(val, 'ObjectID') &&
103
102
  (!Array.isArray(val) || val.length !== 0) &&
104
103
  !(val instanceof Buffer) &&
105
- !(val instanceof Decimal128) &&
104
+ !isBsonType(val, 'Decimal128') &&
106
105
  !(val instanceof Binary);
107
106
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const ObjectId = require('../../types/objectid');
3
+ const isBsonType = require('../isBsonType');
4
4
 
5
5
  module.exports = function areDiscriminatorValuesEqual(a, b) {
6
6
  if (typeof a === 'string' && typeof b === 'string') {
@@ -9,7 +9,7 @@ module.exports = function areDiscriminatorValuesEqual(a, b) {
9
9
  if (typeof a === 'number' && typeof b === 'number') {
10
10
  return a === b;
11
11
  }
12
- if (a instanceof ObjectId && b instanceof ObjectId) {
12
+ if (isBsonType(a, 'ObjectID') && isBsonType(b, 'ObjectID')) {
13
13
  return a.toString() === b.toString();
14
14
  }
15
15
  return false;
@@ -1,13 +1,15 @@
1
1
  'use strict';
2
2
 
3
- const get = require('./get');
4
-
5
3
  /*!
6
4
  * Get the bson type, if it exists
7
5
  */
8
6
 
9
7
  function isBsonType(obj, typename) {
10
- return get(obj, '_bsontype', void 0) === typename;
8
+ return (
9
+ typeof obj === 'object' &&
10
+ obj !== null &&
11
+ obj._bsontype === typename
12
+ );
11
13
  }
12
14
 
13
15
  module.exports = isBsonType;
@@ -1,14 +1,25 @@
1
1
  'use strict';
2
2
 
3
+ const specialProperties = require('../specialProperties');
4
+
5
+
3
6
  module.exports = function setDottedPath(obj, path, val) {
4
7
  if (path.indexOf('.') === -1) {
8
+ if (specialProperties.has(path)) {
9
+ return;
10
+ }
11
+
5
12
  obj[path] = val;
6
13
  return;
7
14
  }
8
15
  const parts = path.split('.');
16
+
9
17
  const last = parts.pop();
10
18
  let cur = obj;
11
19
  for (const part of parts) {
20
+ if (specialProperties.has(part)) {
21
+ continue;
22
+ }
12
23
  if (cur[part] == null) {
13
24
  cur[part] = {};
14
25
  }
@@ -16,5 +27,7 @@ module.exports = function setDottedPath(obj, path, val) {
16
27
  cur = cur[part];
17
28
  }
18
29
 
19
- cur[last] = val;
30
+ if (!specialProperties.has(last)) {
31
+ cur[last] = val;
32
+ }
20
33
  };
@@ -40,7 +40,8 @@ function createImmutableSetter(path, immutable) {
40
40
  const _value = this.$__.priorDoc != null ?
41
41
  this.$__.priorDoc.$__getValue(path) :
42
42
  this.$__getValue(path);
43
- if (this.$__.strictMode === 'throw' && v !== _value) {
43
+ const strict = this.$__.strictMode == null ? this.$__schema.options.strict : this.$__.strictMode;
44
+ if (strict === 'throw' && v !== _value) {
44
45
  throw new StrictModeError(path, 'Path `' + path + '` is immutable ' +
45
46
  'and strict mode is set to throw.', true);
46
47
  }
@@ -8,6 +8,19 @@ module.exports = function isAtlas(topologyDescription) {
8
8
  }
9
9
 
10
10
  const hostnames = Array.from(topologyDescription.servers.keys());
11
- return hostnames.length > 0 &&
12
- hostnames.every(host => host.endsWith('.mongodb.net:27017'));
11
+
12
+ if (hostnames.length === 0) {
13
+ return false;
14
+ }
15
+
16
+ for (let i = 0, il = hostnames.length; i < il; ++i) {
17
+ const url = new URL(hostnames[i]);
18
+ if (
19
+ url.hostname.endsWith('.mongodb.net') === false ||
20
+ url.port !== '27017'
21
+ ) {
22
+ return false;
23
+ }
24
+ }
25
+ return true;
13
26
  };
@@ -61,6 +61,8 @@ function applyTimestampsToChildren(now, update, schema) {
61
61
  if (createdAt != null) {
62
62
  subdoc[createdAt] = now;
63
63
  }
64
+
65
+ applyTimestampsToChildren(now, subdoc, $path.schema);
64
66
  });
65
67
  } else {
66
68
  if (updatedAt != null) {
@@ -69,6 +71,8 @@ function applyTimestampsToChildren(now, update, schema) {
69
71
  if (createdAt != null) {
70
72
  op[key][createdAt] = now;
71
73
  }
74
+
75
+ applyTimestampsToChildren(now, op[key], $path.schema);
72
76
  }
73
77
  }
74
78
  }
@@ -15,6 +15,9 @@ module.exports = function castArrayFilters(query) {
15
15
  if (query._mongooseOptions.strict != null) {
16
16
  strictQuery = query._mongooseOptions.strict;
17
17
  }
18
+ if (query.model && query.model.base.options.strictQuery != null) {
19
+ strictQuery = query.model.base.options.strictQuery;
20
+ }
18
21
  if (schema._userProvidedOptions.strictQuery != null) {
19
22
  strictQuery = schema._userProvidedOptions.strictQuery;
20
23
  }
package/lib/index.js CHANGED
@@ -34,6 +34,7 @@ const PromiseProvider = require('./promise_provider');
34
34
  const shardingPlugin = require('./plugins/sharding');
35
35
  const trusted = require('./helpers/query/trusted').trusted;
36
36
  const sanitizeFilter = require('./helpers/query/sanitizeFilter');
37
+ const isBsonType = require('./helpers/isBsonType');
37
38
 
38
39
  const defaultMongooseSymbol = Symbol.for('mongoose:default');
39
40
 
@@ -153,7 +154,7 @@ Mongoose.prototype.driver = driver;
153
154
  * mongoose.set('debug', function(collectionName, methodName, ...methodArgs) {}); // use custom function to log collection methods + arguments
154
155
  *
155
156
  * Currently supported options are:
156
- * - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arugments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
157
+ * - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arguments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
157
158
  * - 'returnOriginal': If `false`, changes the default `returnOriginal` option to `findOneAndUpdate()`, `findByIdAndUpdate`, and `findOneAndReplace()` to false. This is equivalent to setting the `new` option to `true` for `findOneAndX()` calls by default. Read our [`findOneAndUpdate()` tutorial](/docs/tutorials/findoneandupdate.html) for more information.
158
159
  * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models
159
160
  * - 'cloneSchemas': false by default. Set to `true` to `clone()` all schemas before compiling into a model.
@@ -274,6 +275,7 @@ Mongoose.prototype.get = Mongoose.prototype.set;
274
275
  Mongoose.prototype.createConnection = function(uri, options, callback) {
275
276
  const _mongoose = this instanceof Mongoose ? this : mongoose;
276
277
 
278
+ const Connection = driver.get().getConnection();
277
279
  const conn = new Connection(_mongoose);
278
280
  if (typeof options === 'function') {
279
281
  callback = options;
@@ -995,8 +997,7 @@ Mongoose.prototype.isValidObjectId = function(v) {
995
997
  */
996
998
 
997
999
  Mongoose.prototype.isObjectIdOrHexString = function(v) {
998
- const _mongoose = this instanceof Mongoose ? this : mongoose;
999
- return v instanceof _mongoose.Types.ObjectId || (typeof v === 'string' && objectIdHexRegexp.test(v));
1000
+ return isBsonType(v, 'ObjectID') || (typeof v === 'string' && objectIdHexRegexp.test(v));
1000
1001
  };
1001
1002
 
1002
1003
  /**
@@ -119,6 +119,19 @@ Object.defineProperty(SchemaTypeOptions.prototype, 'default', opts);
119
119
 
120
120
  Object.defineProperty(SchemaTypeOptions.prototype, 'ref', opts);
121
121
 
122
+ /**
123
+ * The path in the document that `populate()` should use to find the model
124
+ * to use.
125
+ *
126
+ * @api public
127
+ * @property ref
128
+ * @memberOf SchemaTypeOptions
129
+ * @type Function|String
130
+ * @instance
131
+ */
132
+
133
+ Object.defineProperty(SchemaTypeOptions.prototype, 'refPath', opts);
134
+
122
135
  /**
123
136
  * Whether to include or exclude this path by default when loading documents
124
137
  * using `find()`, `findOne()`, etc.
package/lib/query.js CHANGED
@@ -124,7 +124,10 @@ function Query(conditions, options, model, collection) {
124
124
  }
125
125
 
126
126
  // inherit mquery
127
- mquery.call(this, this.mongooseCollection, options);
127
+ mquery.call(this, null, options);
128
+ if (collection) {
129
+ this.collection(collection);
130
+ }
128
131
 
129
132
  if (conditions) {
130
133
  this.find(conditions);
@@ -33,6 +33,13 @@ module.exports = SubdocumentPath;
33
33
  */
34
34
 
35
35
  function SubdocumentPath(schema, path, options) {
36
+ const schemaTypeIdOption = SubdocumentPath.defaultOptions &&
37
+ SubdocumentPath.defaultOptions._id;
38
+ if (schemaTypeIdOption != null) {
39
+ options = options || {};
40
+ options._id = schemaTypeIdOption;
41
+ }
42
+
36
43
  schema = handleIdOption(schema, options);
37
44
 
38
45
  this.caster = _createConstructor(schema);
@@ -160,7 +167,7 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
160
167
  }
161
168
  return obj;
162
169
  }, null);
163
- options = Object.assign({}, options, { priorDoc: priorVal });
170
+ options = priorVal != null ? Object.assign({}, options, { priorDoc: priorVal }) : options;
164
171
  if (init) {
165
172
  subdoc = new Constructor(void 0, selected, doc);
166
173
  subdoc.$init(val);
@@ -6,9 +6,9 @@
6
6
 
7
7
  const SchemaType = require('../schematype');
8
8
  const CastError = SchemaType.CastError;
9
- const Decimal128Type = require('../types/decimal128');
10
9
  const castDecimal128 = require('../cast/decimal128');
11
10
  const utils = require('../utils');
11
+ const isBsonType = require('../helpers/isBsonType');
12
12
 
13
13
  /**
14
14
  * Decimal128 SchemaType constructor.
@@ -105,7 +105,7 @@ Decimal128.cast = function cast(caster) {
105
105
  */
106
106
 
107
107
  Decimal128._defaultCaster = v => {
108
- if (v != null && !(v instanceof Decimal128Type)) {
108
+ if (v != null && !isBsonType(v, 'Decimal128')) {
109
109
  throw new Error();
110
110
  }
111
111
  return v;
@@ -115,7 +115,7 @@ Decimal128._defaultCaster = v => {
115
115
  * ignore
116
116
  */
117
117
 
118
- Decimal128._checkRequired = v => v instanceof Decimal128Type;
118
+ Decimal128._checkRequired = v => isBsonType(v, 'Decimal128');
119
119
 
120
120
  /**
121
121
  * Override the function the required validator uses to check whether a string
@@ -164,7 +164,7 @@ Decimal128.prototype.checkRequired = function checkRequired(value, doc) {
164
164
 
165
165
  Decimal128.prototype.cast = function(value, doc, init) {
166
166
  if (SchemaType._isRef(this, value, doc, init)) {
167
- if (value instanceof Decimal128Type) {
167
+ if (isBsonType(value, 'Decimal128')) {
168
168
  return value;
169
169
  }
170
170
 
@@ -391,8 +391,6 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
391
391
  let selected;
392
392
  let subdoc;
393
393
 
394
- options = options || {};
395
-
396
394
  if (!Array.isArray(value)) {
397
395
  if (!init && !DocumentArrayPath.options.castNonArrays) {
398
396
  throw new CastError('DocumentArray', value, this.path, null, this);
@@ -407,7 +405,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
407
405
 
408
406
  // We need to create a new array, otherwise change tracking will
409
407
  // update the old doc (gh-4449)
410
- if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
408
+ if (!options || !options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
411
409
  value = new MongooseDocumentArray(value, this.path, doc);
412
410
  }
413
411
 
@@ -415,7 +413,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
415
413
  value[arrayAtomicsSymbol] = prev[arrayAtomicsSymbol] || {};
416
414
  }
417
415
 
418
- if (options.arrayPathIndex != null) {
416
+ if (options && options.arrayPathIndex != null) {
419
417
  value[arrayPathSymbol] = this.path + '.' + options.arrayPathIndex;
420
418
  }
421
419
 
package/lib/schema/map.js CHANGED
@@ -69,6 +69,14 @@ class Map extends SchemaType {
69
69
  }
70
70
  }
71
71
 
72
+ /**
73
+ * This schema type's name, to defend against minifiers that mangle
74
+ * function names.
75
+ *
76
+ * @api public
77
+ */
78
+ Map.schemaName = 'Map';
79
+
72
80
  Map.prototype.OptionsConstructor = SchemaMapOptions;
73
81
 
74
82
  Map.defaultOptions = {};