mongoose 8.2.0 → 8.2.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.
package/lib/connection.js CHANGED
@@ -829,6 +829,30 @@ Connection.prototype.openUri = async function openUri(uri, options) {
829
829
  return this;
830
830
  };
831
831
 
832
+ /*!
833
+ * Treat `on('error')` handlers as handling the initialConnection promise
834
+ * to avoid uncaught exceptions when using `on('error')`. See gh-14377.
835
+ */
836
+
837
+ Connection.prototype.on = function on(event, callback) {
838
+ if (event === 'error' && this.$initialConnection) {
839
+ this.$initialConnection.catch(() => {});
840
+ }
841
+ return EventEmitter.prototype.on.call(this, event, callback);
842
+ };
843
+
844
+ /*!
845
+ * Treat `once('error')` handlers as handling the initialConnection promise
846
+ * to avoid uncaught exceptions when using `on('error')`. See gh-14377.
847
+ */
848
+
849
+ Connection.prototype.once = function on(event, callback) {
850
+ if (event === 'error' && this.$initialConnection) {
851
+ this.$initialConnection.catch(() => {});
852
+ }
853
+ return EventEmitter.prototype.once.call(this, event, callback);
854
+ };
855
+
832
856
  /*!
833
857
  * ignore
834
858
  */
package/lib/document.js CHANGED
@@ -4735,7 +4735,7 @@ Document.prototype.$clone = function() {
4735
4735
  const clonedDoc = new Model();
4736
4736
  clonedDoc.$isNew = this.$isNew;
4737
4737
  if (this._doc) {
4738
- clonedDoc._doc = clone(this._doc);
4738
+ clonedDoc._doc = clone(this._doc, { retainDocuments: true });
4739
4739
  }
4740
4740
  if (this.$__) {
4741
4741
  const Cache = this.$__.constructor;
@@ -36,10 +36,23 @@ function clone(obj, options, isArrayChild) {
36
36
  }
37
37
 
38
38
  if (isMongooseObject(obj)) {
39
- // Single nested subdocs should apply getters later in `applyGetters()`
40
- // when calling `toObject()`. See gh-7442, gh-8295
41
- if (options && options._skipSingleNestedGetters && obj.$isSingleNested) {
42
- options = Object.assign({}, options, { getters: false });
39
+ if (options) {
40
+ // Single nested subdocs should apply getters later in `applyGetters()`
41
+ // when calling `toObject()`. See gh-7442, gh-8295
42
+ if (options._skipSingleNestedGetters && obj.$isSingleNested) {
43
+ options = Object.assign({}, options, { getters: false });
44
+ }
45
+ if (options.retainDocuments && obj.$__ != null) {
46
+ const clonedDoc = obj.$clone();
47
+ if (obj.__index != null) {
48
+ clonedDoc.__index = obj.__index;
49
+ }
50
+ if (obj.__parentArray != null) {
51
+ clonedDoc.__parentArray = obj.__parentArray;
52
+ }
53
+ clonedDoc.$__parent = obj.$__parent;
54
+ return clonedDoc;
55
+ }
43
56
  }
44
57
  const isSingleNested = obj.$isSingleNested;
45
58
 
@@ -19,11 +19,10 @@ function applyEmbeddedDiscriminators(schema, seen = new WeakSet()) {
19
19
  if (schemaType._appliedDiscriminators) {
20
20
  continue;
21
21
  }
22
- for (const disc of schemaType.schema._applyDiscriminators.keys()) {
23
- schemaType.discriminator(
24
- disc,
25
- schemaType.schema._applyDiscriminators.get(disc)
26
- );
22
+ for (const discriminatorKey of schemaType.schema._applyDiscriminators.keys()) {
23
+ const discriminatorSchema = schemaType.schema._applyDiscriminators.get(discriminatorKey);
24
+ applyEmbeddedDiscriminators(discriminatorSchema, seen);
25
+ schemaType.discriminator(discriminatorKey, discriminatorSchema);
27
26
  }
28
27
  schemaType._appliedDiscriminators = true;
29
28
  }
@@ -6,6 +6,12 @@ module.exports = function applyWriteConcern(schema, options) {
6
6
  if (options.writeConcern != null) {
7
7
  return;
8
8
  }
9
+ // Don't apply default write concern to operations in transactions,
10
+ // because setting write concern on an operation in a transaction is an error
11
+ // See: https://www.mongodb.com/docs/manual/reference/write-concern/
12
+ if (options && options.session && options.session.transaction) {
13
+ return;
14
+ }
9
15
  const writeConcern = get(schema, 'options.writeConcern', {});
10
16
  if (Object.keys(writeConcern).length != 0) {
11
17
  options.writeConcern = {};
package/lib/model.js CHANGED
@@ -2532,6 +2532,7 @@ Model.$where = function $where() {
2532
2532
  * @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
2533
2533
  * @param {Boolean} [options.includeResultMetadata] if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html)
2534
2534
  * @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.
2535
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
2535
2536
  * @return {Query}
2536
2537
  * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
2537
2538
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -2624,6 +2625,7 @@ Model.findOneAndUpdate = function(conditions, update, options) {
2624
2625
  * @param {Boolean} [options.new=false] if true, return the modified document rather than the original
2625
2626
  * @param {Object|String} [options.select] sets the document fields to return.
2626
2627
  * @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
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
2627
2629
  * @return {Query}
2628
2630
  * @see Model.findOneAndUpdate https://mongoosejs.com/docs/api/model.html#Model.findOneAndUpdate()
2629
2631
  * @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
@@ -3944,6 +3946,7 @@ Model.hydrate = function(obj, projection, options) {
3944
3946
  * @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)
3945
3947
  * @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.
3946
3948
  * @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.
3949
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3947
3950
  * @return {Query}
3948
3951
  * @see Query docs https://mongoosejs.com/docs/queries.html
3949
3952
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
@@ -3983,6 +3986,7 @@ Model.updateMany = function updateMany(conditions, doc, options) {
3983
3986
  * @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)
3984
3987
  * @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.
3985
3988
  * @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.
3989
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3986
3990
  * @return {Query}
3987
3991
  * @see Query docs https://mongoosejs.com/docs/queries.html
3988
3992
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
package/lib/query.js CHANGED
@@ -3191,6 +3191,7 @@ function prepareDiscriminatorCriteria(query) {
3191
3191
  * @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.
3192
3192
  * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3193
3193
  * @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.
3194
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3194
3195
  * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
3195
3196
  * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3196
3197
  * @see ModifyResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html
@@ -3887,6 +3888,7 @@ Query.prototype._replaceOne = async function _replaceOne() {
3887
3888
  * @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)
3888
3889
  * @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.
3889
3890
  * @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.
3891
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3890
3892
  * @param {Function} [callback] params are (error, writeOpResult)
3891
3893
  * @return {Query} this
3892
3894
  * @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
@@ -3955,7 +3957,8 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
3955
3957
  * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
3956
3958
  * @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)
3957
3959
  * @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.
3958
- @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.
3960
+ * @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.
3961
+ * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3959
3962
  * @param {Function} [callback] params are (error, writeOpResult)
3960
3963
  * @return {Query} this
3961
3964
  * @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "8.2.0",
4
+ "version": "8.2.1",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -28,8 +28,8 @@
28
28
  "sift": "16.0.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@babel/core": "7.23.9",
32
- "@babel/preset-env": "7.23.9",
31
+ "@babel/core": "7.24.0",
32
+ "@babel/preset-env": "7.24.0",
33
33
  "@typescript-eslint/eslint-plugin": "^6.2.1",
34
34
  "@typescript-eslint/parser": "^6.2.1",
35
35
  "acquit": "1.3.0",
@@ -43,9 +43,9 @@
43
43
  "buffer": "^5.6.0",
44
44
  "cheerio": "1.0.0-rc.12",
45
45
  "crypto-browserify": "3.12.0",
46
- "dotenv": "16.4.1",
46
+ "dotenv": "16.4.5",
47
47
  "dox": "1.0.0",
48
- "eslint": "8.56.0",
48
+ "eslint": "8.57.0",
49
49
  "eslint-plugin-markdown": "^3.0.1",
50
50
  "eslint-plugin-mocha-no-only": "1.1.1",
51
51
  "express": "^4.18.1",
@@ -56,7 +56,7 @@
56
56
  "markdownlint-cli2": "^0.12.1",
57
57
  "marked": "4.3.0",
58
58
  "mkdirp": "^3.0.1",
59
- "mocha": "10.2.0",
59
+ "mocha": "10.3.0",
60
60
  "moment": "2.x",
61
61
  "mongodb-memory-server": "8.15.1",
62
62
  "ncp": "^2.0.0",
@@ -65,10 +65,10 @@
65
65
  "q": "1.5.1",
66
66
  "sinon": "17.0.1",
67
67
  "stream-browserify": "3.0.0",
68
- "tsd": "0.30.4",
68
+ "tsd": "0.30.7",
69
69
  "typescript": "5.3.3",
70
70
  "uuid": "9.0.1",
71
- "webpack": "5.90.1"
71
+ "webpack": "5.90.3"
72
72
  },
73
73
  "directories": {
74
74
  "lib": "./lib/mongoose"
package/types/models.d.ts CHANGED
@@ -228,7 +228,7 @@ declare module 'mongoose' {
228
228
  /** Creates a `countDocuments` query: counts the number of documents that match `filter`. */
229
229
  countDocuments(
230
230
  filter?: FilterQuery<TRawDocType>,
231
- options?: (mongodb.CountOptions & Omit<MongooseQueryOptions<TRawDocType>, 'lean' | 'timestamps'>) | null
231
+ options?: (mongodb.CountOptions & MongooseBaseQueryOptions<TRawDocType>) | null
232
232
  ): QueryWithHelpers<
233
233
  number,
234
234
  THydratedDocumentType,
@@ -266,7 +266,7 @@ declare module 'mongoose' {
266
266
  */
267
267
  deleteMany(
268
268
  filter?: FilterQuery<TRawDocType>,
269
- options?: (mongodb.DeleteOptions & Omit<MongooseQueryOptions<TRawDocType>, 'lean' | 'timestamps'>) | null
269
+ options?: (mongodb.DeleteOptions & MongooseBaseQueryOptions<TRawDocType>) | null
270
270
  ): QueryWithHelpers<
271
271
  mongodb.DeleteResult,
272
272
  THydratedDocumentType,
@@ -291,7 +291,7 @@ declare module 'mongoose' {
291
291
  */
292
292
  deleteOne(
293
293
  filter?: FilterQuery<TRawDocType>,
294
- options?: (mongodb.DeleteOptions & Omit<MongooseQueryOptions<TRawDocType>, 'lean' | 'timestamps'>) | null
294
+ options?: (mongodb.DeleteOptions & MongooseBaseQueryOptions<TRawDocType>) | null
295
295
  ): QueryWithHelpers<
296
296
  mongodb.DeleteResult,
297
297
  THydratedDocumentType,
@@ -743,14 +743,14 @@ declare module 'mongoose' {
743
743
  updateMany<ResultDoc = THydratedDocumentType>(
744
744
  filter?: FilterQuery<TRawDocType>,
745
745
  update?: UpdateQuery<TRawDocType> | UpdateWithAggregationPipeline,
746
- options?: (mongodb.UpdateOptions & Omit<MongooseQueryOptions<TRawDocType>, 'lean'>) | null
746
+ options?: (mongodb.UpdateOptions & MongooseUpdateQueryOptions<TRawDocType>) | null
747
747
  ): QueryWithHelpers<UpdateWriteOpResult, ResultDoc, TQueryHelpers, TRawDocType, 'updateMany'>;
748
748
 
749
749
  /** Creates a `updateOne` query: updates the first document that matches `filter` with `update`. */
750
750
  updateOne<ResultDoc = THydratedDocumentType>(
751
751
  filter?: FilterQuery<TRawDocType>,
752
752
  update?: UpdateQuery<TRawDocType> | UpdateWithAggregationPipeline,
753
- options?: (mongodb.UpdateOptions & Omit<MongooseQueryOptions<TRawDocType>, 'lean'>) | null
753
+ options?: (mongodb.UpdateOptions & MongooseUpdateQueryOptions<TRawDocType>) | null
754
754
  ): QueryWithHelpers<UpdateWriteOpResult, ResultDoc, TQueryHelpers, TRawDocType, 'updateOne'>;
755
755
 
756
756
  /** Creates a Query, applies the passed conditions, and returns the Query. */
package/types/query.d.ts CHANGED
@@ -17,25 +17,33 @@ declare module 'mongoose' {
17
17
  */
18
18
  type FilterQuery<T> = _FilterQuery<T>;
19
19
 
20
- type MongooseQueryOptions<DocType = unknown> = Pick<
21
- QueryOptions<DocType>,
22
- 'context' |
23
- 'lean' |
24
- 'multipleCastError' |
25
- 'overwriteDiscriminatorKey' |
26
- 'populate' |
27
- 'runValidators' |
28
- 'sanitizeProjection' |
29
- 'sanitizeFilter' |
30
- 'setDefaultsOnInsert' |
31
- 'strict' |
32
- 'strictQuery' |
33
- 'timestamps' |
34
- 'translateAliases'
35
- > & {
20
+ type MongooseBaseQueryOptionKeys =
21
+ | 'context'
22
+ | 'multipleCastError'
23
+ | 'overwriteDiscriminatorKey'
24
+ | 'populate'
25
+ | 'runValidators'
26
+ | 'sanitizeProjection'
27
+ | 'sanitizeFilter'
28
+ | 'setDefaultsOnInsert'
29
+ | 'strict'
30
+ | 'strictQuery'
31
+ | 'translateAliases';
32
+
33
+ type MongooseQueryOptions<
34
+ DocType = unknown,
35
+ Keys extends keyof QueryOptions<DocType> = MongooseBaseQueryOptionKeys | 'timestamps' | 'lean'
36
+ > = Pick<QueryOptions<DocType>, Keys> & {
36
37
  [other: string]: any;
37
38
  };
38
39
 
40
+ type MongooseBaseQueryOptions<DocType = unknown> = MongooseQueryOptions<DocType, MongooseBaseQueryOptionKeys>;
41
+
42
+ type MongooseUpdateQueryOptions<DocType = unknown> = MongooseQueryOptions<
43
+ DocType,
44
+ MongooseBaseQueryOptionKeys | 'timestamps'
45
+ >;
46
+
39
47
  type ProjectionFields<DocType> = { [Key in keyof DocType]?: any } & Record<string, any>;
40
48
 
41
49
  type QueryWithHelpers<ResultType, DocType, THelpers = {}, RawDocType = DocType, QueryOp = 'find'> = Query<ResultType, DocType, THelpers, RawDocType, QueryOp> & THelpers;
@@ -208,7 +216,7 @@ declare module 'mongoose' {
208
216
  * A QueryCursor exposes a Streams3 interface, as well as a `.next()` function.
209
217
  * This is equivalent to calling `.cursor()` with no arguments.
210
218
  */
211
- [Symbol.asyncIterator](): AsyncIterableIterator<DocType>;
219
+ [Symbol.asyncIterator](): AsyncIterableIterator<Unpacked<ResultType>>;
212
220
 
213
221
  /** Executes the query */
214
222
  exec(): Promise<ResultType>;
@@ -286,7 +294,7 @@ declare module 'mongoose' {
286
294
  * Returns a wrapper around a [mongodb driver cursor](https://mongodb.github.io/node-mongodb-native/4.9/classes/FindCursor.html).
287
295
  * A QueryCursor exposes a Streams3 interface, as well as a `.next()` function.
288
296
  */
289
- cursor(options?: QueryOptions<DocType>): Cursor<DocType, QueryOptions<DocType>>;
297
+ cursor(options?: QueryOptions<DocType>): Cursor<Unpacked<ResultType>, QueryOptions<DocType>>;
290
298
 
291
299
  /**
292
300
  * Declare and/or execute this query as a `deleteMany()` operation. Works like
@@ -647,7 +655,7 @@ declare module 'mongoose' {
647
655
 
648
656
  /** Specifies which document fields to include or exclude (also known as the query "projection") */
649
657
  select<RawDocTypeOverride extends { [P in keyof RawDocType]?: any } = {}>(
650
- arg: string | string[] | Record<string, number | boolean | object>
658
+ arg: string | string[] | Record<string, number | boolean | string | object>
651
659
  ): QueryWithHelpers<
652
660
  IfEquals<
653
661
  RawDocTypeOverride,
@@ -2,6 +2,17 @@ declare module 'mongoose' {
2
2
  type IfAny<IFTYPE, THENTYPE, ELSETYPE = IFTYPE> = 0 extends (1 & IFTYPE) ? THENTYPE : ELSETYPE;
3
3
  type IfUnknown<IFTYPE, THENTYPE> = unknown extends IFTYPE ? THENTYPE : IFTYPE;
4
4
 
5
+ /**
6
+ * @summary Removes keys from a type
7
+ * @description It helps to exclude keys from a type
8
+ * @param {T} T A generic type to be checked.
9
+ * @param {K} K Keys from T that are to be excluded from the generic type
10
+ * @returns T with the keys in K excluded
11
+ */
12
+ type ExcludeKeys<T, K extends keyof T> = {
13
+ [P in keyof T as P extends K ? never : P]: T[P];
14
+ };
15
+
5
16
  type Unpacked<T> = T extends (infer U)[] ?
6
17
  U :
7
18
  T extends ReadonlyArray<infer U> ? U : T;