mongoose 6.4.7 → 6.5.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/lib/connection.js +23 -3
- package/lib/cursor/ChangeStream.js +39 -1
- package/lib/document.js +129 -154
- package/lib/error/index.js +1 -0
- package/lib/error/validation.js +9 -0
- package/lib/helpers/document/applyDefaults.js +115 -0
- package/lib/helpers/document/cleanModifiedSubpaths.js +3 -3
- package/lib/helpers/document/compile.js +7 -6
- package/lib/helpers/firstKey.js +8 -0
- package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
- package/lib/helpers/model/castBulkWrite.js +1 -1
- package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
- package/lib/helpers/populate/markArraySubdocsPopulated.js +1 -0
- package/lib/helpers/projection/hasIncludedChildren.js +1 -0
- package/lib/helpers/promiseOrCallback.js +24 -15
- package/lib/helpers/update/applyTimestampsToChildren.js +6 -2
- package/lib/index.js +2 -1
- package/lib/internal.js +3 -1
- package/lib/model.js +237 -95
- package/lib/options/SchemaArrayOptions.js +19 -0
- package/lib/options/SchemaNumberOptions.js +2 -0
- package/lib/options/SchemaObjectIdOptions.js +1 -0
- package/lib/plugins/trackTransaction.js +2 -2
- package/lib/query.js +30 -11
- package/lib/schema/SubdocumentPath.js +10 -0
- package/lib/schema/array.js +2 -1
- package/lib/schema/documentarray.js +14 -1
- package/lib/schema/string.js +3 -0
- package/lib/schema.js +22 -3
- package/lib/schematype.js +5 -1
- package/lib/statemachine.js +23 -9
- package/lib/types/buffer.js +23 -21
- package/lib/types/map.js +2 -0
- package/lib/utils.js +8 -0
- package/lib/validoptions.js +1 -0
- package/package.json +14 -14
- package/{build-browser.js → scripts/build-browser.js} +1 -1
- package/types/connection.d.ts +7 -1
- package/types/document.d.ts +8 -1
- package/types/expressions.d.ts +1 -1
- package/types/index.d.ts +31 -28
- package/types/inferschematype.d.ts +3 -20
- package/types/models.d.ts +53 -49
- package/types/mongooseoptions.d.ts +6 -0
- package/types/schemaoptions.d.ts +15 -4
- package/types/utility.d.ts +19 -0
- package/types/virtuals.d.ts +14 -0
package/lib/query.js
CHANGED
|
@@ -166,7 +166,7 @@ Query.base = mquery.prototype;
|
|
|
166
166
|
*
|
|
167
167
|
* MongoDB 2.4 deprecated the use of `$within`, replacing it with `$geoWithin`. Mongoose uses `$geoWithin` by default (which is 100% backward compatible with `$within`). If you are running an older version of MongoDB, set this flag to `false` so your `within()` queries continue to work.
|
|
168
168
|
*
|
|
169
|
-
* @see https://docs.mongodb.org/manual/reference/operator/geoWithin/
|
|
169
|
+
* @see geoWithin https://docs.mongodb.org/manual/reference/operator/geoWithin/
|
|
170
170
|
* @default true
|
|
171
171
|
* @property use$geoWithin
|
|
172
172
|
* @memberOf Query
|
|
@@ -262,6 +262,7 @@ Query.prototype.toConstructor = function toConstructor() {
|
|
|
262
262
|
* Make a copy of this query so you can re-execute it.
|
|
263
263
|
*
|
|
264
264
|
* #### Example:
|
|
265
|
+
*
|
|
265
266
|
* const q = Book.findOne({ title: 'Casino Royale' });
|
|
266
267
|
* await q.exec();
|
|
267
268
|
* await q.exec(); // Throws an error because you can't execute a query twice
|
|
@@ -1071,7 +1072,7 @@ Query.prototype.projection = function(arg) {
|
|
|
1071
1072
|
* @instance
|
|
1072
1073
|
* @param {Object|String|String[]} arg
|
|
1073
1074
|
* @return {Query} this
|
|
1074
|
-
* @see SchemaType
|
|
1075
|
+
* @see SchemaType /docs/api/schematype
|
|
1075
1076
|
* @api public
|
|
1076
1077
|
*/
|
|
1077
1078
|
|
|
@@ -1598,6 +1599,8 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
1598
1599
|
throw new Error('Options must be an object, got "' + options + '"');
|
|
1599
1600
|
}
|
|
1600
1601
|
|
|
1602
|
+
options = Object.assign({}, options);
|
|
1603
|
+
|
|
1601
1604
|
if (Array.isArray(options.populate)) {
|
|
1602
1605
|
const populate = options.populate;
|
|
1603
1606
|
delete options.populate;
|
|
@@ -1632,6 +1635,9 @@ Query.prototype.setOptions = function(options, overwrite) {
|
|
|
1632
1635
|
this._mongooseOptions.defaults = options.defaults;
|
|
1633
1636
|
// deleting options.defaults will cause 7287 to fail
|
|
1634
1637
|
}
|
|
1638
|
+
if (options.lean == null && this.schema && 'lean' in this.schema.options) {
|
|
1639
|
+
this._mongooseOptions.lean = this.schema.options.lean;
|
|
1640
|
+
}
|
|
1635
1641
|
|
|
1636
1642
|
if (typeof options.limit === 'string') {
|
|
1637
1643
|
try {
|
|
@@ -2038,6 +2044,9 @@ Query.prototype.set = function(path, val) {
|
|
|
2038
2044
|
}
|
|
2039
2045
|
|
|
2040
2046
|
this._update = this._update || {};
|
|
2047
|
+
if (path in this._update) {
|
|
2048
|
+
delete this._update[path];
|
|
2049
|
+
}
|
|
2041
2050
|
this._update.$set = this._update.$set || {};
|
|
2042
2051
|
this._update.$set[path] = val;
|
|
2043
2052
|
return this;
|
|
@@ -2097,6 +2106,7 @@ Query.prototype.get = function get(path) {
|
|
|
2097
2106
|
* custom errors.
|
|
2098
2107
|
*
|
|
2099
2108
|
* #### Example:
|
|
2109
|
+
*
|
|
2100
2110
|
* const TestSchema = new Schema({ num: Number });
|
|
2101
2111
|
* const TestModel = db.model('Test', TestSchema);
|
|
2102
2112
|
* TestModel.find({ num: 'not a number' }).error(new Error('woops')).exec(function(error) {
|
|
@@ -3294,6 +3304,7 @@ function prepareDiscriminatorCriteria(query) {
|
|
|
3294
3304
|
* - `rawResult`: if true, returns the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
|
|
3295
3305
|
*
|
|
3296
3306
|
* #### Callback Signature
|
|
3307
|
+
*
|
|
3297
3308
|
* function(error, doc) {
|
|
3298
3309
|
* // error: any errors that occurred
|
|
3299
3310
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
@@ -3436,6 +3447,7 @@ Query.prototype._findOneAndUpdate = wrapThunk(function(callback) {
|
|
|
3436
3447
|
* - `rawResult`: if true, resolves to the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
|
|
3437
3448
|
*
|
|
3438
3449
|
* #### Callback Signature
|
|
3450
|
+
*
|
|
3439
3451
|
* function(error, doc) {
|
|
3440
3452
|
* // error: any errors that occurred
|
|
3441
3453
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
@@ -3523,6 +3535,7 @@ Query.prototype.findOneAndRemove = function(conditions, options, callback) {
|
|
|
3523
3535
|
* - `rawResult`: if true, resolves to the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
|
|
3524
3536
|
*
|
|
3525
3537
|
* #### Callback Signature
|
|
3538
|
+
*
|
|
3526
3539
|
* function(error, doc) {
|
|
3527
3540
|
* // error: any errors that occurred
|
|
3528
3541
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
@@ -3642,6 +3655,7 @@ Query.prototype._findOneAndDelete = wrapThunk(function(callback) {
|
|
|
3642
3655
|
* - `rawResult`: if true, resolves to the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.3/interfaces/ModifyResult.html)
|
|
3643
3656
|
*
|
|
3644
3657
|
* #### Callback Signature
|
|
3658
|
+
*
|
|
3645
3659
|
* function(error, doc) {
|
|
3646
3660
|
* // error: any errors that occurred
|
|
3647
3661
|
* // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
|
|
@@ -4414,6 +4428,7 @@ Query.prototype.update = function(conditions, doc, options, callback) {
|
|
|
4414
4428
|
* and `post('updateMany')` instead.
|
|
4415
4429
|
*
|
|
4416
4430
|
* #### Example:
|
|
4431
|
+
*
|
|
4417
4432
|
* const res = await Person.updateMany({ name: /Stark$/ }, { isDeleted: true });
|
|
4418
4433
|
* res.n; // Number of documents matched
|
|
4419
4434
|
* res.nModified; // Number of documents modified
|
|
@@ -4479,6 +4494,7 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
|
|
|
4479
4494
|
* and `post('updateOne')` instead.
|
|
4480
4495
|
*
|
|
4481
4496
|
* #### Example:
|
|
4497
|
+
*
|
|
4482
4498
|
* const res = await Person.updateOne({ name: 'Jean-Luc Picard' }, { ship: 'USS Enterprise' });
|
|
4483
4499
|
* res.n; // Number of documents matched
|
|
4484
4500
|
* res.nModified; // Number of documents modified
|
|
@@ -4542,6 +4558,7 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
|
|
|
4542
4558
|
* and `post('replaceOne')` instead.
|
|
4543
4559
|
*
|
|
4544
4560
|
* #### Example:
|
|
4561
|
+
*
|
|
4545
4562
|
* const res = await Person.replaceOne({ _id: 24601 }, { name: 'Jean Valjean' });
|
|
4546
4563
|
* res.n; // Number of documents matched
|
|
4547
4564
|
* res.nModified; // Number of documents modified
|
|
@@ -5059,7 +5076,7 @@ function castQuery(query) {
|
|
|
5059
5076
|
* @param {Object|Function} [options.match=null] Add an additional filter to the populate query. Can be a filter object containing [MongoDB query syntax](https://docs.mongodb.com/manual/tutorial/query-documents/), or a function that returns a filter object.
|
|
5060
5077
|
* @param {Function} [options.transform=null] Function that Mongoose will call on every populated document that allows you to transform the populated document.
|
|
5061
5078
|
* @param {Object} [options.options=null] Additional options like `limit` and `lean`.
|
|
5062
|
-
* @see population
|
|
5079
|
+
* @see population /docs/populate
|
|
5063
5080
|
* @see Query#select #query_Query-select
|
|
5064
5081
|
* @see Model.populate #model_Model-populate
|
|
5065
5082
|
* @return {Query} this
|
|
@@ -5125,6 +5142,7 @@ Query.prototype.populate = function() {
|
|
|
5125
5142
|
* Gets a list of paths to be populated by this query
|
|
5126
5143
|
*
|
|
5127
5144
|
* #### Example:
|
|
5145
|
+
*
|
|
5128
5146
|
* bookSchema.pre('findOne', function() {
|
|
5129
5147
|
* let keys = this.getPopulatedPaths(); // ['author']
|
|
5130
5148
|
* });
|
|
@@ -5132,6 +5150,7 @@ Query.prototype.populate = function() {
|
|
|
5132
5150
|
* Book.findOne({}).populate('author');
|
|
5133
5151
|
*
|
|
5134
5152
|
* #### Example:
|
|
5153
|
+
*
|
|
5135
5154
|
* // Deep populate
|
|
5136
5155
|
* const q = L1.find().populate({
|
|
5137
5156
|
* path: 'level2',
|
|
@@ -5328,7 +5347,7 @@ Query.prototype._applyPaths = function applyPaths() {
|
|
|
5328
5347
|
*
|
|
5329
5348
|
* @return {QueryCursor}
|
|
5330
5349
|
* @param {Object} [options]
|
|
5331
|
-
* @see QueryCursor
|
|
5350
|
+
* @see QueryCursor /docs/api/querycursor
|
|
5332
5351
|
* @api public
|
|
5333
5352
|
*/
|
|
5334
5353
|
|
|
@@ -5484,8 +5503,8 @@ Query.prototype.tailable = function(val, opts) {
|
|
|
5484
5503
|
* @param {Object} object Must contain a `type` property which is a String and a `coordinates` property which is an Array. See the examples.
|
|
5485
5504
|
* @return {Query} this
|
|
5486
5505
|
* @see $geometry https://docs.mongodb.org/manual/reference/operator/geometry/
|
|
5487
|
-
* @see https://
|
|
5488
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5506
|
+
* @see Geospatial Support Enhancements https://www.mongodb.com/docs/manual/release-notes/2.4/#geospatial-support-enhancements
|
|
5507
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5489
5508
|
* @api public
|
|
5490
5509
|
*/
|
|
5491
5510
|
|
|
@@ -5510,7 +5529,7 @@ Query.prototype.tailable = function(val, opts) {
|
|
|
5510
5529
|
* @see $near https://docs.mongodb.org/manual/reference/operator/near/
|
|
5511
5530
|
* @see $nearSphere https://docs.mongodb.org/manual/reference/operator/nearSphere/
|
|
5512
5531
|
* @see $maxDistance https://docs.mongodb.org/manual/reference/operator/maxDistance/
|
|
5513
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5532
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5514
5533
|
* @api public
|
|
5515
5534
|
*/
|
|
5516
5535
|
|
|
@@ -5646,7 +5665,7 @@ if (Symbol.asyncIterator != null) {
|
|
|
5646
5665
|
* @param {Array|Object} [coordinatePairs...]
|
|
5647
5666
|
* @return {Query} this
|
|
5648
5667
|
* @see $polygon https://docs.mongodb.org/manual/reference/operator/polygon/
|
|
5649
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5668
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5650
5669
|
* @api public
|
|
5651
5670
|
*/
|
|
5652
5671
|
|
|
@@ -5666,7 +5685,7 @@ if (Symbol.asyncIterator != null) {
|
|
|
5666
5685
|
* @instance
|
|
5667
5686
|
* @see $box https://docs.mongodb.org/manual/reference/operator/box/
|
|
5668
5687
|
* @see within() Query#within #query_Query-within
|
|
5669
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5688
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5670
5689
|
* @param {Object|Array<Number>} val1 Lower Left Coordinates OR a object of lower-left(ll) and upper-right(ur) Coordinates
|
|
5671
5690
|
* @param {Array<Number>} [val2] Upper Right Coordinates
|
|
5672
5691
|
* @return {Query} this
|
|
@@ -5712,7 +5731,7 @@ Query.prototype.box = function(ll, ur) {
|
|
|
5712
5731
|
* @see $center https://docs.mongodb.org/manual/reference/operator/center/
|
|
5713
5732
|
* @see $centerSphere https://docs.mongodb.org/manual/reference/operator/centerSphere/
|
|
5714
5733
|
* @see $geoWithin https://docs.mongodb.org/manual/reference/operator/geoWithin/
|
|
5715
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5734
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5716
5735
|
* @api public
|
|
5717
5736
|
*/
|
|
5718
5737
|
|
|
@@ -5744,7 +5763,7 @@ Query.prototype.center = Query.base.circle;
|
|
|
5744
5763
|
* @param {String} [path]
|
|
5745
5764
|
* @param {Object} val
|
|
5746
5765
|
* @return {Query} this
|
|
5747
|
-
* @see https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5766
|
+
* @see MongoDB Geospatial Indexing https://www.mongodb.org/display/DOCS/Geospatial+Indexing
|
|
5748
5767
|
* @see $centerSphere https://docs.mongodb.org/manual/reference/operator/centerSphere/
|
|
5749
5768
|
* @api public
|
|
5750
5769
|
*/
|
|
@@ -47,6 +47,7 @@ function SubdocumentPath(schema, path, options) {
|
|
|
47
47
|
this.caster.prototype.$basePath = path;
|
|
48
48
|
this.schema = schema;
|
|
49
49
|
this.$isSingleNested = true;
|
|
50
|
+
this.base = schema.base;
|
|
50
51
|
SchemaType.call(this, path, options, 'Embedded');
|
|
51
52
|
}
|
|
52
53
|
|
|
@@ -280,6 +281,7 @@ SubdocumentPath.prototype.doValidateSync = function(value, scope, options) {
|
|
|
280
281
|
* Adds a discriminator to this single nested subdocument.
|
|
281
282
|
*
|
|
282
283
|
* #### Example:
|
|
284
|
+
*
|
|
283
285
|
* const shapeSchema = Schema({ name: String }, { discriminatorKey: 'kind' });
|
|
284
286
|
* const schema = Schema({ shape: shapeSchema });
|
|
285
287
|
*
|
|
@@ -338,6 +340,14 @@ SubdocumentPath.defaultOptions = {};
|
|
|
338
340
|
|
|
339
341
|
SubdocumentPath.set = SchemaType.set;
|
|
340
342
|
|
|
343
|
+
/*!
|
|
344
|
+
* ignore
|
|
345
|
+
*/
|
|
346
|
+
|
|
347
|
+
SubdocumentPath.prototype.toJSON = function toJSON() {
|
|
348
|
+
return { path: this.path, options: this.options };
|
|
349
|
+
};
|
|
350
|
+
|
|
341
351
|
/*!
|
|
342
352
|
* ignore
|
|
343
353
|
*/
|
package/lib/schema/array.js
CHANGED
|
@@ -393,7 +393,8 @@ SchemaArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
393
393
|
return value;
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
|
|
396
|
+
const castNonArraysOption = this.options.castNonArrays != null ? this.options.castNonArrays : SchemaArray.options.castNonArrays;
|
|
397
|
+
if (init || castNonArraysOption) {
|
|
397
398
|
// gh-2442: if we're loading this from the db and its not an array, mark
|
|
398
399
|
// the whole array as modified.
|
|
399
400
|
if (!!doc && !!init) {
|
|
@@ -36,6 +36,13 @@ let Subdocument;
|
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
38
|
function DocumentArrayPath(key, schema, options, schemaOptions) {
|
|
39
|
+
const schemaTypeIdOption = DocumentArrayPath.defaultOptions &&
|
|
40
|
+
DocumentArrayPath.defaultOptions._id;
|
|
41
|
+
if (schemaTypeIdOption != null) {
|
|
42
|
+
schemaOptions = schemaOptions || {};
|
|
43
|
+
schemaOptions._id = schemaTypeIdOption;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
if (schemaOptions != null && schemaOptions._id != null) {
|
|
40
47
|
schema = handleIdOption(schema, schemaOptions);
|
|
41
48
|
} else if (options != null && options._id != null) {
|
|
@@ -140,6 +147,7 @@ function _createConstructor(schema, options, baseClass) {
|
|
|
140
147
|
EmbeddedDocument.prototype.constructor = EmbeddedDocument;
|
|
141
148
|
EmbeddedDocument.$isArraySubdocument = true;
|
|
142
149
|
EmbeddedDocument.events = new EventEmitter();
|
|
150
|
+
EmbeddedDocument.base = schema.base;
|
|
143
151
|
|
|
144
152
|
// apply methods
|
|
145
153
|
for (const i in schema.methods) {
|
|
@@ -164,6 +172,7 @@ function _createConstructor(schema, options, baseClass) {
|
|
|
164
172
|
* Adds a discriminator to this document array.
|
|
165
173
|
*
|
|
166
174
|
* #### Example:
|
|
175
|
+
*
|
|
167
176
|
* const shapeSchema = Schema({ name: String }, { discriminatorKey: 'kind' });
|
|
168
177
|
* const schema = Schema({ shapes: [shapeSchema] });
|
|
169
178
|
*
|
|
@@ -342,7 +351,7 @@ DocumentArrayPath.prototype.doValidateSync = function(array, scope, options) {
|
|
|
342
351
|
* ignore
|
|
343
352
|
*/
|
|
344
353
|
|
|
345
|
-
DocumentArrayPath.prototype.getDefault = function(scope) {
|
|
354
|
+
DocumentArrayPath.prototype.getDefault = function(scope, init, options) {
|
|
346
355
|
let ret = typeof this.defaultValue === 'function'
|
|
347
356
|
? this.defaultValue.call(scope)
|
|
348
357
|
: this.defaultValue;
|
|
@@ -351,6 +360,10 @@ DocumentArrayPath.prototype.getDefault = function(scope) {
|
|
|
351
360
|
return ret;
|
|
352
361
|
}
|
|
353
362
|
|
|
363
|
+
if (options && options.skipCast) {
|
|
364
|
+
return ret;
|
|
365
|
+
}
|
|
366
|
+
|
|
354
367
|
// lazy load
|
|
355
368
|
MongooseDocumentArray || (MongooseDocumentArray = require('../types/DocumentArray'));
|
|
356
369
|
|
package/lib/schema/string.js
CHANGED
|
@@ -267,6 +267,7 @@ SchemaString.prototype.enum = function() {
|
|
|
267
267
|
* Note that `lowercase` does **not** affect regular expression queries:
|
|
268
268
|
*
|
|
269
269
|
* #### Example:
|
|
270
|
+
*
|
|
270
271
|
* // Still queries for documents whose `email` matches the regular
|
|
271
272
|
* // expression /SomeEmail/. Mongoose does **not** convert the RegExp
|
|
272
273
|
* // to lowercase.
|
|
@@ -305,6 +306,7 @@ SchemaString.prototype.lowercase = function(shouldApply) {
|
|
|
305
306
|
* Note that `uppercase` does **not** affect regular expression queries:
|
|
306
307
|
*
|
|
307
308
|
* #### Example:
|
|
309
|
+
*
|
|
308
310
|
* // Mongoose does **not** convert the RegExp to uppercase.
|
|
309
311
|
* M.find({ email: /an example/ });
|
|
310
312
|
*
|
|
@@ -347,6 +349,7 @@ SchemaString.prototype.uppercase = function(shouldApply) {
|
|
|
347
349
|
* Note that `trim` does **not** affect regular expression queries:
|
|
348
350
|
*
|
|
349
351
|
* #### Example:
|
|
352
|
+
*
|
|
350
353
|
* // Mongoose does **not** trim whitespace from the RegExp.
|
|
351
354
|
* M.find({ name: / some name / });
|
|
352
355
|
*
|
package/lib/schema.js
CHANGED
|
@@ -133,6 +133,24 @@ function Schema(obj, options) {
|
|
|
133
133
|
this.add(obj);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
// build virtual paths
|
|
137
|
+
if (options && options.virtuals) {
|
|
138
|
+
const virtuals = options.virtuals;
|
|
139
|
+
const pathNames = Object.keys(virtuals);
|
|
140
|
+
for (const pathName of pathNames) {
|
|
141
|
+
const pathOptions = virtuals[pathName].options ? virtuals[pathName].options : undefined;
|
|
142
|
+
const virtual = this.virtual(pathName, pathOptions);
|
|
143
|
+
|
|
144
|
+
if (virtuals[pathName].get) {
|
|
145
|
+
virtual.get(virtuals[pathName].get);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (virtuals[pathName].set) {
|
|
149
|
+
virtual.set(virtuals[pathName].set);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
136
154
|
// check if _id's value is a subdocument (gh-2276)
|
|
137
155
|
const _idSubDoc = obj && obj._id && utils.isObject(obj._id);
|
|
138
156
|
|
|
@@ -438,8 +456,8 @@ Schema.prototype.pick = function(paths, options) {
|
|
|
438
456
|
Schema.prototype.defaultOptions = function(options) {
|
|
439
457
|
this._userProvidedOptions = options == null ? {} : utils.clone(options);
|
|
440
458
|
const baseOptions = this.base && this.base.options || {};
|
|
441
|
-
|
|
442
459
|
const strict = 'strict' in baseOptions ? baseOptions.strict : true;
|
|
460
|
+
const id = 'id' in baseOptions ? baseOptions.id : true;
|
|
443
461
|
options = utils.options({
|
|
444
462
|
strict: strict,
|
|
445
463
|
strictQuery: 'strict' in this._userProvidedOptions ?
|
|
@@ -458,7 +476,7 @@ Schema.prototype.defaultOptions = function(options) {
|
|
|
458
476
|
validateBeforeSave: true,
|
|
459
477
|
// the following are only applied at construction time
|
|
460
478
|
_id: true,
|
|
461
|
-
id:
|
|
479
|
+
id: id,
|
|
462
480
|
typeKey: 'type'
|
|
463
481
|
}, utils.clone(options));
|
|
464
482
|
|
|
@@ -1385,6 +1403,7 @@ Schema.prototype.indexedPaths = function indexedPaths() {
|
|
|
1385
1403
|
* Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path.
|
|
1386
1404
|
*
|
|
1387
1405
|
* #### Example:
|
|
1406
|
+
*
|
|
1388
1407
|
* const s = new Schema({ name: String, nested: { foo: String } });
|
|
1389
1408
|
* s.virtual('foo').get(() => 42);
|
|
1390
1409
|
* s.pathType('name'); // "real"
|
|
@@ -1849,7 +1868,7 @@ Schema.prototype.index = function(fields, options) {
|
|
|
1849
1868
|
*
|
|
1850
1869
|
* @param {String} key The name of the option to set the value to
|
|
1851
1870
|
* @param {Object} [value] The value to set the option to, if not passed, the option will be reset to default
|
|
1852
|
-
* @see Schema
|
|
1871
|
+
* @see Schema #schema_Schema
|
|
1853
1872
|
* @api public
|
|
1854
1873
|
*/
|
|
1855
1874
|
|
package/lib/schematype.js
CHANGED
|
@@ -1110,7 +1110,7 @@ SchemaType.prototype.ref = function(ref) {
|
|
|
1110
1110
|
* @api private
|
|
1111
1111
|
*/
|
|
1112
1112
|
|
|
1113
|
-
SchemaType.prototype.getDefault = function(scope, init) {
|
|
1113
|
+
SchemaType.prototype.getDefault = function(scope, init, options) {
|
|
1114
1114
|
let ret;
|
|
1115
1115
|
if (typeof this.defaultValue === 'function') {
|
|
1116
1116
|
if (
|
|
@@ -1131,6 +1131,10 @@ SchemaType.prototype.getDefault = function(scope, init) {
|
|
|
1131
1131
|
ret = utils.clone(ret);
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
|
+
if (options && options.skipCast) {
|
|
1135
|
+
return this._applySetters(ret, scope);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1134
1138
|
const casted = this.applySetters(ret, scope, init, undefined, setOptionsForDefaults);
|
|
1135
1139
|
if (casted && !Array.isArray(casted) && casted.$isSingleNested) {
|
|
1136
1140
|
casted.$__parent = scope;
|
package/lib/statemachine.js
CHANGED
|
@@ -38,19 +38,12 @@ StateMachine.ctor = function() {
|
|
|
38
38
|
StateMachine.apply(this, arguments);
|
|
39
39
|
this.paths = {};
|
|
40
40
|
this.states = {};
|
|
41
|
-
this.stateNames = states;
|
|
42
|
-
|
|
43
|
-
let i = states.length,
|
|
44
|
-
state;
|
|
45
|
-
|
|
46
|
-
while (i--) {
|
|
47
|
-
state = states[i];
|
|
48
|
-
this.states[state] = {};
|
|
49
|
-
}
|
|
50
41
|
};
|
|
51
42
|
|
|
52
43
|
ctor.prototype = new StateMachine();
|
|
53
44
|
|
|
45
|
+
ctor.prototype.stateNames = states;
|
|
46
|
+
|
|
54
47
|
states.forEach(function(state) {
|
|
55
48
|
// Changes the `path`'s state to `state`.
|
|
56
49
|
ctor.prototype[state] = function(path) {
|
|
@@ -76,6 +69,7 @@ StateMachine.prototype._changeState = function _changeState(path, nextState) {
|
|
|
76
69
|
if (prevBucket) delete prevBucket[path];
|
|
77
70
|
|
|
78
71
|
this.paths[path] = nextState;
|
|
72
|
+
this.states[nextState] = this.states[nextState] || {};
|
|
79
73
|
this.states[nextState][path] = true;
|
|
80
74
|
};
|
|
81
75
|
|
|
@@ -84,6 +78,9 @@ StateMachine.prototype._changeState = function _changeState(path, nextState) {
|
|
|
84
78
|
*/
|
|
85
79
|
|
|
86
80
|
StateMachine.prototype.clear = function clear(state) {
|
|
81
|
+
if (this.states[state] == null) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
87
84
|
const keys = Object.keys(this.states[state]);
|
|
88
85
|
let i = keys.length;
|
|
89
86
|
let path;
|
|
@@ -108,6 +105,17 @@ StateMachine.prototype.clearPath = function clearPath(path) {
|
|
|
108
105
|
delete this.states[state][path];
|
|
109
106
|
};
|
|
110
107
|
|
|
108
|
+
/*!
|
|
109
|
+
* Gets the paths for the given state, or empty object `{}` if none.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
StateMachine.prototype.getStatePaths = function getStatePaths(state) {
|
|
113
|
+
if (this.states[state] != null) {
|
|
114
|
+
return this.states[state];
|
|
115
|
+
}
|
|
116
|
+
return {};
|
|
117
|
+
};
|
|
118
|
+
|
|
111
119
|
/*!
|
|
112
120
|
* Checks to see if at least one path is in the states passed in via `arguments`
|
|
113
121
|
* e.g., this.some('required', 'inited')
|
|
@@ -120,6 +128,9 @@ StateMachine.prototype.some = function some() {
|
|
|
120
128
|
const _this = this;
|
|
121
129
|
const what = arguments.length ? arguments : this.stateNames;
|
|
122
130
|
return Array.prototype.some.call(what, function(state) {
|
|
131
|
+
if (_this.states[state] == null) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
123
134
|
return Object.keys(_this.states[state]).length;
|
|
124
135
|
});
|
|
125
136
|
};
|
|
@@ -143,6 +154,9 @@ StateMachine.prototype._iter = function _iter(iterMethod) {
|
|
|
143
154
|
const _this = this;
|
|
144
155
|
|
|
145
156
|
const paths = states.reduce(function(paths, state) {
|
|
157
|
+
if (_this.states[state] == null) {
|
|
158
|
+
return paths;
|
|
159
|
+
}
|
|
146
160
|
return paths.concat(Object.keys(_this.states[state]));
|
|
147
161
|
}, []);
|
|
148
162
|
|
package/lib/types/buffer.js
CHANGED
|
@@ -142,30 +142,32 @@ MongooseBuffer.mixin = {
|
|
|
142
142
|
* Compile other Buffer methods marking this buffer as modified.
|
|
143
143
|
*/
|
|
144
144
|
|
|
145
|
-
(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
'
|
|
149
|
-
'
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
'
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
145
|
+
utils.each(
|
|
146
|
+
[
|
|
147
|
+
// node < 0.5
|
|
148
|
+
'writeUInt8', 'writeUInt16', 'writeUInt32', 'writeInt8', 'writeInt16', 'writeInt32',
|
|
149
|
+
'writeFloat', 'writeDouble', 'fill',
|
|
150
|
+
'utf8Write', 'binaryWrite', 'asciiWrite', 'set',
|
|
151
|
+
|
|
152
|
+
// node >= 0.5
|
|
153
|
+
'writeUInt16LE', 'writeUInt16BE', 'writeUInt32LE', 'writeUInt32BE',
|
|
154
|
+
'writeInt16LE', 'writeInt16BE', 'writeInt32LE', 'writeInt32BE', 'writeFloatLE', 'writeFloatBE', 'writeDoubleLE', 'writeDoubleBE']
|
|
155
|
+
, function(method) {
|
|
156
|
+
if (!Buffer.prototype[method]) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
MongooseBuffer.mixin[method] = function() {
|
|
160
|
+
const ret = Buffer.prototype[method].apply(this, arguments);
|
|
161
|
+
this._markModified();
|
|
162
|
+
return ret;
|
|
163
|
+
};
|
|
164
|
+
});
|
|
164
165
|
|
|
165
166
|
/**
|
|
166
167
|
* Converts this buffer to its Binary type representation.
|
|
167
168
|
*
|
|
168
169
|
* #### SubTypes:
|
|
170
|
+
*
|
|
169
171
|
* const bson = require('bson')
|
|
170
172
|
* bson.BSON_BINARY_SUBTYPE_DEFAULT
|
|
171
173
|
* bson.BSON_BINARY_SUBTYPE_FUNCTION
|
|
@@ -175,7 +177,7 @@ MongooseBuffer.mixin = {
|
|
|
175
177
|
* bson.BSON_BINARY_SUBTYPE_USER_DEFINED
|
|
176
178
|
* doc.buffer.toObject(bson.BSON_BINARY_SUBTYPE_USER_DEFINED);
|
|
177
179
|
*
|
|
178
|
-
* @see https://bsonspec.org/#/specification
|
|
180
|
+
* @see bsonspec https://bsonspec.org/#/specification
|
|
179
181
|
* @param {Hex} [subtype]
|
|
180
182
|
* @return {Binary}
|
|
181
183
|
* @api public
|
|
@@ -247,7 +249,7 @@ MongooseBuffer.mixin.equals = function(other) {
|
|
|
247
249
|
*
|
|
248
250
|
* doc.buffer.subtype(bson.BSON_BINARY_SUBTYPE_UUID);
|
|
249
251
|
*
|
|
250
|
-
* @see https://bsonspec.org/#/specification
|
|
252
|
+
* @see bsonspec https://bsonspec.org/#/specification
|
|
251
253
|
* @param {Hex} subtype
|
|
252
254
|
* @api public
|
|
253
255
|
* @method subtype
|
package/lib/types/map.js
CHANGED
|
@@ -68,6 +68,7 @@ class MongooseMap extends Map {
|
|
|
68
68
|
* ObjectIds as keys.
|
|
69
69
|
*
|
|
70
70
|
* #### Example:
|
|
71
|
+
*
|
|
71
72
|
* doc.myMap.set('test', 42); // works
|
|
72
73
|
* doc.myMap.set({ obj: 42 }, 42); // Throws "Mongoose maps only support string keys"
|
|
73
74
|
*
|
|
@@ -197,6 +198,7 @@ class MongooseMap extends Map {
|
|
|
197
198
|
* the `flattenMaps` option to convert this map to a POJO instead.
|
|
198
199
|
*
|
|
199
200
|
* #### Example:
|
|
201
|
+
*
|
|
200
202
|
* doc.myMap.toJSON() instanceof Map; // true
|
|
201
203
|
* doc.myMap.toJSON({ flattenMaps: true }) instanceof Map; // false
|
|
202
204
|
*
|
package/lib/utils.js
CHANGED
|
@@ -972,3 +972,11 @@ exports.errorToPOJO = function errorToPOJO(error) {
|
|
|
972
972
|
exports.warn = function warn(message) {
|
|
973
973
|
return process.emitWarning(message, { code: 'MONGOOSE' });
|
|
974
974
|
};
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
exports.injectTimestampsOption = function injectTimestampsOption(writeOperation, timestampsOption) {
|
|
978
|
+
if (timestampsOption == null) {
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
writeOperation.timestamps = timestampsOption;
|
|
982
|
+
};
|
package/lib/validoptions.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.5.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -19,18 +19,18 @@
|
|
|
19
19
|
],
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"bson": "^4.6.
|
|
22
|
+
"bson": "^4.6.5",
|
|
23
23
|
"kareem": "2.4.1",
|
|
24
|
-
"mongodb": "4.
|
|
24
|
+
"mongodb": "4.8.1",
|
|
25
25
|
"mpath": "0.9.0",
|
|
26
26
|
"mquery": "4.0.3",
|
|
27
27
|
"ms": "2.1.3",
|
|
28
28
|
"sift": "16.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/core": "7.18.
|
|
32
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
33
|
-
"@typescript-eslint/parser": "5.
|
|
31
|
+
"@babel/core": "7.18.10",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "5.32.0",
|
|
33
|
+
"@typescript-eslint/parser": "5.32.0",
|
|
34
34
|
"acquit": "1.2.1",
|
|
35
35
|
"acquit-ignore": "0.2.0",
|
|
36
36
|
"acquit-require": "0.1.1",
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"cheerio": "1.0.0-rc.12",
|
|
44
44
|
"crypto-browserify": "3.12.0",
|
|
45
45
|
"dox": "0.9.1",
|
|
46
|
-
"eslint": "8.
|
|
46
|
+
"eslint": "8.21.0",
|
|
47
47
|
"eslint-plugin-mocha-no-only": "1.1.1",
|
|
48
|
-
"highlight.js": "11.
|
|
48
|
+
"highlight.js": "11.6.0",
|
|
49
49
|
"lodash.isequal": "4.5.0",
|
|
50
50
|
"lodash.isequalwith": "4.4.0",
|
|
51
|
-
"marked": "4.0.
|
|
51
|
+
"marked": "4.0.18",
|
|
52
52
|
"mkdirp": "^1.0.4",
|
|
53
53
|
"mocha": "10.0.0",
|
|
54
54
|
"moment": "2.x",
|
|
55
|
-
"mongodb-memory-server": "8.
|
|
55
|
+
"mongodb-memory-server": "8.8.0",
|
|
56
56
|
"ncp": "^2.0.0",
|
|
57
57
|
"nyc": "15.1.0",
|
|
58
58
|
"pug": "3.0.2",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"tsd": "0.20.0",
|
|
65
65
|
"typescript": "4.7.4",
|
|
66
66
|
"uuid": "8.3.2",
|
|
67
|
-
"webpack": "5.
|
|
67
|
+
"webpack": "5.74.0"
|
|
68
68
|
},
|
|
69
69
|
"directories": {
|
|
70
70
|
"lib": "./lib/mongoose"
|
|
@@ -77,18 +77,18 @@
|
|
|
77
77
|
"docs:copy:tmp:legacy": "rimraf ./docs/5.x && ncp ./tmp ./docs/5.x",
|
|
78
78
|
"docs:checkout:gh-pages": "git checkout gh-pages",
|
|
79
79
|
"docs:checkout:legacy": "git checkout 5.x",
|
|
80
|
-
"docs:generate": "node website.js",
|
|
80
|
+
"docs:generate": "node ./scripts/website.js",
|
|
81
81
|
"docs:generate:search": "node docs/search.js",
|
|
82
82
|
"docs:merge:stable": "git merge master",
|
|
83
83
|
"docs:merge:legacy": "git merge 5.x",
|
|
84
84
|
"docs:test": "npm run docs:generate && npm run docs:generate:search",
|
|
85
|
-
"docs:view": "node
|
|
85
|
+
"docs:view": "node ./scripts/static.js",
|
|
86
86
|
"docs:prepare:publish:stable": "npm run docs:checkout:gh-pages && npm run docs:merge:stable && npm run docs:clean:stable && npm run docs:generate && npm run docs:generate:search",
|
|
87
87
|
"docs:prepare:publish:legacy": "npm run docs:checkout:legacy && npm run docs:merge:legacy && npm run docs:clean:stable && npm run docs:generate && npm run docs:copy:tmp && docs:checkout:gh-pages && docs:copy:tmp:legacy",
|
|
88
88
|
"lint": "eslint .",
|
|
89
89
|
"lint-js": "eslint . --ext .js",
|
|
90
90
|
"lint-ts": "eslint . --ext .ts",
|
|
91
|
-
"build-browser": "node build-browser.js",
|
|
91
|
+
"build-browser": "node ./scripts/build-browser.js",
|
|
92
92
|
"prepublishOnly": "npm run build-browser",
|
|
93
93
|
"release": "git pull && git push origin master --tags && npm publish",
|
|
94
94
|
"release-legacy": "git pull origin 5.x && git push origin 5.x --tags && npm publish --tag legacy",
|