UNPKG

30.9 kBJavaScriptView Raw
1'use strict';
2
3/*!
4 * Module dependencies.
5 */
6
7if (global.MONGOOSE_DRIVER_PATH) {
8 const deprecationWarning = 'The `MONGOOSE_DRIVER_PATH` global property is ' +
9 'deprecated. Use `mongoose.driver.set()` instead.';
10 const setDriver = require('util').deprecate(function() {
11 require('./driver').set(require(global.MONGOOSE_DRIVER_PATH));
12 }, deprecationWarning);
13 setDriver();
14} else {
15 require('./driver').set(require('./drivers/node-mongodb-native'));
16}
17
18const Schema = require('./schema');
19const SchemaType = require('./schematype');
20const SchemaTypes = require('./schema/index');
21const VirtualType = require('./virtualtype');
22const STATES = require('./connectionstate');
23const Types = require('./types');
24const Query = require('./query');
25const Model = require('./model');
26const Document = require('./document');
27const applyPlugins = require('./helpers/schema/applyPlugins');
28const get = require('./helpers/get');
29const legacyPluralize = require('mongoose-legacy-pluralize');
30const utils = require('./utils');
31const pkg = require('../package.json');
32
33const removeSubdocs = require('./plugins/removeSubdocs');
34const saveSubdocs = require('./plugins/saveSubdocs');
35const validateBeforeSave = require('./plugins/validateBeforeSave');
36
37const Aggregate = require('./aggregate');
38const PromiseProvider = require('./promise_provider');
39const shardingPlugin = require('./plugins/sharding');
40
41const defaultMongooseSymbol = Symbol.for('mongoose:default');
42
43require('./helpers/printJestWarning');
44
45/**
46 * Mongoose constructor.
47 *
48 * The exports object of the `mongoose` module is an instance of this class.
49 * Most apps will only use this one instance.
50 *
51 * @api public
52 */
53
54function Mongoose(options) {
55 this.connections = [];
56 this.models = {};
57 this.modelSchemas = {};
58 // default global options
59 this.options = {
60 pluralization: true
61 };
62 const conn = this.createConnection(); // default connection
63 conn.models = this.models;
64
65 this._pluralize = legacyPluralize;
66
67 // If a user creates their own Mongoose instance, give them a separate copy
68 // of the `Schema` constructor so they get separate custom types. (gh-6933)
69 if (!options || !options[defaultMongooseSymbol]) {
70 const _this = this;
71 this.Schema = function() {
72 this.base = _this;
73 return Schema.apply(this, arguments);
74 };
75 this.Schema.prototype = Object.create(Schema.prototype);
76
77 Object.assign(this.Schema, Schema);
78 this.Schema.base = this;
79 this.Schema.Types = Object.assign({}, Schema.Types);
80 } else {
81 // Hack to work around babel's strange behavior with
82 // `import mongoose, { Schema } from 'mongoose'`. Because `Schema` is not
83 // an own property of a Mongoose global, Schema will be undefined. See gh-5648
84 for (const key of ['Schema', 'model']) {
85 this[key] = Mongoose.prototype[key];
86 }
87 }
88 this.Schema.prototype.base = this;
89
90 Object.defineProperty(this, 'plugins', {
91 configurable: false,
92 enumerable: true,
93 writable: false,
94 value: [
95 [saveSubdocs, { deduplicate: true }],
96 [validateBeforeSave, { deduplicate: true }],
97 [shardingPlugin, { deduplicate: true }],
98 [removeSubdocs, { deduplicate: true }]
99 ]
100 });
101}
102
103/**
104 * Expose connection states for user-land
105 *
106 * @memberOf Mongoose
107 * @property STATES
108 * @api public
109 */
110Mongoose.prototype.STATES = STATES;
111
112/**
113 * The underlying driver this Mongoose instance uses to communicate with
114 * the database. A driver is a Mongoose-specific interface that defines functions
115 * like `find()`.
116 *
117 * @memberOf Mongoose
118 * @property driver
119 * @api public
120 */
121
122Mongoose.prototype.driver = require('./driver');
123
124/**
125 * Sets mongoose options
126 *
127 * ####Example:
128 *
129 * mongoose.set('test', value) // sets the 'test' option to `value`
130 *
131 * mongoose.set('debug', true) // enable logging collection methods + arguments to the console
132 *
133 * mongoose.set('debug', function(collectionName, methodName, arg1, arg2...) {}); // use custom function to log collection methods + arguments
134 *
135 * Currently supported options are:
136 * - 'debug': prints the operations mongoose sends to MongoDB to the console
137 * - 'bufferCommands': enable/disable mongoose's buffering mechanism for all connections and models
138 * - 'useCreateIndex': false by default. Set to `true` to make Mongoose's default index build use `createIndex()` instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver.
139 * - 'useFindAndModify': true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`.
140 * - 'useNewUrlParser': false by default. Set to `true` to make all connections set the `useNewUrlParser` option by default
141 * - 'cloneSchemas': false by default. Set to `true` to `clone()` all schemas before compiling into a model.
142 * - '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.
143 * - 'applyPluginsToChildSchemas': true by default. Set to false to skip applying global plugins to child schemas
144 * - '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.
145 * - 'runValidators': false by default. Set to true to enable [update validators](/docs/validation.html#update-validators) for all validators by default.
146 * - 'toObject': `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to [`toObject()`](/docs/api.html#document_Document-toObject)
147 * - '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()`
148 * - 'strict': true by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas.
149 * - '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.
150 * - 'maxTimeMS': If set, attaches [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/) to every query
151 *
152 * @param {String} key
153 * @param {String|Function|Boolean} value
154 * @api public
155 */
156
157Mongoose.prototype.set = function(key, value) {
158 if (arguments.length === 1) {
159 return this.options[key];
160 }
161
162 this.options[key] = value;
163
164 if (key === 'objectIdGetter') {
165 if (value) {
166 Object.defineProperty(mongoose.Types.ObjectId.prototype, '_id', {
167 enumerable: false,
168 configurable: true,
169 get: function() {
170 return this;
171 }
172 });
173 } else {
174 delete mongoose.Types.ObjectId.prototype._id;
175 }
176 }
177
178 return this;
179};
180
181/**
182 * Gets mongoose options
183 *
184 * ####Example:
185 *
186 * mongoose.get('test') // returns the 'test' value
187 *
188 * @param {String} key
189 * @method get
190 * @api public
191 */
192
193Mongoose.prototype.get = Mongoose.prototype.set;
194
195/**
196 * Creates a Connection instance.
197 *
198 * Each `connection` instance maps to a single database. This method is helpful when mangaging multiple db connections.
199 *
200 *
201 * _Options passed take precedence over options included in connection strings._
202 *
203 * ####Example:
204 *
205 * // with mongodb:// URI
206 * db = mongoose.createConnection('mongodb://user:pass@localhost:port/database');
207 *
208 * // and options
209 * var opts = { db: { native_parser: true }}
210 * db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', opts);
211 *
212 * // replica sets
213 * db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database');
214 *
215 * // and options
216 * var opts = { replset: { strategy: 'ping', rs_name: 'testSet' }}
217 * db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database', opts);
218 *
219 * // and options
220 * var opts = { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' }
221 * db = mongoose.createConnection('localhost', 'database', port, opts)
222 *
223 * // initialize now, connect later
224 * db = mongoose.createConnection();
225 * db.openUri('localhost', 'database', port, [opts]);
226 *
227 * @param {String} [uri] a mongodb:// URI
228 * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
229 * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
230 * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
231 * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
232 * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
233 * @return {Connection} the created Connection object. Connections are thenable, so you can do `await mongoose.createConnection()`
234 * @api public
235 */
236
237Mongoose.prototype.createConnection = function(uri, options, callback) {
238 const conn = new Connection(this);
239 if (typeof options === 'function') {
240 callback = options;
241 options = null;
242 }
243 this.connections.push(conn);
244
245 if (arguments.length > 0) {
246 return conn.openUri(uri, options, callback);
247 }
248
249 return conn;
250};
251
252/**
253 * Opens the default mongoose connection.
254 *
255 * ####Example:
256 *
257 * mongoose.connect('mongodb://user:pass@localhost:port/database');
258 *
259 * // replica sets
260 * var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
261 * mongoose.connect(uri);
262 *
263 * // with options
264 * mongoose.connect(uri, options);
265 *
266 * // optional callback that gets fired when initial connection completed
267 * var uri = 'mongodb://nonexistent.domain:27000';
268 * mongoose.connect(uri, function(error) {
269 * // if error is truthy, the initial connection failed.
270 * })
271 *
272 * @param {String} uri(s)
273 * @param {Object} [options] passed down to the [MongoDB driver's `connect()` function](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html), except for 4 mongoose-specific options explained below.
274 * @param {String} [options.dbName] The name of the database we want to use. If not provided, use database name from connection string.
275 * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
276 * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
277 * @param {Boolean} [options.autoIndex=true] Mongoose-specific option. Set to false to disable automatic index creation for all models associated with this connection.
278 * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
279 * @param {Boolean} [options.useCreateIndex=true] Mongoose-specific option. If `true`, this connection will use [`createIndex()` instead of `ensureIndex()`](/docs/deprecations.html#-ensureindex-) for automatic index builds via [`Model.init()`](/docs/api.html#model_Model.init).
280 * @param {Boolean} [options.useFindAndModify=true] True by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()` use native `findOneAndUpdate()` rather than `findAndModify()`.
281 * @param {Boolean} [options.useNewUrlParser=false] False by default. Set to `true` to make all connections set the `useNewUrlParser` option by default.
282 * @param {Function} [callback]
283 * @see Mongoose#createConnection #index_Mongoose-createConnection
284 * @api public
285 * @return {Promise} resolves to `this` if connection succeeded
286 */
287
288Mongoose.prototype.connect = function() {
289 const _mongoose = this instanceof Mongoose ? this : mongoose;
290 const conn = _mongoose.connection;
291 if (conn.readyState !== STATES.disconnected) {
292 throw new _mongoose.Error('You can not `mongoose.connect()` multiple times while connected.');
293 }
294 return conn.openUri(arguments[0], arguments[1], arguments[2]).then(() => _mongoose);
295};
296
297/**
298 * Runs `.close()` on all connections in parallel.
299 *
300 * @param {Function} [callback] called after all connection close, or when first error occurred.
301 * @return {Promise} resolves when all connections are closed, or rejects with the first error that occurred.
302 * @api public
303 */
304
305Mongoose.prototype.disconnect = function(callback) {
306 return utils.promiseOrCallback(callback, cb => {
307 let remaining = this.connections.length;
308 if (remaining <= 0) {
309 return cb(null);
310 }
311 this.connections.forEach(conn => {
312 conn.close(function(error) {
313 if (error) {
314 return cb(error);
315 }
316 if (!--remaining) {
317 cb(null);
318 }
319 });
320 });
321 });
322};
323
324/**
325 * _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
326 * for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
327 * and [transactions](http://thecodebarbarian.com/a-node-js-perspective-on-mongodb-4-transactions.html).
328 *
329 * Calling `mongoose.startSession()` is equivalent to calling `mongoose.connection.startSession()`.
330 * Sessions are scoped to a connection, so calling `mongoose.startSession()`
331 * starts a session on the [default mongoose connection](/docs/api.html#mongoose_Mongoose-connection).
332 *
333 * @param {Object} [options] see the [mongodb driver options](http://mongodb.github.io/node-mongodb-native/3.0/api/MongoClient.html#startSession)
334 * @param {Boolean} [options.causalConsistency=true] set to false to disable causal consistency
335 * @param {Function} [callback]
336 * @return {Promise<ClientSession>} promise that resolves to a MongoDB driver `ClientSession`
337 * @api public
338 */
339
340Mongoose.prototype.startSession = function() {
341 return this.connection.startSession.apply(this.connection, arguments);
342};
343
344/**
345 * Getter/setter around function for pluralizing collection names.
346 *
347 * @param {Function|null} [fn] overwrites the function used to pluralize collection names
348 * @return {Function|null} the current function used to pluralize collection names, defaults to the legacy function from `mongoose-legacy-pluralize`.
349 * @api public
350 */
351
352Mongoose.prototype.pluralize = function(fn) {
353 if (arguments.length > 0) {
354 this._pluralize = fn;
355 }
356 return this._pluralize;
357};
358
359/**
360 * Defines a model or retrieves it.
361 *
362 * Models defined on the `mongoose` instance are available to all connection
363 * created by the same `mongoose` instance.
364 *
365 * If you call `mongoose.model()` with twice the same name but a different schema,
366 * you will get an `OverwriteModelError`. If you call `mongoose.model()` with
367 * the same name and same schema, you'll get the same schema back.
368 *
369 * ####Example:
370 *
371 * var mongoose = require('mongoose');
372 *
373 * // define an Actor model with this mongoose instance
374 * const Schema = new Schema({ name: String });
375 * mongoose.model('Actor', schema);
376 *
377 * // create a new connection
378 * var conn = mongoose.createConnection(..);
379 *
380 * // create Actor model
381 * var Actor = conn.model('Actor', schema);
382 * conn.model('Actor') === Actor; // true
383 * conn.model('Actor', schema) === Actor; // true, same schema
384 * conn.model('Actor', schema, 'actors') === Actor; // true, same schema and collection name
385 *
386 * // This throws an `OverwriteModelError` because the schema is different.
387 * conn.model('Actor', new Schema({ name: String }));
388 *
389 * _When no `collection` argument is passed, Mongoose uses the model name. If you don't like this behavior, either pass a collection name, use `mongoose.pluralize()`, or set your schemas collection name option._
390 *
391 * ####Example:
392 *
393 * var schema = new Schema({ name: String }, { collection: 'actor' });
394 *
395 * // or
396 *
397 * schema.set('collection', 'actor');
398 *
399 * // or
400 *
401 * var collectionName = 'actor'
402 * var M = mongoose.model('Actor', schema, collectionName)
403 *
404 * @param {String|Function} name model name or class extending Model
405 * @param {Schema} [schema] the schema to use.
406 * @param {String} [collection] name (optional, inferred from model name)
407 * @param {Boolean} [skipInit] whether to skip initialization (defaults to false)
408 * @return {Model} The model associated with `name`. Mongoose will create the model if it doesn't already exist.
409 * @api public
410 */
411
412Mongoose.prototype.model = function(name, schema, collection, skipInit) {
413 const _mongoose = this instanceof Mongoose ? this : mongoose;
414 let model;
415 if (typeof name === 'function') {
416 model = name;
417 name = model.name;
418 if (!(model.prototype instanceof Model)) {
419 throw new _mongoose.Error('The provided class ' + name + ' must extend Model');
420 }
421 }
422
423 if (typeof schema === 'string') {
424 collection = schema;
425 schema = false;
426 }
427
428 if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
429 schema = new Schema(schema);
430 }
431 if (schema && !schema.instanceOfSchema) {
432 throw new Error('The 2nd parameter to `mongoose.model()` should be a ' +
433 'schema or a POJO');
434 }
435
436 if (typeof collection === 'boolean') {
437 skipInit = collection;
438 collection = null;
439 }
440
441 // handle internal options from connection.model()
442 let options;
443 if (skipInit && utils.isObject(skipInit)) {
444 options = skipInit;
445 skipInit = true;
446 } else {
447 options = {};
448 }
449
450 // look up schema for the collection.
451 if (!_mongoose.modelSchemas[name]) {
452 if (schema) {
453 // cache it so we only apply plugins once
454 _mongoose.modelSchemas[name] = schema;
455 } else {
456 throw new mongoose.Error.MissingSchemaError(name);
457 }
458 }
459
460 const originalSchema = schema;
461 if (schema) {
462 if (_mongoose.get('cloneSchemas')) {
463 schema = schema.clone();
464 }
465 _mongoose._applyPlugins(schema);
466 }
467
468 let sub;
469
470 // connection.model() may be passing a different schema for
471 // an existing model name. in this case don't read from cache.
472 if (_mongoose.models[name] && options.cache !== false) {
473 if (originalSchema &&
474 originalSchema.instanceOfSchema &&
475 originalSchema !== _mongoose.models[name].schema) {
476 throw new _mongoose.Error.OverwriteModelError(name);
477 }
478
479 if (collection && collection !== _mongoose.models[name].collection.name) {
480 // subclass current model with alternate collection
481 model = _mongoose.models[name];
482 schema = model.prototype.schema;
483 sub = model.__subclass(_mongoose.connection, schema, collection);
484 // do not cache the sub model
485 return sub;
486 }
487
488 return _mongoose.models[name];
489 }
490
491 // ensure a schema exists
492 if (!schema) {
493 schema = this.modelSchemas[name];
494 if (!schema) {
495 throw new mongoose.Error.MissingSchemaError(name);
496 }
497 }
498
499 // Apply relevant "global" options to the schema
500 if (!('pluralization' in schema.options)) {
501 schema.options.pluralization = _mongoose.options.pluralization;
502 }
503
504 if (!collection) {
505 collection = schema.get('collection') ||
506 utils.toCollectionName(name, _mongoose.pluralize());
507 }
508
509 const connection = options.connection || _mongoose.connection;
510 model = _mongoose.Model.compile(model || name, schema, collection, connection, _mongoose);
511
512 if (!skipInit) {
513 // Errors handled internally, so safe to ignore error
514 model.init(function $modelInitNoop() {});
515 }
516
517 if (options.cache === false) {
518 return model;
519 }
520
521 _mongoose.models[name] = model;
522 return _mongoose.models[name];
523};
524
525/**
526 * Removes the model named `name` from the default connection, if it exists.
527 * You can use this function to clean up any models you created in your tests to
528 * prevent OverwriteModelErrors.
529 *
530 * Equivalent to `mongoose.connection.deleteModel(name)`.
531 *
532 * ####Example:
533 *
534 * mongoose.model('User', new Schema({ name: String }));
535 * console.log(mongoose.model('User')); // Model object
536 * mongoose.deleteModel('User');
537 * console.log(mongoose.model('User')); // undefined
538 *
539 * // Usually useful in a Mocha `afterEach()` hook
540 * afterEach(function() {
541 * mongoose.deleteModel(/.+/); // Delete every model
542 * });
543 *
544 * @api public
545 * @param {String|RegExp} name if string, the name of the model to remove. If regexp, removes all models whose name matches the regexp.
546 * @return {Mongoose} this
547 */
548
549Mongoose.prototype.deleteModel = function(name) {
550 this.connection.deleteModel(name);
551 return this;
552};
553
554/**
555 * Returns an array of model names created on this instance of Mongoose.
556 *
557 * ####Note:
558 *
559 * _Does not include names of models created using `connection.model()`._
560 *
561 * @api public
562 * @return {Array}
563 */
564
565Mongoose.prototype.modelNames = function() {
566 const names = Object.keys(this.models);
567 return names;
568};
569
570/**
571 * Applies global plugins to `schema`.
572 *
573 * @param {Schema} schema
574 * @api private
575 */
576
577Mongoose.prototype._applyPlugins = function(schema, options) {
578 options = options || {};
579 options.applyPluginsToDiscriminators = get(this,
580 'options.applyPluginsToDiscriminators', false);
581 options.applyPluginsToChildSchemas = get(this,
582 'options.applyPluginsToChildSchemas', true);
583 applyPlugins(schema, this.plugins, options, '$globalPluginsApplied');
584};
585
586/**
587 * Declares a global plugin executed on all Schemas.
588 *
589 * Equivalent to calling `.plugin(fn)` on each Schema you create.
590 *
591 * @param {Function} fn plugin callback
592 * @param {Object} [opts] optional options
593 * @return {Mongoose} this
594 * @see plugins ./plugins.html
595 * @api public
596 */
597
598Mongoose.prototype.plugin = function(fn, opts) {
599 this.plugins.push([fn, opts]);
600 return this;
601};
602
603/**
604 * The Mongoose module's default connection. Equivalent to `mongoose.connections][0]`, see [`connections`](#mongoose_Mongoose-connections).
605 *
606 * ####Example:
607 *
608 * var mongoose = require('mongoose');
609 * mongoose.connect(...);
610 * mongoose.connection.on('error', cb);
611 *
612 * This is the connection used by default for every model created using [mongoose.model](#index_Mongoose-model).
613 *
614 * To create a new connection, use [`createConnection()`](#mongoose_Mongoose-createConnection).
615 *
616 * @memberOf Mongoose
617 * @instance
618 * @property {Connection} connection
619 * @api public
620 */
621
622Mongoose.prototype.__defineGetter__('connection', function() {
623 return this.connections[0];
624});
625
626Mongoose.prototype.__defineSetter__('connection', function(v) {
627 if (v instanceof Connection) {
628 this.connections[0] = v;
629 this.models = v.models;
630 }
631});
632
633/**
634 * An array containing all [connections](connections.html) associated with this
635 * Mongoose instance. By default, there is 1 connection. Calling
636 * [`createConnection()`](#mongoose_Mongoose-createConnection) adds a connection
637 * to this array.
638 *
639 * ####Example:
640 *
641 * const mongoose = require('mongoose');
642 * mongoose.connections.length; // 1, just the default connection
643 * mongoose.connections[0] === mongoose.connection; // true
644 *
645 * mongoose.createConnection('mongodb://localhost:27017/test');
646 * mongoose.connections.length; // 2
647 *
648 * @memberOf Mongoose
649 * @instance
650 * @property {Array} connections
651 * @api public
652 */
653
654Mongoose.prototype.connections;
655
656/*!
657 * Driver dependent APIs
658 */
659
660const driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
661
662/*!
663 * Connection
664 */
665
666const Connection = require(driver + '/connection');
667
668/*!
669 * Collection
670 */
671
672const Collection = require(driver + '/collection');
673
674/**
675 * The Mongoose Aggregate constructor
676 *
677 * @method Aggregate
678 * @api public
679 */
680
681Mongoose.prototype.Aggregate = Aggregate;
682
683/**
684 * The Mongoose Collection constructor
685 *
686 * @method Collection
687 * @api public
688 */
689
690Mongoose.prototype.Collection = Collection;
691
692/**
693 * The Mongoose [Connection](#connection_Connection) constructor
694 *
695 * @memberOf Mongoose
696 * @instance
697 * @method Connection
698 * @api public
699 */
700
701Mongoose.prototype.Connection = Connection;
702
703/**
704 * The Mongoose version
705 *
706 * #### Example
707 *
708 * console.log(mongoose.version); // '5.x.x'
709 *
710 * @property version
711 * @api public
712 */
713
714Mongoose.prototype.version = pkg.version;
715
716/**
717 * The Mongoose constructor
718 *
719 * The exports of the mongoose module is an instance of this class.
720 *
721 * ####Example:
722 *
723 * var mongoose = require('mongoose');
724 * var mongoose2 = new mongoose.Mongoose();
725 *
726 * @method Mongoose
727 * @api public
728 */
729
730Mongoose.prototype.Mongoose = Mongoose;
731
732/**
733 * The Mongoose [Schema](#schema_Schema) constructor
734 *
735 * ####Example:
736 *
737 * var mongoose = require('mongoose');
738 * var Schema = mongoose.Schema;
739 * var CatSchema = new Schema(..);
740 *
741 * @method Schema
742 * @api public
743 */
744
745Mongoose.prototype.Schema = Schema;
746
747/**
748 * The Mongoose [SchemaType](#schematype_SchemaType) constructor
749 *
750 * @method SchemaType
751 * @api public
752 */
753
754Mongoose.prototype.SchemaType = SchemaType;
755
756/**
757 * The various Mongoose SchemaTypes.
758 *
759 * ####Note:
760 *
761 * _Alias of mongoose.Schema.Types for backwards compatibility._
762 *
763 * @property SchemaTypes
764 * @see Schema.SchemaTypes #schema_Schema.Types
765 * @api public
766 */
767
768Mongoose.prototype.SchemaTypes = Schema.Types;
769
770/**
771 * The Mongoose [VirtualType](#virtualtype_VirtualType) constructor
772 *
773 * @method VirtualType
774 * @api public
775 */
776
777Mongoose.prototype.VirtualType = VirtualType;
778
779/**
780 * The various Mongoose Types.
781 *
782 * ####Example:
783 *
784 * var mongoose = require('mongoose');
785 * var array = mongoose.Types.Array;
786 *
787 * ####Types:
788 *
789 * - [ObjectId](#types-objectid-js)
790 * - [Buffer](#types-buffer-js)
791 * - [SubDocument](#types-embedded-js)
792 * - [Array](#types-array-js)
793 * - [DocumentArray](#types-documentarray-js)
794 *
795 * Using this exposed access to the `ObjectId` type, we can construct ids on demand.
796 *
797 * var ObjectId = mongoose.Types.ObjectId;
798 * var id1 = new ObjectId;
799 *
800 * @property Types
801 * @api public
802 */
803
804Mongoose.prototype.Types = Types;
805
806/**
807 * The Mongoose [Query](#query_Query) constructor.
808 *
809 * @method Query
810 * @api public
811 */
812
813Mongoose.prototype.Query = Query;
814
815/**
816 * The Mongoose [Promise](#promise_Promise) constructor.
817 *
818 * @memberOf Mongoose
819 * @instance
820 * @property Promise
821 * @api public
822 */
823
824Object.defineProperty(Mongoose.prototype, 'Promise', {
825 get: function() {
826 return PromiseProvider.get();
827 },
828 set: function(lib) {
829 PromiseProvider.set(lib);
830 }
831});
832
833/**
834 * Storage layer for mongoose promises
835 *
836 * @method PromiseProvider
837 * @api public
838 */
839
840Mongoose.prototype.PromiseProvider = PromiseProvider;
841
842/**
843 * The Mongoose [Model](#model_Model) constructor.
844 *
845 * @method Model
846 * @api public
847 */
848
849Mongoose.prototype.Model = Model;
850
851/**
852 * The Mongoose [Document](#document-js) constructor.
853 *
854 * @method Document
855 * @api public
856 */
857
858Mongoose.prototype.Document = Document;
859
860/**
861 * The Mongoose DocumentProvider constructor. Mongoose users should not have to
862 * use this directly
863 *
864 * @method DocumentProvider
865 * @api public
866 */
867
868Mongoose.prototype.DocumentProvider = require('./document_provider');
869
870/**
871 * The Mongoose ObjectId [SchemaType](/docs/schematypes.html). Used for
872 * declaring paths in your schema that should be
873 * [MongoDB ObjectIds](https://docs.mongodb.com/manual/reference/method/ObjectId/).
874 * Do not use this to create a new ObjectId instance, use `mongoose.Types.ObjectId`
875 * instead.
876 *
877 * ####Example:
878 *
879 * const childSchema = new Schema({ parentId: mongoose.ObjectId });
880 *
881 * @property ObjectId
882 * @api public
883 */
884
885Mongoose.prototype.ObjectId = SchemaTypes.ObjectId;
886
887/**
888 * The Mongoose Decimal128 [SchemaType](/docs/schematypes.html). Used for
889 * declaring paths in your schema that should be
890 * [128-bit decimal floating points](http://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-34-decimal.html).
891 * Do not use this to create a new Decimal128 instance, use `mongoose.Types.Decimal128`
892 * instead.
893 *
894 * ####Example:
895 *
896 * const vehicleSchema = new Schema({ fuelLevel: mongoose.Decimal128 });
897 *
898 * @property Decimal128
899 * @api public
900 */
901
902Mongoose.prototype.Decimal128 = SchemaTypes.Decimal128;
903
904/**
905 * The Mongoose Mixed [SchemaType](/docs/schematypes.html). Used for
906 * declaring paths in your schema that Mongoose's change tracking, casting,
907 * and validation should ignore.
908 *
909 * ####Example:
910 *
911 * const schema = new Schema({ arbitrary: mongoose.Mixed });
912 *
913 * @property Mixed
914 * @api public
915 */
916
917Mongoose.prototype.Mixed = SchemaTypes.Mixed;
918
919/**
920 * The Mongoose Number [SchemaType](/docs/schematypes.html). Used for
921 * declaring paths in your schema that Mongoose should cast to numbers.
922 *
923 * ####Example:
924 *
925 * const schema = new Schema({ num: mongoose.Number });
926 * // Equivalent to:
927 * const schema = new Schema({ num: 'number' });
928 *
929 * @property Number
930 * @api public
931 */
932
933Mongoose.prototype.Number = SchemaTypes.Number;
934
935/**
936 * The [MongooseError](#error_MongooseError) constructor.
937 *
938 * @method Error
939 * @api public
940 */
941
942Mongoose.prototype.Error = require('./error');
943
944/**
945 * Mongoose uses this function to get the current time when setting
946 * [timestamps](/docs/guide.html#timestamps). You may stub out this function
947 * using a tool like [Sinon](https://www.npmjs.com/package/sinon) for testing.
948 *
949 * @method now
950 * @returns Date the current time
951 * @api public
952 */
953
954Mongoose.prototype.now = function now() { return new Date(); };
955
956/**
957 * The Mongoose CastError constructor
958 *
959 * @method CastError
960 * @param {String} type The name of the type
961 * @param {Any} value The value that failed to cast
962 * @param {String} path The path `a.b.c` in the doc where this cast error occurred
963 * @param {Error} [reason] The original error that was thrown
964 * @api public
965 */
966
967Mongoose.prototype.CastError = require('./error/cast');
968
969/**
970 * The [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver Mongoose uses.
971 *
972 * @property mongo
973 * @api public
974 */
975
976Mongoose.prototype.mongo = require('mongodb');
977
978/**
979 * The [mquery](https://github.com/aheckmann/mquery) query builder Mongoose uses.
980 *
981 * @property mquery
982 * @api public
983 */
984
985Mongoose.prototype.mquery = require('mquery');
986
987/*!
988 * The exports object is an instance of Mongoose.
989 *
990 * @api public
991 */
992
993const mongoose = module.exports = exports = new Mongoose({
994 [defaultMongooseSymbol]: true
995});