UNPKG

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