mongoose 4.11.14 → 4.12.3

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/History.md CHANGED
@@ -1,3 +1,44 @@
1
+ 4.12.3 / 2017-10-16
2
+ ===================
3
+ * fix(connection): emit 'reconnect' event as well as 'reconnected' for consistency with driver #5719
4
+ * fix: correctly bubble up left/joined events for replica set #5718
5
+ * fix(connection): allow passing in `autoIndex` as top-level option rather than requiring `config.autoIndex` #5711
6
+ * docs(connection): improve docs regarding reconnectTries, autoReconnect, and bufferMaxEntries #5711
7
+ * fix(query): handle null with addToSet/push/pull/pullAll update validators #5710
8
+ * fix(model): handle setDefaultsOnInsert option for bulkWrite updateOne and updateMany #5708
9
+ * fix(query): avoid infinite recursion edge case when cloning a buffer #5702
10
+
11
+ 4.12.2 / 2017-10-14
12
+ ===================
13
+ * docs(faq): add FAQ about using arrow functions for getters/setters, virtuals, and methods #5700
14
+ * docs(schema): document the childSchemas property and add to public API #5695
15
+ * fix(query): don't project in populated field if parent field is already projected in #5669
16
+ * fix: bump mongodb -> 2.2.33 for issue with autoReconnect #4513
17
+
18
+ 4.12.1 / 2017-10-08
19
+ ===================
20
+ * fix(document): create new doc when setting single nested, no more set() on copy of priorVal #5693
21
+ * fix(model): recursively call applyMethods on child schemas for global plugins #5690
22
+ * docs: fix bad promise lib example on home page #5686
23
+ * fix(query): handle false when checking for inclusive/exclusive projection #5685
24
+ * fix(discriminator): allow reusing child schema #5684
25
+ * fix: make addToSet() on empty array with subdoc trigger manual population #5504
26
+
27
+ 4.12.0 / 2017-10-02
28
+ ===================
29
+ * docs(validation): add docs coverage for ValidatorError.reason #5681
30
+ * feat(discriminator): always add discriminatorKey to base schema to allow updating #5613
31
+ * fix(document): make nested docs no longer inherit parent doc's schema props #5586 #5546 #5470
32
+ * feat(query): run update validators on $pull and $pullAll #5555
33
+ * feat(query): add .error() helper to query to error out in pre hooks #5520
34
+ * feat(connection): add dropCollection() helper #5393
35
+ * feat(schema): add schema-level collation option #5295
36
+ * feat(types): add `discriminator()` function for single nested subdocs #5244
37
+ * feat(document): add $isDeleted() getter/setter for better support for soft deletes #4428
38
+ * feat(connection): bubble up reconnectFailed event when driver gives up reconnecting #4027
39
+ * fix(query): report error if passing array or other non-object as filter to update query #3677
40
+ * fix(collection): use createIndex() instead of deprecated ensureIndex() #3280
41
+
1
42
  4.11.14 / 2017-09-30
2
43
  ====================
3
44
  * chore: add nsp check to the CI build #5679 [hairyhenderson](https://github.com/hairyhenderson)
package/lib/aggregate.js CHANGED
@@ -63,10 +63,15 @@ function Aggregate() {
63
63
 
64
64
  Aggregate.prototype.model = function(model) {
65
65
  this._model = model;
66
- if (this.options.readPreference == null &&
67
- model.schema &&
68
- model.schema.options.read != null) {
69
- this.options.readPreference = model.schema.options.read;
66
+ if (model.schema != null) {
67
+ if (this.options.readPreference == null &&
68
+ model.schema.options.read != null) {
69
+ this.options.readPreference = model.schema.options.read;
70
+ }
71
+ if (this.options.collation == null &&
72
+ model.schema.options.collation != null) {
73
+ this.options.collation = model.schema.options.collation;
74
+ }
70
75
  }
71
76
  return this;
72
77
  };
package/lib/collection.js CHANGED
@@ -139,6 +139,14 @@ Collection.prototype.ensureIndex = function() {
139
139
  throw new Error('Collection#ensureIndex unimplemented by driver');
140
140
  };
141
141
 
142
+ /**
143
+ * Abstract method that drivers must implement.
144
+ */
145
+
146
+ Collection.prototype.createIndex = function() {
147
+ throw new Error('Collection#ensureIndex unimplemented by driver');
148
+ };
149
+
142
150
  /**
143
151
  * Abstract method that drivers must implement.
144
152
  */
package/lib/connection.js CHANGED
@@ -369,42 +369,70 @@ Connection.prototype._openWithoutPromise = function() {
369
369
  };
370
370
 
371
371
  /**
372
- * Helper for `dropDatabase()`.
372
+ * Helper for `dropCollection()`. Will delete the given collection, including
373
+ * all documents and indexes.
373
374
  *
374
- * @param {Function} callback
375
+ * @param {string} collection The collection to delete
376
+ * @param {Function} [callback]
375
377
  * @return {Promise}
376
378
  * @api public
377
379
  */
378
380
 
379
- Connection.prototype.dropDatabase = function(callback) {
380
- var Promise = PromiseProvider.get();
381
- var _this = this;
382
- var promise = new Promise.ES6(function(resolve, reject) {
383
- if (_this.readyState !== STATES.connected) {
384
- _this.on('open', function() {
385
- _this.db.dropDatabase(function(error) {
381
+ Connection.prototype.dropCollection = _wrapConnHelper(function dropCollection(collection, cb) {
382
+ this.db.dropCollection(collection, cb);
383
+ });
384
+
385
+ /**
386
+ * Helper for `dropDatabase()`. Deletes the given database, including all
387
+ * collections, documents, and indexes.
388
+ *
389
+ * @param {Function} [callback]
390
+ * @return {Promise}
391
+ * @api public
392
+ */
393
+
394
+ Connection.prototype.dropDatabase = _wrapConnHelper(function dropDatabase(cb) {
395
+ this.db.dropDatabase(cb);
396
+ });
397
+
398
+ /*!
399
+ * ignore
400
+ */
401
+
402
+ function _wrapConnHelper(fn) {
403
+ return function() {
404
+ var _this = this;
405
+ var Promise = PromiseProvider.get();
406
+ var argsWithoutCb = Array.prototype.slice.call(arguments, 0, fn.length - 1);
407
+ var cb = arguments[arguments.length - 1];
408
+ var promise = new Promise.ES6(function(resolve, reject) {
409
+ if (_this.readyState !== STATES.connected) {
410
+ _this.on('open', function() {
411
+ fn.apply(_this, argsWithoutCb.concat([function(error) {
412
+ if (error) {
413
+ reject(error);
414
+ } else {
415
+ resolve();
416
+ }
417
+ }]));
418
+ });
419
+ } else {
420
+ fn.apply(_this, argsWithoutCb.concat([function(error) {
386
421
  if (error) {
387
422
  reject(error);
388
423
  } else {
389
424
  resolve();
390
425
  }
391
- });
392
- });
393
- } else {
394
- _this.db.dropDatabase(function(error) {
395
- if (error) {
396
- reject(error);
397
- } else {
398
- resolve();
399
- }
400
- });
426
+ }]));
427
+ }
428
+ });
429
+ if (cb) {
430
+ promise.
431
+ then(function() { cb(); }, function(error) { cb(error); });
401
432
  }
402
- });
403
- if (callback) {
404
- promise.then(function() { callback(); }, callback);
405
- }
406
- return promise;
407
- };
433
+ return promise;
434
+ };
435
+ }
408
436
 
409
437
  /*!
410
438
  * ignore
@@ -735,9 +763,13 @@ Connection.prototype.openUri = function(uri, options, callback) {
735
763
  if (options) {
736
764
  options = utils.clone(options, { retainKeyOrder: true });
737
765
  delete options.useMongoClient;
738
- if (options.config && options.config.autoIndex != null) {
739
- this.config.autoIndex = options.config.autoIndex !== false;
766
+ var autoIndex = options.config && options.config.autoIndex != null ?
767
+ options.config.autoIndex :
768
+ options.autoIndex;
769
+ if (autoIndex != null) {
770
+ this.config.autoIndex = autoIndex !== false;
740
771
  delete options.config;
772
+ delete options.autoIndex;
741
773
  }
742
774
 
743
775
  // Backwards compat
@@ -767,8 +799,12 @@ Connection.prototype.openUri = function(uri, options, callback) {
767
799
  // Backwards compat for mongoose 4.x
768
800
  db.on('reconnect', function() {
769
801
  _this.readyState = STATES.connected;
802
+ _this.emit('reconnect');
770
803
  _this.emit('reconnected');
771
804
  });
805
+ db.s.topology.on('reconnectFailed', function() {
806
+ _this.emit('reconnectFailed');
807
+ });
772
808
  db.s.topology.on('close', function() {
773
809
  // Implicitly emits 'disconnected'
774
810
  _this.readyState = STATES.disconnected;
package/lib/document.js CHANGED
@@ -41,11 +41,12 @@ var idGetter = require('./plugins/idGetter');
41
41
  * @api private
42
42
  */
43
43
 
44
- function Document(obj, fields, skipId) {
44
+ function Document(obj, fields, skipId, options) {
45
45
  this.$__ = new InternalCache;
46
46
  this.$__.emitter = new EventEmitter();
47
47
  this.isNew = true;
48
48
  this.errors = undefined;
49
+ this.$__.$options = options || {};
49
50
 
50
51
  var schema = this.schema;
51
52
 
@@ -757,7 +758,10 @@ Document.prototype.set = function(path, val, type, options) {
757
758
  didPopulate = true;
758
759
  }
759
760
 
760
- val = schema.applySetters(val, this, false, priorVal);
761
+ var setterContext = constructing && this.$__.$options.priorDoc ?
762
+ this.$__.$options.priorDoc :
763
+ this;
764
+ val = schema.applySetters(val, setterContext, false, priorVal);
761
765
 
762
766
  if (!didPopulate && this.$__.populated) {
763
767
  delete this.$__.populated[path];
@@ -1126,6 +1130,33 @@ Document.prototype.$isDefault = function(path) {
1126
1130
  return (path in this.$__.activePaths.states.default);
1127
1131
  };
1128
1132
 
1133
+ /**
1134
+ * Getter/setter, determines whether the document was removed or not.
1135
+ *
1136
+ * ####Example:
1137
+ * product.remove(function (err, product) {
1138
+ * product.isDeleted(); // true
1139
+ * product.remove(); // no-op, doesn't send anything to the db
1140
+ *
1141
+ * product.isDeleted(false);
1142
+ * product.isDeleted(); // false
1143
+ * product.remove(); // will execute a remove against the db
1144
+ * })
1145
+ *
1146
+ * @param {Boolean} [val] optional, overrides whether mongoose thinks the doc is deleted
1147
+ * @return {Boolean} whether mongoose thinks this doc is deleted.
1148
+ * @api public
1149
+ */
1150
+
1151
+ Document.prototype.$isDeleted = function(val) {
1152
+ if (arguments.length === 0) {
1153
+ return !!this.$__.isDeleted;
1154
+ }
1155
+
1156
+ this.$__.isDeleted = !!val;
1157
+ return this;
1158
+ };
1159
+
1129
1160
  /**
1130
1161
  * Returns true if `path` was directly set and modified, else false.
1131
1162
  *
@@ -2,9 +2,10 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseCollection = require('../../collection'),
6
- Collection = require('mongodb').Collection,
7
- utils = require('../../utils');
5
+ var MongooseCollection = require('../../collection');
6
+ var Collection = require('mongodb').Collection;
7
+ var util = require('util');
8
+ var utils = require('../../utils');
8
9
 
9
10
  /**
10
11
  * A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
@@ -155,6 +156,13 @@ for (var i in Collection.prototype) {
155
156
  iter(i);
156
157
  }
157
158
 
159
+ /*!
160
+ * ignore
161
+ */
162
+
163
+ Collection.prototype.ensureIndex = util.deprecate(Collection.prototype.ensureIndex,
164
+ '`ensureIndex()` is deprecated in Mongoose >= 4.12.0, use `createIndex()` instead');
165
+
158
166
  /**
159
167
  * Debug print helper
160
168
  *
@@ -162,6 +162,7 @@ function listen(conn) {
162
162
  });
163
163
  conn.db.on('reconnect', function() {
164
164
  conn.readyState = STATES.connected;
165
+ conn.emit('reconnect');
165
166
  conn.emit('reconnected');
166
167
  conn.onOpen();
167
168
  });
@@ -171,6 +172,7 @@ function listen(conn) {
171
172
  conn.db.on('open', function(err, db) {
172
173
  if (STATES.disconnected === conn.readyState && db && db.databaseName) {
173
174
  conn.readyState = STATES.connected;
175
+ conn.emit('reconnect');
174
176
  conn.emit('reconnected');
175
177
  }
176
178
  });
@@ -204,6 +206,14 @@ NativeConnection.prototype.doOpenSet = function(fn) {
204
206
  : new ReplSetServers(servers, this.options.replset || this.options.replSet);
205
207
  this.db = new Db(this.name, server, this.options.db);
206
208
 
209
+ this.db.s.topology.on('left', function(data) {
210
+ _this.emit('left', data);
211
+ });
212
+
213
+ this.db.s.topology.on('joined', function(data) {
214
+ _this.emit('joined', data);
215
+ });
216
+
207
217
  this.db.on('fullsetup', function() {
208
218
  _this.emit('fullsetup');
209
219
  });
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
 
7
7
  /*!
8
8
  * MissingSchema Error constructor.
package/lib/error/cast.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
  var util = require('util');
7
7
 
8
8
  /**
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
 
7
7
  /**
8
8
  * Casting Error constructor.
@@ -3,7 +3,7 @@
3
3
  * Module dependencies.
4
4
  */
5
5
 
6
- var MongooseError = require('../error.js');
6
+ var MongooseError = require('./');
7
7
 
8
8
  /*!
9
9
  * DivergentArrayError constructor.
@@ -37,7 +37,7 @@ module.exports = exports = MongooseError;
37
37
  * @api public
38
38
  */
39
39
 
40
- MongooseError.messages = require('./error/messages');
40
+ MongooseError.messages = require('./messages');
41
41
 
42
42
  // backward compat
43
43
  MongooseError.Messages = MongooseError.messages;
@@ -51,16 +51,16 @@ MongooseError.Messages = MongooseError.messages;
51
51
  * @api public
52
52
  */
53
53
 
54
- MongooseError.DocumentNotFoundError = require('./error/notFound');
54
+ MongooseError.DocumentNotFoundError = require('./notFound');
55
55
 
56
56
  /*!
57
57
  * Expose subclasses
58
58
  */
59
59
 
60
- MongooseError.CastError = require('./error/cast');
61
- MongooseError.ValidationError = require('./error/validation');
62
- MongooseError.ValidatorError = require('./error/validator');
63
- MongooseError.VersionError = require('./error/version');
64
- MongooseError.OverwriteModelError = require('./error/overwriteModel');
65
- MongooseError.MissingSchemaError = require('./error/missingSchema');
66
- MongooseError.DivergentArrayError = require('./error/divergentArray');
60
+ MongooseError.CastError = require('./cast');
61
+ MongooseError.ValidationError = require('./validation');
62
+ MongooseError.ValidatorError = require('./validator');
63
+ MongooseError.VersionError = require('./version');
64
+ MongooseError.OverwriteModelError = require('./overwriteModel');
65
+ MongooseError.MissingSchemaError = require('./missingSchema');
66
+ MongooseError.DivergentArrayError = require('./divergentArray');
@@ -3,7 +3,7 @@
3
3
  * Module dependencies.
4
4
  */
5
5
 
6
- var MongooseError = require('../error.js');
6
+ var MongooseError = require('./');
7
7
 
8
8
  /*!
9
9
  * MissingSchema Error constructor.
@@ -4,7 +4,7 @@
4
4
  * Module dependencies.
5
5
  */
6
6
 
7
- var MongooseError = require('../error.js');
7
+ var MongooseError = require('./');
8
8
  var util = require('util');
9
9
 
10
10
  /*!
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
 
7
7
  /**
8
8
  * Strict mode error constructor
@@ -0,0 +1,36 @@
1
+ /*!
2
+ * Module dependencies.
3
+ */
4
+
5
+ var MongooseError = require('./');
6
+
7
+ /**
8
+ * Constructor for errors that happen when a parameter that's expected to be
9
+ * an object isn't an object
10
+ *
11
+ * @param {Any} value
12
+ * @param {String} paramName
13
+ * @param {String} fnName
14
+ * @inherits MongooseError
15
+ * @api private
16
+ */
17
+
18
+ function ObjectParameterError(value, paramName, fnName) {
19
+ MongooseError.call(this, 'Parameter "' + paramName + '" to ' + fnName +
20
+ '() must be an object, got ' + value.toString());
21
+ this.name = 'ObjectParameterError';
22
+ if (Error.captureStackTrace) {
23
+ Error.captureStackTrace(this);
24
+ } else {
25
+ this.stack = new Error().stack;
26
+ }
27
+ }
28
+
29
+ /*!
30
+ * Inherits from MongooseError.
31
+ */
32
+
33
+ ObjectParameterError.prototype = Object.create(MongooseError.prototype);
34
+ ObjectParameterError.prototype.constructor = MongooseError;
35
+
36
+ module.exports = ObjectParameterError;
@@ -3,7 +3,7 @@
3
3
  * Module dependencies.
4
4
  */
5
5
 
6
- var MongooseError = require('../error.js');
6
+ var MongooseError = require('./');
7
7
 
8
8
  /*!
9
9
  * OverwriteModel Error constructor.
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
 
7
7
  /**
8
8
  * Strict mode error constructor
@@ -2,7 +2,7 @@
2
2
  * Module requirements
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
  var utils = require('../utils');
7
7
 
8
8
  /**
@@ -2,7 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
- var MongooseError = require('../error.js');
5
+ var MongooseError = require('./');
6
6
 
7
7
  /**
8
8
  * Schema validator error
@@ -4,7 +4,7 @@
4
4
  * Module dependencies.
5
5
  */
6
6
 
7
- var MongooseError = require('../error.js');
7
+ var MongooseError = require('./');
8
8
 
9
9
  /**
10
10
  * Version Error constructor.