mongoose 7.3.4 → 7.4.1

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 (41) hide show
  1. package/dist/browser.umd.js +1 -1
  2. package/lib/cast.js +2 -2
  3. package/lib/connection.js +32 -200
  4. package/lib/document.js +34 -42
  5. package/lib/drivers/node-mongodb-native/connection.js +247 -0
  6. package/lib/error/cast.js +10 -9
  7. package/lib/error/messages.js +1 -1
  8. package/lib/helpers/schema/applyWriteConcern.js +3 -0
  9. package/lib/helpers/schema/getPath.js +0 -1
  10. package/lib/helpers/schema/idGetter.js +12 -1
  11. package/lib/model.js +49 -18
  12. package/lib/query.js +36 -22
  13. package/lib/schema/SubdocumentPath.js +10 -4
  14. package/lib/schema/array.js +2 -0
  15. package/lib/schema/bigint.js +2 -0
  16. package/lib/schema/boolean.js +2 -0
  17. package/lib/schema/buffer.js +2 -0
  18. package/lib/schema/date.js +2 -0
  19. package/lib/schema/decimal128.js +2 -0
  20. package/lib/schema/documentarray.js +2 -0
  21. package/lib/schema/mixed.js +2 -0
  22. package/lib/schema/number.js +2 -0
  23. package/lib/schema/objectid.js +2 -0
  24. package/lib/schema/string.js +2 -0
  25. package/lib/schema/uuid.js +2 -0
  26. package/lib/schema.js +9 -7
  27. package/lib/schematype.js +20 -4
  28. package/lib/types/ArraySubdocument.js +9 -1
  29. package/lib/types/DocumentArray/methods/index.js +2 -2
  30. package/lib/types/array/methods/index.js +1 -1
  31. package/lib/types/subdocument.js +4 -0
  32. package/package.json +3 -3
  33. package/types/augmentations.d.ts +9 -0
  34. package/types/index.d.ts +12 -0
  35. package/types/inferschematype.d.ts +8 -7
  36. package/types/models.d.ts +7 -2
  37. package/types/query.d.ts +5 -1
  38. package/types/schemaoptions.d.ts +3 -0
  39. package/types/schematypes.d.ts +5 -1
  40. package/types/types.d.ts +0 -1
  41. package/lib/helpers/path/flattenObjectWithDottedPaths.js +0 -39
package/lib/query.js CHANGED
@@ -24,6 +24,7 @@ const getDiscriminatorByValue = require('./helpers/discriminator/getDiscriminato
24
24
  const hasDollarKeys = require('./helpers/query/hasDollarKeys');
25
25
  const helpers = require('./queryhelpers');
26
26
  const immediate = require('./helpers/immediate');
27
+ const internalToObjectOptions = require('./options').internalToObjectOptions;
27
28
  const isExclusive = require('./helpers/projection/isExclusive');
28
29
  const isInclusive = require('./helpers/projection/isInclusive');
29
30
  const isPathSelectedInclusive = require('./helpers/projection/isPathSelectedInclusive');
@@ -1635,6 +1636,10 @@ Query.prototype.setOptions = function(options, overwrite) {
1635
1636
  delete options.translateAliases;
1636
1637
  }
1637
1638
 
1639
+ if ('rawResult' in options) {
1640
+ printRawResultDeprecationWarning();
1641
+ }
1642
+
1638
1643
  if (options.lean == null && this.schema && 'lean' in this.schema.options) {
1639
1644
  this._mongooseOptions.lean = this.schema.options.lean;
1640
1645
  }
@@ -1669,6 +1674,15 @@ Query.prototype.setOptions = function(options, overwrite) {
1669
1674
  return this;
1670
1675
  };
1671
1676
 
1677
+ /*!
1678
+ * ignore
1679
+ */
1680
+
1681
+ const printRawResultDeprecationWarning = util.deprecate(
1682
+ function printRawResultDeprecationWarning() {},
1683
+ 'The `rawResult` option for Mongoose queries is deprecated. Use `includeResultMetadata: false` as a replacement for `rawResult: true`.'
1684
+ );
1685
+
1672
1686
  /**
1673
1687
  * Sets the [`explain` option](https://www.mongodb.com/docs/manual/reference/method/cursor.explain/),
1674
1688
  * which makes this query return detailed execution stats instead of the actual
@@ -1954,7 +1968,6 @@ Query.prototype._optionsForExec = function(model) {
1954
1968
  if (!model) {
1955
1969
  return options;
1956
1970
  }
1957
-
1958
1971
  // Apply schema-level `writeConcern` option
1959
1972
  applyWriteConcern(model.schema, options);
1960
1973
 
@@ -2319,8 +2332,6 @@ Query.prototype.find = function(conditions) {
2319
2332
 
2320
2333
  this.op = 'find';
2321
2334
 
2322
- conditions = utils.toObject(conditions);
2323
-
2324
2335
  if (mquery.canMerge(conditions)) {
2325
2336
  this.merge(conditions);
2326
2337
 
@@ -2392,6 +2403,8 @@ Query.prototype.merge = function(source) {
2392
2403
  utils.merge(this._conditions, { _id: source }, opts);
2393
2404
 
2394
2405
  return this;
2406
+ } else if (source && source.$__) {
2407
+ source = source.toObject(internalToObjectOptions);
2395
2408
  }
2396
2409
 
2397
2410
  opts.omit = {};
@@ -2434,7 +2447,7 @@ Query.prototype.collation = function(value) {
2434
2447
  */
2435
2448
 
2436
2449
  Query.prototype._completeOne = function(doc, res, callback) {
2437
- if (!doc && !this.options.rawResult) {
2450
+ if (!doc && !this.options.rawResult && !this.options.includeResultMetadata) {
2438
2451
  return callback(null, null);
2439
2452
  }
2440
2453
 
@@ -2560,9 +2573,6 @@ Query.prototype.findOne = function(conditions, projection, options) {
2560
2573
  this.op = 'findOne';
2561
2574
  this._validateOp();
2562
2575
 
2563
- // make sure we don't send in the whole Document to merge()
2564
- conditions = utils.toObject(conditions);
2565
-
2566
2576
  if (options) {
2567
2577
  this.setOptions(options);
2568
2578
  }
@@ -2726,8 +2736,6 @@ Query.prototype.count = function(filter) {
2726
2736
  this.op = 'count';
2727
2737
  this._validateOp();
2728
2738
 
2729
- filter = utils.toObject(filter);
2730
-
2731
2739
  if (mquery.canMerge(filter)) {
2732
2740
  this.merge(filter);
2733
2741
  }
@@ -2822,8 +2830,6 @@ Query.prototype.countDocuments = function(conditions, options) {
2822
2830
  this.op = 'countDocuments';
2823
2831
  this._validateOp();
2824
2832
 
2825
- conditions = utils.toObject(conditions);
2826
-
2827
2833
  if (mquery.canMerge(conditions)) {
2828
2834
  this.merge(conditions);
2829
2835
  }
@@ -2886,7 +2892,6 @@ Query.prototype.distinct = function(field, conditions) {
2886
2892
 
2887
2893
  this.op = 'distinct';
2888
2894
  this._validateOp();
2889
- conditions = utils.toObject(conditions);
2890
2895
 
2891
2896
  if (mquery.canMerge(conditions)) {
2892
2897
  this.merge(conditions);
@@ -2981,8 +2986,6 @@ Query.prototype.deleteOne = function deleteOne(filter, options) {
2981
2986
  this.op = 'deleteOne';
2982
2987
  this.setOptions(options);
2983
2988
 
2984
- filter = utils.toObject(filter);
2985
-
2986
2989
  if (mquery.canMerge(filter)) {
2987
2990
  this.merge(filter);
2988
2991
 
@@ -3058,8 +3061,6 @@ Query.prototype.deleteMany = function(filter, options) {
3058
3061
  this.setOptions(options);
3059
3062
  this.op = 'deleteMany';
3060
3063
 
3061
- filter = utils.toObject(filter);
3062
-
3063
3064
  if (mquery.canMerge(filter)) {
3064
3065
  this.merge(filter);
3065
3066
 
@@ -3110,7 +3111,7 @@ Query.prototype._deleteMany = async function _deleteMany() {
3110
3111
  */
3111
3112
 
3112
3113
  function completeOne(model, doc, res, options, fields, userProvidedFields, pop, callback) {
3113
- if (options.rawResult && doc == null) {
3114
+ if ((options.rawResult || options.includeResultMetadata) && doc == null) {
3114
3115
  _init(null);
3115
3116
  return null;
3116
3117
  }
@@ -3123,7 +3124,7 @@ function completeOne(model, doc, res, options, fields, userProvidedFields, pop,
3123
3124
  }
3124
3125
 
3125
3126
 
3126
- if (options.rawResult) {
3127
+ if (options.rawResult || options.includeResultMetadata) {
3127
3128
  if (doc && casted) {
3128
3129
  if (options.session != null) {
3129
3130
  casted.$session(options.session);
@@ -3298,6 +3299,10 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3298
3299
  applyGlobalMaxTimeMS(this.options, this.model);
3299
3300
  applyGlobalDiskUse(this.options, this.model);
3300
3301
 
3302
+ if (this.options.rawResult && this.options.includeResultMetadata === false) {
3303
+ throw new MongooseError('Cannot set `rawResult` option when `includeResultMetadata` is false');
3304
+ }
3305
+
3301
3306
  if ('strict' in this.options) {
3302
3307
  this._mongooseOptions.strict = this.options.strict;
3303
3308
  }
@@ -3348,7 +3353,7 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3348
3353
  for (const fn of this._transforms) {
3349
3354
  res = fn(res);
3350
3355
  }
3351
- const doc = res.value;
3356
+ const doc = options.includeResultMetadata === false ? res : res.value;
3352
3357
 
3353
3358
  return new Promise((resolve, reject) => {
3354
3359
  this._completeOne(doc, res, _wrapThunkCallback(this, (err, res) => {
@@ -3489,6 +3494,11 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
3489
3494
  throw this.error();
3490
3495
  }
3491
3496
 
3497
+ const includeResultMetadata = this.options.includeResultMetadata;
3498
+ if (this.options.rawResult && includeResultMetadata === false) {
3499
+ throw new MongooseError('Cannot set `rawResult` option when `includeResultMetadata` is false');
3500
+ }
3501
+
3492
3502
  const filter = this._conditions;
3493
3503
  const options = this._optionsForExec(this.model);
3494
3504
  this._applyTranslateAliases(options);
@@ -3497,7 +3507,7 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
3497
3507
  for (const fn of this._transforms) {
3498
3508
  res = fn(res);
3499
3509
  }
3500
- const doc = res.value;
3510
+ const doc = includeResultMetadata === false ? res : res.value;
3501
3511
 
3502
3512
  return new Promise((resolve, reject) => {
3503
3513
  this._completeOne(doc, res, _wrapThunkCallback(this, (err, res) => {
@@ -3624,6 +3634,11 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3624
3634
  this._applyTranslateAliases(options);
3625
3635
  convertNewToReturnDocument(options);
3626
3636
 
3637
+ const includeResultMetadata = this.options.includeResultMetadata;
3638
+ if (this.options.rawResult && includeResultMetadata === false) {
3639
+ throw new MongooseError('Cannot set `rawResult` option when `includeResultMetadata` is false');
3640
+ }
3641
+
3627
3642
  const modelOpts = { skipId: true };
3628
3643
  if ('strict' in this._mongooseOptions) {
3629
3644
  modelOpts.strict = this._mongooseOptions.strict;
@@ -3654,7 +3669,7 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3654
3669
  res = fn(res);
3655
3670
  }
3656
3671
 
3657
- const doc = res.value;
3672
+ const doc = includeResultMetadata === false ? res : res.value;
3658
3673
  return new Promise((resolve, reject) => {
3659
3674
  this._completeOne(doc, res, _wrapThunkCallback(this, (err, res) => {
3660
3675
  if (err) {
@@ -4168,7 +4183,6 @@ function _update(query, op, filter, doc, options, callback) {
4168
4183
  // make sure we don't send in the whole Document to merge()
4169
4184
  query.op = op;
4170
4185
  query._validateOp();
4171
- filter = utils.toObject(filter);
4172
4186
  doc = doc || {};
4173
4187
 
4174
4188
  // strict is an option used in the update checking, make sure it gets set
@@ -165,22 +165,22 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
165
165
  let subdoc;
166
166
 
167
167
  // Only pull relevant selected paths and pull out the base path
168
- const parentSelected = doc && doc.$__ && doc.$__.selected || {};
168
+ const parentSelected = doc && doc.$__ && doc.$__.selected;
169
169
  const path = this.path;
170
- const selected = Object.keys(parentSelected).reduce((obj, key) => {
170
+ const selected = parentSelected == null ? null : Object.keys(parentSelected).reduce((obj, key) => {
171
171
  if (key.startsWith(path + '.')) {
172
172
  obj = obj || {};
173
173
  obj[key.substring(path.length + 1)] = parentSelected[key];
174
174
  }
175
175
  return obj;
176
176
  }, null);
177
- options = Object.assign({}, options, { priorDoc: priorVal });
178
177
  if (init) {
179
178
  subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
180
179
  delete subdoc.$__.defaults;
181
180
  subdoc.$init(val);
182
181
  applyDefaults(subdoc, selected);
183
182
  } else {
183
+ options = Object.assign({}, options, { priorDoc: priorVal });
184
184
  if (Object.keys(val).length === 0) {
185
185
  return new Constructor({}, selected, doc, undefined, options);
186
186
  }
@@ -212,11 +212,15 @@ SubdocumentPath.prototype.castForQuery = function($conditional, val, context, op
212
212
  return val;
213
213
  }
214
214
 
215
+ const Constructor = getConstructor(this.caster, val);
216
+ if (val instanceof Constructor) {
217
+ return val;
218
+ }
219
+
215
220
  if (this.options.runSetters) {
216
221
  val = this._applySetters(val, context);
217
222
  }
218
223
 
219
- const Constructor = getConstructor(this.caster, val);
220
224
  const overrideStrict = options != null && options.strict != null ?
221
225
  options.strict :
222
226
  void 0;
@@ -347,6 +351,8 @@ SubdocumentPath.defaultOptions = {};
347
351
 
348
352
  SubdocumentPath.set = SchemaType.set;
349
353
 
354
+ SubdocumentPath.setters = [];
355
+
350
356
  /**
351
357
  * Attaches a getter for all SubdocumentPath instances
352
358
  *
@@ -170,6 +170,8 @@ SchemaArray.defaultOptions = {};
170
170
  */
171
171
  SchemaArray.set = SchemaType.set;
172
172
 
173
+ SchemaArray.setters = [];
174
+
173
175
  /**
174
176
  * Attaches a getter for all Array instances
175
177
  *
@@ -62,6 +62,8 @@ SchemaBigInt._cast = castBigInt;
62
62
 
63
63
  SchemaBigInt.set = SchemaType.set;
64
64
 
65
+ SchemaBigInt.setters = [];
66
+
65
67
  /**
66
68
  * Attaches a getter for all BigInt instances
67
69
  *
@@ -65,6 +65,8 @@ SchemaBoolean._cast = castBoolean;
65
65
 
66
66
  SchemaBoolean.set = SchemaType.set;
67
67
 
68
+ SchemaBoolean.setters = [];
69
+
68
70
  /**
69
71
  * Attaches a getter for all Boolean instances
70
72
  *
@@ -70,6 +70,8 @@ SchemaBuffer._checkRequired = v => !!(v && v.length);
70
70
 
71
71
  SchemaBuffer.set = SchemaType.set;
72
72
 
73
+ SchemaBuffer.setters = [];
74
+
73
75
  /**
74
76
  * Attaches a getter for all Buffer instances
75
77
  *
@@ -70,6 +70,8 @@ SchemaDate._cast = castDate;
70
70
 
71
71
  SchemaDate.set = SchemaType.set;
72
72
 
73
+ SchemaDate.setters = [];
74
+
73
75
  /**
74
76
  * Attaches a getter for all Date instances
75
77
  *
@@ -66,6 +66,8 @@ Decimal128._cast = castDecimal128;
66
66
 
67
67
  Decimal128.set = SchemaType.set;
68
68
 
69
+ Decimal128.setters = [];
70
+
69
71
  /**
70
72
  * Attaches a getter for all Decimal128 instances
71
73
  *
@@ -605,6 +605,8 @@ DocumentArrayPath.defaultOptions = {};
605
605
 
606
606
  DocumentArrayPath.set = SchemaType.set;
607
607
 
608
+ DocumentArrayPath.setters = [];
609
+
608
610
  /**
609
611
  * Attaches a getter for all DocumentArrayPath instances
610
612
  *
@@ -94,6 +94,8 @@ Mixed.get = SchemaType.get;
94
94
 
95
95
  Mixed.set = SchemaType.set;
96
96
 
97
+ Mixed.setters = [];
98
+
97
99
  /**
98
100
  * Casts `val` for Mixed.
99
101
  *
@@ -67,6 +67,8 @@ SchemaNumber.get = SchemaType.get;
67
67
 
68
68
  SchemaNumber.set = SchemaType.set;
69
69
 
70
+ SchemaNumber.setters = [];
71
+
70
72
  /*!
71
73
  * ignore
72
74
  */
@@ -94,6 +94,8 @@ ObjectId.get = SchemaType.get;
94
94
 
95
95
  ObjectId.set = SchemaType.set;
96
96
 
97
+ ObjectId.setters = [];
98
+
97
99
  /**
98
100
  * Adds an auto-generated ObjectId default if turnOn is true.
99
101
  * @param {Boolean} turnOn auto generated ObjectId defaults
@@ -143,6 +143,8 @@ SchemaString.get = SchemaType.get;
143
143
 
144
144
  SchemaString.set = SchemaType.set;
145
145
 
146
+ SchemaString.setters = [];
147
+
146
148
  /*!
147
149
  * ignore
148
150
  */
@@ -194,6 +194,8 @@ SchemaUUID.get = SchemaType.get;
194
194
 
195
195
  SchemaUUID.set = SchemaType.set;
196
196
 
197
+ SchemaUUID.setters = [];
198
+
197
199
  /**
198
200
  * Get/set the function used to cast arbitrary values to UUIDs.
199
201
  *
package/lib/schema.js CHANGED
@@ -80,6 +80,7 @@ let id = 0;
80
80
  * - [timestamps](https://mongoosejs.com/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.
81
81
  * - [pluginTags](https://mongoosejs.com/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.
82
82
  * - [virtuals](https://mongoosejs.com/docs/tutorials/virtuals.html#virtuals-via-schema-options): object - virtuals to define, alias for [`.virtual`](https://mongoosejs.com/docs/api/schema.html#Schema.prototype.virtual())
83
+ * - [collectionOptions]: object with options passed to [`createCollection()`](https://www.mongodb.com/docs/manual/reference/method/db.createCollection/) when calling `Model.createCollection()` or `autoCreate` set to true.
83
84
  *
84
85
  * #### Options for Nested Schemas:
85
86
  *
@@ -747,10 +748,10 @@ Schema.prototype.add = function add(obj, prefix) {
747
748
  childSchemaOptions.strict = this._userProvidedOptions.strict;
748
749
  }
749
750
  if (this._userProvidedOptions.toObject != null) {
750
- childSchemaOptions.toObject = this._userProvidedOptions.toObject;
751
+ childSchemaOptions.toObject = utils.omit(this._userProvidedOptions.toObject, ['transform']);
751
752
  }
752
753
  if (this._userProvidedOptions.toJSON != null) {
753
- childSchemaOptions.toJSON = this._userProvidedOptions.toJSON;
754
+ childSchemaOptions.toJSON = utils.omit(this._userProvidedOptions.toJSON, ['transform']);
754
755
  }
755
756
 
756
757
  const _schema = new Schema(_typeDef, childSchemaOptions);
@@ -1345,10 +1346,10 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
1345
1346
  childSchemaOptions.strictQuery = options.strictQuery;
1346
1347
  }
1347
1348
  if (options.hasOwnProperty('toObject')) {
1348
- childSchemaOptions.toObject = options.toObject;
1349
+ childSchemaOptions.toObject = utils.omit(options.toObject, ['transform']);
1349
1350
  }
1350
1351
  if (options.hasOwnProperty('toJSON')) {
1351
- childSchemaOptions.toJSON = options.toJSON;
1352
+ childSchemaOptions.toJSON = utils.omit(options.toJSON, ['transform']);
1352
1353
  }
1353
1354
 
1354
1355
  if (this._userProvidedOptions.hasOwnProperty('_id')) {
@@ -1585,9 +1586,6 @@ Schema.prototype.indexedPaths = function indexedPaths() {
1585
1586
  */
1586
1587
 
1587
1588
  Schema.prototype.pathType = function(path) {
1588
- // Convert to '.$' to check subpaths re: gh-6405
1589
- const cleanPath = _pathToPositionalSyntax(path);
1590
-
1591
1589
  if (this.paths.hasOwnProperty(path)) {
1592
1590
  return 'real';
1593
1591
  }
@@ -1597,6 +1595,10 @@ Schema.prototype.pathType = function(path) {
1597
1595
  if (this.nested.hasOwnProperty(path)) {
1598
1596
  return 'nested';
1599
1597
  }
1598
+
1599
+ // Convert to '.$' to check subpaths re: gh-6405
1600
+ const cleanPath = _pathToPositionalSyntax(path);
1601
+
1600
1602
  if (this.subpaths.hasOwnProperty(cleanPath) || this.subpaths.hasOwnProperty(path)) {
1601
1603
  return 'real';
1602
1604
  }
package/lib/schematype.js CHANGED
@@ -48,7 +48,9 @@ function SchemaType(path, options, instance) {
48
48
  this.getters = this.constructor.hasOwnProperty('getters') ?
49
49
  this.constructor.getters.slice() :
50
50
  [];
51
- this.setters = [];
51
+ this.setters = this.constructor.hasOwnProperty('setters') ?
52
+ this.constructor.setters.slice() :
53
+ [];
52
54
 
53
55
  this.splitPath();
54
56
 
@@ -80,7 +82,11 @@ function SchemaType(path, options, instance) {
80
82
  const keys = Object.keys(this.options);
81
83
  for (const prop of keys) {
82
84
  if (prop === 'cast') {
83
- this.castFunction(this.options[prop]);
85
+ if (Array.isArray(this.options[prop])) {
86
+ this.castFunction.apply(this, this.options[prop]);
87
+ } else {
88
+ this.castFunction(this.options[prop]);
89
+ }
84
90
  continue;
85
91
  }
86
92
  if (utils.hasUserDefinedProperty(this.options, prop) && typeof this[prop] === 'function') {
@@ -253,14 +259,24 @@ SchemaType.cast = function cast(caster) {
253
259
  * @api public
254
260
  */
255
261
 
256
- SchemaType.prototype.castFunction = function castFunction(caster) {
262
+ SchemaType.prototype.castFunction = function castFunction(caster, message) {
257
263
  if (arguments.length === 0) {
258
264
  return this._castFunction;
259
265
  }
266
+
260
267
  if (caster === false) {
261
268
  caster = this.constructor._defaultCaster || (v => v);
262
269
  }
263
- this._castFunction = caster;
270
+ if (typeof caster === 'string') {
271
+ this._castErrorMessage = caster;
272
+ return this._castFunction;
273
+ }
274
+ if (caster != null) {
275
+ this._castFunction = caster;
276
+ }
277
+ if (message != null) {
278
+ this._castErrorMessage = message;
279
+ }
264
280
 
265
281
  return this._castFunction;
266
282
  };
@@ -33,7 +33,15 @@ function ArraySubdocument(obj, parentArr, skipId, fields, index) {
33
33
  this.$setIndex(index);
34
34
  this.$__parent = this[documentArrayParent];
35
35
 
36
- Subdocument.call(this, obj, fields, this[documentArrayParent], skipId, { isNew: true });
36
+ let options;
37
+ if (typeof skipId === 'object' && skipId != null) {
38
+ options = { isNew: true, ...skipId };
39
+ skipId = undefined;
40
+ } else {
41
+ options = { isNew: true };
42
+ }
43
+
44
+ Subdocument.call(this, obj, fields, this[documentArrayParent], skipId, options);
37
45
  }
38
46
 
39
47
  /*!
@@ -38,7 +38,7 @@ const methods = {
38
38
  * @memberOf MongooseDocumentArray
39
39
  */
40
40
 
41
- _cast(value, index) {
41
+ _cast(value, index, options) {
42
42
  if (this[arraySchemaSymbol] == null) {
43
43
  return value;
44
44
  }
@@ -89,7 +89,7 @@ const methods = {
89
89
  if (Constructor.$isMongooseDocumentArray) {
90
90
  return Constructor.cast(value, this, undefined, undefined, index);
91
91
  }
92
- const ret = new Constructor(value, this, undefined, undefined, index);
92
+ const ret = new Constructor(value, this, options, undefined, index);
93
93
  ret.isNew = true;
94
94
  return ret;
95
95
  },
@@ -595,7 +595,7 @@ const methods = {
595
595
  */
596
596
 
597
597
  pull() {
598
- const values = [].map.call(arguments, this._cast, this);
598
+ const values = [].map.call(arguments, (v, i) => this._cast(v, i, { defaults: false }), this);
599
599
  const cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
600
600
  let i = cur.length;
601
601
  let mem;
@@ -16,6 +16,10 @@ module.exports = Subdocument;
16
16
  */
17
17
 
18
18
  function Subdocument(value, fields, parent, skipId, options) {
19
+ if (typeof skipId === 'object' && skipId != null && options == null) {
20
+ options = skipId;
21
+ skipId = undefined;
22
+ }
19
23
  if (parent != null) {
20
24
  // If setting a nested path, should copy isNew from parent re: gh-7048
21
25
  const parentOptions = { isNew: parent.isNew };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "7.3.4",
4
+ "version": "7.4.1",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -19,9 +19,9 @@
19
19
  ],
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "bson": "^5.3.0",
22
+ "bson": "^5.4.0",
23
23
  "kareem": "2.5.1",
24
- "mongodb": "5.6.0",
24
+ "mongodb": "5.7.0",
25
25
  "mpath": "0.9.0",
26
26
  "mquery": "5.0.0",
27
27
  "ms": "2.1.3",
@@ -0,0 +1,9 @@
1
+ // this import is required so that types get merged instead of completely overwritten
2
+ import 'bson';
3
+
4
+ declare module 'bson' {
5
+ interface ObjectId {
6
+ /** Mongoose automatically adds a conveniency "_id" getter on the base ObjectId class */
7
+ _id: this;
8
+ }
9
+ }
package/types/index.d.ts CHANGED
@@ -22,6 +22,7 @@
22
22
  /// <reference path="./validation.d.ts" />
23
23
  /// <reference path="./inferschematype.d.ts" />
24
24
  /// <reference path="./virtuals.d.ts" />
25
+ /// <reference path="./augmentations.d.ts" />
25
26
 
26
27
  declare class NativeDate extends global.Date { }
27
28
 
@@ -377,11 +378,22 @@ declare module 'mongoose' {
377
378
  pre<T = never>(method: MongooseQueryOrDocumentMiddleware | MongooseQueryOrDocumentMiddleware[] | RegExp, options: SchemaPreOptions & { document: false, query: false }, fn: PreMiddlewareFunction<T>): this;
378
379
  pre<T = never>(method: MongooseDistinctQueryMiddleware|MongooseDistinctQueryMiddleware[], options: SchemaPreOptions & { document: boolean, query: false }, fn: PreMiddlewareFunction<T>): this;
379
380
  pre<T = never>(method: MongooseDistinctDocumentMiddleware | MongooseDistinctDocumentMiddleware[] | RegExp, options: SchemaPreOptions & { document: false, query: boolean }, fn: PreMiddlewareFunction<T>): this;
381
+ // this = Union of Document and Query, could be called with any of them
382
+ pre<T = THydratedDocumentType | Query<any, any>>(
383
+ method: MongooseQueryAndDocumentMiddleware | MongooseQueryAndDocumentMiddleware[] | RegExp,
384
+ options: SchemaPreOptions & { document: true, query: true },
385
+ fn: PreMiddlewareFunction<T>
386
+ ): this;
380
387
  // this = Document
381
388
  pre<T = THydratedDocumentType>(method: 'save', fn: PreSaveMiddlewareFunction<T>): this;
382
389
  pre<T = THydratedDocumentType>(method: 'save', options: SchemaPreOptions, fn: PreSaveMiddlewareFunction<T>): this;
383
390
  pre<T = THydratedDocumentType>(method: MongooseDistinctDocumentMiddleware|MongooseDistinctDocumentMiddleware[], fn: PreMiddlewareFunction<T>): this;
384
391
  pre<T = THydratedDocumentType>(method: MongooseDistinctDocumentMiddleware|MongooseDistinctDocumentMiddleware[], options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
392
+ pre<T = THydratedDocumentType>(
393
+ method: MongooseQueryAndDocumentMiddleware | MongooseQueryAndDocumentMiddleware[] | RegExp,
394
+ options: SchemaPreOptions & { document: true },
395
+ fn: PreMiddlewareFunction<T>
396
+ ): this;
385
397
  pre<T = THydratedDocumentType>(method: MongooseQueryOrDocumentMiddleware | MongooseQueryOrDocumentMiddleware[] | RegExp, options: SchemaPreOptions & { document: true, query: false }, fn: PreMiddlewareFunction<T>): this;
386
398
  // this = Query
387
399
  pre<T = Query<any, any>>(method: MongooseDefaultQueryMiddleware|MongooseDefaultQueryMiddleware[], fn: PreMiddlewareFunction<T>): this;
@@ -218,10 +218,11 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
218
218
  PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer :
219
219
  IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
220
220
  PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
221
- PathValueType extends ArrayConstructor ? any[] :
222
- PathValueType extends typeof Schema.Types.Mixed ? any:
223
- IfEquals<PathValueType, ObjectConstructor> extends true ? any:
224
- IfEquals<PathValueType, {}> extends true ? any:
225
- PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
226
- PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
227
- unknown;
221
+ IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ResolvePathType<Options['of']>> :
222
+ PathValueType extends ArrayConstructor ? any[] :
223
+ PathValueType extends typeof Schema.Types.Mixed ? any:
224
+ IfEquals<PathValueType, ObjectConstructor> extends true ? any:
225
+ IfEquals<PathValueType, {}> extends true ? any:
226
+ PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
227
+ PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, { typeKey: TypeKey }> :
228
+ unknown;
package/types/models.d.ts CHANGED
@@ -123,7 +123,6 @@ declare module 'mongoose' {
123
123
  SessionOption {
124
124
  checkKeys?: boolean;
125
125
  j?: boolean;
126
- ordered?: boolean;
127
126
  safe?: boolean | WriteConcern;
128
127
  timestamps?: boolean | QueryTimestampsConfig;
129
128
  validateBeforeSave?: boolean;
@@ -132,6 +131,11 @@ declare module 'mongoose' {
132
131
  wtimeout?: number;
133
132
  }
134
133
 
134
+ interface CreateOptions extends SaveOptions {
135
+ ordered?: boolean;
136
+ aggregateErrors?: boolean;
137
+ }
138
+
135
139
  interface RemoveOptions extends SessionOption, Omit<mongodb.DeleteOptions, 'session'> {}
136
140
 
137
141
  const Model: Model<any>;
@@ -217,7 +221,8 @@ declare module 'mongoose' {
217
221
  >;
218
222
 
219
223
  /** Creates a new document or documents */
220
- create<DocContents = AnyKeys<TRawDocType>>(docs: Array<TRawDocType | DocContents>, options?: SaveOptions): Promise<THydratedDocumentType[]>;
224
+ create<DocContents = AnyKeys<TRawDocType>>(docs: Array<TRawDocType | DocContents>, options: CreateOptions & { aggregateErrors: true }): Promise<(THydratedDocumentType | Error)[]>;
225
+ create<DocContents = AnyKeys<TRawDocType>>(docs: Array<TRawDocType | DocContents>, options?: CreateOptions): Promise<THydratedDocumentType[]>;
221
226
  create<DocContents = AnyKeys<TRawDocType>>(doc: DocContents | TRawDocType): Promise<THydratedDocumentType>;
222
227
  create<DocContents = AnyKeys<TRawDocType>>(...docs: Array<TRawDocType | DocContents>): Promise<THydratedDocumentType[]>;
223
228