mongoose 4.13.8 → 4.13.12

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,28 @@
1
+ 4.13.12 / 2018-03-13
2
+ ====================
3
+ * fix(document): make virtual get() return undefined instead of null if no getters #6223
4
+ * docs: fix url in useMongoClient error message #6219 #6217 [lineus](https://github.com/lineus)
5
+ * fix(discriminator): don't copy `discriminators` property from base schema #6122 #6064
6
+
7
+ 4.13.11 / 2018-02-07
8
+ ====================
9
+ * docs: fix links in 4.x docs #6081
10
+ * chore: add release script that uses --tag for npm publish for 4.x releases #6063
11
+
12
+ 4.13.10 / 2018-01-28
13
+ ====================
14
+ * docs(model+query): add lean() option to Model helpers #5996 [aguyinmontreal](https://github.com/aguyinmontreal)
15
+ * fix: use lazy loading so we can build mongoose with webpack #5993 #5842
16
+ * docs(connections): clarify multi-mongos with useMongoClient for 4.x docs #5984
17
+ * fix(populate): handle populating embedded discriminator paths #5970
18
+ * docs(query+aggregate): add more detail re: maxTimeMS #4066
19
+
20
+ 4.13.9 / 2018-01-07
21
+ ===================
22
+ * chore: update marked (dev dependency) re: security vulnerability #5951 [ChristianMurphy](https://github.com/ChristianMurphy)
23
+ * fix: upgrade mongodb -> 2.2.34 for ipv6 and autoReconnect fixes #5794 #5760
24
+ * docs: use useMongooseAggCursor for aggregate docs #2955
25
+
1
26
  4.13.8 / 2017-12-27
2
27
  ===================
3
28
  * docs(guide): use more up-to-date syntax for autoIndex example #5933
package/README.md CHANGED
@@ -5,8 +5,6 @@ Mongoose is a [MongoDB](https://www.mongodb.org/) object modeling tool designed
5
5
  [![Slack Status](http://slack.mongoosejs.io/badge.svg)](http://slack.mongoosejs.io)
6
6
  [![Build Status](https://api.travis-ci.org/Automattic/mongoose.svg?branch=master)](https://travis-ci.org/Automattic/mongoose)
7
7
  [![NPM version](https://badge.fury.io/js/mongoose.svg)](http://badge.fury.io/js/mongoose)
8
- [![Dependency Status](https://gemnasium.com/Automattic/mongoose.svg)](https://gemnasium.com/Automattic/mongoose)
9
- [![Get help on Codementor](https://cdn.codementor.io/badges/get_help_github.svg)](https://www.codementor.io/vkarpov?utm_source=github&utm_medium=button&utm_term=vkarpov&utm_campaign=github)
10
8
 
11
9
  ## Documentation
12
10
 
package/lib/aggregate.js CHANGED
@@ -554,7 +554,10 @@ Aggregate.prototype.allowDiskUse = function(value) {
554
554
  * var agg = Model.aggregate(..).option({ allowDiskUse: true }); // Set the `allowDiskUse` option
555
555
  * agg.options; // `{ allowDiskUse: true }`
556
556
  *
557
- * @param {Object} value keys to merge into current options
557
+ * @param {Object} options keys to merge into current options
558
+ * @param [options.maxTimeMS] number limits the time this aggregation will run, see [MongoDB docs on `maxTimeMS`](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/)
559
+ * @param [options.allowDiskUse] boolean if true, the MongoDB server will use the hard drive to store data during this aggregation
560
+ * @param [options.collation] object see [`Aggregate.prototype.collation()`](./docs/api.html#aggregate_Aggregate-collation)
558
561
  * @see mongodb http://docs.mongodb.org/manual/reference/command/aggregate/
559
562
  * @return {Aggregate} this
560
563
  * @api public
@@ -574,7 +577,7 @@ Aggregate.prototype.option = function(value) {
574
577
  *
575
578
  * ####Example:
576
579
  *
577
- * var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
580
+ * var cursor = Model.aggregate(..).cursor({ batchSize: 1000, useMongooseAggCursor: true }).exec();
578
581
  * cursor.each(function(error, doc) {
579
582
  * // use doc
580
583
  * });
@@ -621,7 +624,6 @@ Aggregate.prototype.addCursorFlag = function(flag, value) {
621
624
  * Model.aggregate(..).collation({ locale: 'en_US', strength: 1 }).exec();
622
625
  *
623
626
  * @param {Object} collation options
624
- * @param {Boolean} value
625
627
  * @see mongodb http://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#aggregate
626
628
  */
627
629
 
package/lib/connection.js CHANGED
@@ -340,7 +340,7 @@ Connection.prototype.open = util.deprecate(function() {
340
340
  };
341
341
 
342
342
  return promise;
343
- }, '`open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client');
343
+ }, '`open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/4.x/docs/connections.html#use-mongo-client');
344
344
 
345
345
  /*!
346
346
  * ignore
@@ -653,7 +653,7 @@ Connection.prototype.openSet = util.deprecate(function(uris, database, options,
653
653
  };
654
654
 
655
655
  return promise;
656
- }, '`openSet()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client');
656
+ }, '`openSet()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/4.x/docs/connections.html#use-mongo-client');
657
657
 
658
658
  /**
659
659
  * error
package/lib/document.js CHANGED
@@ -487,10 +487,11 @@ Document.prototype.update = function update() {
487
487
  * @param {Any} val the value to set
488
488
  * @param {Schema|String|Number|Buffer|*} [type] optionally specify a type for "on-the-fly" attributes
489
489
  * @param {Object} [options] optionally specify options that modify the behavior of the set
490
+ * @method $set
490
491
  * @api public
491
492
  */
492
493
 
493
- Document.prototype.$set = function(path, val, type, options) {
494
+ Document.prototype.$set = function $set(path, val, type, options) {
494
495
  if (type && utils.getFunctionName(type.constructor) === 'Object') {
495
496
  options = type;
496
497
  type = undefined;
@@ -987,6 +988,9 @@ Document.prototype.get = function(path, type) {
987
988
  var obj = this._doc;
988
989
 
989
990
  if (schema instanceof VirtualType) {
991
+ if (schema.getters.length === 0) {
992
+ return void 0;
993
+ }
990
994
  return schema.applyGetters(null, this);
991
995
  }
992
996
 
@@ -1178,6 +1182,7 @@ Document.prototype.$isDefault = function(path) {
1178
1182
  *
1179
1183
  * @param {Boolean} [val] optional, overrides whether mongoose thinks the doc is deleted
1180
1184
  * @return {Boolean} whether mongoose thinks this doc is deleted.
1185
+ * @method $isDeleted
1181
1186
  * @api public
1182
1187
  */
1183
1188
 
package/lib/index.js CHANGED
@@ -188,14 +188,14 @@ var checkReplicaSetInUri = function(uri) {
188
188
  * @api public
189
189
  */
190
190
 
191
- Mongoose.prototype.createConnection = function(uri, options) {
191
+ Mongoose.prototype.createConnection = function(uri, options, callback) {
192
192
  var conn = new Connection(this);
193
193
  this.connections.push(conn);
194
194
 
195
195
  var rsOption = options && (options.replset || options.replSet);
196
196
 
197
197
  if (options && options.useMongoClient) {
198
- return conn.openUri(uri, options);
198
+ return conn.openUri(uri, options, callback);
199
199
  }
200
200
 
201
201
  if (arguments.length) {
package/lib/model.js CHANGED
@@ -21,6 +21,7 @@ var castUpdate = require('./services/query/castUpdate');
21
21
  var discriminator = require('./services/model/discriminator');
22
22
  var isPathSelectedInclusive = require('./services/projection/isPathSelectedInclusive');
23
23
  var get = require('lodash.get');
24
+ var getSchemaTypes = require('./services/populate/getSchemaTypes');
24
25
  var mpath = require('mpath');
25
26
  var parallel = require('async/parallel');
26
27
  var parallelLimit = require('async/parallelLimit');
@@ -1686,6 +1687,7 @@ Model.$where = function $where() {
1686
1687
  * @param {Object} [conditions]
1687
1688
  * @param {Object} [update]
1688
1689
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
1690
+ * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](http://mongoosejs.com/docs/api.html#query_Query-lean).
1689
1691
  * @param {Function} [callback]
1690
1692
  * @return {Query}
1691
1693
  * @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
@@ -1805,6 +1807,7 @@ Model.findOneAndUpdate = function(conditions, update, options, callback) {
1805
1807
  * @param {Object|Number|String} id value of `_id` to query by
1806
1808
  * @param {Object} [update]
1807
1809
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](http://mongoosejs.com/docs/api.html#query_Query-setOptions)
1810
+ * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](http://mongoosejs.com/docs/api.html#query_Query-lean).
1808
1811
  * @param {Function} [callback]
1809
1812
  * @return {Query}
1810
1813
  * @see Model.findOneAndUpdate #model_Model.findOneAndUpdate
@@ -2968,7 +2971,8 @@ Model.aggregate = function aggregate() {
2968
2971
  * - `lean` {Boolean} return the raw object instead of the Mongoose Model
2969
2972
  *
2970
2973
  * @param {Object} conditions an object that specifies the match condition (required)
2971
- * @param {Object} options for the geoSearch, some (near, maxDistance) are required
2974
+ * @param {Object} [options] for the geoSearch, some (near, maxDistance) are required
2975
+ * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](http://mongoosejs.com/docs/api.html#query_Query-lean).
2972
2976
  * @param {Function} [callback] optional callback
2973
2977
  * @return {Promise}
2974
2978
  * @see http://docs.mongodb.org/manual/reference/command/geoSearch/
@@ -3548,95 +3552,42 @@ function getModelsMapForPopulate(model, docs, options) {
3548
3552
  var originalModel = options.model;
3549
3553
  var isVirtual = false;
3550
3554
  var isRefPathArray = false;
3551
-
3552
- schema = model._getSchema(options.path);
3553
- var isUnderneathDocArray = schema && schema.$isUnderneathDocArray;
3554
- if (isUnderneathDocArray &&
3555
- options &&
3556
- options.options &&
3557
- options.options.sort) {
3558
- return new Error('Cannot populate with `sort` on path ' + options.path +
3559
- ' because it is a subproperty of a document array');
3560
- }
3561
-
3562
- if (schema && schema.caster) {
3563
- schema = schema.caster;
3564
- }
3565
-
3566
- if (!schema && model.discriminators) {
3567
- discriminatorKey = model.schema.discriminatorMapping.key;
3568
- }
3569
-
3570
- refPath = schema && schema.options && schema.options.refPath;
3555
+ var modelSchema = model.schema;
3571
3556
 
3572
3557
  for (i = 0; i < len; i++) {
3573
3558
  doc = docs[i];
3574
3559
 
3575
- if (refPath) {
3576
- modelNames = utils.getValue(refPath, doc);
3577
- isRefPathArray = Array.isArray(modelNames);
3578
- } else {
3579
- if (!modelNameFromQuery) {
3580
- var modelForCurrentDoc = model;
3581
- var schemaForCurrentDoc;
3582
-
3583
- if (!schema && discriminatorKey) {
3584
- modelForFindSchema = utils.getValue(discriminatorKey, doc);
3585
-
3586
- if (modelForFindSchema) {
3587
- try {
3588
- modelForCurrentDoc = model.db.model(modelForFindSchema);
3589
- } catch (error) {
3590
- return error;
3591
- }
3592
-
3593
- schemaForCurrentDoc = modelForCurrentDoc._getSchema(options.path);
3560
+ schema = getSchemaTypes(modelSchema, doc, options.path);
3561
+ var isUnderneathDocArray = schema && schema.$isUnderneathDocArray;
3562
+ if (isUnderneathDocArray &&
3563
+ options &&
3564
+ options.options &&
3565
+ options.options.sort) {
3566
+ return new Error('Cannot populate with `sort` on path ' + options.path +
3567
+ ' because it is a subproperty of a document array');
3568
+ }
3594
3569
 
3595
- if (schemaForCurrentDoc && schemaForCurrentDoc.caster) {
3596
- schemaForCurrentDoc = schemaForCurrentDoc.caster;
3597
- }
3598
- }
3599
- } else {
3600
- schemaForCurrentDoc = schema;
3570
+ if (Array.isArray(schema)) {
3571
+ for (var j = 0; j < schema.length; ++j) {
3572
+ var _modelNames = _getModelNames(doc, schema[j]);
3573
+ if (!_modelNames) {
3574
+ continue;
3601
3575
  }
3602
- var virtual = modelForCurrentDoc.schema._getVirtual(options.path);
3603
-
3604
- var ref;
3605
- if ((ref = get(schemaForCurrentDoc, 'options.ref')) != null) {
3606
- modelNames = [ref];
3607
- } else if ((ref = get(virtual, 'options.ref')) != null) {
3608
- if (typeof ref === 'function') {
3609
- ref = ref.call(doc, doc);
3610
- }
3611
-
3612
- // When referencing nested arrays, the ref should be an Array
3613
- // of modelNames.
3614
- if (Array.isArray(ref)) {
3615
- modelNames = ref;
3616
- } else {
3617
- modelNames = [ref];
3576
+ modelNames = (modelNames || []);
3577
+ for (var x = 0; x < _modelNames.length; ++x) {
3578
+ if (modelNames.indexOf(_modelNames[x]) === -1) {
3579
+ modelNames.push(_modelNames[x]);
3618
3580
  }
3619
-
3620
- isVirtual = true;
3621
- } else {
3622
- // We may have a discriminator, in which case we don't want to
3623
- // populate using the base model by default
3624
- modelNames = discriminatorKey ? null : [model.modelName];
3625
3581
  }
3626
- } else {
3627
- modelNames = [modelNameFromQuery]; // query options
3582
+ }
3583
+ } else {
3584
+ modelNames = _getModelNames(doc, schema);
3585
+ if (!modelNames) {
3586
+ continue;
3628
3587
  }
3629
3588
  }
3630
3589
 
3631
- if (!modelNames) {
3632
- continue;
3633
- }
3634
-
3635
- if (!Array.isArray(modelNames)) {
3636
- modelNames = [modelNames];
3637
- }
3638
-
3639
- virtual = model.schema._getVirtual(options.path);
3590
+ var virtual = model.schema._getVirtual(options.path);
3640
3591
  var localField;
3641
3592
  if (virtual && virtual.options) {
3642
3593
  var virtualPrefix = virtual.$nestedSchemaPath ?
@@ -3726,6 +3677,87 @@ function getModelsMapForPopulate(model, docs, options) {
3726
3677
  }
3727
3678
  }
3728
3679
 
3680
+ function _getModelNames(doc, schema) {
3681
+ var modelNames;
3682
+ var discriminatorKey;
3683
+
3684
+ if (schema && schema.caster) {
3685
+ schema = schema.caster;
3686
+ }
3687
+
3688
+ if (!schema && model.discriminators) {
3689
+ discriminatorKey = model.schema.discriminatorMapping.key;
3690
+ }
3691
+
3692
+ refPath = schema && schema.options && schema.options.refPath;
3693
+
3694
+ if (refPath) {
3695
+ modelNames = utils.getValue(refPath, doc);
3696
+ isRefPathArray = Array.isArray(modelNames);
3697
+ } else {
3698
+ if (!modelNameFromQuery) {
3699
+ var modelForCurrentDoc = model;
3700
+ var schemaForCurrentDoc;
3701
+
3702
+ if (!schema && discriminatorKey) {
3703
+ modelForFindSchema = utils.getValue(discriminatorKey, doc);
3704
+
3705
+ if (modelForFindSchema) {
3706
+ try {
3707
+ modelForCurrentDoc = model.db.model(modelForFindSchema);
3708
+ } catch (error) {
3709
+ return error;
3710
+ }
3711
+
3712
+ schemaForCurrentDoc = modelForCurrentDoc.schema._getSchema(options.path);
3713
+
3714
+ if (schemaForCurrentDoc && schemaForCurrentDoc.caster) {
3715
+ schemaForCurrentDoc = schemaForCurrentDoc.caster;
3716
+ }
3717
+ }
3718
+ } else {
3719
+ schemaForCurrentDoc = schema;
3720
+ }
3721
+ var virtual = modelForCurrentDoc.schema._getVirtual(options.path);
3722
+
3723
+ var ref;
3724
+ if ((ref = get(schemaForCurrentDoc, 'options.ref')) != null) {
3725
+ modelNames = [ref];
3726
+ } else if ((ref = get(virtual, 'options.ref')) != null) {
3727
+ if (typeof ref === 'function') {
3728
+ ref = ref.call(doc, doc);
3729
+ }
3730
+
3731
+ // When referencing nested arrays, the ref should be an Array
3732
+ // of modelNames.
3733
+ if (Array.isArray(ref)) {
3734
+ modelNames = ref;
3735
+ } else {
3736
+ modelNames = [ref];
3737
+ }
3738
+
3739
+ isVirtual = true;
3740
+ } else {
3741
+ // We may have a discriminator, in which case we don't want to
3742
+ // populate using the base model by default
3743
+ modelNames = discriminatorKey ? null : [model.modelName];
3744
+ }
3745
+ } else {
3746
+ modelNames = [modelNameFromQuery]; // query options
3747
+ }
3748
+ }
3749
+
3750
+ if (!modelNames) {
3751
+ return;
3752
+ }
3753
+
3754
+ if (!Array.isArray(modelNames)) {
3755
+ modelNames = [modelNames];
3756
+ }
3757
+
3758
+ return modelNames;
3759
+ }
3760
+
3729
3761
  return map;
3730
3762
  }
3731
3763
 
@@ -3854,20 +3886,6 @@ function isDoc(doc) {
3854
3886
  return true;
3855
3887
  }
3856
3888
 
3857
- /**
3858
- * Finds the schema for `path`. This is different than
3859
- * calling `schema.path` as it also resolves paths with
3860
- * positional selectors (something.$.another.$.path).
3861
- *
3862
- * @param {String} path
3863
- * @return {Schema}
3864
- * @api private
3865
- */
3866
-
3867
- Model._getSchema = function _getSchema(path) {
3868
- return this.schema._getSchema(path);
3869
- };
3870
-
3871
3889
  /*!
3872
3890
  * Compiler utility.
3873
3891
  *
package/lib/query.js CHANGED
@@ -1002,13 +1002,16 @@ Query.prototype.read = function read(pref, tags) {
1002
1002
  * - [readPreference](http://docs.mongodb.org/manual/applications/replication/#read-preference)
1003
1003
  * - [hint](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24hint)
1004
1004
  *
1005
- * The following options are only for `update()`, `updateOne()`, `updateMany()`, `replaceOne()`, and `findOneAndUpdate()`:
1005
+ * The following options are only for `update()`, `updateOne()`, `updateMany()`, `replaceOne()`, `findOneAndUpdate()`, and `findByIdAndUpdate()`:
1006
1006
  * - [upsert](https://docs.mongodb.com/manual/reference/method/db.collection.update/)
1007
1007
  * - [writeConcern](https://docs.mongodb.com/manual/reference/method/db.collection.update/)
1008
1008
  *
1009
- * The following options are only for `find()`, `findOne()`, `findById()`, and `findOneAndUpdate()`:
1009
+ * The following options are only for `find()`, `findOne()`, `findById()`, `findOneAndUpdate()`, and `findByIdAndUpdate()`:
1010
1010
  * - [lean](./api.html#query_Query-lean)
1011
1011
  *
1012
+ * The following options are only for all operations **except** `update()`, `updateOne()`, `updateMany()`, `remove()`, `deleteOne()`, and `deleteMany()`:
1013
+ * - [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/)
1014
+ *
1012
1015
  * The following options are for all operations:
1013
1016
  * - [collation](https://docs.mongodb.com/manual/reference/collation/)
1014
1017
  *
@@ -15,8 +15,6 @@ var Types = {
15
15
  ObjectId: require('./objectid'),
16
16
  Buffer: require('./buffer')
17
17
  };
18
- var MongooseArray = require('../types').Array;
19
- var EmbeddedDoc = require('../types').Embedded;
20
18
  var Mixed = require('./mixed');
21
19
  var cast = require('../cast');
22
20
  var util = require('util');
@@ -24,6 +22,9 @@ var utils = require('../utils');
24
22
  var castToNumber = require('./operators/helpers').castToNumber;
25
23
  var geospatial = require('./operators/geospatial');
26
24
 
25
+ var MongooseArray;
26
+ var EmbeddedDoc;
27
+
27
28
  /**
28
29
  * Array SchemaType constructor
29
30
  *
@@ -35,6 +36,9 @@ var geospatial = require('./operators/geospatial');
35
36
  */
36
37
 
37
38
  function SchemaArray(key, cast, options, schemaOptions) {
39
+ // lazy load
40
+ EmbeddedDoc || (EmbeddedDoc = require('../types').Embedded);
41
+
38
42
  var typeKey = 'type';
39
43
  if (schemaOptions && schemaOptions.typeKey) {
40
44
  typeKey = schemaOptions.typeKey;
@@ -155,6 +159,9 @@ SchemaArray.prototype.applyGetters = function(value, scope) {
155
159
  */
156
160
 
157
161
  SchemaArray.prototype.cast = function(value, doc, init) {
162
+ // lazy load
163
+ MongooseArray || (MongooseArray = require('../types').Array);
164
+
158
165
  if (Array.isArray(value)) {
159
166
  if (!value.length && doc) {
160
167
  var indexes = doc.schema.indexedPaths();
@@ -5,7 +5,7 @@
5
5
  var handleBitwiseOperator = require('./operators/bitwise');
6
6
  var utils = require('../utils');
7
7
 
8
- var MongooseBuffer = require('../types').Buffer;
8
+ var MongooseBuffer = require('../types/buffer');
9
9
  var SchemaType = require('../schematype');
10
10
 
11
11
  var Binary = MongooseBuffer.Binary;
@@ -8,13 +8,14 @@ var ArrayType = require('./array');
8
8
  var CastError = require('../error/cast');
9
9
  var Document = require('../document');
10
10
  var EventEmitter = require('events').EventEmitter;
11
- var MongooseDocumentArray = require('../types/documentarray');
12
11
  var SchemaType = require('../schematype');
13
- var Subdocument = require('../types/embedded');
14
12
  var discriminator = require('../services/model/discriminator');
15
13
  var util = require('util');
16
14
  var utils = require('../utils');
17
15
 
16
+ var MongooseDocumentArray;
17
+ var Subdocument;
18
+
18
19
  /**
19
20
  * SubdocsArray SchemaType constructor
20
21
  *
@@ -66,6 +67,8 @@ DocumentArray.prototype.constructor = DocumentArray;
66
67
  */
67
68
 
68
69
  function _createConstructor(schema, options) {
70
+ Subdocument || (Subdocument = require('../types/embedded'));
71
+
69
72
  // compile an embedded document for this schema
70
73
  function EmbeddedDocument() {
71
74
  Subdocument.apply(this, arguments);
@@ -130,6 +133,9 @@ DocumentArray.prototype.discriminator = function(name, schema) {
130
133
  */
131
134
 
132
135
  DocumentArray.prototype.doValidate = function(array, fn, scope, options) {
136
+ // lazy load
137
+ MongooseDocumentArray || (MongooseDocumentArray = require('../types/documentarray'));
138
+
133
139
  var _this = this;
134
140
  SchemaType.prototype.doValidate.call(this, array, function(err) {
135
141
  if (err) {
@@ -251,6 +257,9 @@ DocumentArray.prototype.doValidateSync = function(array, scope) {
251
257
  */
252
258
 
253
259
  DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
260
+ // lazy load
261
+ MongooseDocumentArray || (MongooseDocumentArray = require('../types/documentarray'));
262
+
254
263
  var selected;
255
264
  var subdoc;
256
265
  var i;
@@ -7,11 +7,12 @@
7
7
  var $exists = require('./operators/exists');
8
8
  var EventEmitter = require('events').EventEmitter;
9
9
  var SchemaType = require('../schematype');
10
- var Subdocument = require('../types/subdocument');
11
10
  var castToNumber = require('./operators/helpers').castToNumber;
12
11
  var discriminator = require('../services/model/discriminator');
13
12
  var geospatial = require('./operators/geospatial');
14
13
 
14
+ var Subdocument;
15
+
15
16
  module.exports = Embedded;
16
17
 
17
18
  /**
@@ -43,6 +44,9 @@ Embedded.prototype = Object.create(SchemaType.prototype);
43
44
  */
44
45
 
45
46
  function _createConstructor(schema) {
47
+ // lazy load
48
+ Subdocument || (Subdocument = require('../types/subdocument'));
49
+
46
50
  var _embedded = function SingleNested(value, path, parent) {
47
51
  var _this = this;
48
52
 
package/lib/schema.js CHANGED
@@ -804,22 +804,17 @@ Schema.prototype.hasMixedParent = function(path) {
804
804
  */
805
805
  Schema.prototype.setupTimestamp = function(timestamps) {
806
806
  if (timestamps) {
807
- var paths = ['createdAt', 'updatedAt'].map(handleTimestampOption.bind(null, timestamps));
808
- var createdAt = paths[0];
809
- var updatedAt = paths[1];
810
- var schemaAdditions = paths.reduce(function(cur, path) {
811
- if (path != null) {
812
- var parts = path.split('.');
813
- if (this.pathType(path) === 'adhocOrUndefined') {
814
- for (var i = 0; i < parts.length; ++i) {
815
- cur[parts[i]] = (i < parts.length - 1 ?
816
- cur[parts[i]] || {} :
817
- Date);
818
- }
819
- }
820
- }
821
- return cur;
822
- }.bind(this), {});
807
+ var createdAt = handleTimestampOption(timestamps, 'createdAt');
808
+ var updatedAt = handleTimestampOption(timestamps, 'updatedAt');
809
+ var schemaAdditions = {};
810
+
811
+ if (updatedAt && !this.paths[updatedAt]) {
812
+ schemaAdditions[updatedAt] = Date;
813
+ }
814
+
815
+ if (createdAt && !this.paths[createdAt]) {
816
+ schemaAdditions[createdAt] = Date;
817
+ }
823
818
 
824
819
  this.add(schemaAdditions);
825
820
 
@@ -1403,7 +1398,8 @@ Object.defineProperty(Schema, 'indexTypes', {
1403
1398
  });
1404
1399
 
1405
1400
  /**
1406
- * Compiles indexes from fields and schema-level indexes
1401
+ * Returns a list of indexes that this schema declares, via `schema.index()`
1402
+ * or by `index: true` in a path's options.
1407
1403
  *
1408
1404
  * @api public
1409
1405
  */
@@ -62,7 +62,10 @@ module.exports = function discriminator(model, name, schema) {
62
62
  delete schema.paths._id;
63
63
  delete schema.tree._id;
64
64
  }
65
- utils.merge(schema, baseSchema, { retainKeyOrder: true });
65
+ utils.merge(schema, baseSchema, {
66
+ retainKeyOrder: true,
67
+ omit: { discriminators: true }
68
+ });
66
69
 
67
70
  var obj = {};
68
71
  obj[key] = {
@@ -128,8 +131,11 @@ module.exports = function discriminator(model, name, schema) {
128
131
 
129
132
  if (!model.schema.discriminatorMapping) {
130
133
  model.schema.discriminatorMapping = {key: key, value: null, isRoot: true};
134
+ model.schema.discriminators = {};
131
135
  }
132
136
 
137
+ model.schema.discriminators[name] = schema;
138
+
133
139
  if (model.discriminators[name]) {
134
140
  throw new Error('Discriminator with name "' + name + '" already exists');
135
141
  }