mongoose 6.3.7 → 6.4.0
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 +61 -34
- package/lib/connection.js +50 -9
- package/lib/document.js +55 -18
- package/lib/error/disconnected.js +3 -4
- package/lib/helpers/schematype/handleImmutable.js +1 -2
- package/lib/helpers/timestamps/setupTimestamps.js +4 -1
- package/lib/helpers/updateValidators.js +11 -18
- package/lib/index.js +108 -33
- package/lib/model.js +1 -1
- package/lib/query.js +61 -6
- package/lib/schema/SubdocumentPath.js +1 -1
- package/lib/schema/documentarray.js +14 -2
- package/lib/schema.js +3 -4
- package/lib/schematype.js +0 -1
- package/lib/statemachine.js +13 -0
- package/lib/utils.js +3 -0
- package/lib/validoptions.js +1 -0
- package/package.json +3 -3
- package/tsconfig.json +1 -0
- package/types/aggregate.d.ts +3 -0
- package/types/connection.d.ts +5 -0
- package/types/document.d.ts +5 -2
- package/types/expressions.d.ts +2880 -0
- package/types/index.d.ts +43 -14
- package/types/inferschematype.d.ts +155 -0
- package/types/models.d.ts +84 -69
- package/types/mongooseoptions.d.ts +8 -0
- package/types/pipelinestage.d.ts +76 -80
- package/types/query.d.ts +1 -1
- package/types/schemaoptions.d.ts +21 -3
- package/types/utility.d.ts +2 -0
package/lib/index.js
CHANGED
|
@@ -8,6 +8,7 @@ require('./driver').set(require('./drivers/node-mongodb-native'));
|
|
|
8
8
|
|
|
9
9
|
const Document = require('./document');
|
|
10
10
|
const EventEmitter = require('events').EventEmitter;
|
|
11
|
+
const Kareem = require('kareem');
|
|
11
12
|
const Schema = require('./schema');
|
|
12
13
|
const SchemaType = require('./schematype');
|
|
13
14
|
const SchemaTypes = require('./schema/index');
|
|
@@ -35,6 +36,7 @@ const shardingPlugin = require('./plugins/sharding');
|
|
|
35
36
|
const trusted = require('./helpers/query/trusted').trusted;
|
|
36
37
|
const sanitizeFilter = require('./helpers/query/sanitizeFilter');
|
|
37
38
|
const isBsonType = require('./helpers/isBsonType');
|
|
39
|
+
const MongooseError = require('./error/mongooseError');
|
|
38
40
|
|
|
39
41
|
const defaultMongooseSymbol = Symbol.for('mongoose:default');
|
|
40
42
|
|
|
@@ -62,6 +64,7 @@ function Mongoose(options) {
|
|
|
62
64
|
this.connections = [];
|
|
63
65
|
this.models = {};
|
|
64
66
|
this.events = new EventEmitter();
|
|
67
|
+
this.__driver = driver.get();
|
|
65
68
|
// default global options
|
|
66
69
|
this.options = Object.assign({
|
|
67
70
|
pluralization: true,
|
|
@@ -135,6 +138,7 @@ Mongoose.prototype.ConnectionStates = STATES;
|
|
|
135
138
|
* uses to communicate with the database. A driver is a Mongoose-specific interface that defines functions
|
|
136
139
|
* like `find()`.
|
|
137
140
|
*
|
|
141
|
+
* @deprecated
|
|
138
142
|
* @memberOf Mongoose
|
|
139
143
|
* @property driver
|
|
140
144
|
* @api public
|
|
@@ -142,6 +146,36 @@ Mongoose.prototype.ConnectionStates = STATES;
|
|
|
142
146
|
|
|
143
147
|
Mongoose.prototype.driver = driver;
|
|
144
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Overwrites the current driver used by this Mongoose instance. A driver is a
|
|
151
|
+
* Mongoose-specific interface that defines functions like `find()`.
|
|
152
|
+
*
|
|
153
|
+
* @memberOf Mongoose
|
|
154
|
+
* @method setDriver
|
|
155
|
+
* @api public
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
Mongoose.prototype.setDriver = function setDriver(driver) {
|
|
159
|
+
const _mongoose = this instanceof Mongoose ? this : mongoose;
|
|
160
|
+
|
|
161
|
+
if (_mongoose.__driver === driver) {
|
|
162
|
+
return _mongoose;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const openConnection = _mongoose.connections && _mongoose.connections.find(conn => conn.readyState !== STATES.disconnected);
|
|
166
|
+
if (openConnection) {
|
|
167
|
+
const msg = 'Cannot modify Mongoose driver if a connection is already open. ' +
|
|
168
|
+
'Call `mongoose.disconnect()` before modifying the driver';
|
|
169
|
+
throw new MongooseError(msg);
|
|
170
|
+
}
|
|
171
|
+
_mongoose.__driver = driver;
|
|
172
|
+
|
|
173
|
+
const Connection = driver.getConnection();
|
|
174
|
+
_mongoose.connections = [new Connection(_mongoose)];
|
|
175
|
+
|
|
176
|
+
return _mongoose;
|
|
177
|
+
};
|
|
178
|
+
|
|
145
179
|
/**
|
|
146
180
|
* Sets mongoose options
|
|
147
181
|
*
|
|
@@ -154,23 +188,26 @@ Mongoose.prototype.driver = driver;
|
|
|
154
188
|
* mongoose.set('debug', function(collectionName, methodName, ...methodArgs) {}); // use custom function to log collection methods + arguments
|
|
155
189
|
*
|
|
156
190
|
* Currently supported options are:
|
|
191
|
+
* - 'applyPluginsToChildSchemas': `true` by default. Set to false to skip applying global plugins to child schemas
|
|
192
|
+
* - 'applyPluginsToDiscriminators': `false` by default. Set to true to apply global plugins to discriminator schemas. This typically isn't necessary because plugins are applied to the base schema and discriminators copy all middleware, methods, statics, and properties from the base schema.
|
|
193
|
+
* - 'autoCreate': Set to `true` to make Mongoose call [`Model.createCollection()`](/docs/api/model.html#model_Model.createCollection) automatically when you create a model with `mongoose.model()` or `conn.model()`. This is useful for testing transactions, change streams, and other features that require the collection to exist.
|
|
194
|
+
* - 'autoIndex': `true` by default. Set to false to disable automatic index creation for all models associated with this Mongoose instance.
|
|
157
195
|
* - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arguments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
|
|
158
196
|
* - '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.
|
|
159
197
|
* - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models
|
|
160
|
-
* - 'cloneSchemas': false by default. Set to `true` to `clone()` all schemas before compiling into a model.
|
|
161
|
-
* - '
|
|
162
|
-
* - '
|
|
163
|
-
* - 'objectIdGetter': true by default. Mongoose adds a getter to MongoDB ObjectId's called `_id` that returns `this` for convenience with populate. Set this to false to remove the getter.
|
|
164
|
-
* - 'runValidators': false by default. Set to true to enable [update validators](/docs/validation.html#update-validators) for all validators by default.
|
|
165
|
-
* - 'toObject': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toObject()`](/docs/api.html#document_Document-toObject)
|
|
166
|
-
* - 'toJSON': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toJSON()`](/docs/api.html#document_Document-toJSON), for determining how Mongoose documents get serialized by `JSON.stringify()`
|
|
167
|
-
* - 'strict': true by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
|
|
168
|
-
* - '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.
|
|
169
|
-
* - '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.
|
|
198
|
+
* - 'cloneSchemas': `false` by default. Set to `true` to `clone()` all schemas before compiling into a model.
|
|
199
|
+
* - 'debug': If `true`, prints the operations mongoose sends to MongoDB to the console. If a writable stream is passed, it will log to that stream, without colorization. If a callback function is passed, it will receive the collection name, the method name, then all arugments passed to the method. For example, if you wanted to replicate the default logging, you could output from the callback `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
|
|
200
|
+
* - 'timestamps.createdAt.immutable': `true` by default. If `false`, it will change the `createdAt` field to be [`immutable: false`](https://mongoosejs.com/docs/api/schematype.html#schematype_SchemaType-immutable) which means you can update the `createdAt`
|
|
170
201
|
* - 'maxTimeMS': If set, attaches [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/) to every query
|
|
171
|
-
* - '
|
|
172
|
-
* - 'autoCreate': Set to `true` to make Mongoose call [`Model.createCollection()`](/docs/api/model.html#model_Model.createCollection) automatically when you create a model with `mongoose.model()` or `conn.model()`. This is useful for testing transactions, change streams, and other features that require the collection to exist.
|
|
202
|
+
* - 'objectIdGetter': `true` by default. Mongoose adds a getter to MongoDB ObjectId's called `_id` that returns `this` for convenience with populate. Set this to false to remove the getter.
|
|
173
203
|
* - 'overwriteModels': Set to `true` to default to overwriting models with the same name when calling `mongoose.model()`, as opposed to throwing an `OverwriteModelError`.
|
|
204
|
+
* - '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
|
+
* - 'runValidators': `false` by default. Set to true to enable [update validators](/docs/validation.html#update-validators) for all validators by default.
|
|
206
|
+
* - '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
|
+
* - 'strict': `true` by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
|
|
208
|
+
* - '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.
|
|
209
|
+
* - 'toJSON': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toJSON()`](/docs/api.html#document_Document-toJSON), for determining how Mongoose documents get serialized by `JSON.stringify()`
|
|
210
|
+
* - 'toObject': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toObject()`](/docs/api.html#document_Document-toObject)
|
|
174
211
|
*
|
|
175
212
|
* @param {String} key
|
|
176
213
|
* @param {String|Function|Boolean} value
|
|
@@ -260,8 +297,6 @@ Mongoose.prototype.get = Mongoose.prototype.set;
|
|
|
260
297
|
* @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
|
|
261
298
|
* @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
|
|
262
299
|
* @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
|
|
263
|
-
* @param {Number} [options.reconnectTries=30] If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect every `reconnectInterval` milliseconds for `reconnectTries` times, and give up afterward. When the driver gives up, the mongoose connection emits a `reconnectFailed` event. This option does nothing for replica set connections.
|
|
264
|
-
* @param {Number} [options.reconnectInterval=1000] See `reconnectTries` option above.
|
|
265
300
|
* @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
|
|
266
301
|
* @param {Number} [options.maxPoolSize=5] The maximum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](https://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
|
|
267
302
|
* @param {Number} [options.minPoolSize=1] The minimum number of sockets the MongoDB driver will keep open for this connection. Keep in mind that MongoDB only allows one operation per socket at a time, so you may want to increase this if you find you have a few slow queries that are blocking faster queries from proceeding. See [Slow Trains in MongoDB and Node.js](https://thecodebarbarian.com/slow-trains-in-mongodb-and-nodejs).
|
|
@@ -275,7 +310,7 @@ Mongoose.prototype.get = Mongoose.prototype.set;
|
|
|
275
310
|
Mongoose.prototype.createConnection = function(uri, options, callback) {
|
|
276
311
|
const _mongoose = this instanceof Mongoose ? this : mongoose;
|
|
277
312
|
|
|
278
|
-
const Connection =
|
|
313
|
+
const Connection = _mongoose.__driver.getConnection();
|
|
279
314
|
const conn = new Connection(_mongoose);
|
|
280
315
|
if (typeof options === 'function') {
|
|
281
316
|
callback = options;
|
|
@@ -323,8 +358,6 @@ Mongoose.prototype.createConnection = function(uri, options, callback) {
|
|
|
323
358
|
* @param {Number} [options.serverSelectionTimeoutMS] If `useUnifiedTopology = true`, the MongoDB driver will try to find a server to send any given operation to, and keep retrying for `serverSelectionTimeoutMS` milliseconds before erroring out. If not set, the MongoDB driver defaults to using `30000` (30 seconds).
|
|
324
359
|
* @param {Number} [options.heartbeatFrequencyMS] If `useUnifiedTopology = true`, the MongoDB driver sends a heartbeat every `heartbeatFrequencyMS` to check on the status of the connection. A heartbeat is subject to `serverSelectionTimeoutMS`, so the MongoDB driver will retry failed heartbeats for up to 30 seconds by default. Mongoose only emits a `'disconnected'` event after a heartbeat has failed, so you may want to decrease this setting to reduce the time between when your server goes down and when Mongoose emits `'disconnected'`. We recommend you do **not** set this setting below 1000, too many heartbeats can lead to performance degradation.
|
|
325
360
|
* @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
|
|
326
|
-
* @param {Number} [options.reconnectTries=30] If you're connected to a single server or mongos proxy (as opposed to a replica set), the MongoDB driver will try to reconnect every `reconnectInterval` milliseconds for `reconnectTries` times, and give up afterward. When the driver gives up, the mongoose connection emits a `reconnectFailed` event. This option does nothing for replica set connections.
|
|
327
|
-
* @param {Number} [options.reconnectInterval=1000] See `reconnectTries` option above.
|
|
328
361
|
* @param {Class} [options.promiseLibrary] Sets the [underlying driver's promise library](https://mongodb.github.io/node-mongodb-native/3.1/api/MongoClient.html).
|
|
329
362
|
* @param {Number} [options.connectTimeoutMS=30000] How long the MongoDB driver will wait before killing a socket due to inactivity _during initial connection_. Defaults to 30000. This option is passed transparently to [Node.js' `socket#setTimeout()` function](https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback).
|
|
330
363
|
* @param {Number} [options.socketTimeoutMS=30000] How long the MongoDB driver will wait before killing a socket due to inactivity _after initial connection_. A socket may be inactive because of either no activity or a long-running operation. This is set to `30000` by default, you should set this to 2-3x your longest running operation if you expect some of your database operations to run longer than 20 seconds. This option is passed to [Node.js `socket#setTimeout()` function](https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback) after the MongoDB driver successfully completes.
|
|
@@ -471,7 +504,6 @@ Mongoose.prototype.pluralize = function(fn) {
|
|
|
471
504
|
*/
|
|
472
505
|
|
|
473
506
|
Mongoose.prototype.model = function(name, schema, collection, options) {
|
|
474
|
-
|
|
475
507
|
const _mongoose = this instanceof Mongoose ? this : mongoose;
|
|
476
508
|
|
|
477
509
|
if (typeof schema === 'string') {
|
|
@@ -688,7 +720,7 @@ Mongoose.prototype.__defineGetter__('connection', function() {
|
|
|
688
720
|
});
|
|
689
721
|
|
|
690
722
|
Mongoose.prototype.__defineSetter__('connection', function(v) {
|
|
691
|
-
if (v instanceof
|
|
723
|
+
if (v instanceof this.__driver.getConnection()) {
|
|
692
724
|
this.connections[0] = v;
|
|
693
725
|
this.models = v.models;
|
|
694
726
|
}
|
|
@@ -717,18 +749,6 @@ Mongoose.prototype.__defineSetter__('connection', function(v) {
|
|
|
717
749
|
|
|
718
750
|
Mongoose.prototype.connections;
|
|
719
751
|
|
|
720
|
-
/*!
|
|
721
|
-
* Connection
|
|
722
|
-
*/
|
|
723
|
-
|
|
724
|
-
const Connection = driver.get().getConnection();
|
|
725
|
-
|
|
726
|
-
/*!
|
|
727
|
-
* Collection
|
|
728
|
-
*/
|
|
729
|
-
|
|
730
|
-
const Collection = driver.get().Collection;
|
|
731
|
-
|
|
732
752
|
/**
|
|
733
753
|
* The Mongoose Aggregate constructor
|
|
734
754
|
*
|
|
@@ -745,7 +765,14 @@ Mongoose.prototype.Aggregate = Aggregate;
|
|
|
745
765
|
* @api public
|
|
746
766
|
*/
|
|
747
767
|
|
|
748
|
-
Mongoose.prototype
|
|
768
|
+
Object.defineProperty(Mongoose.prototype, 'Collection', {
|
|
769
|
+
get: function() {
|
|
770
|
+
return this.__driver.Collection;
|
|
771
|
+
},
|
|
772
|
+
set: function(Collection) {
|
|
773
|
+
this.__driver.Collection = Collection;
|
|
774
|
+
}
|
|
775
|
+
});
|
|
749
776
|
|
|
750
777
|
/**
|
|
751
778
|
* The Mongoose [Connection](#connection_Connection) constructor
|
|
@@ -756,7 +783,18 @@ Mongoose.prototype.Collection = Collection;
|
|
|
756
783
|
* @api public
|
|
757
784
|
*/
|
|
758
785
|
|
|
759
|
-
Mongoose.prototype
|
|
786
|
+
Object.defineProperty(Mongoose.prototype, 'Connection', {
|
|
787
|
+
get: function() {
|
|
788
|
+
return this.__driver.getConnection();
|
|
789
|
+
},
|
|
790
|
+
set: function(Connection) {
|
|
791
|
+
if (Connection === this.__driver.getConnection()) {
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
this.__driver.getConnection = () => Connection;
|
|
796
|
+
}
|
|
797
|
+
});
|
|
760
798
|
|
|
761
799
|
/**
|
|
762
800
|
* The Mongoose version
|
|
@@ -1182,6 +1220,43 @@ Mongoose.prototype._promiseOrCallback = function(callback, fn, ee) {
|
|
|
1182
1220
|
return promiseOrCallback(callback, fn, ee, this.Promise);
|
|
1183
1221
|
};
|
|
1184
1222
|
|
|
1223
|
+
/**
|
|
1224
|
+
* Use this function in `pre()` middleware to skip calling the wrapped function.
|
|
1225
|
+
*
|
|
1226
|
+
* ####Example:
|
|
1227
|
+
*
|
|
1228
|
+
* schema.pre('save', function() {
|
|
1229
|
+
* // Will skip executing `save()`, but will execute post hooks as if
|
|
1230
|
+
* // `save()` had executed with the result `{ matchedCount: 0 }`
|
|
1231
|
+
* return mongoose.skipMiddlewareFunction({ matchedCount: 0 });
|
|
1232
|
+
* });
|
|
1233
|
+
*
|
|
1234
|
+
* @method skipMiddlewareFunction
|
|
1235
|
+
* @param {any} result
|
|
1236
|
+
* @api public
|
|
1237
|
+
*/
|
|
1238
|
+
|
|
1239
|
+
Mongoose.prototype.skipMiddlewareFunction = Kareem.skipWrappedFunction;
|
|
1240
|
+
|
|
1241
|
+
/**
|
|
1242
|
+
* Use this function in `post()` middleware to replace the result
|
|
1243
|
+
*
|
|
1244
|
+
* ####Example:
|
|
1245
|
+
*
|
|
1246
|
+
* schema.post('find', function(res) {
|
|
1247
|
+
* // Normally you have to modify `res` in place. But with
|
|
1248
|
+
* // `overwriteMiddlewarResult()`, you can make `find()` return a
|
|
1249
|
+
* // completely different value.
|
|
1250
|
+
* return mongoose.overwriteMiddlewareResult(res.filter(doc => !doc.isDeleted));
|
|
1251
|
+
* });
|
|
1252
|
+
*
|
|
1253
|
+
* @method overwriteMiddlewareResult
|
|
1254
|
+
* @param {any} result
|
|
1255
|
+
* @api public
|
|
1256
|
+
*/
|
|
1257
|
+
|
|
1258
|
+
Mongoose.prototype.overwriteMiddlewareResult = Kareem.overwriteResult;
|
|
1259
|
+
|
|
1185
1260
|
/*!
|
|
1186
1261
|
* The exports object is an instance of Mongoose.
|
|
1187
1262
|
*
|
package/lib/model.js
CHANGED
|
@@ -4281,7 +4281,7 @@ Model.validate = function validate(obj, pathsToValidate, context, callback) {
|
|
|
4281
4281
|
|
|
4282
4282
|
for (const path of paths) {
|
|
4283
4283
|
const schemaType = schema.path(path);
|
|
4284
|
-
if (!schemaType || !schemaType.$isMongooseArray) {
|
|
4284
|
+
if (!schemaType || !schemaType.$isMongooseArray || schemaType.$isMongooseDocumentArray) {
|
|
4285
4285
|
continue;
|
|
4286
4286
|
}
|
|
4287
4287
|
|
package/lib/query.js
CHANGED
|
@@ -27,6 +27,7 @@ const immediate = require('./helpers/immediate');
|
|
|
27
27
|
const isExclusive = require('./helpers/projection/isExclusive');
|
|
28
28
|
const isInclusive = require('./helpers/projection/isInclusive');
|
|
29
29
|
const isSubpath = require('./helpers/projection/isSubpath');
|
|
30
|
+
const mpath = require('mpath');
|
|
30
31
|
const mquery = require('mquery');
|
|
31
32
|
const parseProjection = require('./helpers/projection/parseProjection');
|
|
32
33
|
const removeUnusedArrayFilters = require('./helpers/update/removeUnusedArrayFilters');
|
|
@@ -2196,7 +2197,6 @@ function _castArrayFilters(query) {
|
|
|
2196
2197
|
* @api private
|
|
2197
2198
|
*/
|
|
2198
2199
|
Query.prototype._find = wrapThunk(function(callback) {
|
|
2199
|
-
|
|
2200
2200
|
this._castConditions();
|
|
2201
2201
|
|
|
2202
2202
|
if (this.error() != null) {
|
|
@@ -2220,7 +2220,8 @@ Query.prototype._find = wrapThunk(function(callback) {
|
|
|
2220
2220
|
// Separate options to pass down to `completeMany()` in case we need to
|
|
2221
2221
|
// set a session on the document
|
|
2222
2222
|
const completeManyOptions = Object.assign({}, {
|
|
2223
|
-
session: this && this.options && this.options.session || null
|
|
2223
|
+
session: this && this.options && this.options.session || null,
|
|
2224
|
+
lean: mongooseOptions.lean || null
|
|
2224
2225
|
});
|
|
2225
2226
|
|
|
2226
2227
|
const cb = (err, docs) => {
|
|
@@ -2244,7 +2245,9 @@ Query.prototype._find = wrapThunk(function(callback) {
|
|
|
2244
2245
|
});
|
|
2245
2246
|
}
|
|
2246
2247
|
return mongooseOptions.lean ?
|
|
2247
|
-
|
|
2248
|
+
// call _completeManyLean here?
|
|
2249
|
+
_completeManyLean(_this.model.schema, docs, null, completeManyOptions, callback) :
|
|
2250
|
+
// callback(null, docs) :
|
|
2248
2251
|
completeMany(_this.model, docs, fields, userProvidedFields, completeManyOptions, callback);
|
|
2249
2252
|
}
|
|
2250
2253
|
|
|
@@ -2418,6 +2421,9 @@ Query.prototype._completeOne = function(doc, res, callback) {
|
|
|
2418
2421
|
const mongooseOptions = this._mongooseOptions;
|
|
2419
2422
|
// `rawResult`
|
|
2420
2423
|
const options = this.options;
|
|
2424
|
+
if (!options.lean && mongooseOptions.lean) {
|
|
2425
|
+
options.lean = mongooseOptions.lean;
|
|
2426
|
+
}
|
|
2421
2427
|
|
|
2422
2428
|
if (options.explain) {
|
|
2423
2429
|
return callback(null, doc);
|
|
@@ -2431,7 +2437,7 @@ Query.prototype._completeOne = function(doc, res, callback) {
|
|
|
2431
2437
|
}
|
|
2432
2438
|
}
|
|
2433
2439
|
return mongooseOptions.lean ?
|
|
2434
|
-
_completeOneLean(doc, res, options, callback) :
|
|
2440
|
+
_completeOneLean(model.schema, doc, null, res, options, callback) :
|
|
2435
2441
|
completeOne(model, doc, res, options, projection, userProvidedFields,
|
|
2436
2442
|
null, callback);
|
|
2437
2443
|
}
|
|
@@ -2442,7 +2448,7 @@ Query.prototype._completeOne = function(doc, res, callback) {
|
|
|
2442
2448
|
if (err != null) {
|
|
2443
2449
|
return callback(err);
|
|
2444
2450
|
}
|
|
2445
|
-
_completeOneLean(doc, res, options, callback);
|
|
2451
|
+
_completeOneLean(model.schema, doc, null, res, options, callback);
|
|
2446
2452
|
});
|
|
2447
2453
|
}
|
|
2448
2454
|
|
|
@@ -4009,13 +4015,62 @@ Query.prototype._findAndModify = function(type, callback) {
|
|
|
4009
4015
|
* ignore
|
|
4010
4016
|
*/
|
|
4011
4017
|
|
|
4012
|
-
function _completeOneLean(doc, res, opts, callback) {
|
|
4018
|
+
function _completeOneLean(schema, doc, path, res, opts, callback) {
|
|
4019
|
+
if (opts.lean && opts.lean.transform) {
|
|
4020
|
+
for (let i = 0; i < schema.childSchemas.length; i++) {
|
|
4021
|
+
const childPath = path ? path + '.' + schema.childSchemas[i].model.path : schema.childSchemas[i].model.path;
|
|
4022
|
+
const _schema = schema.childSchemas[i].schema;
|
|
4023
|
+
const obj = mpath.get(childPath, doc);
|
|
4024
|
+
if (obj == null) {
|
|
4025
|
+
continue;
|
|
4026
|
+
}
|
|
4027
|
+
if (Array.isArray(obj)) {
|
|
4028
|
+
for (let i = 0; i < obj.length; i++) {
|
|
4029
|
+
opts.lean.transform(obj[i]);
|
|
4030
|
+
}
|
|
4031
|
+
} else {
|
|
4032
|
+
opts.lean.transform(obj);
|
|
4033
|
+
}
|
|
4034
|
+
_completeOneLean(_schema, obj, childPath, res, opts);
|
|
4035
|
+
}
|
|
4036
|
+
if (callback) {
|
|
4037
|
+
return callback(null, doc);
|
|
4038
|
+
} else {
|
|
4039
|
+
return;
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4013
4042
|
if (opts.rawResult) {
|
|
4014
4043
|
return callback(null, res);
|
|
4015
4044
|
}
|
|
4016
4045
|
return callback(null, doc);
|
|
4017
4046
|
}
|
|
4018
4047
|
|
|
4048
|
+
/*!
|
|
4049
|
+
* ignore
|
|
4050
|
+
*/
|
|
4051
|
+
|
|
4052
|
+
function _completeManyLean(schema, docs, path, opts, callback) {
|
|
4053
|
+
if (opts.lean && opts.lean.transform) {
|
|
4054
|
+
for (let i = 0; i < schema.childSchemas.length; i++) {
|
|
4055
|
+
const childPath = path ? path + '.' + schema.childSchemas[i].model.path : schema.childSchemas[i].model.path;
|
|
4056
|
+
const _schema = schema.childSchemas[i].schema;
|
|
4057
|
+
let doc = mpath.get(childPath, docs);
|
|
4058
|
+
if (doc == null) {
|
|
4059
|
+
continue;
|
|
4060
|
+
}
|
|
4061
|
+
doc = doc.flat();
|
|
4062
|
+
for (let i = 0; i < doc.length; i++) {
|
|
4063
|
+
opts.lean.transform(doc[i]);
|
|
4064
|
+
}
|
|
4065
|
+
_completeManyLean(_schema, doc, childPath, opts);
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
if (!callback) {
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4072
|
+
return callback(null, docs);
|
|
4073
|
+
}
|
|
4019
4074
|
/*!
|
|
4020
4075
|
* Override mquery.prototype._mergeUpdate to handle mongoose objects in
|
|
4021
4076
|
* updates.
|
|
@@ -167,7 +167,7 @@ SubdocumentPath.prototype.cast = function(val, doc, init, priorVal, options) {
|
|
|
167
167
|
}
|
|
168
168
|
return obj;
|
|
169
169
|
}, null);
|
|
170
|
-
options =
|
|
170
|
+
options = Object.assign({}, options, { priorDoc: priorVal });
|
|
171
171
|
if (init) {
|
|
172
172
|
subdoc = new Constructor(void 0, selected, doc);
|
|
173
173
|
subdoc.$init(val);
|
|
@@ -10,6 +10,7 @@ const EventEmitter = require('events').EventEmitter;
|
|
|
10
10
|
const SchemaDocumentArrayOptions =
|
|
11
11
|
require('../options/SchemaDocumentArrayOptions');
|
|
12
12
|
const SchemaType = require('../schematype');
|
|
13
|
+
const SubdocumentPath = require('./SubdocumentPath');
|
|
13
14
|
const discriminator = require('../helpers/model/discriminator');
|
|
14
15
|
const handleIdOption = require('../helpers/schema/handleIdOption');
|
|
15
16
|
const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
|
|
@@ -75,6 +76,15 @@ function DocumentArrayPath(key, schema, options, schemaOptions) {
|
|
|
75
76
|
this.$embeddedSchemaType.cast = function(value, doc, init) {
|
|
76
77
|
return parentSchemaType.cast(value, doc, init)[0];
|
|
77
78
|
};
|
|
79
|
+
this.$embeddedSchemaType.doValidate = function(value, fn, scope, options) {
|
|
80
|
+
const Constructor = getConstructor(this.caster, value);
|
|
81
|
+
|
|
82
|
+
if (value && !(value instanceof Constructor)) {
|
|
83
|
+
value = new Constructor(value, scope, null, null, options && options.index != null ? options.index : null);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return SubdocumentPath.prototype.doValidate.call(this, value, fn, scope, options);
|
|
87
|
+
};
|
|
78
88
|
this.$embeddedSchemaType.$isMongooseDocumentArrayElement = true;
|
|
79
89
|
this.$embeddedSchemaType.caster = this.Constructor;
|
|
80
90
|
this.$embeddedSchemaType.schema = this.schema;
|
|
@@ -391,6 +401,8 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
391
401
|
let selected;
|
|
392
402
|
let subdoc;
|
|
393
403
|
|
|
404
|
+
options = options || {};
|
|
405
|
+
|
|
394
406
|
if (!Array.isArray(value)) {
|
|
395
407
|
if (!init && !DocumentArrayPath.options.castNonArrays) {
|
|
396
408
|
throw new CastError('DocumentArray', value, this.path, null, this);
|
|
@@ -405,7 +417,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
405
417
|
|
|
406
418
|
// We need to create a new array, otherwise change tracking will
|
|
407
419
|
// update the old doc (gh-4449)
|
|
408
|
-
if (!options
|
|
420
|
+
if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
|
|
409
421
|
value = new MongooseDocumentArray(value, this.path, doc);
|
|
410
422
|
}
|
|
411
423
|
|
|
@@ -413,7 +425,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
413
425
|
value[arrayAtomicsSymbol] = prev[arrayAtomicsSymbol] || {};
|
|
414
426
|
}
|
|
415
427
|
|
|
416
|
-
if (options
|
|
428
|
+
if (options.arrayPathIndex != null) {
|
|
417
429
|
value[arrayPathSymbol] = this.path + '.' + options.arrayPathIndex;
|
|
418
430
|
}
|
|
419
431
|
|
package/lib/schema.js
CHANGED
|
@@ -107,11 +107,11 @@ function Schema(obj, options) {
|
|
|
107
107
|
this.inherits = {};
|
|
108
108
|
this.callQueue = [];
|
|
109
109
|
this._indexes = [];
|
|
110
|
-
this.methods = {};
|
|
110
|
+
this.methods = (options && options.methods) || {};
|
|
111
111
|
this.methodOptions = {};
|
|
112
|
-
this.statics = {};
|
|
112
|
+
this.statics = (options && options.statics) || {};
|
|
113
113
|
this.tree = {};
|
|
114
|
-
this.query = {};
|
|
114
|
+
this.query = (options && options.query) || {};
|
|
115
115
|
this.childSchemas = [];
|
|
116
116
|
this.plugins = [];
|
|
117
117
|
// For internal debugging. Do not use this to try to save a schema in MDB.
|
|
@@ -766,7 +766,6 @@ reserved['prototype'] =
|
|
|
766
766
|
// EventEmitter
|
|
767
767
|
reserved.emit =
|
|
768
768
|
reserved.listeners =
|
|
769
|
-
reserved.on =
|
|
770
769
|
reserved.removeListener =
|
|
771
770
|
|
|
772
771
|
// document properties and functions
|
package/lib/schematype.js
CHANGED
|
@@ -1181,7 +1181,6 @@ SchemaType.prototype._castNullish = function _castNullish(v) {
|
|
|
1181
1181
|
|
|
1182
1182
|
SchemaType.prototype.applySetters = function(value, scope, init, priorVal, options) {
|
|
1183
1183
|
let v = this._applySetters(value, scope, init, priorVal, options);
|
|
1184
|
-
|
|
1185
1184
|
if (v == null) {
|
|
1186
1185
|
return this._castNullish(v);
|
|
1187
1186
|
}
|
package/lib/statemachine.js
CHANGED
|
@@ -95,6 +95,19 @@ StateMachine.prototype.clear = function clear(state) {
|
|
|
95
95
|
}
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
+
/*!
|
|
99
|
+
* ignore
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
StateMachine.prototype.clearPath = function clearPath(path) {
|
|
103
|
+
const state = this.paths[path];
|
|
104
|
+
if (!state) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
delete this.paths[path];
|
|
108
|
+
delete this.states[state][path];
|
|
109
|
+
};
|
|
110
|
+
|
|
98
111
|
/*!
|
|
99
112
|
* Checks to see if at least one path is in the states passed in via `arguments`
|
|
100
113
|
* e.g., this.some('required', 'inited')
|
package/lib/utils.js
CHANGED
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.4.0",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"bson": "^4.6.2",
|
|
23
|
-
"kareem": "2.
|
|
24
|
-
"mongodb": "4.
|
|
23
|
+
"kareem": "2.4.1",
|
|
24
|
+
"mongodb": "4.7.0",
|
|
25
25
|
"mpath": "0.9.0",
|
|
26
26
|
"mquery": "4.0.3",
|
|
27
27
|
"ms": "2.1.3",
|
package/tsconfig.json
CHANGED
package/types/aggregate.d.ts
CHANGED
package/types/connection.d.ts
CHANGED
|
@@ -66,6 +66,11 @@ declare module 'mongoose' {
|
|
|
66
66
|
close(callback: CallbackWithoutResult): void;
|
|
67
67
|
close(force?: boolean): Promise<void>;
|
|
68
68
|
|
|
69
|
+
/** Closes and destroys the connection. Connection once destroyed cannot be reopened */
|
|
70
|
+
destroy(force: boolean, callback: CallbackWithoutResult): void;
|
|
71
|
+
destroy(callback: CallbackWithoutResult): void;
|
|
72
|
+
destroy(force?: boolean): Promise<void>;
|
|
73
|
+
|
|
69
74
|
/** Retrieves a collection, creating it if not cached. */
|
|
70
75
|
collection<T extends AnyObject = AnyObject>(name: string, options?: mongodb.CreateCollectionOptions): Collection<T>;
|
|
71
76
|
|
package/types/document.d.ts
CHANGED
|
@@ -19,6 +19,9 @@ declare module 'mongoose' {
|
|
|
19
19
|
/** This documents __v. */
|
|
20
20
|
__v?: any;
|
|
21
21
|
|
|
22
|
+
/** Assert that a given path or paths is populated. Throws an error if not populated. */
|
|
23
|
+
$assertPopulated<Paths = {}>(paths: string | string[]): Omit<this, keyof Paths> & Paths;
|
|
24
|
+
|
|
22
25
|
/* Get all subdocs (by bfs) */
|
|
23
26
|
$getAllSubdocs(): Document[];
|
|
24
27
|
|
|
@@ -193,8 +196,8 @@ declare module 'mongoose' {
|
|
|
193
196
|
/** Populates document references. */
|
|
194
197
|
populate<Paths = {}>(path: string | PopulateOptions | (string | PopulateOptions)[]): Promise<this & Paths>;
|
|
195
198
|
populate<Paths = {}>(path: string | PopulateOptions | (string | PopulateOptions)[], callback: Callback<this & Paths>): void;
|
|
196
|
-
populate<Paths = {}>(path: string, select?: string | AnyObject, model?: Model<
|
|
197
|
-
populate<Paths = {}>(path: string, select?: string | AnyObject, model?: Model<
|
|
199
|
+
populate<Paths = {}>(path: string, select?: string | AnyObject, model?: Model<any>, match?: AnyObject, options?: PopulateOptions): Promise<this & Paths>;
|
|
200
|
+
populate<Paths = {}>(path: string, select?: string | AnyObject, model?: Model<any>, match?: AnyObject, options?: PopulateOptions, callback?: Callback<this & Paths>): void;
|
|
198
201
|
|
|
199
202
|
/** Gets _id(s) used during population of the given `path`. If the path was not populated, returns `undefined`. */
|
|
200
203
|
populated(path: string): any;
|