mongoose 7.4.1 → 7.4.3

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/lib/document.js CHANGED
@@ -2216,7 +2216,7 @@ Document.prototype.isModified = function(paths, modifiedPaths) {
2216
2216
  }
2217
2217
 
2218
2218
  if (typeof paths === 'string') {
2219
- paths = [paths];
2219
+ paths = paths.indexOf(' ') === -1 ? [paths] : paths.split(' ');
2220
2220
  }
2221
2221
 
2222
2222
  for (const path of paths) {
@@ -2619,7 +2619,7 @@ function _evaluateRequiredFunctions(doc) {
2619
2619
  */
2620
2620
 
2621
2621
  function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
2622
- const skipSchemaValidators = {};
2622
+ const doValidateOptions = {};
2623
2623
 
2624
2624
  _evaluateRequiredFunctions(doc);
2625
2625
  // only validate required fields when necessary
@@ -2656,8 +2656,17 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
2656
2656
  !doc.isDirectModified(fullPathToSubdoc) &&
2657
2657
  !doc.$isDefault(fullPathToSubdoc)) {
2658
2658
  paths.add(fullPathToSubdoc);
2659
+ if (doc.$__.pathsToScopes == null) {
2660
+ doc.$__.pathsToScopes = {};
2661
+ }
2662
+ doc.$__.pathsToScopes[fullPathToSubdoc] = subdoc.$isDocumentArrayElement ?
2663
+ subdoc.__parentArray :
2664
+ subdoc.$parent();
2659
2665
 
2660
- skipSchemaValidators[fullPathToSubdoc] = true;
2666
+ doValidateOptions[fullPathToSubdoc] = { skipSchemaValidators: true };
2667
+ if (subdoc.$isDocumentArrayElement && subdoc.__index != null) {
2668
+ doValidateOptions[fullPathToSubdoc].index = subdoc.__index;
2669
+ }
2661
2670
  }
2662
2671
  }
2663
2672
  }
@@ -2791,7 +2800,7 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
2791
2800
  }
2792
2801
 
2793
2802
  paths = Array.from(paths);
2794
- return [paths, skipSchemaValidators];
2803
+ return [paths, doValidateOptions];
2795
2804
  }
2796
2805
 
2797
2806
  /*!
@@ -2862,7 +2871,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2862
2871
  const paths = shouldValidateModifiedOnly ?
2863
2872
  pathDetails[0].filter((path) => this.$isModified(path)) :
2864
2873
  pathDetails[0];
2865
- const skipSchemaValidators = pathDetails[1];
2874
+ const doValidateOptionsByPath = pathDetails[1];
2866
2875
  if (typeof pathsToValidate === 'string') {
2867
2876
  pathsToValidate = pathsToValidate.split(' ');
2868
2877
  }
@@ -2930,7 +2939,7 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2930
2939
  _this;
2931
2940
 
2932
2941
  const doValidateOptions = {
2933
- skipSchemaValidators: skipSchemaValidators[path],
2942
+ ...doValidateOptionsByPath[path],
2934
2943
  path: path,
2935
2944
  validateModifiedOnly: shouldValidateModifiedOnly
2936
2945
  };
@@ -2938,8 +2947,8 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2938
2947
  schemaType.doValidate(val, function(err) {
2939
2948
  if (err) {
2940
2949
  const isSubdoc = schemaType.$isSingleNested ||
2941
- schemaType.$isArraySubdocument ||
2942
- schemaType.$isMongooseDocumentArray;
2950
+ schemaType.$isArraySubdocument ||
2951
+ schemaType.$isMongooseDocumentArray;
2943
2952
  if (isSubdoc && err instanceof ValidationError) {
2944
2953
  return --total || complete();
2945
2954
  }
@@ -20,7 +20,6 @@ const setDefaultsOnInsert = require('../setDefaultsOnInsert');
20
20
 
21
21
  module.exports = function castBulkWrite(originalModel, op, options) {
22
22
  const now = originalModel.base.now();
23
-
24
23
  if (op['insertOne']) {
25
24
  return (callback) => {
26
25
  const model = decideModelByObject(originalModel, op['insertOne']['document']);
@@ -66,7 +65,9 @@ module.exports = function castBulkWrite(originalModel, op, options) {
66
65
  applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateOne']['update'], {});
67
66
  }
68
67
 
69
- applyTimestampsToChildren(now, op['updateOne']['update'], model.schema);
68
+ if (op['updateOne'].timestamps !== false) {
69
+ applyTimestampsToChildren(now, op['updateOne']['update'], model.schema);
70
+ }
70
71
 
71
72
  if (op['updateOne'].setDefaultsOnInsert !== false) {
72
73
  setDefaultsOnInsert(op['updateOne']['filter'], model.schema, op['updateOne']['update'], {
@@ -117,8 +118,9 @@ module.exports = function castBulkWrite(originalModel, op, options) {
117
118
  const updatedAt = model.schema.$timestamps.updatedAt;
118
119
  applyTimestampsToUpdate(now, createdAt, updatedAt, op['updateMany']['update'], {});
119
120
  }
120
-
121
- applyTimestampsToChildren(now, op['updateMany']['update'], model.schema);
121
+ if (op['updateMany'].timestamps !== false) {
122
+ applyTimestampsToChildren(now, op['updateMany']['update'], model.schema);
123
+ }
122
124
 
123
125
  _addDiscriminatorToObject(schema, op['updateMany']['filter']);
124
126
 
@@ -12,6 +12,9 @@ module.exports = function addIdGetter(schema) {
12
12
  if (!autoIdGetter) {
13
13
  return schema;
14
14
  }
15
+ if (schema.aliases && schema.aliases.id) {
16
+ return schema;
17
+ }
15
18
  schema.virtual('id').get(idGetter);
16
19
  schema.virtual('id').set(idSetter);
17
20
 
package/lib/model.js CHANGED
@@ -77,7 +77,8 @@ const modelSymbol = require('./helpers/symbols').modelSymbol;
77
77
  const subclassedSymbol = Symbol('mongoose#Model#subclassed');
78
78
 
79
79
  const saveToObjectOptions = Object.assign({}, internalToObjectOptions, {
80
- bson: true
80
+ bson: true,
81
+ flattenObjectIds: false
81
82
  });
82
83
 
83
84
  /**
@@ -3471,18 +3472,22 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
3471
3472
  let validOps = [];
3472
3473
  let validationErrors = [];
3473
3474
  const results = [];
3474
- for (let i = 0; i < validations.length; ++i) {
3475
- validations[i]((err) => {
3476
- if (err == null) {
3477
- validOps.push(i);
3478
- } else {
3479
- validationErrors.push({ index: i, error: err });
3480
- results[i] = err;
3481
- }
3482
- if (--remaining <= 0) {
3483
- completeUnorderedValidation.call(this);
3484
- }
3485
- });
3475
+ if (remaining === 0) {
3476
+ completeUnorderedValidation.call(this);
3477
+ } else {
3478
+ for (let i = 0; i < validations.length; ++i) {
3479
+ validations[i]((err) => {
3480
+ if (err == null) {
3481
+ validOps.push(i);
3482
+ } else {
3483
+ validationErrors.push({ index: i, error: err });
3484
+ results[i] = err;
3485
+ }
3486
+ if (--remaining <= 0) {
3487
+ completeUnorderedValidation.call(this);
3488
+ }
3489
+ });
3490
+ }
3486
3491
  }
3487
3492
 
3488
3493
  validationErrors = validationErrors.
@@ -325,7 +325,7 @@ exports.applyPaths = function applyPaths(fields, schema) {
325
325
  // If set to 0, we're explicitly excluding the discriminator key. Can't do this for all fields,
326
326
  // because we have tests that assert that using `-path` to exclude schema-level `select: true`
327
327
  // fields counts as an exclusive projection. See gh-11546
328
- if (exclude && type.selected && path === schema.options.discriminatorKey && fields[path] != null && !fields[path]) {
328
+ if (!exclude && type.selected && path === schema.options.discriminatorKey && fields[path] != null && !fields[path]) {
329
329
  delete fields[path];
330
330
  return;
331
331
  }
package/lib/schema.js CHANGED
@@ -413,7 +413,25 @@ Schema.prototype._clone = function _clone(Constructor) {
413
413
  s.paths = clone(this.paths);
414
414
  s.nested = clone(this.nested);
415
415
  s.subpaths = clone(this.subpaths);
416
- s.singleNestedPaths = clone(this.singleNestedPaths);
416
+ for (const schemaType of Object.values(s.paths)) {
417
+ if (schemaType.$isSingleNested) {
418
+ const path = schemaType.path;
419
+ for (const key of Object.keys(schemaType.schema.paths)) {
420
+ s.singleNestedPaths[path + '.' + key] = schemaType.schema.paths[key];
421
+ }
422
+ for (const key of Object.keys(schemaType.schema.singleNestedPaths)) {
423
+ s.singleNestedPaths[path + '.' + key] =
424
+ schemaType.schema.singleNestedPaths[key];
425
+ }
426
+ for (const key of Object.keys(schemaType.schema.subpaths)) {
427
+ s.singleNestedPaths[path + '.' + key] =
428
+ schemaType.schema.subpaths[key];
429
+ }
430
+ for (const key of Object.keys(schemaType.schema.nested)) {
431
+ s.singleNestedPaths[path + '.' + key] = 'nested';
432
+ }
433
+ }
434
+ }
417
435
  s.childSchemas = gatherChildSchemas(s);
418
436
 
419
437
  s.virtuals = clone(this.virtuals);
package/lib/utils.js CHANGED
@@ -630,9 +630,22 @@ function _populateObj(obj) {
630
630
  */
631
631
 
632
632
  exports.getValue = function(path, obj, map) {
633
- return mpath.get(path, obj, '_doc', map);
633
+ return mpath.get(path, obj, getValueLookup, map);
634
634
  };
635
635
 
636
+ /*!
637
+ * ignore
638
+ */
639
+
640
+ const mapGetterOptions = Object.freeze({ getters: false });
641
+
642
+ function getValueLookup(obj, part) {
643
+ const _from = obj?._doc || obj;
644
+ return _from instanceof Map ?
645
+ _from.get(part, mapGetterOptions) :
646
+ _from[part];
647
+ }
648
+
636
649
  /**
637
650
  * Sets the value of `obj` at the given `path`.
638
651
  *
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "7.4.1",
4
+ "version": "7.4.3",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -28,10 +28,10 @@
28
28
  "sift": "16.0.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@babel/core": "7.22.5",
32
- "@babel/preset-env": "7.22.5",
31
+ "@babel/core": "7.22.9",
32
+ "@babel/preset-env": "7.22.9",
33
33
  "@typescript-eslint/eslint-plugin": "5.61.0",
34
- "@typescript-eslint/parser": "5.61.0",
34
+ "@typescript-eslint/parser": "5.62.0",
35
35
  "acquit": "1.3.0",
36
36
  "acquit-ignore": "0.2.1",
37
37
  "acquit-require": "0.1.1",
@@ -46,7 +46,7 @@
46
46
  "crypto-browserify": "3.12.0",
47
47
  "dotenv": "16.3.1",
48
48
  "dox": "1.0.0",
49
- "eslint": "8.44.0",
49
+ "eslint": "8.46.0",
50
50
  "eslint-plugin-markdown": "^3.0.0",
51
51
  "eslint-plugin-mocha-no-only": "1.1.1",
52
52
  "express": "^4.18.1",
@@ -69,7 +69,7 @@
69
69
  "tsd": "0.28.1",
70
70
  "typescript": "5.1.6",
71
71
  "uuid": "9.0.0",
72
- "webpack": "5.88.1"
72
+ "webpack": "5.88.2"
73
73
  },
74
74
  "directories": {
75
75
  "lib": "./lib/mongoose"
package/types/index.d.ts CHANGED
@@ -278,7 +278,7 @@ declare module 'mongoose' {
278
278
  * Returns a list of indexes that this schema declares, via `schema.index()`
279
279
  * or by `index: true` in a path's options.
280
280
  */
281
- indexes(): Array<IndexDefinition>;
281
+ indexes(): Array<[IndexDefinition, IndexOptions]>;
282
282
 
283
283
  /** Gets a schema option. */
284
284
  get<K extends keyof SchemaOptions>(key: K): SchemaOptions[K];
@@ -406,8 +406,25 @@ declare module 'mongoose' {
406
406
  pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PreMiddlewareFunction<T>): this;
407
407
  pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
408
408
  /* method insertMany */
409
- pre<T = TModelType>(method: 'insertMany' | RegExp, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
410
- pre<T = TModelType>(method: 'insertMany' | RegExp, options: SchemaPreOptions, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
409
+ pre<T = TModelType>(
410
+ method: 'insertMany' | RegExp,
411
+ fn: (
412
+ this: T,
413
+ next: (err?: CallbackError) => void,
414
+ docs: any | Array<any>,
415
+ options?: InsertManyOptions & { lean?: boolean }
416
+ ) => void | Promise<void>
417
+ ): this;
418
+ pre<T = TModelType>(
419
+ method: 'insertMany' | RegExp,
420
+ options: SchemaPreOptions,
421
+ fn: (
422
+ this: T,
423
+ next: (err?: CallbackError) => void,
424
+ docs: any | Array<any>,
425
+ options?: InsertManyOptions & { lean?: boolean }
426
+ ) => void | Promise<void>
427
+ ): this;
411
428
 
412
429
  /** Object of currently defined query helpers on this schema. */
413
430
  query: TQueryHelpers;
@@ -578,24 +595,24 @@ declare module 'mongoose' {
578
595
 
579
596
  export type SortOrder = -1 | 1 | 'asc' | 'ascending' | 'desc' | 'descending';
580
597
 
581
- type _UpdateQuery<TSchema> = {
598
+ type _UpdateQuery<TSchema, AdditionalProperties = AnyObject> = {
582
599
  /** @see https://www.mongodb.com/docs/manual/reference/operator/update-field/ */
583
- $currentDate?: AnyKeys<TSchema> & AnyObject;
584
- $inc?: AnyKeys<TSchema> & AnyObject;
585
- $min?: AnyKeys<TSchema> & AnyObject;
586
- $max?: AnyKeys<TSchema> & AnyObject;
587
- $mul?: AnyKeys<TSchema> & AnyObject;
600
+ $currentDate?: AnyKeys<TSchema> & AdditionalProperties;
601
+ $inc?: AnyKeys<TSchema> & AdditionalProperties;
602
+ $min?: AnyKeys<TSchema> & AdditionalProperties;
603
+ $max?: AnyKeys<TSchema> & AdditionalProperties;
604
+ $mul?: AnyKeys<TSchema> & AdditionalProperties;
588
605
  $rename?: Record<string, string>;
589
- $set?: AnyKeys<TSchema> & AnyObject;
590
- $setOnInsert?: AnyKeys<TSchema> & AnyObject;
591
- $unset?: AnyKeys<TSchema> & AnyObject;
606
+ $set?: AnyKeys<TSchema> & AdditionalProperties;
607
+ $setOnInsert?: AnyKeys<TSchema> & AdditionalProperties;
608
+ $unset?: AnyKeys<TSchema> & AdditionalProperties;
592
609
 
593
610
  /** @see https://www.mongodb.com/docs/manual/reference/operator/update-array/ */
594
- $addToSet?: AnyKeys<TSchema> & AnyObject;
595
- $pop?: AnyKeys<TSchema> & AnyObject;
596
- $pull?: AnyKeys<TSchema> & AnyObject;
597
- $push?: AnyKeys<TSchema> & AnyObject;
598
- $pullAll?: AnyKeys<TSchema> & AnyObject;
611
+ $addToSet?: AnyKeys<TSchema> & AdditionalProperties;
612
+ $pop?: AnyKeys<TSchema> & AdditionalProperties;
613
+ $pull?: AnyKeys<TSchema> & AdditionalProperties;
614
+ $push?: AnyKeys<TSchema> & AdditionalProperties;
615
+ $pullAll?: AnyKeys<TSchema> & AdditionalProperties;
599
616
 
600
617
  /** @see https://www.mongodb.com/docs/manual/reference/operator/update-bitwise/ */
601
618
  $bit?: AnyKeys<TSchema>;
@@ -618,6 +635,18 @@ declare module 'mongoose' {
618
635
  */
619
636
  export type UpdateQuery<T> = _UpdateQuery<T> & AnyObject;
620
637
 
638
+ /**
639
+ * A more strict form of UpdateQuery that enforces updating only
640
+ * known top-level properties.
641
+ * @example
642
+ * ```ts
643
+ * function updateUser(_id: mongoose.Types.ObjectId, update: UpdateQueryKnownOnly<IUser>) {
644
+ * return User.updateOne({ _id }, update);
645
+ * }
646
+ * ```
647
+ */
648
+ export type UpdateQueryKnownOnly<T> = _UpdateQuery<T, {}>;
649
+
621
650
  export type FlattenMaps<T> = {
622
651
  [K in keyof T]: FlattenProperty<T[K]>;
623
652
  };
@@ -86,7 +86,7 @@ type IsPathDefaultUndefined<PathType> = PathType extends { default: undefined }
86
86
  * @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
87
87
  */
88
88
  type IsPathRequired<P, TypeKey extends string = DefaultTypeKey> =
89
- P extends { required: true | [true, string | undefined] } | ArrayConstructor | any[]
89
+ P extends { required: true | [true, string | undefined] | { isRequired: true } } | ArrayConstructor | any[]
90
90
  ? true
91
91
  : P extends { required: boolean }
92
92
  ? P extends { required: false }
@@ -31,8 +31,16 @@ declare module 'mongoose' {
31
31
  type SchemaPreOptions = MiddlewareOptions;
32
32
  type SchemaPostOptions = MiddlewareOptions;
33
33
 
34
- type PreMiddlewareFunction<ThisType = any> = (this: ThisType, next: CallbackWithoutResultAndOptionalError) => void | Promise<void>;
35
- type PreSaveMiddlewareFunction<ThisType = any> = (this: ThisType, next: CallbackWithoutResultAndOptionalError, opts: SaveOptions) => void | Promise<void>;
34
+ type PreMiddlewareFunction<ThisType = any> = (
35
+ this: ThisType,
36
+ next: CallbackWithoutResultAndOptionalError,
37
+ opts?: Record<string, any>
38
+ ) => void | Promise<void>;
39
+ type PreSaveMiddlewareFunction<ThisType = any> = (
40
+ this: ThisType,
41
+ next: CallbackWithoutResultAndOptionalError,
42
+ opts: SaveOptions
43
+ ) => void | Promise<void>;
36
44
  type PostMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, res: ResType, next: CallbackWithoutResultAndOptionalError) => void | Promise<void>;
37
45
  type ErrorHandlingMiddlewareFunction<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType, next: CallbackWithoutResultAndOptionalError) => void;
38
46
  type ErrorHandlingMiddlewareWithOption<ThisType = any, ResType = any> = (this: ThisType, err: NativeError, res: ResType | null, next: CallbackWithoutResultAndOptionalError) => void | Promise<void>;
package/types/models.d.ts CHANGED
@@ -297,6 +297,17 @@ declare module 'mongoose' {
297
297
  * equivalent to `findOne({ _id: id })`. If you want to query by a document's
298
298
  * `_id`, use `findById()` instead of `findOne()`.
299
299
  */
300
+ findById<ResultDoc = THydratedDocumentType>(
301
+ id: any,
302
+ projection: ProjectionType<TRawDocType> | null | undefined,
303
+ options: QueryOptions<TRawDocType> & { lean: true }
304
+ ): QueryWithHelpers<
305
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOne'> | null,
306
+ ResultDoc,
307
+ TQueryHelpers,
308
+ TRawDocType,
309
+ 'findOne'
310
+ >;
300
311
  findById<ResultDoc = THydratedDocumentType>(
301
312
  id: any,
302
313
  projection?: ProjectionType<TRawDocType> | null,
@@ -308,6 +319,17 @@ declare module 'mongoose' {
308
319
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOne'>;
309
320
 
310
321
  /** Finds one document. */
322
+ findOne<ResultDoc = THydratedDocumentType>(
323
+ filter: FilterQuery<TRawDocType>,
324
+ projection: ProjectionType<TRawDocType> | null | undefined,
325
+ options: QueryOptions<TRawDocType> & { lean: true }
326
+ ): QueryWithHelpers<
327
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOne'> | null,
328
+ ResultDoc,
329
+ TQueryHelpers,
330
+ TRawDocType,
331
+ 'findOne'
332
+ >;
311
333
  findOne<ResultDoc = THydratedDocumentType>(
312
334
  filter?: FilterQuery<TRawDocType>,
313
335
  projection?: ProjectionType<TRawDocType> | null,
@@ -460,6 +482,17 @@ declare module 'mongoose' {
460
482
  >;
461
483
 
462
484
  /** Creates a `find` query: gets a list of documents that match `filter`. */
485
+ find<ResultDoc = THydratedDocumentType>(
486
+ filter: FilterQuery<TRawDocType>,
487
+ projection: ProjectionType<TRawDocType> | null | undefined,
488
+ options: QueryOptions<TRawDocType> & { lean: true }
489
+ ): QueryWithHelpers<
490
+ GetLeanResultType<TRawDocType, TRawDocType[], 'find'>,
491
+ ResultDoc,
492
+ TQueryHelpers,
493
+ TRawDocType,
494
+ 'find'
495
+ >;
463
496
  find<ResultDoc = THydratedDocumentType>(
464
497
  filter: FilterQuery<TRawDocType>,
465
498
  projection?: ProjectionType<TRawDocType> | null | undefined,
@@ -476,18 +509,49 @@ declare module 'mongoose' {
476
509
  ): QueryWithHelpers<Array<ResultDoc>, ResultDoc, TQueryHelpers, TRawDocType, 'find'>;
477
510
 
478
511
  /** Creates a `findByIdAndDelete` query, filtering by the given `_id`. */
512
+ findByIdAndDelete<ResultDoc = THydratedDocumentType>(
513
+ id: mongodb.ObjectId | any,
514
+ options: QueryOptions<TRawDocType> & { lean: true }
515
+ ): QueryWithHelpers<
516
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndDelete'> | null,
517
+ ResultDoc,
518
+ TQueryHelpers,
519
+ TRawDocType,
520
+ 'findOneAndDelete'
521
+ >;
479
522
  findByIdAndDelete<ResultDoc = THydratedDocumentType>(
480
523
  id?: mongodb.ObjectId | any,
481
524
  options?: QueryOptions<TRawDocType> | null
482
525
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOneAndDelete'>;
483
526
 
484
527
  /** Creates a `findByIdAndRemove` query, filtering by the given `_id`. */
528
+ findByIdAndRemove<ResultDoc = THydratedDocumentType>(
529
+ id: mongodb.ObjectId | any,
530
+ options: QueryOptions<TRawDocType> & { lean: true }
531
+ ): QueryWithHelpers<
532
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndDelete'> | null,
533
+ ResultDoc,
534
+ TQueryHelpers,
535
+ TRawDocType,
536
+ 'findOneAndDelete'
537
+ >;
485
538
  findByIdAndRemove<ResultDoc = THydratedDocumentType>(
486
539
  id?: mongodb.ObjectId | any,
487
540
  options?: QueryOptions<TRawDocType> | null
488
541
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOneAndDelete'>;
489
542
 
490
543
  /** Creates a `findOneAndUpdate` query, filtering by the given `_id`. */
544
+ findByIdAndUpdate<ResultDoc = THydratedDocumentType>(
545
+ id: mongodb.ObjectId | any,
546
+ update: UpdateQuery<TRawDocType>,
547
+ options: QueryOptions<TRawDocType> & { lean: true }
548
+ ): QueryWithHelpers<
549
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndUpdate'> | null,
550
+ ResultDoc,
551
+ TQueryHelpers,
552
+ TRawDocType,
553
+ 'findOneAndUpdate'
554
+ >;
491
555
  findByIdAndUpdate<ResultDoc = THydratedDocumentType>(
492
556
  id: mongodb.ObjectId | any,
493
557
  update: UpdateQuery<TRawDocType>,
@@ -509,6 +573,16 @@ declare module 'mongoose' {
509
573
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOneAndUpdate'>;
510
574
 
511
575
  /** Creates a `findOneAndDelete` query: atomically finds the given document, deletes it, and returns the document as it was before deletion. */
576
+ findOneAndDelete<ResultDoc = THydratedDocumentType>(
577
+ filter: FilterQuery<TRawDocType>,
578
+ options: QueryOptions<TRawDocType> & { lean: true }
579
+ ): QueryWithHelpers<
580
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndDelete'> | null,
581
+ ResultDoc,
582
+ TQueryHelpers,
583
+ TRawDocType,
584
+ 'findOneAndDelete'
585
+ >;
512
586
  findOneAndDelete<ResultDoc = THydratedDocumentType>(
513
587
  filter?: FilterQuery<TRawDocType>,
514
588
  options?: QueryOptions<TRawDocType> | null
@@ -521,6 +595,17 @@ declare module 'mongoose' {
521
595
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOneAndRemove'>;
522
596
 
523
597
  /** Creates a `findOneAndReplace` query: atomically finds the given document and replaces it with `replacement`. */
598
+ findOneAndReplace<ResultDoc = THydratedDocumentType>(
599
+ filter: FilterQuery<TRawDocType>,
600
+ replacement: TRawDocType | AnyObject,
601
+ options: QueryOptions<TRawDocType> & { lean: true }
602
+ ): QueryWithHelpers<
603
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndReplace'> | null,
604
+ ResultDoc,
605
+ TQueryHelpers,
606
+ TRawDocType,
607
+ 'findOneAndReplace'
608
+ >;
524
609
  findOneAndReplace<ResultDoc = THydratedDocumentType>(
525
610
  filter: FilterQuery<TRawDocType>,
526
611
  replacement: TRawDocType | AnyObject,
@@ -538,6 +623,17 @@ declare module 'mongoose' {
538
623
  ): QueryWithHelpers<ResultDoc | null, ResultDoc, TQueryHelpers, TRawDocType, 'findOneAndReplace'>;
539
624
 
540
625
  /** Creates a `findOneAndUpdate` query: atomically find the first document that matches `filter` and apply `update`. */
626
+ findOneAndUpdate<ResultDoc = THydratedDocumentType>(
627
+ filter: FilterQuery<TRawDocType>,
628
+ update: UpdateQuery<TRawDocType>,
629
+ options: QueryOptions<TRawDocType> & { lean: true }
630
+ ): QueryWithHelpers<
631
+ GetLeanResultType<TRawDocType, TRawDocType, 'findOneAndUpdate'> | null,
632
+ ResultDoc,
633
+ TQueryHelpers,
634
+ TRawDocType,
635
+ 'findOneAndUpdate'
636
+ >;
541
637
  findOneAndUpdate<ResultDoc = THydratedDocumentType>(
542
638
  filter: FilterQuery<TRawDocType>,
543
639
  update: UpdateQuery<TRawDocType>,
package/types/query.d.ts CHANGED
@@ -179,6 +179,10 @@ declare module 'mongoose' {
179
179
 
180
180
  type QueryOpThatReturnsDocument = 'find' | 'findOne' | 'findOneAndUpdate' | 'findOneAndReplace' | 'findOneAndDelete';
181
181
 
182
+ type GetLeanResultType<RawDocType, ResultType, QueryOp> = QueryOp extends QueryOpThatReturnsDocument
183
+ ? (ResultType extends any[] ? Require_id<FlattenMaps<RawDocType>>[] : Require_id<FlattenMaps<RawDocType>>)
184
+ : ResultType;
185
+
182
186
  class Query<ResultType, DocType, THelpers = {}, RawDocType = DocType, QueryOp = 'find'> implements SessionOperation {
183
187
  _mongooseOptions: MongooseQueryOptions<DocType>;
184
188
 
@@ -499,9 +503,19 @@ declare module 'mongoose' {
499
503
  j(val: boolean | null): this;
500
504
 
501
505
  /** Sets the lean option. */
502
- lean<LeanResultType = QueryOp extends QueryOpThatReturnsDocument ? (ResultType extends any[] ? Require_id<FlattenMaps<RawDocType>>[] : Require_id<FlattenMaps<RawDocType>>) : ResultType>(
506
+ lean<
507
+ LeanResultType = GetLeanResultType<RawDocType, ResultType, QueryOp>
508
+ >(
503
509
  val?: boolean | any
504
- ): QueryWithHelpers<ResultType extends null ? LeanResultType | null : LeanResultType, DocType, THelpers, RawDocType, QueryOp>;
510
+ ): QueryWithHelpers<
511
+ ResultType extends null
512
+ ? LeanResultType | null
513
+ : LeanResultType,
514
+ DocType,
515
+ THelpers,
516
+ RawDocType,
517
+ QueryOp
518
+ >;
505
519
 
506
520
  /** Specifies the maximum number of documents the query will return. */
507
521
  limit(val: number): this;