mongoose 4.3.0 → 4.3.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.
package/History.md CHANGED
@@ -1,3 +1,38 @@
1
+ 4.3.4 / 2015-12-23
2
+ ==================
3
+ * fix: upgrade mongodb driver to 2.1.2 for repl set error #3712 [sansmischevia](https://github.com/sansmischevia)
4
+ * docs: validation docs typo #3709 [ivanmaeder](https://github.com/ivanmaeder)
5
+ * style: remove unused variables #3708 [ChristianMurphy](https://github.com/ChristianMurphy)
6
+ * fix(schema): duck-typing for schemas #3703 [mgcrea](https://github.com/mgcrea)
7
+ * docs: connection sample code issue #3697
8
+ * fix(schema): duck-typing for schemas #3693 [mgcrea](https://github.com/mgcrea)
9
+ * docs: clarify id schema option #3638
10
+
11
+ 4.3.3 / 2015-12-18
12
+ ==================
13
+ * fix(connection): properly support 'replSet' as well as 'replset' #3688 [taxilian](https://github.com/taxilian)
14
+ * fix(document): single nested doc pre hooks called before nested doc array #3687 [aliatsis](https://github.com/aliatsis)
15
+
16
+ 4.3.2 / 2015-12-17
17
+ ==================
18
+ * fix(document): .set() into single nested schemas #3686
19
+ * fix(connection): support 'replSet' as well as 'replset' option #3685
20
+ * fix(document): bluebird unhandled rejection when validating doc arrays #3681
21
+ * fix(document): hooks for doc arrays in single nested schemas #3680
22
+ * fix(document): post hooks for single nested schemas #3679
23
+ * fix: remove unused npm module #3674 [sybarite](https://github.com/sybarite)
24
+ * fix(model): don't swallow exceptions in nested doc save callback #3671
25
+ * docs: update keepAlive info #3667 [ChrisZieba](https://github.com/ChrisZieba)
26
+ * fix(document): strict 'throw' throws a specific mongoose error #3662
27
+ * fix: flakey test #3332
28
+ * fix(query): more robust check for RegExp #2969
29
+
30
+ 4.3.1 / 2015-12-11
31
+ ==================
32
+ * feat(aggregate): `.sample()` helper #3665
33
+ * fix(query): bitwise query operators with buffers #3663
34
+ * docs(migration): clarify `new` option and findByIdAndUpdate #3661
35
+
1
36
  4.3.0 / 2015-12-09
2
37
  ==================
3
38
  * feat(query): support for mongodb 3.2 bitwise query operators #3660
package/README.md CHANGED
@@ -41,7 +41,7 @@ $ npm install mongoose
41
41
 
42
42
  ## Stability
43
43
 
44
- The current stable branch is [master](https://github.com/Automattic/mongoose/tree/master). The [3.8.x](https://github.com/Automattic/mongoose/tree/3.8.x) branch contains legacy support for the 3.x release series, which will continue to be actively maintained until September 1, 2015.
44
+ The current stable branch is [master](https://github.com/Automattic/mongoose/tree/master). The [3.8.x](https://github.com/Automattic/mongoose/tree/3.8.x) branch contains legacy support for the 3.x release series, which is no longer under active development as of September 2015. The [3.8.x docs](http://mongoosejs.com/docs/3.8.x/) are still available.
45
45
 
46
46
  ## Overview
47
47
 
package/lib/aggregate.js CHANGED
@@ -294,6 +294,23 @@ Aggregate.prototype.lookup = function(options) {
294
294
  return this.append({ $lookup: options });
295
295
  };
296
296
 
297
+ /**
298
+ * Appends new custom $sample operator(s) to this aggregate pipeline.
299
+ *
300
+ * ####Examples:
301
+ *
302
+ * aggregate.sample(3); // Add a pipeline that picks 3 random documents
303
+ *
304
+ * @see $sample https://docs.mongodb.org/manual/reference/operator/aggregation/sample/#pipe._S_sample
305
+ * @param {Number} size number of random documents to pick
306
+ * @return {Aggregate}
307
+ * @api public
308
+ */
309
+
310
+ Aggregate.prototype.sample = function(size) {
311
+ return this.append({ $sample: { size: size } });
312
+ };
313
+
297
314
  /**
298
315
  * Appends a new $sort operator to this aggregate pipeline.
299
316
  *
@@ -28,7 +28,7 @@ function Document(obj, schema, fields, skipId, skipInit) {
28
28
  return new Document( obj, schema, fields, skipId, skipInit );
29
29
 
30
30
 
31
- if (utils.isObject(schema) && !(schema instanceof Schema)) {
31
+ if (utils.isObject(schema) && !schema.instanceOfSchema) {
32
32
  schema = new Schema(schema);
33
33
  }
34
34
 
package/lib/connection.js CHANGED
@@ -619,13 +619,13 @@ Connection.prototype.model = function(name, schema, collection) {
619
619
  schema = false;
620
620
  }
621
621
 
622
- if (utils.isObject(schema) && !(schema instanceof Schema)) {
622
+ if (utils.isObject(schema) && !schema.instanceOfSchema) {
623
623
  schema = new Schema(schema);
624
624
  }
625
625
 
626
626
  if (this.models[name] && !collection) {
627
627
  // model exists but we are not subclassing with custom collection
628
- if (schema instanceof Schema && schema != this.models[name].schema) {
628
+ if (schema && schema.instanceOfSchema && schema != this.models[name].schema) {
629
629
  throw new MongooseError.OverwriteModelError(name);
630
630
  }
631
631
  return this.models[name];
@@ -634,7 +634,7 @@ Connection.prototype.model = function(name, schema, collection) {
634
634
  var opts = { cache: false, connection: this };
635
635
  var model;
636
636
 
637
- if (schema instanceof Schema) {
637
+ if (schema && schema.instanceOfSchema) {
638
638
  // compile a model
639
639
  model = this.base.model(name, schema, collection, opts);
640
640
 
package/lib/document.js CHANGED
@@ -8,6 +8,7 @@ var EventEmitter = require('events').EventEmitter,
8
8
  MongooseError = require('./error'),
9
9
  MixedSchema = require('./schema/mixed'),
10
10
  Schema = require('./schema'),
11
+ StrictModeError = require('./error/strict'),
11
12
  ValidatorError = require('./schematype').ValidatorError,
12
13
  utils = require('./utils'),
13
14
  clone = utils.clone,
@@ -514,7 +515,7 @@ Document.prototype.set = function(path, val, type, options) {
514
515
  this.set(prefix + key,
515
516
  path[key].toObject({ virtuals: false }), constructing);
516
517
  } else if ('throw' == strict) {
517
- throw new Error('Field `' + key + '` is not in schema.');
518
+ throw new StrictModeError(key);
518
519
  }
519
520
  } else if (undefined !== path[key]) {
520
521
  this.set(prefix + key, path[key], constructing);
@@ -560,7 +561,7 @@ Document.prototype.set = function(path, val, type, options) {
560
561
 
561
562
  if (!mixed) {
562
563
  if ('throw' == strict) {
563
- throw new Error("Field `" + path + "` is not in schema.");
564
+ throw new StrictModeError(path);
564
565
  }
565
566
  return this;
566
567
  }
@@ -742,6 +743,8 @@ Document.prototype.$__set = function(
742
743
  obj = obj[parts[i]];
743
744
  } else if (obj[parts[i]] && obj[parts[i]] instanceof Embedded) {
744
745
  obj = obj[parts[i]];
746
+ } else if (obj[parts[i]] && obj[parts[i]].$isSingleNested) {
747
+ obj = obj[parts[i]];
745
748
  } else if (obj[parts[i]] && Array.isArray(obj[parts[i]])) {
746
749
  obj = obj[parts[i]];
747
750
  } else {
@@ -1628,6 +1631,7 @@ Document.prototype.$__getAllSubdocs = function() {
1628
1631
 
1629
1632
  if (val instanceof Embedded) seed.push(val);
1630
1633
  if (val && val.$isSingleNested) {
1634
+ seed = Object.keys(val._doc).reduce(docReducer.bind(val._doc), seed);
1631
1635
  seed.push(val);
1632
1636
  }
1633
1637
  if (val && val.isMongooseDocumentArray) {
@@ -188,7 +188,7 @@ NativeConnection.prototype.doOpenSet = function(fn) {
188
188
 
189
189
  var server = this.options.mongos
190
190
  ? new Mongos(servers, this.options.mongos)
191
- : new ReplSetServers(servers, this.options.replset);
191
+ : new ReplSetServers(servers, this.options.replset || this.options.replSet);
192
192
  this.db = new Db(this.name, server, this.options.db);
193
193
 
194
194
  this.db.on('fullsetup', function() {
@@ -232,7 +232,7 @@ NativeConnection.prototype.parseOptions = function(passed, connStrOpts) {
232
232
  o.db || (o.db = {});
233
233
  o.auth || (o.auth = {});
234
234
  o.server || (o.server = {});
235
- o.replset || (o.replset = {});
235
+ o.replset || (o.replset = o.replSet) || (o.replset = {});
236
236
  o.server.socketOptions || (o.server.socketOptions = {});
237
237
  o.replset.socketOptions || (o.replset.socketOptions = {});
238
238
 
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * Module dependencies.
3
+ */
4
+
5
+ var MongooseError = require('../error.js');
6
+
7
+ /**
8
+ * Strict mode error constructor
9
+ *
10
+ * @param {String} type
11
+ * @param {String} value
12
+ * @inherits MongooseError
13
+ * @api private
14
+ */
15
+
16
+ function StrictModeError(path) {
17
+ MongooseError.call(this, 'Field `' + path + '` is not in schema and strict ' +
18
+ 'mode is set to throw.');
19
+ if (Error.captureStackTrace) {
20
+ Error.captureStackTrace(this);
21
+ } else {
22
+ this.stack = new Error().stack;
23
+ }
24
+ this.name = 'StrictModeError';
25
+ this.path = path;
26
+ }
27
+
28
+ /*!
29
+ * Inherits from MongooseError.
30
+ */
31
+
32
+ StrictModeError.prototype = Object.create(MongooseError.prototype);
33
+ StrictModeError.prototype.constructor = MongooseError;
34
+
35
+ module.exports = StrictModeError;
package/lib/index.js CHANGED
@@ -307,7 +307,7 @@ Mongoose.prototype.model = function(name, schema, collection, skipInit) {
307
307
  schema = false;
308
308
  }
309
309
 
310
- if (utils.isObject(schema) && !(schema instanceof Schema)) {
310
+ if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
311
311
  schema = new Schema(schema);
312
312
  }
313
313
 
@@ -342,7 +342,7 @@ Mongoose.prototype.model = function(name, schema, collection, skipInit) {
342
342
  // connection.model() may be passing a different schema for
343
343
  // an existing model name. in this case don't read from cache.
344
344
  if (this.models[name] && false !== options.cache) {
345
- if (schema instanceof Schema && schema != this.models[name].schema) {
345
+ if (schema && schema.instanceOfSchema && schema != this.models[name].schema) {
346
346
  throw new mongoose.Error.OverwriteModelError(name);
347
347
  }
348
348
 
package/lib/model.js CHANGED
@@ -775,7 +775,7 @@ Model.prototype.model = function model(name) {
775
775
  */
776
776
 
777
777
  Model.discriminator = function discriminator(name, schema) {
778
- if (!(schema instanceof Schema)) {
778
+ if (!(schema && schema.instanceOfSchema)) {
779
779
  throw new Error("You must pass a valid discriminator Schema");
780
780
  }
781
781
 
package/lib/query.js CHANGED
@@ -13,6 +13,7 @@ var utils = require('./utils');
13
13
  var helpers = require('./queryhelpers');
14
14
  var Document = require('./document');
15
15
  var QueryStream = require('./querystream');
16
+ var StrictModeError = require('./error/strict');
16
17
  var cast = require('./cast');
17
18
 
18
19
  /**
@@ -847,7 +848,7 @@ Query.prototype.read = function read(pref, tags) {
847
848
  * - [sort](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsort(\)%7D%7D) *
848
849
  * - [limit](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Blimit%28%29%7D%7D) *
849
850
  * - [skip](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bskip%28%29%7D%7D) *
850
- * - [maxscan](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24maxScan) *
851
+ * - [maxscan](https://docs.mongodb.org/v3.2/reference/operator/meta/maxScan/#metaOp._S_maxScan) *
851
852
  * - [batchSize](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7BbatchSize%28%29%7D%7D) *
852
853
  * - [comment](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24comment) *
853
854
  * - [snapshot](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%7B%7Bsnapshot%28%29%7D%7D) *
@@ -2342,7 +2343,7 @@ Query.prototype._walkUpdatePath = function _walkUpdatePath(obj, op, pref) {
2342
2343
  this.model.schema.pathType(positionalPath) === 'adhocOrUndefined' &&
2343
2344
  !this.model.schema.hasMixedParent(positionalPath)) {
2344
2345
  if (strict === 'throw') {
2345
- throw new Error('Field `' + pathToCheck + '` is not in schema.');
2346
+ throw new StrictModeError(pathToCheck);
2346
2347
  } else if (strict) {
2347
2348
  delete obj[key];
2348
2349
  continue;
@@ -2365,8 +2366,8 @@ Query.prototype._walkUpdatePath = function _walkUpdatePath(obj, op, pref) {
2365
2366
  !/real|nested/.test(this.model.schema.pathType(prefix + key));
2366
2367
 
2367
2368
  if (skip) {
2368
- if ('throw' == strict) {
2369
- throw new Error('Field `' + prefix + key + '` is not in schema.');
2369
+ if (strict === 'throw') {
2370
+ throw new StrictModeError(prefix + key);
2370
2371
  } else {
2371
2372
  delete obj[key];
2372
2373
  }
@@ -2,6 +2,7 @@
2
2
  * Module dependencies.
3
3
  */
4
4
 
5
+ var handleBitwiseOperator = require('./operators/bitwise');
5
6
  var utils = require('../utils');
6
7
 
7
8
  var MongooseBuffer = require('../types').Buffer;
@@ -140,6 +141,10 @@ function handleSingle(val) {
140
141
 
141
142
  SchemaBuffer.prototype.$conditionalHandlers =
142
143
  utils.options(SchemaType.prototype.$conditionalHandlers, {
144
+ '$bitsAllClear': handleBitwiseOperator,
145
+ '$bitsAnyClear': handleBitwiseOperator,
146
+ '$bitsAllSet': handleBitwiseOperator,
147
+ '$bitsAnySet': handleBitwiseOperator,
143
148
  '$gt' : handleSingle,
144
149
  '$gte': handleSingle,
145
150
  '$lt' : handleSingle,
@@ -97,7 +97,7 @@ DocumentArray.prototype.doValidate = function(array, fn, scope) {
97
97
  continue;
98
98
  }
99
99
 
100
- doc.validate(function(err) {
100
+ doc.validate({ __noPromise: true }, function(err) {
101
101
  if (err) {
102
102
  error = err;
103
103
  }
@@ -14,8 +14,15 @@ module.exports = Embedded;
14
14
  */
15
15
 
16
16
  function Embedded(schema, path, options) {
17
- var _embedded = function() {
17
+ var _embedded = function(value, path, parent) {
18
+ var _this = this;
18
19
  Subdocument.apply(this, arguments);
20
+ this.$parent = parent;
21
+ if (parent) {
22
+ parent.on('save', function() {
23
+ _this.emit('save', _this);
24
+ });
25
+ }
19
26
  };
20
27
  _embedded.prototype = Object.create(Subdocument.prototype);
21
28
  _embedded.prototype.$__setSchema(schema);
@@ -52,8 +59,7 @@ Embedded.prototype.cast = function(val, doc, init) {
52
59
  if (val && val.$isSingleNested) {
53
60
  return val;
54
61
  }
55
- var subdoc = new this.caster();
56
- subdoc.$parent = doc;
62
+ var subdoc = new this.caster(undefined, undefined, doc);
57
63
  if (init) {
58
64
  subdoc.init(val);
59
65
  } else {
@@ -2,11 +2,12 @@
2
2
  * Module requirements.
3
3
  */
4
4
 
5
- var SchemaType = require('../schematype'),
6
- CastError = SchemaType.CastError,
7
- errorMessages = require('../error').messages,
8
- utils = require('../utils'),
9
- Document;
5
+ var SchemaType = require('../schematype');
6
+ var CastError = SchemaType.CastError;
7
+ var handleBitwiseOperator = require('./operators/bitwise');
8
+ var errorMessages = require('../error').messages;
9
+ var utils = require('../utils');
10
+ var Document;
10
11
 
11
12
  /**
12
13
  * Number SchemaType constructor.
@@ -239,18 +240,6 @@ function handleArray(val) {
239
240
  });
240
241
  }
241
242
 
242
- function handleBitwiseOperator(val) {
243
- var _this = this;
244
- if (Array.isArray(val)) {
245
- return val.map(function(v) { return _this.cast(v); });
246
- } else if (Buffer.isBuffer(val)) {
247
- return val;
248
- } else {
249
- // Assume trying to cast to number
250
- return this.cast(val);
251
- }
252
- }
253
-
254
243
  SchemaNumber.prototype.$conditionalHandlers =
255
244
  utils.options(SchemaType.prototype.$conditionalHandlers, {
256
245
  '$bitsAllClear': handleBitwiseOperator,
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * Module requirements.
3
+ */
4
+
5
+ var CastError = require('../../error/cast');
6
+
7
+ /*!
8
+ * ignore
9
+ */
10
+
11
+ function handleBitwiseOperator(val) {
12
+ var _this = this;
13
+ if (Array.isArray(val)) {
14
+ return val.map(function(v) {
15
+ return _castNumber(_this, v);
16
+ });
17
+ } else if (Buffer.isBuffer(val)) {
18
+ return val;
19
+ } else {
20
+ // Assume trying to cast to number
21
+ return _castNumber(_this, val);
22
+ }
23
+ }
24
+
25
+ /*!
26
+ * ignore
27
+ */
28
+
29
+ function _castNumber(_this, num) {
30
+ var v = Number(num);
31
+ if (isNaN(v)) {
32
+ throw new CastError('number', num, _this.path);
33
+ }
34
+ return v;
35
+ }
36
+
37
+ module.exports = handleBitwiseOperator;
@@ -3,11 +3,11 @@
3
3
  * Module dependencies.
4
4
  */
5
5
 
6
- var SchemaType = require('../schematype'),
7
- CastError = SchemaType.CastError,
8
- errorMessages = require('../error').messages,
9
- utils = require('../utils'),
10
- Document;
6
+ var SchemaType = require('../schematype');
7
+ var CastError = SchemaType.CastError;
8
+ var errorMessages = require('../error').messages;
9
+ var utils = require('../utils');
10
+ var Document;
11
11
 
12
12
  /**
13
13
  * String SchemaType constructor.
@@ -480,7 +480,9 @@ SchemaString.prototype.castForQuery = function($conditional, val) {
480
480
  return handler.call(this, val);
481
481
  } else {
482
482
  val = $conditional;
483
- if (val instanceof RegExp) return val;
483
+ if (Object.prototype.toString.call(val) === '[object RegExp]') {
484
+ return val;
485
+ }
484
486
  return this.cast(val);
485
487
  }
486
488
  };
package/lib/schema.js CHANGED
@@ -9,7 +9,6 @@ var utils = require('./utils');
9
9
  var MongooseTypes;
10
10
  var Kareem = require('kareem');
11
11
  var async = require('async');
12
- var PromiseProvider = require('./promise_provider');
13
12
 
14
13
  var IS_QUERY_HOOK = {
15
14
  count: true,
@@ -186,6 +185,7 @@ function idGetter() {
186
185
  */
187
186
  Schema.prototype = Object.create( EventEmitter.prototype );
188
187
  Schema.prototype.constructor = Schema;
188
+ Schema.prototype.instanceOfSchema = true;
189
189
 
190
190
  /**
191
191
  * Default middleware attached to a schema. Cannot be changed.
@@ -243,8 +243,7 @@ Object.defineProperty(Schema.prototype, '_defaultMiddleware', {
243
243
  hook: 'save',
244
244
  isAsync: true,
245
245
  fn: function(next, done) {
246
- var Promise = PromiseProvider.get(),
247
- subdocs = this.$__getAllSubdocs();
246
+ var subdocs = this.$__getAllSubdocs();
248
247
 
249
248
  if (!subdocs.length || this.$__preSavingFromParent) {
250
249
  done();
@@ -252,26 +251,22 @@ Object.defineProperty(Schema.prototype, '_defaultMiddleware', {
252
251
  return;
253
252
  }
254
253
 
255
- new Promise.ES6(function(resolve, reject) {
256
- async.each(subdocs, function(subdoc, cb) {
257
- subdoc.$__preSavingFromParent = true;
258
- subdoc.save(function(err) {
259
- cb(err);
260
- });
261
- }, function(error) {
262
- for (var i = 0; i < subdocs.length; ++i) {
263
- delete subdocs[i].$__preSavingFromParent;
264
- }
265
- if (error) {
266
- reject(error);
267
- return;
268
- }
269
- resolve();
254
+ async.each(subdocs, function(subdoc, cb) {
255
+ subdoc.$__preSavingFromParent = true;
256
+ subdoc.save(function(err) {
257
+ cb(err);
270
258
  });
271
- }).then(function() {
259
+ }, function(error) {
260
+ for (var i = 0; i < subdocs.length; ++i) {
261
+ delete subdocs[i].$__preSavingFromParent;
262
+ }
263
+ if (error) {
264
+ done(error);
265
+ return;
266
+ }
272
267
  next();
273
268
  done();
274
- }, done);
269
+ });
275
270
  }
276
271
  }]
277
272
  });
@@ -460,6 +455,9 @@ Schema.prototype.path = function(path, obj) {
460
455
  if (obj == undefined) {
461
456
  if (this.paths[path]) return this.paths[path];
462
457
  if (this.subpaths[path]) return this.subpaths[path];
458
+ if (this.singleNestedPaths[path]) {
459
+ return this.singleNestedPaths[path];
460
+ }
463
461
 
464
462
  // subpaths?
465
463
  return /\.\d+\.?.*$/.test(path)
@@ -541,7 +539,7 @@ Schema.interpretAsType = function(path, obj, options) {
541
539
  ? obj.cast
542
540
  : type[0];
543
541
 
544
- if (cast instanceof Schema) {
542
+ if (cast && cast.instanceOfSchema) {
545
543
  return new MongooseTypes.DocumentArray(path, cast, obj);
546
544
  }
547
545
 
@@ -565,7 +563,7 @@ Schema.interpretAsType = function(path, obj, options) {
565
563
  return new MongooseTypes.Array(path, cast || MongooseTypes.Mixed, obj);
566
564
  }
567
565
 
568
- if (type instanceof Schema) {
566
+ if (type && type.instanceOfSchema) {
569
567
  return new MongooseTypes.Embedded(type, path, obj);
570
568
  }
571
569
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "4.3.0",
4
+ "version": "4.3.4",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -23,7 +23,7 @@
23
23
  "bson": "0.4.19",
24
24
  "hooks-fixed": "1.1.0",
25
25
  "kareem": "1.0.1",
26
- "mongodb": "2.1.0",
26
+ "mongodb": "2.1.2",
27
27
  "mpath": "0.1.1",
28
28
  "mpromise": "0.5.4",
29
29
  "mquery": "1.6.3",
package/contRun.sh DELETED
@@ -1,10 +0,0 @@
1
- #!/bin/bash
2
-
3
- make test
4
-
5
- ret=$?
6
-
7
- while [ $ret == 0 ]; do
8
- make test
9
- ret=$?
10
- done