mongoose 8.2.0 → 8.2.2
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/dist/browser.umd.js +1 -1
- package/lib/connection.js +24 -0
- package/lib/document.js +17 -14
- package/lib/drivers/node-mongodb-native/collection.js +3 -4
- package/lib/helpers/clone.js +17 -4
- package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +4 -5
- package/lib/helpers/schema/applyWriteConcern.js +6 -0
- package/lib/model.js +49 -13
- package/lib/mongoose.js +4 -2
- package/lib/query.js +6 -3
- package/lib/schema.js +3 -0
- package/lib/types/array/methods/index.js +8 -9
- package/lib/types/arraySubdocument.js +1 -1
- package/package.json +8 -8
- package/types/inferschematype.d.ts +1 -1
- package/types/models.d.ts +86 -13
- package/types/pipelinestage.d.ts +14 -1
- package/types/query.d.ts +33 -19
- package/types/utility.d.ts +11 -0
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
|
@@ -742,7 +742,7 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
742
742
|
if (i === '__proto__' || i === 'constructor') {
|
|
743
743
|
return;
|
|
744
744
|
}
|
|
745
|
-
path = prefix + i;
|
|
745
|
+
path = prefix ? prefix + i : i;
|
|
746
746
|
schemaType = docSchema.path(path);
|
|
747
747
|
// Should still work if not a model-level discriminator, but should not be
|
|
748
748
|
// necessary. This is *only* to catch the case where we queried using the
|
|
@@ -751,7 +751,8 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
751
751
|
return;
|
|
752
752
|
}
|
|
753
753
|
|
|
754
|
-
|
|
754
|
+
const value = obj[i];
|
|
755
|
+
if (!schemaType && utils.isPOJO(value)) {
|
|
755
756
|
// assume nested object
|
|
756
757
|
if (!doc[i]) {
|
|
757
758
|
doc[i] = {};
|
|
@@ -759,29 +760,30 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
759
760
|
self[i] = doc[i];
|
|
760
761
|
}
|
|
761
762
|
}
|
|
762
|
-
init(self,
|
|
763
|
+
init(self, value, doc[i], opts, path + '.');
|
|
763
764
|
} else if (!schemaType) {
|
|
764
|
-
doc[i] =
|
|
765
|
+
doc[i] = value;
|
|
765
766
|
if (!strict && !prefix) {
|
|
766
|
-
self[i] =
|
|
767
|
+
self[i] = value;
|
|
767
768
|
}
|
|
768
769
|
} else {
|
|
769
770
|
// Retain order when overwriting defaults
|
|
770
|
-
if (doc.hasOwnProperty(i) &&
|
|
771
|
+
if (doc.hasOwnProperty(i) && value !== void 0 && !opts.hydratedPopulatedDocs) {
|
|
771
772
|
delete doc[i];
|
|
772
773
|
}
|
|
773
|
-
if (
|
|
774
|
+
if (value === null) {
|
|
774
775
|
doc[i] = schemaType._castNullish(null);
|
|
775
|
-
} else if (
|
|
776
|
-
const wasPopulated =
|
|
777
|
-
|
|
776
|
+
} else if (value !== undefined) {
|
|
777
|
+
const wasPopulated = value.$__ == null ? null : value.$__.wasPopulated;
|
|
778
|
+
|
|
779
|
+
if (schemaType && !wasPopulated && !opts.hydratedPopulatedDocs) {
|
|
778
780
|
try {
|
|
779
781
|
if (opts && opts.setters) {
|
|
780
782
|
// Call applySetters with `init = false` because otherwise setters are a noop
|
|
781
783
|
const overrideInit = false;
|
|
782
|
-
doc[i] = schemaType.applySetters(
|
|
784
|
+
doc[i] = schemaType.applySetters(value, self, overrideInit);
|
|
783
785
|
} else {
|
|
784
|
-
doc[i] = schemaType.cast(
|
|
786
|
+
doc[i] = schemaType.cast(value, self, true);
|
|
785
787
|
}
|
|
786
788
|
} catch (e) {
|
|
787
789
|
self.invalidate(e.path, new ValidatorError({
|
|
@@ -793,7 +795,7 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
793
795
|
}));
|
|
794
796
|
}
|
|
795
797
|
} else {
|
|
796
|
-
doc[i] =
|
|
798
|
+
doc[i] = value;
|
|
797
799
|
}
|
|
798
800
|
}
|
|
799
801
|
// mark as hydrated
|
|
@@ -1388,6 +1390,7 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1388
1390
|
if (schema.options &&
|
|
1389
1391
|
Array.isArray(schema.options[typeKey]) &&
|
|
1390
1392
|
schema.options[typeKey].length &&
|
|
1393
|
+
schema.options[typeKey][0] &&
|
|
1391
1394
|
schema.options[typeKey][0].ref &&
|
|
1392
1395
|
_isManuallyPopulatedArray(val, schema.options[typeKey][0].ref)) {
|
|
1393
1396
|
popOpts = { [populateModelSymbol]: val[0].constructor };
|
|
@@ -4735,7 +4738,7 @@ Document.prototype.$clone = function() {
|
|
|
4735
4738
|
const clonedDoc = new Model();
|
|
4736
4739
|
clonedDoc.$isNew = this.$isNew;
|
|
4737
4740
|
if (this._doc) {
|
|
4738
|
-
clonedDoc._doc = clone(this._doc);
|
|
4741
|
+
clonedDoc._doc = clone(this._doc, { retainDocuments: true });
|
|
4739
4742
|
}
|
|
4740
4743
|
if (this.$__) {
|
|
4741
4744
|
const Cache = this.$__.constructor;
|
|
@@ -136,11 +136,10 @@ function iter(i) {
|
|
|
136
136
|
let promise = null;
|
|
137
137
|
let timeout = null;
|
|
138
138
|
if (syncCollectionMethods[i] && typeof lastArg === 'function') {
|
|
139
|
-
this.addQueue(
|
|
140
|
-
|
|
141
|
-
}, []);
|
|
139
|
+
this.addQueue(i, _args);
|
|
140
|
+
callback = lastArg;
|
|
142
141
|
} else if (syncCollectionMethods[i]) {
|
|
143
|
-
promise = new Promise((resolve, reject) => {
|
|
142
|
+
promise = new this.Promise((resolve, reject) => {
|
|
144
143
|
callback = function collectionOperationCallback(err, res) {
|
|
145
144
|
if (timeout != null) {
|
|
146
145
|
clearTimeout(timeout);
|
package/lib/helpers/clone.js
CHANGED
|
@@ -36,10 +36,23 @@ function clone(obj, options, isArrayChild) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
if (isMongooseObject(obj)) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
23
|
-
schemaType.
|
|
24
|
-
|
|
25
|
-
|
|
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
|
@@ -351,12 +351,22 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
351
351
|
|
|
352
352
|
const update = delta[1];
|
|
353
353
|
if (this.$__schema.options.minimize) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
354
|
+
for (const updateOp of Object.values(update)) {
|
|
355
|
+
if (updateOp == null) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
for (const key of Object.keys(updateOp)) {
|
|
359
|
+
if (updateOp[key] == null || typeof updateOp[key] !== 'object') {
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (!utils.isPOJO(updateOp[key])) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
minimize(updateOp[key]);
|
|
366
|
+
if (Object.keys(updateOp[key]).length === 0) {
|
|
367
|
+
updateOp[key] = null;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
360
370
|
}
|
|
361
371
|
}
|
|
362
372
|
|
|
@@ -2532,6 +2542,7 @@ Model.$where = function $where() {
|
|
|
2532
2542
|
* @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
2543
|
* @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
2544
|
* @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.
|
|
2545
|
+
* @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
2546
|
* @return {Query}
|
|
2536
2547
|
* @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
|
|
2537
2548
|
* @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
|
|
@@ -2624,6 +2635,7 @@ Model.findOneAndUpdate = function(conditions, update, options) {
|
|
|
2624
2635
|
* @param {Boolean} [options.new=false] if true, return the modified document rather than the original
|
|
2625
2636
|
* @param {Object|String} [options.select] sets the document fields to return.
|
|
2626
2637
|
* @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.
|
|
2638
|
+
* @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
2639
|
* @return {Query}
|
|
2628
2640
|
* @see Model.findOneAndUpdate https://mongoosejs.com/docs/api/model.html#Model.findOneAndUpdate()
|
|
2629
2641
|
* @see mongodb https://www.mongodb.com/docs/manual/reference/command/findAndModify/
|
|
@@ -3073,7 +3085,7 @@ Model.startSession = function() {
|
|
|
3073
3085
|
* @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#insertMany)
|
|
3074
3086
|
* @param {Boolean} [options.ordered=true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An `insertMany()` with `ordered = false` is called an "unordered" `insertMany()`.
|
|
3075
3087
|
* @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` and `results` if this is an unordered `insertMany`.
|
|
3076
|
-
* @param {Boolean} [options.lean=false] if `true`, skips hydrating
|
|
3088
|
+
* @param {Boolean} [options.lean=false] if `true`, skips hydrating the documents. This means Mongoose will **not** cast or validate any of the documents passed to `insertMany()`. This option is useful if you need the extra performance, but comes with data integrity risk. Consider using with [`castObject()`](https://mongoosejs.com/docs/api/model.html#Model.castObject()).
|
|
3077
3089
|
* @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.
|
|
3078
3090
|
* @param {String|Object|Array} [options.populate=null] populates the result documents. This option is a no-op if `rawResult` is set.
|
|
3079
3091
|
* @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.
|
|
@@ -3134,6 +3146,13 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3134
3146
|
const results = ordered ? null : new Array(arr.length);
|
|
3135
3147
|
const toExecute = arr.map((doc, index) =>
|
|
3136
3148
|
callback => {
|
|
3149
|
+
// If option `lean` is set to true bypass validation and hydration
|
|
3150
|
+
if (lean) {
|
|
3151
|
+
// we have to execute callback at the nextTick to be compatible
|
|
3152
|
+
// with parallelLimit, as `results` variable has TDZ issue if we
|
|
3153
|
+
// execute the callback synchronously
|
|
3154
|
+
return immediate(() => callback(null, doc));
|
|
3155
|
+
}
|
|
3137
3156
|
if (!(doc instanceof _this)) {
|
|
3138
3157
|
if (doc != null && typeof doc !== 'object') {
|
|
3139
3158
|
return callback(new ObjectParameterError(doc, 'arr.' + index, 'insertMany'));
|
|
@@ -3214,7 +3233,7 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3214
3233
|
callback(null, []);
|
|
3215
3234
|
return;
|
|
3216
3235
|
}
|
|
3217
|
-
const docObjects = docAttributes.map(function(doc) {
|
|
3236
|
+
const docObjects = lean ? docAttributes : docAttributes.map(function(doc) {
|
|
3218
3237
|
if (doc.$__schema.options.versionKey) {
|
|
3219
3238
|
doc[doc.$__schema.options.versionKey] = 0;
|
|
3220
3239
|
}
|
|
@@ -3227,9 +3246,11 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3227
3246
|
|
|
3228
3247
|
_this.$__collection.insertMany(docObjects, options).then(
|
|
3229
3248
|
res => {
|
|
3230
|
-
|
|
3231
|
-
attribute
|
|
3232
|
-
|
|
3249
|
+
if (!lean) {
|
|
3250
|
+
for (const attribute of docAttributes) {
|
|
3251
|
+
attribute.$__reset();
|
|
3252
|
+
_setIsNew(attribute, false);
|
|
3253
|
+
}
|
|
3233
3254
|
}
|
|
3234
3255
|
|
|
3235
3256
|
if (ordered === false && throwOnValidationError && validationErrors.length > 0) {
|
|
@@ -3331,6 +3352,9 @@ Model.$__insertMany = function(arr, options, callback) {
|
|
|
3331
3352
|
return !isErrored;
|
|
3332
3353
|
}).
|
|
3333
3354
|
map(function setIsNewForInsertedDoc(doc) {
|
|
3355
|
+
if (lean) {
|
|
3356
|
+
return doc;
|
|
3357
|
+
}
|
|
3334
3358
|
doc.$__reset();
|
|
3335
3359
|
_setIsNew(doc, false);
|
|
3336
3360
|
return doc;
|
|
@@ -3373,6 +3397,7 @@ function _setIsNew(doc, val) {
|
|
|
3373
3397
|
* trip to MongoDB.
|
|
3374
3398
|
*
|
|
3375
3399
|
* Mongoose will perform casting on all operations you provide.
|
|
3400
|
+
* The only exception is [setting the `update` operator for `updateOne` or `updateMany` to a pipeline](https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/#updateone-and-updatemany): Mongoose does **not** cast update pipelines.
|
|
3376
3401
|
*
|
|
3377
3402
|
* This function does **not** trigger any middleware, neither `save()`, nor `update()`.
|
|
3378
3403
|
* If you need to trigger
|
|
@@ -3408,6 +3433,15 @@ function _setIsNew(doc, val) {
|
|
|
3408
3433
|
* console.log(res.insertedCount, res.modifiedCount, res.deletedCount);
|
|
3409
3434
|
* });
|
|
3410
3435
|
*
|
|
3436
|
+
* // Mongoose does **not** cast update pipelines, so no casting for the `update` option below.
|
|
3437
|
+
* // Mongoose does still cast `filter`
|
|
3438
|
+
* await Character.bulkWrite([{
|
|
3439
|
+
* updateOne: {
|
|
3440
|
+
* filter: { name: 'Annika Hansen' },
|
|
3441
|
+
* update: [{ $set: { name: 7 } }] // Array means update pipeline, so Mongoose skips casting
|
|
3442
|
+
* }
|
|
3443
|
+
* }]);
|
|
3444
|
+
*
|
|
3411
3445
|
* The [supported operations](https://www.mongodb.com/docs/manual/reference/method/db.collection.bulkWrite/#db.collection.bulkWrite) are:
|
|
3412
3446
|
*
|
|
3413
3447
|
* - `insertOne`
|
|
@@ -3937,13 +3971,14 @@ Model.hydrate = function(obj, projection, options) {
|
|
|
3937
3971
|
* - `updateMany()`
|
|
3938
3972
|
*
|
|
3939
3973
|
* @param {Object} filter
|
|
3940
|
-
* @param {Object|Array} update
|
|
3974
|
+
* @param {Object|Array} update. If array, this update will be treated as an update pipeline and not casted.
|
|
3941
3975
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
|
|
3942
3976
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3943
3977
|
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3944
3978
|
* @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
3979
|
* @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
3980
|
* @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.
|
|
3981
|
+
* @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
3982
|
* @return {Query}
|
|
3948
3983
|
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3949
3984
|
* @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
|
|
@@ -3976,13 +4011,14 @@ Model.updateMany = function updateMany(conditions, doc, options) {
|
|
|
3976
4011
|
* - `updateOne()`
|
|
3977
4012
|
*
|
|
3978
4013
|
* @param {Object} filter
|
|
3979
|
-
* @param {Object|Array} update
|
|
4014
|
+
* @param {Object|Array} update. If array, this update will be treated as an update pipeline and not casted.
|
|
3980
4015
|
* @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
|
|
3981
4016
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
3982
4017
|
* @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
|
|
3983
4018
|
* @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
4019
|
* @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
4020
|
* @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.
|
|
4021
|
+
* @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
4022
|
* @return {Query}
|
|
3987
4023
|
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
3988
4024
|
* @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
|
package/lib/mongoose.js
CHANGED
|
@@ -506,12 +506,14 @@ Mongoose.prototype.pluralize = function(fn) {
|
|
|
506
506
|
*
|
|
507
507
|
* // or
|
|
508
508
|
*
|
|
509
|
-
* const collectionName = 'actor'
|
|
510
|
-
* const M = mongoose.model('Actor', schema, collectionName)
|
|
509
|
+
* const collectionName = 'actor';
|
|
510
|
+
* const M = mongoose.model('Actor', schema, collectionName);
|
|
511
511
|
*
|
|
512
512
|
* @param {String|Function} name model name or class extending Model
|
|
513
513
|
* @param {Schema} [schema] the schema to use.
|
|
514
514
|
* @param {String} [collection] name (optional, inferred from model name)
|
|
515
|
+
* @param {Object} [options]
|
|
516
|
+
* @param {Boolean} [options.overwriteModels=false] If true, overwrite existing models with the same name to avoid `OverwriteModelError`
|
|
515
517
|
* @return {Model} The model associated with `name`. Mongoose will create the model if it doesn't already exist.
|
|
516
518
|
* @api public
|
|
517
519
|
*/
|
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
|
|
@@ -3879,7 +3880,7 @@ Query.prototype._replaceOne = async function _replaceOne() {
|
|
|
3879
3880
|
* - `updateMany()`
|
|
3880
3881
|
*
|
|
3881
3882
|
* @param {Object} [filter]
|
|
3882
|
-
* @param {Object|Array} [update] the update command
|
|
3883
|
+
* @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
|
|
3883
3884
|
* @param {Object} [options]
|
|
3884
3885
|
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3885
3886
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
@@ -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()
|
|
@@ -3948,14 +3950,15 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
3948
3950
|
* - `updateOne()`
|
|
3949
3951
|
*
|
|
3950
3952
|
* @param {Object} [filter]
|
|
3951
|
-
* @param {Object|Array} [update] the update command
|
|
3953
|
+
* @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
|
|
3952
3954
|
* @param {Object} [options]
|
|
3953
3955
|
* @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
|
|
3954
3956
|
* @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
|
|
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/lib/schema.js
CHANGED
|
@@ -1014,6 +1014,9 @@ reserved.collection = 1;
|
|
|
1014
1014
|
|
|
1015
1015
|
Schema.prototype.path = function(path, obj) {
|
|
1016
1016
|
if (obj === undefined) {
|
|
1017
|
+
if (this.paths[path] != null) {
|
|
1018
|
+
return this.paths[path];
|
|
1019
|
+
}
|
|
1017
1020
|
// Convert to '.$' to check subpaths re: gh-6405
|
|
1018
1021
|
const cleanPath = _pathToPositionalSyntax(path);
|
|
1019
1022
|
let schematype = _getPath(this, path, cleanPath);
|
|
@@ -698,22 +698,21 @@ const methods = {
|
|
|
698
698
|
|
|
699
699
|
if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 &&
|
|
700
700
|
atomics.$push.$position != atomic.$position) {
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
701
|
+
if (atomic.$position != null) {
|
|
702
|
+
[].splice.apply(arr, [atomic.$position, 0].concat(values));
|
|
703
|
+
ret = arr.length;
|
|
704
|
+
} else {
|
|
705
|
+
ret = [].push.apply(arr, values);
|
|
706
|
+
}
|
|
704
707
|
|
|
705
|
-
|
|
708
|
+
this._registerAtomic('$set', this);
|
|
709
|
+
} else if (atomic.$position != null) {
|
|
706
710
|
[].splice.apply(arr, [atomic.$position, 0].concat(values));
|
|
707
711
|
ret = this.length;
|
|
708
712
|
} else {
|
|
709
713
|
ret = [].push.apply(arr, values);
|
|
710
714
|
}
|
|
711
715
|
} else {
|
|
712
|
-
if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 &&
|
|
713
|
-
atomics.$push.$position != null) {
|
|
714
|
-
throw new MongooseError('Cannot call `Array#push()` multiple times ' +
|
|
715
|
-
'with different `$position`');
|
|
716
|
-
}
|
|
717
716
|
atomic = values;
|
|
718
717
|
ret = _basePush.apply(arr, values);
|
|
719
718
|
}
|
|
@@ -145,7 +145,7 @@ ArraySubdocument.prototype.$__fullPath = function(path, skipIndex) {
|
|
|
145
145
|
*/
|
|
146
146
|
|
|
147
147
|
ArraySubdocument.prototype.$__pathRelativeToParent = function(path, skipIndex) {
|
|
148
|
-
if (this.__index == null) {
|
|
148
|
+
if (this.__index == null || (!this.__parentArray || !this.__parentArray.$path)) {
|
|
149
149
|
return null;
|
|
150
150
|
}
|
|
151
151
|
if (skipIndex) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.2.
|
|
4
|
+
"version": "8.2.2",
|
|
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.
|
|
32
|
-
"@babel/preset-env": "7.
|
|
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.
|
|
46
|
+
"dotenv": "16.4.5",
|
|
47
47
|
"dox": "1.0.0",
|
|
48
|
-
"eslint": "8.
|
|
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.
|
|
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.
|
|
68
|
+
"tsd": "0.30.7",
|
|
69
69
|
"typescript": "5.3.3",
|
|
70
70
|
"uuid": "9.0.1",
|
|
71
|
-
"webpack": "5.90.
|
|
71
|
+
"webpack": "5.90.3"
|
|
72
72
|
},
|
|
73
73
|
"directories": {
|
|
74
74
|
"lib": "./lib/mongoose"
|
|
@@ -229,7 +229,7 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
|
|
|
229
229
|
ObtainDocumentPathType<Item, TypeKey>[] :
|
|
230
230
|
// If the type key isn't callable, then this is an array of objects, in which case
|
|
231
231
|
// we need to call ObtainDocumentType to correctly infer its type.
|
|
232
|
-
ObtainDocumentType<Item, any, { typeKey: TypeKey }
|
|
232
|
+
Types.DocumentArray<ObtainDocumentType<Item, any, { typeKey: TypeKey }>> :
|
|
233
233
|
IsSchemaTypeFromBuiltinClass<Item> extends true ?
|
|
234
234
|
ObtainDocumentPathType<Item, TypeKey>[] :
|
|
235
235
|
IsItRecordAndNotAny<Item> extends true ?
|