mongoose 6.4.2 → 6.4.5
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/.eslintrc.json +2 -1
- package/lib/aggregate.js +3 -2
- package/lib/connection.js +9 -9
- package/lib/cursor/AggregationCursor.js +3 -2
- package/lib/cursor/QueryCursor.js +5 -4
- package/lib/document.js +48 -16
- package/lib/error/index.js +12 -12
- package/lib/error/messages.js +2 -2
- package/lib/helpers/query/castUpdate.js +4 -4
- package/lib/helpers/timestamps/setDocumentTimestamps.js +26 -0
- package/lib/helpers/timestamps/setupTimestamps.js +14 -18
- package/lib/helpers/topology/isAtlas.js +14 -9
- package/lib/index.js +6 -2
- package/lib/model.js +129 -170
- package/lib/options/SchemaArrayOptions.js +2 -2
- package/lib/options/SchemaBufferOptions.js +1 -1
- package/lib/options/SchemaDateOptions.js +3 -3
- package/lib/options/SchemaDocumentArrayOptions.js +2 -2
- package/lib/options/SchemaMapOptions.js +1 -1
- package/lib/options/SchemaNumberOptions.js +4 -4
- package/lib/options/SchemaObjectIdOptions.js +2 -2
- package/lib/options/SchemaStringOptions.js +8 -8
- package/lib/options/SchemaSubdocumentOptions.js +1 -1
- package/lib/options/SchemaTypeOptions.js +14 -14
- package/lib/options/VirtualOptions.js +11 -11
- package/lib/query.js +74 -71
- package/lib/schema/SubdocumentPath.js +10 -6
- package/lib/schema/array.js +3 -3
- package/lib/schema/boolean.js +5 -5
- package/lib/schema/buffer.js +2 -2
- package/lib/schema/date.js +2 -2
- package/lib/schema/decimal128.js +2 -2
- package/lib/schema/documentarray.js +12 -8
- package/lib/schema/mixed.js +2 -2
- package/lib/schema/number.js +2 -2
- package/lib/schema/objectid.js +2 -2
- package/lib/schema/string.js +2 -2
- package/lib/schema.js +69 -34
- package/lib/schematype.js +9 -10
- package/lib/types/DocumentArray/methods/index.js +1 -1
- package/lib/types/buffer.js +30 -28
- package/lib/types/decimal128.js +4 -4
- package/lib/types/map.js +70 -0
- package/lib/types/objectid.js +1 -1
- package/lib/types/subdocument.js +1 -1
- package/lib/virtualtype.js +5 -5
- package/package.json +15 -15
- package/types/expressions.d.ts +30 -10
- package/types/index.d.ts +10 -7
- package/types/indexes.d.ts +2 -2
- package/types/inferschematype.d.ts +26 -10
- package/types/models.d.ts +2 -1
- package/types/pipelinestage.d.ts +1 -1
- package/types/query.d.ts +6 -1
package/.eslintrc.json
CHANGED
package/lib/aggregate.js
CHANGED
|
@@ -481,7 +481,8 @@ Aggregate.prototype.sortByCount = function(arg) {
|
|
|
481
481
|
*
|
|
482
482
|
* @see $lookup https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/#pipe._S_lookup
|
|
483
483
|
* @param {Object} options to $lookup as described in the above link
|
|
484
|
-
* @return {Aggregate}
|
|
484
|
+
* @return {Aggregate}
|
|
485
|
+
* @api public
|
|
485
486
|
*/
|
|
486
487
|
|
|
487
488
|
Aggregate.prototype.lookup = function(options) {
|
|
@@ -1051,7 +1052,7 @@ Aggregate.prototype.catch = function(reject) {
|
|
|
1051
1052
|
* You do not need to call this function explicitly, the JavaScript runtime
|
|
1052
1053
|
* will call it for you.
|
|
1053
1054
|
*
|
|
1054
|
-
* #### Example
|
|
1055
|
+
* #### Example:
|
|
1055
1056
|
*
|
|
1056
1057
|
* const agg = Model.aggregate([{ $match: { age: { $gte: 25 } } }]);
|
|
1057
1058
|
* for await (const doc of agg) {
|
package/lib/connection.js
CHANGED
|
@@ -93,7 +93,7 @@ Connection.prototype.__proto__ = EventEmitter.prototype;
|
|
|
93
93
|
*
|
|
94
94
|
* Each state change emits its associated event name.
|
|
95
95
|
*
|
|
96
|
-
* #### Example
|
|
96
|
+
* #### Example:
|
|
97
97
|
*
|
|
98
98
|
* conn.on('connected', callback);
|
|
99
99
|
* conn.on('disconnected', callback);
|
|
@@ -193,7 +193,7 @@ Connection.prototype.collections;
|
|
|
193
193
|
/**
|
|
194
194
|
* The name of the database this connection points to.
|
|
195
195
|
*
|
|
196
|
-
* #### Example
|
|
196
|
+
* #### Example:
|
|
197
197
|
*
|
|
198
198
|
* mongoose.createConnection('mongodb://localhost:27017/mydb').name; // "mydb"
|
|
199
199
|
*
|
|
@@ -210,7 +210,7 @@ Connection.prototype.name;
|
|
|
210
210
|
* a map from model names to models. Contains all models that have been
|
|
211
211
|
* added to this connection using [`Connection#model()`](/docs/api/connection.html#connection_Connection-model).
|
|
212
212
|
*
|
|
213
|
-
* #### Example
|
|
213
|
+
* #### Example:
|
|
214
214
|
*
|
|
215
215
|
* const conn = mongoose.createConnection();
|
|
216
216
|
* const Test = conn.model('Test', mongoose.Schema({ name: String }));
|
|
@@ -230,7 +230,7 @@ Connection.prototype.models;
|
|
|
230
230
|
* A number identifier for this connection. Used for debugging when
|
|
231
231
|
* you have [multiple connections](/docs/connections.html#multiple_connections).
|
|
232
232
|
*
|
|
233
|
-
* #### Example
|
|
233
|
+
* #### Example:
|
|
234
234
|
*
|
|
235
235
|
* // The default connection has `id = 0`
|
|
236
236
|
* mongoose.connection.id; // 0
|
|
@@ -274,7 +274,7 @@ Object.defineProperty(Connection.prototype, 'plugins', {
|
|
|
274
274
|
* The host name portion of the URI. If multiple hosts, such as a replica set,
|
|
275
275
|
* this will contain the first host name in the URI
|
|
276
276
|
*
|
|
277
|
-
* #### Example
|
|
277
|
+
* #### Example:
|
|
278
278
|
*
|
|
279
279
|
* mongoose.createConnection('mongodb://localhost:27017/mydb').host; // "localhost"
|
|
280
280
|
*
|
|
@@ -294,7 +294,7 @@ Object.defineProperty(Connection.prototype, 'host', {
|
|
|
294
294
|
* The port portion of the URI. If multiple hosts, such as a replica set,
|
|
295
295
|
* this will contain the port from the first host name in the URI.
|
|
296
296
|
*
|
|
297
|
-
* #### Example
|
|
297
|
+
* #### Example:
|
|
298
298
|
*
|
|
299
299
|
* mongoose.createConnection('mongodb://localhost:27017/mydb').port; // 27017
|
|
300
300
|
*
|
|
@@ -313,7 +313,7 @@ Object.defineProperty(Connection.prototype, 'port', {
|
|
|
313
313
|
/**
|
|
314
314
|
* The username specified in the URI
|
|
315
315
|
*
|
|
316
|
-
* #### Example
|
|
316
|
+
* #### Example:
|
|
317
317
|
*
|
|
318
318
|
* mongoose.createConnection('mongodb://val:psw@localhost:27017/mydb').user; // "val"
|
|
319
319
|
*
|
|
@@ -332,7 +332,7 @@ Object.defineProperty(Connection.prototype, 'user', {
|
|
|
332
332
|
/**
|
|
333
333
|
* The password specified in the URI
|
|
334
334
|
*
|
|
335
|
-
* #### Example
|
|
335
|
+
* #### Example:
|
|
336
336
|
*
|
|
337
337
|
* mongoose.createConnection('mongodb://val:psw@localhost:27017/mydb').pass; // "psw"
|
|
338
338
|
*
|
|
@@ -1452,7 +1452,7 @@ Connection.prototype.setClient = function setClient(client) {
|
|
|
1452
1452
|
*
|
|
1453
1453
|
* @param {Object} options
|
|
1454
1454
|
* @param {Boolean} options.continueOnError `false` by default. If set to `true`, mongoose will not throw an error if one model syncing failed, and will return an object where the keys are the names of the models, and the values are the results/errors for each model.
|
|
1455
|
-
* @
|
|
1455
|
+
* @return {Promise} Returns a Promise, when the Promise resolves the value is a list of the dropped indexes.
|
|
1456
1456
|
*/
|
|
1457
1457
|
Connection.prototype.syncIndexes = async function syncIndexes(options = {}) {
|
|
1458
1458
|
const result = {};
|
|
@@ -107,7 +107,7 @@ if (Symbol.asyncIterator != null) {
|
|
|
107
107
|
* Registers a transform function which subsequently maps documents retrieved
|
|
108
108
|
* via the streams interface or `.next()`
|
|
109
109
|
*
|
|
110
|
-
* #### Example
|
|
110
|
+
* #### Example:
|
|
111
111
|
*
|
|
112
112
|
* // Map documents returned by `data` events
|
|
113
113
|
* Thing.
|
|
@@ -132,6 +132,7 @@ if (Symbol.asyncIterator != null) {
|
|
|
132
132
|
*
|
|
133
133
|
* @param {Function} fn
|
|
134
134
|
* @return {AggregationCursor}
|
|
135
|
+
* @memberOf AggregationCursor
|
|
135
136
|
* @api public
|
|
136
137
|
* @method map
|
|
137
138
|
*/
|
|
@@ -226,7 +227,7 @@ AggregationCursor.prototype.eachAsync = function(fn, opts, callback) {
|
|
|
226
227
|
* You do not need to call this function explicitly, the JavaScript runtime
|
|
227
228
|
* will call it for you.
|
|
228
229
|
*
|
|
229
|
-
* #### Example
|
|
230
|
+
* #### Example:
|
|
230
231
|
*
|
|
231
232
|
* // Async iterator without explicitly calling `cursor()`. Mongoose still
|
|
232
233
|
* // creates an AggregationCursor instance internally.
|
|
@@ -112,7 +112,7 @@ QueryCursor.prototype._read = function() {
|
|
|
112
112
|
* Registers a transform function which subsequently maps documents retrieved
|
|
113
113
|
* via the streams interface or `.next()`
|
|
114
114
|
*
|
|
115
|
-
* #### Example
|
|
115
|
+
* #### Example:
|
|
116
116
|
*
|
|
117
117
|
* // Map documents returned by `data` events
|
|
118
118
|
* Thing.
|
|
@@ -137,6 +137,7 @@ QueryCursor.prototype._read = function() {
|
|
|
137
137
|
*
|
|
138
138
|
* @param {Function} fn
|
|
139
139
|
* @return {QueryCursor}
|
|
140
|
+
* @memberOf QueryCursor
|
|
140
141
|
* @api public
|
|
141
142
|
* @method map
|
|
142
143
|
*/
|
|
@@ -211,7 +212,7 @@ QueryCursor.prototype.next = function(callback) {
|
|
|
211
212
|
* will wait for the promise to resolve before iterating on to the next one.
|
|
212
213
|
* Returns a promise that resolves when done.
|
|
213
214
|
*
|
|
214
|
-
* #### Example
|
|
215
|
+
* #### Example:
|
|
215
216
|
*
|
|
216
217
|
* // Iterate over documents asynchronously
|
|
217
218
|
* Thing.
|
|
@@ -300,7 +301,7 @@ QueryCursor.prototype._transformForAsyncIterator = function() {
|
|
|
300
301
|
* You do not need to call this function explicitly, the JavaScript runtime
|
|
301
302
|
* will call it for you.
|
|
302
303
|
*
|
|
303
|
-
* #### Example
|
|
304
|
+
* #### Example:
|
|
304
305
|
*
|
|
305
306
|
* // Works without using `cursor()`
|
|
306
307
|
* for await (const doc of Model.find([{ $sort: { name: 1 } }])) {
|
|
@@ -320,7 +321,7 @@ QueryCursor.prototype._transformForAsyncIterator = function() {
|
|
|
320
321
|
* support async iterators.
|
|
321
322
|
*
|
|
322
323
|
* @method Symbol.asyncIterator
|
|
323
|
-
* @memberOf
|
|
324
|
+
* @memberOf QueryCursor
|
|
324
325
|
* @instance
|
|
325
326
|
* @api public
|
|
326
327
|
*/
|
package/lib/document.js
CHANGED
|
@@ -300,7 +300,35 @@ Object.defineProperty(Document.prototype, '$locals', {
|
|
|
300
300
|
|
|
301
301
|
|
|
302
302
|
/**
|
|
303
|
-
* Boolean flag specifying if the document is new.
|
|
303
|
+
* Boolean flag specifying if the document is new. If you create a document
|
|
304
|
+
* using `new`, this document will be considered "new". `$isNew` is how
|
|
305
|
+
* Mongoose determines whether `save()` should use `insertOne()` to create
|
|
306
|
+
* a new document or `updateOne()` to update an existing document.
|
|
307
|
+
*
|
|
308
|
+
* #### Example:
|
|
309
|
+
* const user = new User({ name: 'John Smith' });
|
|
310
|
+
* user.$isNew; // true
|
|
311
|
+
*
|
|
312
|
+
* await user.save(); // Sends an `insertOne` to MongoDB
|
|
313
|
+
*
|
|
314
|
+
* On the other hand, if you load an existing document from the database
|
|
315
|
+
* using `findOne()` or another [query operation](/docs/queries.html),
|
|
316
|
+
* `$isNew` will be false.
|
|
317
|
+
*
|
|
318
|
+
* #### Example:
|
|
319
|
+
* const user = await User.findOne({ name: 'John Smith' });
|
|
320
|
+
* user.$isNew; // false
|
|
321
|
+
*
|
|
322
|
+
* For subdocuments, `$isNew` is true if either the parent has `$isNew` set,
|
|
323
|
+
* or if you create a new subdocument.
|
|
324
|
+
*
|
|
325
|
+
* #### Example:
|
|
326
|
+
* // Assume `Group` has a document array `users`
|
|
327
|
+
* const group = await Group.findOne();
|
|
328
|
+
* group.users[0].$isNew; // false
|
|
329
|
+
*
|
|
330
|
+
* group.users.push({ name: 'John Smith' });
|
|
331
|
+
* group.users[1].$isNew; // true
|
|
304
332
|
*
|
|
305
333
|
* @api public
|
|
306
334
|
* @property $isNew
|
|
@@ -311,7 +339,7 @@ Object.defineProperty(Document.prototype, '$locals', {
|
|
|
311
339
|
Document.prototype.$isNew;
|
|
312
340
|
|
|
313
341
|
/**
|
|
314
|
-
*
|
|
342
|
+
* Legacy alias for `$isNew`.
|
|
315
343
|
*
|
|
316
344
|
* @api public
|
|
317
345
|
* @property isNew
|
|
@@ -1409,7 +1437,11 @@ Document.prototype.$set = function $set(path, val, type, options) {
|
|
|
1409
1437
|
// later in `$__set()` because we don't take `_doc` when we iterate through
|
|
1410
1438
|
// a single nested doc. That's to make sure we get the correct context.
|
|
1411
1439
|
// Otherwise we would double-call the setter, see gh-7196.
|
|
1412
|
-
|
|
1440
|
+
if (options != null && options.overwriteImmutable) {
|
|
1441
|
+
val = schema.applySetters(val, this, false, priorVal, { overwriteImmutable: true });
|
|
1442
|
+
} else {
|
|
1443
|
+
val = schema.applySetters(val, this, false, priorVal);
|
|
1444
|
+
}
|
|
1413
1445
|
}
|
|
1414
1446
|
|
|
1415
1447
|
if (Array.isArray(val) &&
|
|
@@ -1718,7 +1750,7 @@ Document.prototype.$__setValue = function(path, val) {
|
|
|
1718
1750
|
/**
|
|
1719
1751
|
* Returns the value of a path.
|
|
1720
1752
|
*
|
|
1721
|
-
* #### Example
|
|
1753
|
+
* #### Example:
|
|
1722
1754
|
*
|
|
1723
1755
|
* // path
|
|
1724
1756
|
* doc.get('age') // 47
|
|
@@ -1891,7 +1923,7 @@ Document.prototype.$ignore = function(path) {
|
|
|
1891
1923
|
* A path `a` may be in `modifiedPaths()` but not in `directModifiedPaths()`
|
|
1892
1924
|
* because a child of `a` was directly modified.
|
|
1893
1925
|
*
|
|
1894
|
-
* #### Example
|
|
1926
|
+
* #### Example:
|
|
1895
1927
|
* const schema = new Schema({ foo: String, nested: { bar: String } });
|
|
1896
1928
|
* const Model = mongoose.model('Test', schema);
|
|
1897
1929
|
* await Model.create({ foo: 'original', nested: { bar: 'original' } });
|
|
@@ -2047,7 +2079,7 @@ Document.prototype[documentModifiedPaths] = Document.prototype.modifiedPaths;
|
|
|
2047
2079
|
*
|
|
2048
2080
|
* If `path` is given, checks if a path or any full path containing `path` as part of its path chain has been modified.
|
|
2049
2081
|
*
|
|
2050
|
-
* #### Example
|
|
2082
|
+
* #### Example:
|
|
2051
2083
|
*
|
|
2052
2084
|
* doc.set('documents.0.title', 'changed');
|
|
2053
2085
|
* doc.isModified() // true
|
|
@@ -2093,7 +2125,7 @@ Document.prototype[documentIsModified] = Document.prototype.isModified;
|
|
|
2093
2125
|
/**
|
|
2094
2126
|
* Checks if a path is set to its default.
|
|
2095
2127
|
*
|
|
2096
|
-
* #### Example
|
|
2128
|
+
* #### Example:
|
|
2097
2129
|
*
|
|
2098
2130
|
* MyModel = mongoose.model('test', { name: { type: String, default: 'Val '} });
|
|
2099
2131
|
* const m = new MyModel();
|
|
@@ -2157,13 +2189,13 @@ Document.prototype.$isDeleted = function(val) {
|
|
|
2157
2189
|
/**
|
|
2158
2190
|
* Returns true if `path` was directly set and modified, else false.
|
|
2159
2191
|
*
|
|
2160
|
-
* #### Example
|
|
2192
|
+
* #### Example:
|
|
2161
2193
|
*
|
|
2162
2194
|
* doc.set('documents.0.title', 'changed');
|
|
2163
2195
|
* doc.isDirectModified('documents.0.title') // true
|
|
2164
2196
|
* doc.isDirectModified('documents') // false
|
|
2165
2197
|
*
|
|
2166
|
-
* @param {String|
|
|
2198
|
+
* @param {String|String[]} path
|
|
2167
2199
|
* @return {Boolean}
|
|
2168
2200
|
* @api public
|
|
2169
2201
|
*/
|
|
@@ -2213,13 +2245,13 @@ Document.prototype.isInit = function(path) {
|
|
|
2213
2245
|
/**
|
|
2214
2246
|
* Checks if `path` was selected in the source query which initialized this document.
|
|
2215
2247
|
*
|
|
2216
|
-
* #### Example
|
|
2248
|
+
* #### Example:
|
|
2217
2249
|
*
|
|
2218
2250
|
* const doc = await Thing.findOne().select('name');
|
|
2219
2251
|
* doc.isSelected('name') // true
|
|
2220
2252
|
* doc.isSelected('age') // false
|
|
2221
2253
|
*
|
|
2222
|
-
* @param {String|
|
|
2254
|
+
* @param {String|String[]} path
|
|
2223
2255
|
* @return {Boolean}
|
|
2224
2256
|
* @api public
|
|
2225
2257
|
*/
|
|
@@ -2294,7 +2326,7 @@ Document.prototype.$__isSelected = Document.prototype.isSelected;
|
|
|
2294
2326
|
* Checks if `path` was explicitly selected. If no projection, always returns
|
|
2295
2327
|
* true.
|
|
2296
2328
|
*
|
|
2297
|
-
* #### Example
|
|
2329
|
+
* #### Example:
|
|
2298
2330
|
*
|
|
2299
2331
|
* Thing.findOne().select('nested.name').exec(function (err, doc) {
|
|
2300
2332
|
* doc.isDirectSelected('nested.name') // true
|
|
@@ -3106,7 +3138,7 @@ function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
|
|
|
3106
3138
|
/**
|
|
3107
3139
|
* Checks if a path is invalid
|
|
3108
3140
|
*
|
|
3109
|
-
* @param {String|
|
|
3141
|
+
* @param {String|String[]} path the field to check
|
|
3110
3142
|
* @method $isValid
|
|
3111
3143
|
* @memberOf Document
|
|
3112
3144
|
* @instance
|
|
@@ -3636,7 +3668,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3636
3668
|
*
|
|
3637
3669
|
* schema.set('toObject', { virtuals: true })
|
|
3638
3670
|
*
|
|
3639
|
-
* #### Transform
|
|
3671
|
+
* #### Transform:
|
|
3640
3672
|
*
|
|
3641
3673
|
* We may need to perform a transformation of the resulting object based on some criteria, say to remove some sensitive information or return a custom object. In this case we set the optional `transform` function.
|
|
3642
3674
|
*
|
|
@@ -3648,7 +3680,7 @@ Document.prototype.$toObject = function(options, json) {
|
|
|
3648
3680
|
* - `ret` The plain object representation which has been converted
|
|
3649
3681
|
* - `options` The options in use (either schema options or the options passed inline)
|
|
3650
3682
|
*
|
|
3651
|
-
* #### Example
|
|
3683
|
+
* #### Example:
|
|
3652
3684
|
*
|
|
3653
3685
|
* // specify the transform schema option
|
|
3654
3686
|
* if (!schema.options.toObject) schema.options.toObject = {};
|
|
@@ -4338,7 +4370,7 @@ Document.prototype.$populated = Document.prototype.populated;
|
|
|
4338
4370
|
* doc.$assertPopulated('other path'); // throws an error
|
|
4339
4371
|
*
|
|
4340
4372
|
*
|
|
4341
|
-
* @param {String|
|
|
4373
|
+
* @param {String|String[]} path
|
|
4342
4374
|
* @return {Document} this
|
|
4343
4375
|
* @memberOf Document
|
|
4344
4376
|
* @method $assertPopulated
|
package/lib/error/index.js
CHANGED
|
@@ -56,7 +56,7 @@ module.exports = exports = MongooseError;
|
|
|
56
56
|
* @see Error.messages #error_messages_MongooseError-messages
|
|
57
57
|
* @api public
|
|
58
58
|
* @memberOf Error
|
|
59
|
-
* @static
|
|
59
|
+
* @static
|
|
60
60
|
*/
|
|
61
61
|
|
|
62
62
|
MongooseError.messages = require('./messages');
|
|
@@ -73,7 +73,7 @@ MongooseError.Messages = MongooseError.messages;
|
|
|
73
73
|
*
|
|
74
74
|
* @api public
|
|
75
75
|
* @memberOf Error
|
|
76
|
-
* @static
|
|
76
|
+
* @static
|
|
77
77
|
*/
|
|
78
78
|
|
|
79
79
|
MongooseError.DocumentNotFoundError = require('./notFound');
|
|
@@ -84,7 +84,7 @@ MongooseError.DocumentNotFoundError = require('./notFound');
|
|
|
84
84
|
*
|
|
85
85
|
* @api public
|
|
86
86
|
* @memberOf Error
|
|
87
|
-
* @static
|
|
87
|
+
* @static
|
|
88
88
|
*/
|
|
89
89
|
|
|
90
90
|
MongooseError.CastError = require('./cast');
|
|
@@ -96,7 +96,7 @@ MongooseError.CastError = require('./cast');
|
|
|
96
96
|
*
|
|
97
97
|
* @api public
|
|
98
98
|
* @memberOf Error
|
|
99
|
-
* @static
|
|
99
|
+
* @static
|
|
100
100
|
*/
|
|
101
101
|
|
|
102
102
|
MongooseError.ValidationError = require('./validation');
|
|
@@ -131,7 +131,7 @@ MongooseError.ValidationError = require('./validation');
|
|
|
131
131
|
*
|
|
132
132
|
* @api public
|
|
133
133
|
* @memberOf Error
|
|
134
|
-
* @static
|
|
134
|
+
* @static
|
|
135
135
|
*/
|
|
136
136
|
|
|
137
137
|
MongooseError.ValidatorError = require('./validator');
|
|
@@ -143,7 +143,7 @@ MongooseError.ValidatorError = require('./validator');
|
|
|
143
143
|
*
|
|
144
144
|
* @api public
|
|
145
145
|
* @memberOf Error
|
|
146
|
-
* @static
|
|
146
|
+
* @static
|
|
147
147
|
*/
|
|
148
148
|
|
|
149
149
|
MongooseError.VersionError = require('./version');
|
|
@@ -155,7 +155,7 @@ MongooseError.VersionError = require('./version');
|
|
|
155
155
|
*
|
|
156
156
|
* @api public
|
|
157
157
|
* @memberOf Error
|
|
158
|
-
* @static
|
|
158
|
+
* @static
|
|
159
159
|
*/
|
|
160
160
|
|
|
161
161
|
MongooseError.ParallelSaveError = require('./parallelSave');
|
|
@@ -166,7 +166,7 @@ MongooseError.ParallelSaveError = require('./parallelSave');
|
|
|
166
166
|
*
|
|
167
167
|
* @api public
|
|
168
168
|
* @memberOf Error
|
|
169
|
-
* @static
|
|
169
|
+
* @static
|
|
170
170
|
*/
|
|
171
171
|
|
|
172
172
|
MongooseError.OverwriteModelError = require('./overwriteModel');
|
|
@@ -176,7 +176,7 @@ MongooseError.OverwriteModelError = require('./overwriteModel');
|
|
|
176
176
|
*
|
|
177
177
|
* @api public
|
|
178
178
|
* @memberOf Error
|
|
179
|
-
* @static
|
|
179
|
+
* @static
|
|
180
180
|
*/
|
|
181
181
|
|
|
182
182
|
MongooseError.MissingSchemaError = require('./missingSchema');
|
|
@@ -187,7 +187,7 @@ MongooseError.MissingSchemaError = require('./missingSchema');
|
|
|
187
187
|
*
|
|
188
188
|
* @api public
|
|
189
189
|
* @memberOf Error
|
|
190
|
-
* @static
|
|
190
|
+
* @static
|
|
191
191
|
*/
|
|
192
192
|
|
|
193
193
|
MongooseError.MongooseServerSelectionError = require('./serverSelection');
|
|
@@ -198,7 +198,7 @@ MongooseError.MongooseServerSelectionError = require('./serverSelection');
|
|
|
198
198
|
*
|
|
199
199
|
* @api public
|
|
200
200
|
* @memberOf Error
|
|
201
|
-
* @static
|
|
201
|
+
* @static
|
|
202
202
|
*/
|
|
203
203
|
|
|
204
204
|
MongooseError.DivergentArrayError = require('./divergentArray');
|
|
@@ -210,7 +210,7 @@ MongooseError.DivergentArrayError = require('./divergentArray');
|
|
|
210
210
|
*
|
|
211
211
|
* @api public
|
|
212
212
|
* @memberOf Error
|
|
213
|
-
* @static
|
|
213
|
+
* @static
|
|
214
214
|
*/
|
|
215
215
|
|
|
216
216
|
MongooseError.StrictModeError = require('./strict');
|
package/lib/error/messages.js
CHANGED
|
@@ -155,12 +155,12 @@ function castPipelineOperator(op, val) {
|
|
|
155
155
|
* according to its schema.
|
|
156
156
|
*
|
|
157
157
|
* @param {Schema} schema
|
|
158
|
-
* @param {Object} obj
|
|
159
|
-
* @param {String} op
|
|
158
|
+
* @param {Object} obj part of a query
|
|
159
|
+
* @param {String} op the atomic operator ($pull, $set, etc)
|
|
160
160
|
* @param {Object} options
|
|
161
161
|
* @param {Boolean|String} [options.strict]
|
|
162
162
|
* @param {Query} context
|
|
163
|
-
* @param {String} pref
|
|
163
|
+
* @param {String} pref path prefix (internal only)
|
|
164
164
|
* @return {Bool} true if this path has keys to update
|
|
165
165
|
* @api private
|
|
166
166
|
*/
|
|
@@ -451,7 +451,7 @@ const overwriteOps = {
|
|
|
451
451
|
*
|
|
452
452
|
* @param {SchemaType} schema
|
|
453
453
|
* @param {Object} val
|
|
454
|
-
* @param {String} op
|
|
454
|
+
* @param {String} op the atomic operator ($pull, $set, etc)
|
|
455
455
|
* @param {String} $conditional
|
|
456
456
|
* @param {Query} context
|
|
457
457
|
* @api private
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function setDocumentTimestamps(doc, timestampOption, currentTime, createdAt, updatedAt) {
|
|
4
|
+
const skipUpdatedAt = timestampOption != null && timestampOption.updatedAt === false;
|
|
5
|
+
const skipCreatedAt = timestampOption != null && timestampOption.createdAt === false;
|
|
6
|
+
|
|
7
|
+
const defaultTimestamp = currentTime != null ?
|
|
8
|
+
currentTime() :
|
|
9
|
+
doc.ownerDocument().constructor.base.now();
|
|
10
|
+
|
|
11
|
+
if (!skipCreatedAt &&
|
|
12
|
+
(doc.isNew || doc.$isSubdocument) &&
|
|
13
|
+
createdAt &&
|
|
14
|
+
!doc.$__getValue(createdAt) &&
|
|
15
|
+
doc.$__isSelected(createdAt)) {
|
|
16
|
+
doc.$set(createdAt, defaultTimestamp, undefined, { overwriteImmutable: true });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!skipUpdatedAt && updatedAt && (doc.isNew || doc.$isModified())) {
|
|
20
|
+
let ts = defaultTimestamp;
|
|
21
|
+
if (doc.isNew && createdAt != null) {
|
|
22
|
+
ts = doc.$__getValue(createdAt);
|
|
23
|
+
}
|
|
24
|
+
doc.$set(updatedAt, ts);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -4,6 +4,7 @@ const applyTimestampsToChildren = require('../update/applyTimestampsToChildren')
|
|
|
4
4
|
const applyTimestampsToUpdate = require('../update/applyTimestampsToUpdate');
|
|
5
5
|
const get = require('../get');
|
|
6
6
|
const handleTimestampOption = require('../schema/handleTimestampOption');
|
|
7
|
+
const setDocumentTimestamps = require('./setDocumentTimestamps');
|
|
7
8
|
const symbols = require('../../schema/symbols');
|
|
8
9
|
|
|
9
10
|
module.exports = function setupTimestamps(schema, timestamps) {
|
|
@@ -44,24 +45,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
44
45
|
return next();
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
const skipCreatedAt = timestampOption != null && timestampOption.createdAt === false;
|
|
49
|
-
|
|
50
|
-
const defaultTimestamp = currentTime != null ?
|
|
51
|
-
currentTime() :
|
|
52
|
-
this.ownerDocument().constructor.base.now();
|
|
53
|
-
|
|
54
|
-
if (!skipCreatedAt && (this.isNew || this.$isSubdocument) && createdAt && !this.$__getValue(createdAt) && this.$__isSelected(createdAt)) {
|
|
55
|
-
this.$set(createdAt, defaultTimestamp, undefined, { overwriteImmutable: true });
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!skipUpdatedAt && updatedAt && (this.isNew || this.$isModified())) {
|
|
59
|
-
let ts = defaultTimestamp;
|
|
60
|
-
if (this.isNew && createdAt != null) {
|
|
61
|
-
ts = this.$__getValue(createdAt);
|
|
62
|
-
}
|
|
63
|
-
this.$set(updatedAt, ts);
|
|
64
|
-
}
|
|
48
|
+
setDocumentTimestamps(this, timestampOption, currentTime, createdAt, updatedAt);
|
|
65
49
|
|
|
66
50
|
next();
|
|
67
51
|
});
|
|
@@ -76,6 +60,18 @@ module.exports = function setupTimestamps(schema, timestamps) {
|
|
|
76
60
|
if (updatedAt && !this.get(updatedAt)) {
|
|
77
61
|
this.$set(updatedAt, ts);
|
|
78
62
|
}
|
|
63
|
+
|
|
64
|
+
if (this.$isSubdocument) {
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const subdocs = this.$getAllSubdocs();
|
|
69
|
+
for (const subdoc of subdocs) {
|
|
70
|
+
if (subdoc.initializeTimestamps) {
|
|
71
|
+
subdoc.initializeTimestamps();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
79
75
|
return this;
|
|
80
76
|
};
|
|
81
77
|
|
|
@@ -2,25 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
const getConstructorName = require('../getConstructorName');
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @typedef { import('mongodb').TopologyDescription } TopologyDescription
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Checks if topologyDescription contains servers connected to an atlas instance
|
|
11
|
+
*
|
|
12
|
+
* @param {TopologyDescription} topologyDescription
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
5
15
|
module.exports = function isAtlas(topologyDescription) {
|
|
6
16
|
if (getConstructorName(topologyDescription) !== 'TopologyDescription') {
|
|
7
17
|
return false;
|
|
8
18
|
}
|
|
9
19
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (hostnames.length === 0) {
|
|
20
|
+
if (topologyDescription.servers.size === 0) {
|
|
13
21
|
return false;
|
|
14
22
|
}
|
|
15
23
|
|
|
16
|
-
for (
|
|
17
|
-
|
|
18
|
-
if (
|
|
19
|
-
url.hostname.endsWith('.mongodb.net') === false ||
|
|
20
|
-
url.port !== '27017'
|
|
21
|
-
) {
|
|
24
|
+
for (const server of topologyDescription.servers.values()) {
|
|
25
|
+
if (server.host.endsWith('.mongodb.net') === false || server.port !== 27017) {
|
|
22
26
|
return false;
|
|
23
27
|
}
|
|
24
28
|
}
|
|
29
|
+
|
|
25
30
|
return true;
|
|
26
31
|
};
|
package/lib/index.js
CHANGED
|
@@ -172,6 +172,7 @@ Mongoose.prototype.setDriver = function setDriver(driver) {
|
|
|
172
172
|
|
|
173
173
|
const Connection = driver.getConnection();
|
|
174
174
|
_mongoose.connections = [new Connection(_mongoose)];
|
|
175
|
+
_mongoose.connections[0].models = _mongoose.models;
|
|
175
176
|
|
|
176
177
|
return _mongoose;
|
|
177
178
|
};
|
|
@@ -203,6 +204,7 @@ Mongoose.prototype.setDriver = function setDriver(driver) {
|
|
|
203
204
|
* - 'overwriteModels': Set to `true` to default to overwriting models with the same name when calling `mongoose.model()`, as opposed to throwing an `OverwriteModelError`.
|
|
204
205
|
* - 'returnOriginal': If `false`, changes the default `returnOriginal` option to `findOneAndUpdate()`, `findByIdAndUpdate`, and `findOneAndReplace()` to false. This is equivalent to setting the `new` option to `true` for `findOneAndX()` calls by default. Read our [`findOneAndUpdate()` tutorial](/docs/tutorials/findoneandupdate.html) for more information.
|
|
205
206
|
* - 'runValidators': `false` by default. Set to true to enable [update validators](/docs/validation.html#update-validators) for all validators by default.
|
|
207
|
+
* - 'sanitizeFilter': `false` by default. Set to true to enable the [sanitization of the query filters](/docs/api.html#mongoose_Mongoose-sanitizeFilter) against query selector injection attacks by wrapping any nested objects that have a property whose name starts with `$` in a `$eq`.
|
|
206
208
|
* - 'selectPopulatedPaths': `true` by default. Set to false to opt out of Mongoose adding all fields that you `populate()` to your `select()`. The schema-level option `selectPopulatedPaths` overwrites this one.
|
|
207
209
|
* - 'strict': `true` by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
|
|
208
210
|
* - 'strictQuery': same value as 'strict' by default (`true`), may be `false`, `true`, or `'throw'`. Sets the default [strictQuery](/docs/guide.html#strictQuery) mode for schemas.
|
|
@@ -761,6 +763,8 @@ Mongoose.prototype.Aggregate = Aggregate;
|
|
|
761
763
|
/**
|
|
762
764
|
* The Mongoose Collection constructor
|
|
763
765
|
*
|
|
766
|
+
* @memberOf Mongoose
|
|
767
|
+
* @instance
|
|
764
768
|
* @method Collection
|
|
765
769
|
* @api public
|
|
766
770
|
*/
|
|
@@ -799,7 +803,7 @@ Object.defineProperty(Mongoose.prototype, 'Connection', {
|
|
|
799
803
|
/**
|
|
800
804
|
* The Mongoose version
|
|
801
805
|
*
|
|
802
|
-
* #### Example
|
|
806
|
+
* #### Example:
|
|
803
807
|
*
|
|
804
808
|
* console.log(mongoose.version); // '5.x.x'
|
|
805
809
|
*
|
|
@@ -1044,7 +1048,7 @@ Mongoose.prototype.isObjectIdOrHexString = function(v) {
|
|
|
1044
1048
|
*
|
|
1045
1049
|
* @param {Object} options
|
|
1046
1050
|
* @param {Boolean} options.continueOnError `false` by default. If set to `true`, mongoose will not throw an error if one model syncing failed, and will return an object where the keys are the names of the models, and the values are the results/errors for each model.
|
|
1047
|
-
* @
|
|
1051
|
+
* @return {Promise} Returns a Promise, when the Promise resolves the value is a list of the dropped indexes.
|
|
1048
1052
|
*/
|
|
1049
1053
|
Mongoose.prototype.syncIndexes = function(options) {
|
|
1050
1054
|
const _mongoose = this instanceof Mongoose ? this : mongoose;
|