mongoose 7.1.2 → 7.2.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.
package/index.js CHANGED
@@ -46,6 +46,7 @@ module.exports.Mixed = mongoose.Mixed;
46
46
  module.exports.Date = mongoose.Date;
47
47
  module.exports.Number = mongoose.Number;
48
48
  module.exports.Error = mongoose.Error;
49
+ module.exports.MongooseError = mongoose.MongooseError;
49
50
  module.exports.now = mongoose.now;
50
51
  module.exports.CastError = mongoose.CastError;
51
52
  module.exports.SchemaTypeOptions = mongoose.SchemaTypeOptions;
package/lib/document.js CHANGED
@@ -3676,6 +3676,15 @@ Document.prototype.$toObject = function(options, json) {
3676
3676
  flattenMaps = schemaOptions.flattenMaps;
3677
3677
  }
3678
3678
 
3679
+ let flattenObjectIds;
3680
+ if (options._calledWithOptions.flattenObjectIds != null) {
3681
+ flattenObjectIds = options.flattenObjectIds;
3682
+ } else if (defaultOptions.flattenObjectIds != null) {
3683
+ flattenObjectIds = defaultOptions.flattenObjectIds;
3684
+ } else {
3685
+ flattenObjectIds = schemaOptions.flattenObjectIds;
3686
+ }
3687
+
3679
3688
  // The original options that will be passed to `clone()`. Important because
3680
3689
  // `clone()` will recursively call `$toObject()` on embedded docs, so we
3681
3690
  // need the original options the user passed in, plus `_isNested` and
@@ -3685,6 +3694,7 @@ Document.prototype.$toObject = function(options, json) {
3685
3694
  json: json,
3686
3695
  minimize: _minimize,
3687
3696
  flattenMaps: flattenMaps,
3697
+ flattenObjectIds: flattenObjectIds,
3688
3698
  _seen: (options && options._seen) || new Map()
3689
3699
  });
3690
3700
 
@@ -3900,6 +3910,7 @@ Document.prototype.$toObject = function(options, json) {
3900
3910
  * @param {Boolean} [options.depopulate=false] if true, replace any conventionally populated paths with the original id in the output. Has no affect on virtual populated paths.
3901
3911
  * @param {Boolean} [options.versionKey=true] if false, exclude the version key (`__v` by default) from the output
3902
3912
  * @param {Boolean} [options.flattenMaps=false] if true, convert Maps to POJOs. Useful if you want to `JSON.stringify()` the result of `toObject()`.
3913
+ * @param {Boolean} [options.flattenObjectIds=false] if true, convert any ObjectIds in the result to 24 character hex strings.
3903
3914
  * @param {Boolean} [options.useProjection=false] - If true, omits fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
3904
3915
  * @return {Object} js object (not a POJO)
3905
3916
  * @see mongodb.Binary https://mongodb.github.io/node-mongodb-native/4.9/classes/Binary.html
@@ -3968,8 +3979,7 @@ function applyVirtuals(self, json, options, toObjectOptions) {
3968
3979
  let virtualsToApply = null;
3969
3980
  if (Array.isArray(options.virtuals)) {
3970
3981
  virtualsToApply = new Set(options.virtuals);
3971
- }
3972
- else if (options.virtuals && options.virtuals.pathsToSkip) {
3982
+ } else if (options.virtuals && options.virtuals.pathsToSkip) {
3973
3983
  virtualsToApply = new Set(paths);
3974
3984
  for (let i = 0; i < options.virtuals.pathsToSkip.length; i++) {
3975
3985
  if (virtualsToApply.has(options.virtuals.pathsToSkip[i])) {
@@ -4181,6 +4191,7 @@ function omitDeselectedFields(self, json) {
4181
4191
  *
4182
4192
  * @param {Object} options
4183
4193
  * @param {Boolean} [options.flattenMaps=true] if true, convert Maps to [POJOs](https://masteringjs.io/tutorials/fundamentals/pojo). Useful if you want to `JSON.stringify()` the result.
4194
+ * @param {Boolean} [options.flattenObjectIds=false] if true, convert any ObjectIds in the result to 24 character hex strings.
4184
4195
  * @return {Object}
4185
4196
  * @see Document#toObject https://mongoosejs.com/docs/api/document.html#Document.prototype.toObject()
4186
4197
  * @see JSON.stringify() in JavaScript https://thecodebarbarian.com/the-80-20-guide-to-json-stringify-in-javascript.html
@@ -4193,6 +4204,9 @@ Document.prototype.toJSON = function(options) {
4193
4204
  return this.$toObject(options, true);
4194
4205
  };
4195
4206
 
4207
+ /*!
4208
+ * ignore
4209
+ */
4196
4210
 
4197
4211
  Document.prototype.ownerDocument = function() {
4198
4212
  return this;
@@ -0,0 +1,41 @@
1
+ /*!
2
+ * Module dependencies.
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const MongooseError = require('./');
8
+
9
+
10
+ /**
11
+ * If `bulkWrite()` or `insertMany()` has validation errors, but
12
+ * all valid operations succeed, and 'throwOnValidationError' is true,
13
+ * Mongoose will throw this error.
14
+ *
15
+ * @api private
16
+ */
17
+
18
+ class MongooseBulkWriteError extends MongooseError {
19
+ constructor(validationErrors, results, rawResult, operation) {
20
+ let preview = validationErrors.map(e => e.message).join(', ');
21
+ if (preview.length > 200) {
22
+ preview = preview.slice(0, 200) + '...';
23
+ }
24
+ super(`${operation} failed with ${validationErrors.length} Mongoose validation errors: ${preview}`);
25
+
26
+ this.validationErrors = validationErrors;
27
+ this.results = results;
28
+ this.rawResult = rawResult;
29
+ this.operation = operation;
30
+ }
31
+ }
32
+
33
+ Object.defineProperty(MongooseBulkWriteError.prototype, 'name', {
34
+ value: 'MongooseBulkWriteError'
35
+ });
36
+
37
+ /*!
38
+ * exports
39
+ */
40
+
41
+ module.exports = MongooseBulkWriteError;
@@ -0,0 +1,30 @@
1
+
2
+ /*!
3
+ * Module dependencies.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const MongooseError = require('./');
9
+
10
+ class InvalidSchemaOptionError extends MongooseError {
11
+ /**
12
+ * InvalidSchemaOption Error constructor.
13
+ * @param {String} name
14
+ * @api private
15
+ */
16
+ constructor(name, option) {
17
+ const msg = `Cannot create use schema for property "${name}" because the schema has the ${option} option enabled.`;
18
+ super(msg);
19
+ }
20
+ }
21
+
22
+ Object.defineProperty(InvalidSchemaOptionError.prototype, 'name', {
23
+ value: 'InvalidSchemaOptionError'
24
+ });
25
+
26
+ /*!
27
+ * exports
28
+ */
29
+
30
+ module.exports = InvalidSchemaOptionError;
@@ -78,6 +78,9 @@ function clone(obj, options, isArrayChild) {
78
78
  }
79
79
 
80
80
  if (isBsonType(obj, 'ObjectId')) {
81
+ if (options && options.flattenObjectIds) {
82
+ return obj.toJSON();
83
+ }
81
84
  return new ObjectId(obj.id);
82
85
  }
83
86
 
package/lib/index.js CHANGED
@@ -1140,6 +1140,7 @@ Mongoose.prototype.Number = SchemaTypes.Number;
1140
1140
  */
1141
1141
 
1142
1142
  Mongoose.prototype.Error = require('./error/index');
1143
+ Mongoose.prototype.MongooseError = require('./error/mongooseError');
1143
1144
 
1144
1145
  /**
1145
1146
  * Mongoose uses this function to get the current time when setting
package/lib/model.js CHANGED
@@ -64,6 +64,7 @@ const setDottedPath = require('./helpers/path/setDottedPath');
64
64
  const STATES = require('./connectionstate');
65
65
  const util = require('util');
66
66
  const utils = require('./utils');
67
+ const MongooseBulkWriteError = require('./error/bulkWriteError');
67
68
 
68
69
  const VERSION_WHERE = 1;
69
70
  const VERSION_INC = 2;
@@ -1855,20 +1856,24 @@ Model.discriminators;
1855
1856
  *
1856
1857
  * #### Example:
1857
1858
  *
1858
- * Character
1859
- * .find(Character.translateAliases({
1860
- * '名': 'Eddard Stark' // Alias for 'name'
1861
- * })
1862
- * .exec(function(err, characters) {})
1859
+ * await Character.find(Character.translateAliases({
1860
+ * '名': 'Eddard Stark' // Alias for 'name'
1861
+ * });
1862
+ *
1863
+ * By default, `translateAliases()` overwrites raw fields with aliased fields.
1864
+ * So if `n` is an alias for `name`, `{ n: 'alias', name: 'raw' }` will resolve to `{ name: 'alias' }`.
1865
+ * However, you can set the `errorOnDuplicates` option to throw an error if there are potentially conflicting paths.
1866
+ * The `translateAliases` option for queries uses `errorOnDuplicates`.
1863
1867
  *
1864
1868
  * #### Note:
1865
1869
  *
1866
1870
  * Only translate arguments of object type anything else is returned raw
1867
1871
  *
1868
1872
  * @param {Object} fields fields/conditions that may contain aliased keys
1873
+ * @param {Boolean} [errorOnDuplicates] if true, throw an error if there's both a key and an alias for that key in `fields`
1869
1874
  * @return {Object} the translated 'pure' fields/conditions
1870
1875
  */
1871
- Model.translateAliases = function translateAliases(fields) {
1876
+ Model.translateAliases = function translateAliases(fields, errorOnDuplicates) {
1872
1877
  _checkContext(this, 'translateAliases');
1873
1878
 
1874
1879
  const translate = (key, value) => {
@@ -1880,6 +1885,9 @@ Model.translateAliases = function translateAliases(fields) {
1880
1885
  const name = fieldKeys[i];
1881
1886
  if (currentSchema && currentSchema.aliases[name]) {
1882
1887
  alias = currentSchema.aliases[name];
1888
+ if (errorOnDuplicates && alias in fields) {
1889
+ throw new MongooseError(`Provided object has both field "${name}" and its alias "${alias}"`);
1890
+ }
1883
1891
  // Alias found,
1884
1892
  translated.push(alias);
1885
1893
  } else {
@@ -1932,6 +1940,8 @@ Model.translateAliases = function translateAliases(fields) {
1932
1940
  // Recursively translate nested queries
1933
1941
  fields[key][i] = this.translateAliases(fields[key][i]);
1934
1942
  }
1943
+ } else {
1944
+ this.translateAliases(fields[key]);
1935
1945
  }
1936
1946
  }
1937
1947
  }
@@ -1961,6 +1971,7 @@ Model.translateAliases = function translateAliases(fields) {
1961
1971
  *
1962
1972
  * @param {Object} conditions
1963
1973
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
1974
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
1964
1975
  * @return {Query}
1965
1976
  * @api public
1966
1977
  */
@@ -1995,6 +2006,7 @@ Model.deleteOne = function deleteOne(conditions, options) {
1995
2006
  *
1996
2007
  * @param {Object} conditions
1997
2008
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2009
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
1998
2010
  * @return {Query}
1999
2011
  * @api public
2000
2012
  */
@@ -2036,6 +2048,7 @@ Model.deleteMany = function deleteMany(conditions, options) {
2036
2048
  * @param {Object|ObjectId} filter
2037
2049
  * @param {Object|String|String[]} [projection] optional fields to return, see [`Query.prototype.select()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.select())
2038
2050
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2051
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2039
2052
  * @return {Query}
2040
2053
  * @see field selection https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
2041
2054
  * @see query casting https://mongoosejs.com/docs/tutorials/query_casting.html
@@ -2124,6 +2137,7 @@ Model.findById = function findById(id, projection, options) {
2124
2137
  * @param {Object} [conditions]
2125
2138
  * @param {Object|String|String[]} [projection] optional fields to return, see [`Query.prototype.select()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.select())
2126
2139
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2140
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2127
2141
  * @return {Query}
2128
2142
  * @see field selection https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
2129
2143
  * @see lean queries https://mongoosejs.com/docs/tutorials/lean.html
@@ -2317,7 +2331,7 @@ Model.$where = function $where() {
2317
2331
  };
2318
2332
 
2319
2333
  /**
2320
- * Issues a mongodb findAndModify update command.
2334
+ * Issues a mongodb findOneAndUpdate command.
2321
2335
  *
2322
2336
  * Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any) to the callback. The query executes if `callback` is passed else a Query object is returned.
2323
2337
  *
@@ -2369,6 +2383,7 @@ Model.$where = function $where() {
2369
2383
  * @param {Boolean} [options.runValidators] if true, runs [update validators](https://mongoosejs.com/docs/validation.html#update-validators) on this command. Update validators validate the update operation against the model's schema
2370
2384
  * @param {Boolean} [options.setDefaultsOnInsert=true] If `setDefaultsOnInsert` and `upsert` are true, mongoose will apply the [defaults](https://mongoosejs.com/docs/defaults.html) specified in the model's schema if a new document is created
2371
2385
  * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html)
2386
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2372
2387
  * @return {Query}
2373
2388
  * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
2374
2389
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -2429,7 +2444,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2429
2444
  }
2430
2445
 
2431
2446
  /**
2432
- * Issues a mongodb findAndModify update command by a document's _id field.
2447
+ * Issues a mongodb findOneAndUpdate command by a document's _id field.
2433
2448
  * `findByIdAndUpdate(id, ...)` is equivalent to `findOneAndUpdate({ _id: id }, ...)`.
2434
2449
  *
2435
2450
  * Finds a matching document, updates it according to the `update` arg,
@@ -2487,6 +2502,7 @@ function _decorateUpdateWithVersionKey(update, options, versionKey) {
2487
2502
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
2488
2503
  * @param {Boolean} [options.new=false] if true, return the modified document rather than the original
2489
2504
  * @param {Object|String} [options.select] sets the document fields to return.
2505
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2490
2506
  * @return {Query}
2491
2507
  * @see Model.findOneAndUpdate https://mongoosejs.com/docs/api/model.html#Model.findOneAndUpdate()
2492
2508
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -2547,6 +2563,7 @@ Model.findByIdAndUpdate = function(id, update, options) {
2547
2563
  * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update.
2548
2564
  * @param {Object|String} [options.select] sets the document fields to return.
2549
2565
  * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0
2566
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2550
2567
  * @return {Query}
2551
2568
  * @api public
2552
2569
  */
@@ -2582,6 +2599,7 @@ Model.findOneAndDelete = function(conditions, options) {
2582
2599
  * @param {Object|Number|String} id value of `_id` to query by
2583
2600
  * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2584
2601
  * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
2602
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2585
2603
  * @return {Query}
2586
2604
  * @see Model.findOneAndRemove https://mongoosejs.com/docs/api/model.html#Model.findOneAndRemove()
2587
2605
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -2625,6 +2643,7 @@ Model.findByIdAndDelete = function(id, options) {
2625
2643
  * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html)
2626
2644
  * @param {Object|String} [options.select] sets the document fields to return.
2627
2645
  * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0
2646
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2628
2647
  * @return {Query}
2629
2648
  * @api public
2630
2649
  */
@@ -2649,7 +2668,7 @@ Model.findOneAndReplace = function(filter, replacement, options) {
2649
2668
  };
2650
2669
 
2651
2670
  /**
2652
- * Issue a mongodb findAndModify remove command.
2671
+ * Issue a mongodb findOneAndRemove command.
2653
2672
  *
2654
2673
  * Finds a matching document, removes it, and returns the found document (if any).
2655
2674
  *
@@ -2682,6 +2701,7 @@ Model.findOneAndReplace = function(filter, replacement, options) {
2682
2701
  * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html)
2683
2702
  * @param {Object|String} [options.select] sets the document fields to return.
2684
2703
  * @param {Number} [options.maxTimeMS] puts a time limit on the query - requires mongodb >= 2.6.0
2704
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2685
2705
  * @return {Query}
2686
2706
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
2687
2707
  * @api public
@@ -2707,7 +2727,7 @@ Model.findOneAndRemove = function(conditions, options) {
2707
2727
  };
2708
2728
 
2709
2729
  /**
2710
- * Issue a mongodb findAndModify remove command by a document's _id field. `findByIdAndRemove(id, ...)` is equivalent to `findOneAndRemove({ _id: id }, ...)`.
2730
+ * Issue a mongodb findOneAndRemove command by a document's _id field. `findByIdAndRemove(id, ...)` is equivalent to `findOneAndRemove({ _id: id }, ...)`.
2711
2731
  *
2712
2732
  * Finds a matching document, removes it, and returns the found document (if any).
2713
2733
  *
@@ -2729,6 +2749,7 @@ Model.findOneAndRemove = function(conditions, options) {
2729
2749
  * @param {Object|String} [options.sort] if multiple docs are found by the conditions, sets the sort order to choose which doc to update.
2730
2750
  * @param {Boolean} [options.rawResult] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html)
2731
2751
  * @param {Object|String} [options.select] sets the document fields to return.
2752
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2732
2753
  * @return {Query}
2733
2754
  * @see Model.findOneAndRemove https://mongoosejs.com/docs/api/model.html#Model.findOneAndRemove()
2734
2755
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -2962,6 +2983,7 @@ Model.startSession = function() {
2962
2983
  * @param {Boolean} [options.lean=false] if `true`, skips hydrating and validating the documents. This option is useful if you need the extra performance, but Mongoose won't validate the documents before inserting.
2963
2984
  * @param {Number} [options.limit=null] this limits the number of documents being processed (validation/casting) by mongoose in parallel, this does **NOT** send the documents in batches to MongoDB. Use this option if you're processing a large number of documents and your app is running out of memory.
2964
2985
  * @param {String|Object|Array} [options.populate=null] populates the result documents. This option is a no-op if `rawResult` is set.
2986
+ * @param {Boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully.
2965
2987
  * @return {Promise} resolving to the raw result from the MongoDB driver if `options.rawResult` was `true`, or the documents that passed validation, otherwise
2966
2988
  * @api public
2967
2989
  */
@@ -3007,6 +3029,7 @@ Model.$__insertMany = function(arr, options, callback) {
3007
3029
  const limit = options.limit || 1000;
3008
3030
  const rawResult = !!options.rawResult;
3009
3031
  const ordered = typeof options.ordered === 'boolean' ? options.ordered : true;
3032
+ const throwOnValidationError = typeof options.throwOnValidationError === 'boolean' ? options.throwOnValidationError : false;
3010
3033
  const lean = !!options.lean;
3011
3034
 
3012
3035
  if (!Array.isArray(arr)) {
@@ -3113,6 +3136,20 @@ Model.$__insertMany = function(arr, options, callback) {
3113
3136
  _setIsNew(attribute, false);
3114
3137
  }
3115
3138
 
3139
+ if (ordered === false && throwOnValidationError && validationErrors.length > 0) {
3140
+ for (let i = 0; i < results.length; ++i) {
3141
+ if (results[i] === void 0) {
3142
+ results[i] = docs[i];
3143
+ }
3144
+ }
3145
+ return callback(new MongooseBulkWriteError(
3146
+ validationErrors,
3147
+ results,
3148
+ res,
3149
+ 'insertMany'
3150
+ ));
3151
+ }
3152
+
3116
3153
  if (rawResult) {
3117
3154
  if (ordered === false) {
3118
3155
  for (let i = 0; i < results.length; ++i) {
@@ -3308,6 +3345,7 @@ function _setIsNew(doc, val) {
3308
3345
  * @param {Boolean} [options.j=true] If false, disable [journal acknowledgement](https://www.mongodb.com/docs/manual/reference/write-concern/#j-option)
3309
3346
  * @param {Boolean} [options.skipValidation=false] Set to true to skip Mongoose schema validation on bulk write operations. Mongoose currently runs validation on `insertOne` and `replaceOne` operations by default.
3310
3347
  * @param {Boolean} [options.bypassDocumentValidation=false] If true, disable [MongoDB server-side schema validation](https://www.mongodb.com/docs/manual/core/schema-validation/) for all writes in this bulk.
3348
+ * @param {Boolean} [options.throwOnValidationError=false] If true and `ordered: false`, throw an error if one of the operations failed validation, but all valid operations completed successfully.
3311
3349
  * @param {Boolean} [options.strict=null] Overwrites the [`strict` option](https://mongoosejs.com/docs/guide.html#strict) on schema. If false, allows filtering and writing fields not defined in the schema for all writes in this bulk.
3312
3350
  * @return {Promise} resolves to a [`BulkWriteOpResult`](https://mongodb.github.io/node-mongodb-native/4.9/classes/BulkWriteResult.html) if the operation succeeds
3313
3351
  * @api public
@@ -3355,12 +3393,14 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
3355
3393
  let remaining = validations.length;
3356
3394
  let validOps = [];
3357
3395
  let validationErrors = [];
3396
+ const results = [];
3358
3397
  for (let i = 0; i < validations.length; ++i) {
3359
3398
  validations[i]((err) => {
3360
3399
  if (err == null) {
3361
3400
  validOps.push(i);
3362
3401
  } else {
3363
3402
  validationErrors.push({ index: i, error: err });
3403
+ results[i] = err;
3364
3404
  }
3365
3405
  if (--remaining <= 0) {
3366
3406
  completeUnorderedValidation.call(this);
@@ -3373,6 +3413,7 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
3373
3413
  map(v => v.error);
3374
3414
 
3375
3415
  function completeUnorderedValidation() {
3416
+ const validOpIndexes = validOps;
3376
3417
  validOps = validOps.sort().map(index => ops[index]);
3377
3418
 
3378
3419
  this.$__collection.bulkWrite(validOps, options, (error, res) => {
@@ -3385,9 +3426,22 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
3385
3426
  return reject(error);
3386
3427
  }
3387
3428
 
3429
+ for (let i = 0; i < validOpIndexes.length; ++i) {
3430
+ results[validOpIndexes[i]] = null;
3431
+ }
3388
3432
  if (validationErrors.length > 0) {
3389
- res.mongoose = res.mongoose || {};
3390
- res.mongoose.validationErrors = validationErrors;
3433
+ if (options.throwOnValidationError) {
3434
+ return reject(new MongooseBulkWriteError(
3435
+ validationErrors,
3436
+ results,
3437
+ res,
3438
+ 'bulkWrite'
3439
+ ));
3440
+ } else {
3441
+ res.mongoose = res.mongoose || {};
3442
+ res.mongoose.validationErrors = validationErrors;
3443
+ res.mongoose.results = results;
3444
+ }
3391
3445
  }
3392
3446
 
3393
3447
  resolve(res);
@@ -3739,6 +3793,7 @@ Model.hydrate = function(obj, projection, options) {
3739
3793
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3740
3794
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
3741
3795
  * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3796
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3742
3797
  * @return {Query}
3743
3798
  * @see Query docs https://mongoosejs.com/docs/queries.html
3744
3799
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
@@ -3777,6 +3832,7 @@ Model.updateMany = function updateMany(conditions, doc, options) {
3777
3832
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3778
3833
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
3779
3834
  * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3835
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3780
3836
  * @return {Query}
3781
3837
  * @see Query docs https://mongoosejs.com/docs/queries.html
3782
3838
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
@@ -3813,6 +3869,7 @@ Model.updateOne = function updateOne(conditions, doc, options) {
3813
3869
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3814
3870
  * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
3815
3871
  * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
3872
+ * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3816
3873
  * @return {Query}
3817
3874
  * @see Query docs https://mongoosejs.com/docs/queries.html
3818
3875
  * @see UpdateResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/UpdateResult.html