mongoose 6.2.9 → 6.3.0

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 (64) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/browser.umd.js +2 -1693
  3. package/lib/aggregate.js +59 -67
  4. package/lib/browser.js +4 -4
  5. package/lib/connection.js +21 -21
  6. package/lib/cursor/AggregationCursor.js +2 -2
  7. package/lib/cursor/ChangeStream.js +42 -2
  8. package/lib/cursor/QueryCursor.js +5 -3
  9. package/lib/document.js +39 -46
  10. package/lib/error/eachAsyncMultiError.js +41 -0
  11. package/lib/error/index.js +2 -2
  12. package/lib/helpers/cursor/eachAsync.js +44 -12
  13. package/lib/helpers/indexes/applySchemaCollation.js +13 -0
  14. package/lib/helpers/indexes/isTextIndex.js +16 -0
  15. package/lib/helpers/model/discriminator.js +1 -3
  16. package/lib/helpers/populate/markArraySubdocsPopulated.js +1 -1
  17. package/lib/helpers/projection/hasIncludedChildren.js +1 -1
  18. package/lib/helpers/query/applyGlobalOption.js +29 -0
  19. package/lib/helpers/query/castUpdate.js +3 -1
  20. package/lib/helpers/update/applyTimestampsToChildren.js +2 -2
  21. package/lib/helpers/update/applyTimestampsToUpdate.js +0 -1
  22. package/lib/index.js +33 -26
  23. package/lib/model.js +88 -90
  24. package/lib/options/SchemaArrayOptions.js +2 -2
  25. package/lib/options/SchemaBufferOptions.js +1 -1
  26. package/lib/options/SchemaDateOptions.js +2 -2
  27. package/lib/options/SchemaDocumentArrayOptions.js +3 -3
  28. package/lib/options/SchemaMapOptions.js +2 -2
  29. package/lib/options/SchemaNumberOptions.js +3 -3
  30. package/lib/options/SchemaObjectIdOptions.js +2 -2
  31. package/lib/options/SchemaStringOptions.js +1 -1
  32. package/lib/options/SchemaSubdocumentOptions.js +2 -2
  33. package/lib/options/SchemaTypeOptions.js +3 -3
  34. package/lib/query.js +273 -249
  35. package/lib/schema/SubdocumentPath.js +4 -3
  36. package/lib/schema/array.js +2 -2
  37. package/lib/schema/boolean.js +4 -4
  38. package/lib/schema/buffer.js +3 -3
  39. package/lib/schema/date.js +7 -7
  40. package/lib/schema/decimal128.js +2 -2
  41. package/lib/schema/documentarray.js +3 -3
  42. package/lib/schema/mixed.js +2 -2
  43. package/lib/schema/number.js +6 -6
  44. package/lib/schema/objectid.js +4 -7
  45. package/lib/schema/string.js +38 -16
  46. package/lib/schema.js +144 -30
  47. package/lib/schematype.js +75 -68
  48. package/lib/types/ArraySubdocument.js +1 -1
  49. package/lib/types/DocumentArray/methods/index.js +2 -2
  50. package/lib/types/array/index.js +1 -1
  51. package/lib/types/array/methods/index.js +13 -13
  52. package/lib/types/buffer.js +1 -1
  53. package/lib/types/decimal128.js +1 -1
  54. package/lib/types/objectid.js +1 -1
  55. package/lib/types/subdocument.js +31 -2
  56. package/lib/validoptions.js +1 -0
  57. package/lib/virtualtype.js +3 -3
  58. package/package.json +19 -13
  59. package/tools/repl.js +2 -1
  60. package/types/aggregate.d.ts +223 -0
  61. package/types/cursor.d.ts +10 -4
  62. package/types/index.d.ts +194 -209
  63. package/types/mongooseoptions.d.ts +10 -4
  64. package/lib/helpers/query/applyGlobalMaxTimeMS.js +0 -15
package/lib/schema.js CHANGED
@@ -22,6 +22,7 @@ const readPref = require('./driver').get().ReadPreference;
22
22
  const setupTimestamps = require('./helpers/timestamps/setupTimestamps');
23
23
  const utils = require('./utils');
24
24
  const validateRef = require('./helpers/populate/validateRef');
25
+ const util = require('util');
25
26
 
26
27
  let MongooseTypes;
27
28
 
@@ -38,7 +39,7 @@ let id = 0;
38
39
  /**
39
40
  * Schema constructor.
40
41
  *
41
- * ####Example:
42
+ * #### Example:
42
43
  *
43
44
  * const child = new Schema({ name: String });
44
45
  * const schema = new Schema({ name: String, age: Number, children: [child] });
@@ -47,7 +48,7 @@ let id = 0;
47
48
  * // setting schema options
48
49
  * new Schema({ name: String }, { _id: false, autoIndex: false })
49
50
  *
50
- * ####Options:
51
+ * #### Options:
51
52
  *
52
53
  * - [autoIndex](/docs/guide.html#autoIndex): bool - defaults to null (which means use the connection's autoIndex option)
53
54
  * - [autoCreate](/docs/guide.html#autoCreate): bool - defaults to null (which means use the connection's autoCreate option)
@@ -77,10 +78,10 @@ let id = 0;
77
78
  * - [timestamps](/docs/guide.html#timestamps): object or boolean - defaults to `false`. If true, Mongoose adds `createdAt` and `updatedAt` properties to your schema and manages those properties for you.
78
79
  * - [pluginTags](/docs/guide.html#pluginTags): array of strings - defaults to `undefined`. If set and plugin called with `tags` option, will only apply that plugin to schemas with a matching tag.
79
80
  *
80
- * ####Options for Nested Schemas:
81
+ * #### Options for Nested Schemas:
81
82
  * - `excludeIndexes`: bool - defaults to `false`. If `true`, skip building indexes on this schema's paths.
82
83
  *
83
- * ####Note:
84
+ * #### Note:
84
85
  *
85
86
  * _When nesting schemas, (`children` in the example above), always declare the child schema first before passing it into its parent._
86
87
  *
@@ -231,7 +232,7 @@ Object.defineProperty(Schema.prototype, 'childSchemas', {
231
232
  * This property is typically only useful for plugin authors and advanced users.
232
233
  * You do not need to interact with this property at all to use mongoose.
233
234
  *
234
- * ####Example:
235
+ * #### Example:
235
236
  * const schema = new Schema({});
236
237
  * schema.virtual('answer').get(() => 42);
237
238
  *
@@ -253,7 +254,7 @@ Object.defineProperty(Schema.prototype, 'virtuals', {
253
254
  /**
254
255
  * The original object passed to the schema constructor
255
256
  *
256
- * ####Example:
257
+ * #### Example:
257
258
  *
258
259
  * const schema = new Schema({ a: String }).add({ b: String });
259
260
  * schema.obj; // { a: String }
@@ -270,7 +271,7 @@ Schema.prototype.obj;
270
271
  * The paths defined on this schema. The keys are the top-level paths
271
272
  * in this schema, and the values are instances of the SchemaType class.
272
273
  *
273
- * ####Example:
274
+ * #### Example:
274
275
  * const schema = new Schema({ name: String }, { _id: false });
275
276
  * schema.paths; // { name: SchemaString { ... } }
276
277
  *
@@ -288,7 +289,7 @@ Schema.prototype.paths;
288
289
  /**
289
290
  * Schema as a tree
290
291
  *
291
- * ####Example:
292
+ * #### Example:
292
293
  * {
293
294
  * '_id' : ObjectId
294
295
  * , 'nested' : {
@@ -307,7 +308,7 @@ Schema.prototype.tree;
307
308
  /**
308
309
  * Returns a deep copy of the schema
309
310
  *
310
- * ####Example:
311
+ * #### Example:
311
312
  *
312
313
  * const schema = new Schema({ name: String });
313
314
  * const clone = schema.clone();
@@ -370,6 +371,9 @@ Schema.prototype._clone = function _clone(Constructor) {
370
371
  if (this.discriminators != null) {
371
372
  s.discriminators = Object.assign({}, this.discriminators);
372
373
  }
374
+ if (this._applyDiscriminators != null) {
375
+ s._applyDiscriminators = Object.assign({}, this._applyDiscriminators);
376
+ }
373
377
 
374
378
  s.aliases = Object.assign({}, this.aliases);
375
379
 
@@ -381,7 +385,7 @@ Schema.prototype._clone = function _clone(Constructor) {
381
385
  *
382
386
  * This method is analagous to [Lodash's `pick()` function](https://lodash.com/docs/4.17.15#pick) for Mongoose schemas.
383
387
  *
384
- * ####Example:
388
+ * #### Example:
385
389
  *
386
390
  * const schema = Schema({ name: String, age: Number });
387
391
  * // Creates a new schema with the same `name` path as `schema`,
@@ -469,10 +473,15 @@ Schema.prototype.defaultOptions = function(options) {
469
473
  return options;
470
474
  };
471
475
 
476
+ Schema.prototype.discriminator = function(name, schema) {
477
+ this._applyDiscriminators = {};
478
+ this._applyDiscriminators[name] = schema;
479
+ };
480
+
472
481
  /**
473
482
  * Adds key path / schema type pairs to this schema.
474
483
  *
475
- * ####Example:
484
+ * #### Example:
476
485
  *
477
486
  * const ToySchema = new Schema();
478
487
  * ToySchema.add({ name: 'string', color: 'string', price: 'number' });
@@ -510,7 +519,6 @@ Schema.prototype.add = function add(obj, prefix) {
510
519
 
511
520
  const keys = Object.keys(obj);
512
521
  const typeKey = this.options.typeKey;
513
-
514
522
  for (const key of keys) {
515
523
  const fullPath = prefix + key;
516
524
  const val = obj[key];
@@ -540,6 +548,25 @@ Schema.prototype.add = function add(obj, prefix) {
540
548
  this.nested[prefix.substring(0, prefix.length - 1)] = true;
541
549
  }
542
550
  this.path(prefix + key, val);
551
+ if (val[0] != null && !(val[0].instanceOfSchema) && utils.isPOJO(val[0].discriminators)) {
552
+ const schemaType = this.path(prefix + key);
553
+ for (const key in val[0].discriminators) {
554
+ schemaType.discriminator(key, val[0].discriminators[key]);
555
+ }
556
+ } else if (val[0] != null && val[0].instanceOfSchema && utils.isPOJO(val[0]._applyDiscriminators)) {
557
+ const applyDiscriminators = val[0]._applyDiscriminators || [];
558
+ const schemaType = this.path(prefix + key);
559
+ for (const disc in applyDiscriminators) {
560
+ schemaType.discriminator(disc, applyDiscriminators[disc]);
561
+ }
562
+ }
563
+ else if (val != null && val.instanceOfSchema && utils.isPOJO(val._applyDiscriminators)) {
564
+ const applyDiscriminators = val._applyDiscriminators || [];
565
+ const schemaType = this.path(prefix + key);
566
+ for (const disc in applyDiscriminators) {
567
+ schemaType.discriminator(disc, applyDiscriminators[disc]);
568
+ }
569
+ }
543
570
  } else if (Object.keys(val).length < 1) {
544
571
  // Special-case: {} always interpreted as Mixed path so leaf at this node
545
572
  if (prefix) {
@@ -569,6 +596,12 @@ Schema.prototype.add = function add(obj, prefix) {
569
596
  this.nested[prefix.substring(0, prefix.length - 1)] = true;
570
597
  }
571
598
  this.path(prefix + key, val);
599
+ if (val != null && !(val.instanceOfSchema) && utils.isPOJO(val.discriminators)) {
600
+ const schemaType = this.path(prefix + key);
601
+ for (const key in val.discriminators) {
602
+ schemaType.discriminator(key, val.discriminators[key]);
603
+ }
604
+ }
572
605
  }
573
606
  }
574
607
  }
@@ -579,6 +612,86 @@ Schema.prototype.add = function add(obj, prefix) {
579
612
  return this;
580
613
  };
581
614
 
615
+ /**
616
+ * Remove an index by name or index specification.
617
+ *
618
+ * removeIndex only removes indexes from your schema object. Does **not** affect the indexes
619
+ * in MongoDB.
620
+ *
621
+ * ####Example:
622
+ *
623
+ * const ToySchema = new Schema({ name: String, color: String, price: Number });
624
+ *
625
+ * // Add a new index on { name, color }
626
+ * ToySchema.index({ name: 1, color: 1 });
627
+ *
628
+ * // Remove index on { name, color }
629
+ * // Keep in mind that order matters! `removeIndex({ color: 1, name: 1 })` won't remove the index
630
+ * ToySchema.removeIndex({ name: 1, color: 1 });
631
+ *
632
+ * // Add an index with a custom name
633
+ * ToySchema.index({ color: 1 }, { name: 'my custom index name' });
634
+ * // Remove index by name
635
+ * ToySchema.removeIndex('my custom index name');
636
+ *
637
+ * @param {Object|string} index name or index specification
638
+ * @return {Schema} the Schema instance
639
+ * @api public
640
+ */
641
+
642
+ Schema.prototype.removeIndex = function removeIndex(index) {
643
+ if (arguments.length > 1) {
644
+ throw new Error('removeIndex() takes only 1 argument');
645
+ }
646
+
647
+ if (typeof index !== 'object' && typeof index !== 'string') {
648
+ throw new Error('removeIndex() may only take either an object or a string as an argument');
649
+ }
650
+
651
+ if (typeof index === 'object') {
652
+ for (let i = this._indexes.length - 1; i >= 0; --i) {
653
+ if (util.isDeepStrictEqual(this._indexes[i][0], index)) {
654
+ this._indexes.splice(i, 1);
655
+ }
656
+ }
657
+ } else {
658
+ for (let i = this._indexes.length - 1; i >= 0; --i) {
659
+ if (this._indexes[i][1] != null && this._indexes[i][1].name === index) {
660
+ this._indexes.splice(i, 1);
661
+ }
662
+ }
663
+ }
664
+
665
+ return this;
666
+ };
667
+
668
+ /**
669
+ * Remove all indexes from this schema.
670
+ *
671
+ * clearIndexes only removes indexes from your schema object. Does **not** affect the indexes
672
+ * in MongoDB.
673
+ *
674
+ * ####Example:
675
+ *
676
+ * const ToySchema = new Schema({ name: String, color: String, price: Number });
677
+ * ToySchema.index({ name: 1 });
678
+ * ToySchema.index({ color: 1 });
679
+ *
680
+ * // Remove all indexes on this schema
681
+ * ToySchema.clearIndexes();
682
+ *
683
+ * ToySchema.indexes(); // []
684
+ *
685
+ * @return {Schema} the Schema instance
686
+ * @api public
687
+ */
688
+
689
+ Schema.prototype.clearIndexes = function clearIndexes() {
690
+ this._indexes.length = 0;
691
+
692
+ return this;
693
+ };
694
+
582
695
  /**
583
696
  * Reserved document keys.
584
697
  *
@@ -646,7 +759,7 @@ reserved.collection = 1;
646
759
  * Sets a path (if arity 2)
647
760
  * Gets a path (if arity 1)
648
761
  *
649
- * ####Example
762
+ * #### Example
650
763
  *
651
764
  * schema.path('name') // returns a SchemaType
652
765
  * schema.path('name', Number) // changes the schemaType of `name` to Number
@@ -1010,6 +1123,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
1010
1123
  if (options.hasOwnProperty('strict')) {
1011
1124
  childSchemaOptions.strict = options.strict;
1012
1125
  }
1126
+
1013
1127
  if (this._userProvidedOptions.hasOwnProperty('_id')) {
1014
1128
  childSchemaOptions._id = this._userProvidedOptions._id;
1015
1129
  } else if (Schema.Types.DocumentArray.defaultOptions._id != null) {
@@ -1133,7 +1247,7 @@ function createMapNestedSchemaType(schema, schemaType, path, obj, options) {
1133
1247
  *
1134
1248
  * The callback is passed the pathname and the schemaType instance.
1135
1249
  *
1136
- * ####Example:
1250
+ * #### Example:
1137
1251
  *
1138
1252
  * const userSchema = new Schema({ name: String, registeredAt: Date });
1139
1253
  * userSchema.eachPath((pathname, schematype) => {
@@ -1162,7 +1276,7 @@ Schema.prototype.eachPath = function(fn) {
1162
1276
  /**
1163
1277
  * Returns an Array of path strings that are required by this schema.
1164
1278
  *
1165
- * ####Example:
1279
+ * #### Example:
1166
1280
  * const s = new Schema({
1167
1281
  * name: { type: String, required: true },
1168
1282
  * age: { type: String, required: true },
@@ -1214,7 +1328,7 @@ Schema.prototype.indexedPaths = function indexedPaths() {
1214
1328
  *
1215
1329
  * Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path.
1216
1330
  *
1217
- * ####Example:
1331
+ * #### Example:
1218
1332
  * const s = new Schema({ name: String, nested: { foo: String } });
1219
1333
  * s.virtual('foo').get(() => 42);
1220
1334
  * s.pathType('name'); // "real"
@@ -1371,7 +1485,7 @@ function getPositionalPath(self, path) {
1371
1485
  /**
1372
1486
  * Adds a method call to the queue.
1373
1487
  *
1374
- * ####Example:
1488
+ * #### Example:
1375
1489
  *
1376
1490
  * schema.methods.print = function() { console.log(this); };
1377
1491
  * schema.queue('print', []); // Print the doc every one is instantiated
@@ -1392,7 +1506,7 @@ Schema.prototype.queue = function(name, args) {
1392
1506
  /**
1393
1507
  * Defines a pre hook for the model.
1394
1508
  *
1395
- * ####Example
1509
+ * #### Example
1396
1510
  *
1397
1511
  * const toySchema = new Schema({ name: String, created: Date });
1398
1512
  *
@@ -1466,7 +1580,7 @@ Schema.prototype.pre = function(name) {
1466
1580
  * });
1467
1581
  *
1468
1582
  * schema.post(/Many$/, function(res) {
1469
- * console.log('this fired after you ran `updateMany()` or `deleteMany()`);
1583
+ * console.log('this fired after you ran `updateMany()` or `deleteMany()`');
1470
1584
  * });
1471
1585
  *
1472
1586
  * const Model = mongoose.model('Model', schema);
@@ -1514,7 +1628,7 @@ Schema.prototype.post = function(name) {
1514
1628
  /**
1515
1629
  * Registers a plugin for this schema.
1516
1630
  *
1517
- * ####Example:
1631
+ * #### Example:
1518
1632
  *
1519
1633
  * const s = new Schema({ name: String });
1520
1634
  * s.plugin(schema => console.log(schema.path('name').path));
@@ -1548,7 +1662,7 @@ Schema.prototype.plugin = function(fn, opts) {
1548
1662
  /**
1549
1663
  * Adds an instance method to documents constructed from Models compiled from this schema.
1550
1664
  *
1551
- * ####Example
1665
+ * #### Example
1552
1666
  *
1553
1667
  * const schema = kittySchema = new Schema(..);
1554
1668
  *
@@ -1595,7 +1709,7 @@ Schema.prototype.method = function(name, fn, options) {
1595
1709
  /**
1596
1710
  * Adds static "class" methods to Models compiled from this schema.
1597
1711
  *
1598
- * ####Example
1712
+ * #### Example
1599
1713
  *
1600
1714
  * const schema = new Schema(..);
1601
1715
  * // Equivalent to `schema.statics.findByName = function(name) {}`;
@@ -1628,7 +1742,7 @@ Schema.prototype.static = function(name, fn) {
1628
1742
  /**
1629
1743
  * Defines an index (most likely compound) for this schema.
1630
1744
  *
1631
- * ####Example
1745
+ * #### Example
1632
1746
  *
1633
1747
  * schema.index({ first: 1, last: -1 })
1634
1748
  *
@@ -1653,7 +1767,7 @@ Schema.prototype.index = function(fields, options) {
1653
1767
  /**
1654
1768
  * Sets a schema option.
1655
1769
  *
1656
- * ####Example
1770
+ * #### Example
1657
1771
  *
1658
1772
  * schema.set('strict'); // 'true' by default
1659
1773
  * schema.set('strict', false); // Sets 'strict' to false
@@ -1702,7 +1816,7 @@ Schema.prototype.set = function(key, value, _tags) {
1702
1816
  /**
1703
1817
  * Gets a schema option.
1704
1818
  *
1705
- * ####Example:
1819
+ * #### Example:
1706
1820
  *
1707
1821
  * schema.get('strict'); // true
1708
1822
  * schema.set('strict', false);
@@ -1740,7 +1854,7 @@ Object.defineProperty(Schema, 'indexTypes', {
1740
1854
  * Returns a list of indexes that this schema declares, via `schema.index()` or by `index: true` in a path's options.
1741
1855
  * Indexes are expressed as an array `[spec, options]`.
1742
1856
  *
1743
- * ####Example:
1857
+ * #### Example:
1744
1858
  *
1745
1859
  * const userSchema = new Schema({
1746
1860
  * email: { type: String, required: true, unique: true },
@@ -1902,7 +2016,7 @@ Schema.prototype.virtualpath = function(name) {
1902
2016
  /**
1903
2017
  * Removes the given `path` (or [`paths`]).
1904
2018
  *
1905
- * ####Example:
2019
+ * #### Example:
1906
2020
  *
1907
2021
  * const schema = new Schema({ name: String, age: Number });
1908
2022
  * schema.remove('name');
@@ -1969,7 +2083,7 @@ function _deletePath(schema, name) {
1969
2083
  * [statics](/docs/guide.html#statics), and
1970
2084
  * [methods](/docs/guide.html#methods).
1971
2085
  *
1972
- * ####Example:
2086
+ * #### Example:
1973
2087
  *
1974
2088
  * ```javascript
1975
2089
  * const md5 = require('md5');
@@ -2232,12 +2346,12 @@ module.exports = exports = Schema;
2232
2346
  /**
2233
2347
  * The various built-in Mongoose Schema Types.
2234
2348
  *
2235
- * ####Example:
2349
+ * #### Example:
2236
2350
  *
2237
2351
  * const mongoose = require('mongoose');
2238
2352
  * const ObjectId = mongoose.Schema.Types.ObjectId;
2239
2353
  *
2240
- * ####Types:
2354
+ * #### Types:
2241
2355
  *
2242
2356
  * - [String](/docs/schematypes.html#strings)
2243
2357
  * - [Number](/docs/schematypes.html#numbers)