mongoose 8.9.0 → 8.9.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/index.js +0 -1
- package/lib/aggregate.js +21 -4
- package/lib/connection.js +41 -19
- package/lib/cursor/aggregationCursor.js +1 -2
- package/lib/document.js +11 -8
- package/lib/drivers/node-mongodb-native/collection.js +0 -1
- package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
- package/lib/helpers/model/discriminator.js +1 -0
- package/lib/model.js +17 -15
- package/lib/mongoose.js +18 -20
- package/lib/query.js +1 -22
- package/lib/schema/string.js +10 -10
- package/lib/schema.js +27 -9
- package/lib/types/map.js +8 -1
- package/package.json +3 -3
- package/types/index.d.ts +57 -50
package/lib/query.js
CHANGED
|
@@ -2247,10 +2247,7 @@ Query.prototype.error = function error(err) {
|
|
|
2247
2247
|
*/
|
|
2248
2248
|
|
|
2249
2249
|
Query.prototype._unsetCastError = function _unsetCastError() {
|
|
2250
|
-
if (this._error == null) {
|
|
2251
|
-
return;
|
|
2252
|
-
}
|
|
2253
|
-
if (this._error != null && !(this._error instanceof CastError)) {
|
|
2250
|
+
if (this._error == null || !(this._error instanceof CastError)) {
|
|
2254
2251
|
return;
|
|
2255
2252
|
}
|
|
2256
2253
|
return this.error(null);
|
|
@@ -3197,7 +3194,6 @@ Query.prototype.deleteMany = function(filter, options) {
|
|
|
3197
3194
|
/**
|
|
3198
3195
|
* Execute a `deleteMany()` query
|
|
3199
3196
|
*
|
|
3200
|
-
* @param {Function} callback
|
|
3201
3197
|
* @method _deleteMany
|
|
3202
3198
|
* @instance
|
|
3203
3199
|
* @memberOf Query
|
|
@@ -3490,13 +3486,6 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
|
|
|
3490
3486
|
* - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
|
|
3491
3487
|
* - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
|
|
3492
3488
|
*
|
|
3493
|
-
* #### Callback Signature
|
|
3494
|
-
*
|
|
3495
|
-
* function(error, doc) {
|
|
3496
|
-
* // error: any errors that occurred
|
|
3497
|
-
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3498
|
-
* }
|
|
3499
|
-
*
|
|
3500
3489
|
* #### Example:
|
|
3501
3490
|
*
|
|
3502
3491
|
* A.where().findOneAndDelete(conditions, options) // return Query
|
|
@@ -3587,13 +3576,6 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
|
|
|
3587
3576
|
* - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
|
|
3588
3577
|
* - `includeResultMetadata`: if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
|
|
3589
3578
|
*
|
|
3590
|
-
* #### Callback Signature
|
|
3591
|
-
*
|
|
3592
|
-
* function(error, doc) {
|
|
3593
|
-
* // error: any errors that occurred
|
|
3594
|
-
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
3595
|
-
* }
|
|
3596
|
-
*
|
|
3597
3579
|
* #### Example:
|
|
3598
3580
|
*
|
|
3599
3581
|
* A.where().findOneAndReplace(filter, replacement, options); // return Query
|
|
@@ -4025,7 +4007,6 @@ Query.prototype._replaceOne = async function _replaceOne() {
|
|
|
4025
4007
|
* @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.
|
|
4026
4008
|
* @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
|
|
4027
4009
|
* @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
|
|
4028
|
-
* @param {Function} [callback] params are (error, writeOpResult)
|
|
4029
4010
|
* @return {Query} this
|
|
4030
4011
|
* @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
|
|
4031
4012
|
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
@@ -4096,7 +4077,6 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
4096
4077
|
* @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.
|
|
4097
4078
|
* @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
|
|
4098
4079
|
* @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
|
|
4099
|
-
* @param {Function} [callback] params are (error, writeOpResult)
|
|
4100
4080
|
* @return {Query} this
|
|
4101
4081
|
* @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
|
|
4102
4082
|
* @see Query docs https://mongoosejs.com/docs/queries.html
|
|
@@ -4163,7 +4143,6 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
|
|
|
4163
4143
|
* @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)
|
|
4164
4144
|
* @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.
|
|
4165
4145
|
* @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.
|
|
4166
|
-
* @param {Function} [callback] params are (error, writeOpResult)
|
|
4167
4146
|
* @return {Query} this
|
|
4168
4147
|
* @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
|
|
4169
4148
|
* @see Query docs https://mongoosejs.com/docs/queries.html
|
package/lib/schema/string.js
CHANGED
|
@@ -181,11 +181,11 @@ SchemaString.checkRequired = SchemaType.checkRequired;
|
|
|
181
181
|
* const s = new Schema({ state: { type: String, enum: states }})
|
|
182
182
|
* const M = db.model('M', s)
|
|
183
183
|
* const m = new M({ state: 'invalid' })
|
|
184
|
-
* m.save(
|
|
185
|
-
* console.error(
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
184
|
+
* await m.save()
|
|
185
|
+
* .catch((err) => console.error(err)); // ValidationError: `invalid` is not a valid enum value for path `state`.
|
|
186
|
+
* m.state = 'open';
|
|
187
|
+
* await m.save();
|
|
188
|
+
* // success
|
|
189
189
|
*
|
|
190
190
|
* // or with custom error messages
|
|
191
191
|
* const enum = {
|
|
@@ -195,11 +195,11 @@ SchemaString.checkRequired = SchemaType.checkRequired;
|
|
|
195
195
|
* const s = new Schema({ state: { type: String, enum: enum })
|
|
196
196
|
* const M = db.model('M', s)
|
|
197
197
|
* const m = new M({ state: 'invalid' })
|
|
198
|
-
* m.save(
|
|
199
|
-
* console.error(
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
198
|
+
* await m.save()
|
|
199
|
+
* .catch((err) => console.error(err)); // ValidationError: enum validator failed for path `state` with value `invalid`
|
|
200
|
+
* m.state = 'open';
|
|
201
|
+
* await m.save();
|
|
202
|
+
* // success
|
|
203
203
|
*
|
|
204
204
|
* @param {...String|Object} [args] enumeration values
|
|
205
205
|
* @return {SchemaType} this
|
package/lib/schema.js
CHANGED
|
@@ -18,13 +18,13 @@ const getConstructorName = require('./helpers/getConstructorName');
|
|
|
18
18
|
const getIndexes = require('./helpers/schema/getIndexes');
|
|
19
19
|
const handleReadPreferenceAliases = require('./helpers/query/handleReadPreferenceAliases');
|
|
20
20
|
const idGetter = require('./helpers/schema/idGetter');
|
|
21
|
+
const isIndexSpecEqual = require('./helpers/indexes/isIndexSpecEqual');
|
|
21
22
|
const merge = require('./helpers/schema/merge');
|
|
22
23
|
const mpath = require('mpath');
|
|
23
24
|
const setPopulatedVirtualValue = require('./helpers/populate/setPopulatedVirtualValue');
|
|
24
25
|
const setupTimestamps = require('./helpers/timestamps/setupTimestamps');
|
|
25
26
|
const utils = require('./utils');
|
|
26
27
|
const validateRef = require('./helpers/populate/validateRef');
|
|
27
|
-
const util = require('util');
|
|
28
28
|
|
|
29
29
|
const hasNumericSubpathRegex = /\.\d+(\.|$)/;
|
|
30
30
|
|
|
@@ -441,7 +441,7 @@ Schema.prototype._clone = function _clone(Constructor) {
|
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
443
|
}
|
|
444
|
-
s.
|
|
444
|
+
s._gatherChildSchemas();
|
|
445
445
|
|
|
446
446
|
s.virtuals = clone(this.virtuals);
|
|
447
447
|
s.$globalPluginsApplied = this.$globalPluginsApplied;
|
|
@@ -899,7 +899,7 @@ Schema.prototype.removeIndex = function removeIndex(index) {
|
|
|
899
899
|
|
|
900
900
|
if (typeof index === 'object') {
|
|
901
901
|
for (let i = this._indexes.length - 1; i >= 0; --i) {
|
|
902
|
-
if (
|
|
902
|
+
if (isIndexSpecEqual(this._indexes[i][0], index)) {
|
|
903
903
|
this._indexes.splice(i, 1);
|
|
904
904
|
}
|
|
905
905
|
}
|
|
@@ -1238,20 +1238,32 @@ Schema.prototype.path = function(path, obj) {
|
|
|
1238
1238
|
* ignore
|
|
1239
1239
|
*/
|
|
1240
1240
|
|
|
1241
|
-
function
|
|
1241
|
+
Schema.prototype._gatherChildSchemas = function _gatherChildSchemas() {
|
|
1242
1242
|
const childSchemas = [];
|
|
1243
1243
|
|
|
1244
|
-
for (const path of Object.keys(
|
|
1245
|
-
|
|
1244
|
+
for (const path of Object.keys(this.paths)) {
|
|
1245
|
+
if (typeof path !== 'string') {
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
const schematype = this.paths[path];
|
|
1246
1249
|
if (schematype.$isMongooseDocumentArray || schematype.$isSingleNested) {
|
|
1247
|
-
childSchemas.push({
|
|
1250
|
+
childSchemas.push({
|
|
1251
|
+
schema: schematype.schema,
|
|
1252
|
+
model: schematype.caster,
|
|
1253
|
+
path: path
|
|
1254
|
+
});
|
|
1248
1255
|
} else if (schematype.$isSchemaMap && schematype.$__schemaType.$isSingleNested) {
|
|
1249
|
-
childSchemas.push({
|
|
1256
|
+
childSchemas.push({
|
|
1257
|
+
schema: schematype.$__schemaType.schema,
|
|
1258
|
+
model: schematype.$__schemaType.caster,
|
|
1259
|
+
path: path
|
|
1260
|
+
});
|
|
1250
1261
|
}
|
|
1251
1262
|
}
|
|
1252
1263
|
|
|
1264
|
+
this.childSchemas = childSchemas;
|
|
1253
1265
|
return childSchemas;
|
|
1254
|
-
}
|
|
1266
|
+
};
|
|
1255
1267
|
|
|
1256
1268
|
/*!
|
|
1257
1269
|
* ignore
|
|
@@ -2134,6 +2146,12 @@ Schema.prototype.index = function(fields, options) {
|
|
|
2134
2146
|
}
|
|
2135
2147
|
}
|
|
2136
2148
|
|
|
2149
|
+
for (const existingIndex of this.indexes()) {
|
|
2150
|
+
if (options.name == null && existingIndex[1].name == null && isIndexSpecEqual(existingIndex[0], fields)) {
|
|
2151
|
+
throw new MongooseError(`Schema already has an index on ${JSON.stringify(fields)}`);
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2137
2155
|
this._indexes.push([fields, options]);
|
|
2138
2156
|
return this;
|
|
2139
2157
|
};
|
package/lib/types/map.js
CHANGED
|
@@ -9,6 +9,7 @@ const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
|
|
|
9
9
|
const util = require('util');
|
|
10
10
|
const specialProperties = require('../helpers/specialProperties');
|
|
11
11
|
const isBsonType = require('../helpers/isBsonType');
|
|
12
|
+
const cleanModifiedSubpaths = require('../helpers/document/cleanModifiedSubpaths');
|
|
12
13
|
|
|
13
14
|
const populateModelSymbol = require('../helpers/symbols').populateModelSymbol;
|
|
14
15
|
|
|
@@ -157,7 +158,13 @@ class MongooseMap extends Map {
|
|
|
157
158
|
super.set(key, value);
|
|
158
159
|
|
|
159
160
|
if (parent != null && parent.$__ != null && !deepEqual(value, priorVal)) {
|
|
160
|
-
|
|
161
|
+
const path = fullPath.call(this);
|
|
162
|
+
parent.markModified(path);
|
|
163
|
+
// If overwriting the full document array or subdoc, make sure to clean up any paths that were modified
|
|
164
|
+
// before re: #15108
|
|
165
|
+
if (this.$__schemaType.$isMongooseDocumentArray || this.$__schemaType.$isSingleNested) {
|
|
166
|
+
cleanModifiedSubpaths(parent, path);
|
|
167
|
+
}
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// Delay calculating full path unless absolutely necessary, because string
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.9.
|
|
4
|
+
"version": "8.9.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@babel/core": "7.26.0",
|
|
32
32
|
"@babel/preset-env": "7.26.0",
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
34
|
-
"@typescript-eslint/parser": "^8.
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
|
34
|
+
"@typescript-eslint/parser": "^8.18.0",
|
|
35
35
|
"acquit": "1.3.0",
|
|
36
36
|
"acquit-ignore": "0.2.1",
|
|
37
37
|
"acquit-require": "0.1.1",
|
package/types/index.d.ts
CHANGED
|
@@ -572,7 +572,8 @@ declare module 'mongoose' {
|
|
|
572
572
|
| typeof Schema.Types.Number
|
|
573
573
|
| typeof Schema.Types.String
|
|
574
574
|
| typeof Schema.Types.Buffer
|
|
575
|
-
| typeof Schema.Types.ObjectId
|
|
575
|
+
| typeof Schema.Types.ObjectId
|
|
576
|
+
| typeof Schema.Types.UUID;
|
|
576
577
|
|
|
577
578
|
|
|
578
579
|
export type InferId<T> = T extends { _id?: any } ? T['_id'] : Types.ObjectId;
|
|
@@ -712,76 +713,82 @@ declare module 'mongoose' {
|
|
|
712
713
|
/**
|
|
713
714
|
* Converts any Buffer properties into mongodb.Binary instances, which is what `lean()` returns
|
|
714
715
|
*/
|
|
715
|
-
export type BufferToBinary<T> = T extends
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
: T[K] extends
|
|
716
|
+
export type BufferToBinary<T> = T extends Buffer
|
|
717
|
+
? mongodb.Binary
|
|
718
|
+
: T extends TreatAsPrimitives
|
|
719
|
+
? T
|
|
720
|
+
: T extends Record<string, any> ? {
|
|
721
|
+
[K in keyof T]: T[K] extends Buffer
|
|
722
|
+
? mongodb.Binary
|
|
723
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
721
724
|
? Types.DocumentArray<BufferToBinary<ItemType>>
|
|
722
725
|
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
723
726
|
? HydratedSingleSubdocument<SubdocType>
|
|
724
727
|
: BufferToBinary<T[K]>;
|
|
725
|
-
|
|
728
|
+
} : T;
|
|
726
729
|
|
|
727
730
|
/**
|
|
728
731
|
* Converts any Buffer properties into { type: 'buffer', data: [1, 2, 3] } format for JSON serialization
|
|
729
732
|
*/
|
|
730
|
-
export type BufferToJSON<T> = T extends
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
: T[K] extends
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
?
|
|
739
|
-
:
|
|
740
|
-
|
|
733
|
+
export type BufferToJSON<T> = T extends Buffer
|
|
734
|
+
? { type: 'buffer', data: number[] }
|
|
735
|
+
: T extends TreatAsPrimitives
|
|
736
|
+
? T
|
|
737
|
+
: T extends Record<string, any> ? {
|
|
738
|
+
[K in keyof T]: T[K] extends Buffer
|
|
739
|
+
? { type: 'buffer', data: number[] }
|
|
740
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
741
|
+
? Types.DocumentArray<BufferToBinary<ItemType>>
|
|
742
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
743
|
+
? HydratedSingleSubdocument<SubdocType>
|
|
744
|
+
: BufferToBinary<T[K]>;
|
|
745
|
+
} : T;
|
|
741
746
|
|
|
742
747
|
/**
|
|
743
748
|
* Converts any ObjectId properties into strings for JSON serialization
|
|
744
749
|
*/
|
|
745
|
-
export type ObjectIdToString<T> = T extends
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
: T[K] extends
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
?
|
|
754
|
-
:
|
|
755
|
-
|
|
750
|
+
export type ObjectIdToString<T> = T extends mongodb.ObjectId
|
|
751
|
+
? string
|
|
752
|
+
: T extends TreatAsPrimitives
|
|
753
|
+
? T
|
|
754
|
+
: T extends Record<string, any> ? {
|
|
755
|
+
[K in keyof T]: T[K] extends mongodb.ObjectId
|
|
756
|
+
? string
|
|
757
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
758
|
+
? Types.DocumentArray<ObjectIdToString<ItemType>>
|
|
759
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
760
|
+
? HydratedSingleSubdocument<ObjectIdToString<SubdocType>>
|
|
761
|
+
: ObjectIdToString<T[K]>;
|
|
762
|
+
} : T;
|
|
756
763
|
|
|
757
764
|
/**
|
|
758
765
|
* Converts any Date properties into strings for JSON serialization
|
|
759
766
|
*/
|
|
760
|
-
export type DateToString<T> = T extends
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
: T[K] extends
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
767
|
+
export type DateToString<T> = T extends NativeDate
|
|
768
|
+
? string
|
|
769
|
+
: T extends TreatAsPrimitives
|
|
770
|
+
? T
|
|
771
|
+
: T extends Record<string, any> ? {
|
|
772
|
+
[K in keyof T]: T[K] extends NativeDate
|
|
773
|
+
? string
|
|
774
|
+
: T[K] extends (NativeDate | null | undefined)
|
|
775
|
+
? string | null | undefined
|
|
776
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
777
|
+
? Types.DocumentArray<DateToString<ItemType>>
|
|
778
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
779
|
+
? HydratedSingleSubdocument<DateToString<SubdocType>>
|
|
780
|
+
: DateToString<T[K]>;
|
|
781
|
+
} : T;
|
|
771
782
|
|
|
772
783
|
/**
|
|
773
784
|
* Converts any Mongoose subdocuments (single nested or doc arrays) into POJO equivalents
|
|
774
785
|
*/
|
|
775
786
|
export type SubdocsToPOJOs<T> = T extends TreatAsPrimitives ? T : T extends Record<string, any> ? {
|
|
776
|
-
[K in keyof T]: T[K] extends
|
|
777
|
-
?
|
|
778
|
-
: T[K] extends
|
|
779
|
-
?
|
|
780
|
-
: T[K]
|
|
781
|
-
? ItemType[]
|
|
782
|
-
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
783
|
-
? SubdocType
|
|
784
|
-
: SubdocsToPOJOs<T[K]>;
|
|
787
|
+
[K in keyof T]: T[K] extends Types.DocumentArray<infer ItemType>
|
|
788
|
+
? ItemType[]
|
|
789
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
790
|
+
? SubdocType
|
|
791
|
+
: SubdocsToPOJOs<T[K]>;
|
|
785
792
|
} : T;
|
|
786
793
|
|
|
787
794
|
export type JSONSerialized<T> = SubdocsToPOJOs<
|