mongoose 5.0.2 → 5.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/schema.js CHANGED
@@ -122,16 +122,20 @@ function aliasFields(schema) {
122
122
 
123
123
  if (alias) {
124
124
  if ('string' === typeof alias && alias.length > 0) {
125
- if (schema.aliases[alias])
125
+ if (schema.aliases[alias]) {
126
126
  throw new Error('Duplicate alias, alias ' + alias + ' is used more than once');
127
- else
127
+ } else {
128
128
  schema.aliases[alias] = prop;
129
+ }
129
130
 
130
131
  schema
131
132
  .virtual(alias)
132
133
  .get((function(p) {
133
134
  return function() {
134
- return this.get(p);
135
+ if (typeof this.get === 'function') {
136
+ return this.get(p);
137
+ }
138
+ return this[p];
135
139
  };
136
140
  })(prop))
137
141
  .set((function(p) {
@@ -231,7 +235,6 @@ Schema.prototype.tree;
231
235
 
232
236
  Schema.prototype.clone = function() {
233
237
  var s = new Schema(this.paths, this.options);
234
- // Clone the call queue
235
238
  var cloneOpts = {};
236
239
  s.callQueue = this.callQueue.map(function(f) { return f; });
237
240
  s.methods = utils.clone(this.methods, cloneOpts);
@@ -240,6 +243,7 @@ Schema.prototype.clone = function() {
240
243
  s.plugins = Array.prototype.slice.call(this.plugins);
241
244
  s._indexes = utils.clone(this._indexes, cloneOpts);
242
245
  s.s.hooks = this.s.hooks.clone();
246
+ s.virtuals = utils.clone(this.virtuals, cloneOpts);
243
247
  return s;
244
248
  };
245
249
 
package/lib/schematype.js CHANGED
@@ -773,7 +773,7 @@ SchemaType.prototype.doValidate = function(value, fn, scope) {
773
773
  }
774
774
  if (ok === undefined || ok) {
775
775
  if (--count <= 0) {
776
- setImmediate(function() {
776
+ utils.immediate(function() {
777
777
  fn(null);
778
778
  });
779
779
  }
@@ -781,7 +781,7 @@ SchemaType.prototype.doValidate = function(value, fn, scope) {
781
781
  var ErrorConstructor = validatorProperties.ErrorConstructor || ValidatorError;
782
782
  err = new ErrorConstructor(validatorProperties);
783
783
  err.$isValidatorError = true;
784
- setImmediate(function() {
784
+ utils.immediate(function() {
785
785
  fn(err);
786
786
  });
787
787
  }
@@ -55,7 +55,7 @@ module.exports = function discriminator(model, name, schema) {
55
55
  delete schema.paths._id;
56
56
  delete schema.tree._id;
57
57
  }
58
- utils.merge(schema, baseSchema);
58
+ utils.merge(schema, baseSchema, { omit: { discriminators: true } });
59
59
 
60
60
  var obj = {};
61
61
  obj[key] = {
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const isDefiningProjection = require('./isDefiningProjection');
4
+
5
+ /*!
6
+ * ignore
7
+ */
8
+
9
+ module.exports = function isExclusive(projection) {
10
+ let keys = Object.keys(projection);
11
+ let ki = keys.length;
12
+ let exclude = null;
13
+
14
+ if (ki === 1 && keys[0] === '_id') {
15
+ exclude = !!projection[keys[ki]];
16
+ } else {
17
+ while (ki--) {
18
+ // Does this projection explicitly define inclusion/exclusion?
19
+ // Explicitly avoid `$meta` and `$slice`
20
+ if (keys[ki] !== '_id' && isDefiningProjection(projection[keys[ki]])) {
21
+ exclude = !projection[keys[ki]];
22
+ break;
23
+ }
24
+ }
25
+ }
26
+
27
+ return exclude;
28
+ };
@@ -66,8 +66,10 @@ module.exports = function castUpdate(schema, obj, options, context) {
66
66
  op = ops[i];
67
67
  val = ret[op];
68
68
  hasDollarKey = hasDollarKey || op.charAt(0) === '$';
69
+
69
70
  if (val &&
70
71
  typeof val === 'object' &&
72
+ !Buffer.isBuffer(val) &&
71
73
  (!overwrite || hasDollarKey)) {
72
74
  hasKeys |= walkUpdatePath(schema, val, op, options.strict, context);
73
75
  } else if (overwrite && ret && typeof ret === 'object') {
@@ -111,8 +113,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
111
113
  var key;
112
114
  var val;
113
115
 
114
- var hasError = false;
115
- var aggregatedError = new ValidationError();
116
+ var aggregatedError = null;
116
117
 
117
118
  var useNestedStrict = schema.options.useNestedStrict;
118
119
 
@@ -133,8 +134,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
133
134
  $each: castUpdateVal(schematype, val.$each, op, context)
134
135
  };
135
136
  } catch (error) {
136
- hasError = true;
137
- _handleCastError(error, context, key, aggregatedError);
137
+ aggregatedError = _handleCastError(error, context, key, aggregatedError);
138
138
  }
139
139
 
140
140
  if (val.$slice != null) {
@@ -152,8 +152,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
152
152
  try {
153
153
  obj[key] = castUpdateVal(schematype, val, op, context);
154
154
  } catch (error) {
155
- hasError = true;
156
- _handleCastError(error, context, key, aggregatedError);
155
+ aggregatedError = _handleCastError(error, context, key, aggregatedError);
157
156
  }
158
157
  }
159
158
  } else if ((op === '$currentDate') || (op in castOps && schematype)) {
@@ -161,8 +160,7 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
161
160
  try {
162
161
  obj[key] = castUpdateVal(schematype, val, op, context);
163
162
  } catch (error) {
164
- hasError = true;
165
- _handleCastError(error, context, key, aggregatedError);
163
+ aggregatedError = _handleCastError(error, context, key, aggregatedError);
166
164
  }
167
165
 
168
166
  hasKeys = true;
@@ -228,14 +226,17 @@ function walkUpdatePath(schema, obj, op, strict, context, pref) {
228
226
  try {
229
227
  obj[key] = castUpdateVal(schematype, val, op, key, context);
230
228
  } catch (error) {
231
- hasError = true;
232
- _handleCastError(error, context, key, aggregatedError);
229
+ aggregatedError = _handleCastError(error, context, key, aggregatedError);
230
+ }
231
+
232
+ if (Array.isArray(obj[key]) && (op === '$addToSet' || op === '$push') && key !== '$each') {
233
+ obj[key] = { $each: obj[key] };
233
234
  }
234
235
  }
235
236
  }
236
237
  }
237
238
 
238
- if (hasError) {
239
+ if (aggregatedError != null) {
239
240
  throw aggregatedError;
240
241
  }
241
242
 
@@ -250,7 +251,9 @@ function _handleCastError(error, query, key, aggregatedError) {
250
251
  if (typeof query !== 'object' || !query.options.multipleCastError) {
251
252
  throw error;
252
253
  }
254
+ aggregatedError = aggregatedError || new ValidationError();
253
255
  aggregatedError.addError(key, error);
256
+ return aggregatedError;
254
257
  }
255
258
 
256
259
  /*!
@@ -9,7 +9,7 @@ const cleanModifiedSubpaths = require('../services/document/cleanModifiedSubpath
9
9
  const internalToObjectOptions = require('../options').internalToObjectOptions;
10
10
  const utils = require('../utils');
11
11
 
12
- var isMongooseObject = utils.isMongooseObject;
12
+ const isMongooseObject = utils.isMongooseObject;
13
13
 
14
14
  /**
15
15
  * Mongoose Array constructor.
@@ -237,8 +237,10 @@ MongooseArray.mixin = {
237
237
  var keys = Object.keys(this._atomics);
238
238
  var i = keys.length;
239
239
 
240
+ const opts = Object.assign({}, internalToObjectOptions, { _isNested: true });
241
+
240
242
  if (i === 0) {
241
- ret[0] = ['$set', this.toObject({depopulate: 1, transform: false, _isNested: true, virtuals: false})];
243
+ ret[0] = ['$set', this.toObject(opts)];
242
244
  return ret;
243
245
  }
244
246
 
@@ -250,9 +252,11 @@ MongooseArray.mixin = {
250
252
  // need to convert their elements as if they were MongooseArrays
251
253
  // to handle populated arrays versus DocumentArrays properly.
252
254
  if (isMongooseObject(val)) {
253
- val = val.toObject({depopulate: 1, transform: false, _isNested: true, virtuals: false});
255
+ val = val.toObject(opts);
254
256
  } else if (Array.isArray(val)) {
255
- val = this.toObject.call(val, {depopulate: 1, transform: false, _isNested: true});
257
+ val = this.toObject.call(val, opts);
258
+ } else if (val != null && Array.isArray(val.$each)) {
259
+ val.$each = this.toObject.call(val.$each, opts);
256
260
  } else if (val.valueOf) {
257
261
  val = val.valueOf();
258
262
  }
@@ -6,7 +6,7 @@
6
6
 
7
7
  const Document = require('../document_provider')();
8
8
  const EventEmitter = require('events').EventEmitter;
9
- var internalToObjectOptions = require('../options').internalToObjectOptions;
9
+ const internalToObjectOptions = require('../options').internalToObjectOptions;
10
10
  const utils = require('../utils');
11
11
 
12
12
  /**
@@ -126,7 +126,7 @@ EmbeddedDocument.prototype.save = function(fn) {
126
126
  */
127
127
 
128
128
  EmbeddedDocument.prototype.$__save = function(fn) {
129
- return setImmediate(() => fn(null, this));
129
+ return utils.immediate(() => fn(null, this));
130
130
  };
131
131
 
132
132
  /*!
@@ -55,7 +55,7 @@ Subdocument.prototype.save = function(fn) {
55
55
  */
56
56
 
57
57
  Subdocument.prototype.$__save = function(fn) {
58
- return setImmediate(() => fn(null, this));
58
+ return utils.immediate(() => fn(null, this));
59
59
  };
60
60
 
61
61
  Subdocument.prototype.$isValid = function(path) {
package/lib/utils.js CHANGED
@@ -210,7 +210,7 @@ exports.promiseOrCallback = function promiseOrCallback(callback, fn) {
210
210
  try {
211
211
  return fn(callback);
212
212
  } catch (error) {
213
- return setImmediate(() => {
213
+ return process.nextTick(() => {
214
214
  throw error;
215
215
  });
216
216
  }
@@ -316,9 +316,15 @@ exports.merge = function merge(to, from, options) {
316
316
 
317
317
  while (i < len) {
318
318
  key = keys[i++];
319
+ if (options.omit && options.omit[key]) {
320
+ continue;
321
+ }
319
322
  if (to[key] == null) {
320
323
  to[key] = from[key];
321
324
  } else if (exports.isObject(from[key])) {
325
+ if (!exports.isObject(to[key])) {
326
+ to[key] = {};
327
+ }
322
328
  merge(to[key], from[key], options);
323
329
  } else if (options.overwrite) {
324
330
  to[key] = from[key];
@@ -756,9 +762,13 @@ exports.mergeClone = function(to, fromObj) {
756
762
  flattenDecimals: false
757
763
  });
758
764
  } else {
759
- if (exports.isObject(fromObj[key])) {
760
- var obj = fromObj[key];
761
- if (isMongooseObject(fromObj[key]) && !fromObj[key].isMongooseBuffer) {
765
+ var val = fromObj[key];
766
+ if (val != null && val.valueOf) {
767
+ val = val.valueOf();
768
+ }
769
+ if (exports.isObject(val)) {
770
+ var obj = val;
771
+ if (isMongooseObject(val) && !val.isMongooseBuffer) {
762
772
  obj = obj.toObject({
763
773
  transform: false,
764
774
  virtuals: false,
@@ -767,14 +777,12 @@ exports.mergeClone = function(to, fromObj) {
767
777
  flattenDecimals: false
768
778
  });
769
779
  }
770
- if (fromObj[key].isMongooseBuffer) {
780
+ if (val.isMongooseBuffer) {
771
781
  obj = new Buffer(obj);
772
782
  }
773
783
  exports.mergeClone(to[key], obj);
774
784
  } else {
775
- // make sure to retain key order here because of a bug handling the
776
- // $each operator in mongodb 2.4.4
777
- to[key] = exports.clone(fromObj[key], {
785
+ to[key] = exports.clone(val, {
778
786
  flattenDecimals: false
779
787
  });
780
788
  }
@@ -796,6 +804,17 @@ exports.each = function(arr, fn) {
796
804
  }
797
805
  };
798
806
 
807
+ /*!
808
+ * Centralize this so we can more easily work around issues with people
809
+ * stubbing out `process.nextTick()` in tests using sinon:
810
+ * https://github.com/sinonjs/lolex#automatically-incrementing-mocked-time
811
+ * See gh-6074
812
+ */
813
+
814
+ exports.immediate = function immediate(cb) {
815
+ return process.nextTick(cb);
816
+ };
817
+
799
818
  /*!
800
819
  * ignore
801
820
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "5.0.2",
4
+ "version": "5.0.6",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -21,10 +21,10 @@
21
21
  "dependencies": {
22
22
  "async": "2.1.4",
23
23
  "bson": "~1.0.4",
24
- "kareem": "2.0.2",
24
+ "kareem": "2.0.4",
25
25
  "lodash.get": "4.4.2",
26
- "mongodb": "3.0.1",
27
- "mongoose-legacy-pluralize": "1.0.1",
26
+ "mongodb": "3.0.2",
27
+ "mongoose-legacy-pluralize": "1.0.2",
28
28
  "mpath": "0.3.0",
29
29
  "mquery": "3.0.0",
30
30
  "ms": "2.0.0",
@@ -65,7 +65,7 @@
65
65
  "lint": "eslint . --quiet",
66
66
  "nsp": "nsp check",
67
67
  "release": "git push origin master --tags && npm publish",
68
- "release-legacy": "git push origin 4.x --tags && npm publish --tag 4.x",
68
+ "release-legacy": "git push origin 4.x --tags && npm publish --tag legacy",
69
69
  "test": "mocha --exit test/*.test.js test/**/*.test.js",
70
70
  "test-cov": "nyc --reporter=html --reporter=text npm test"
71
71
  },