UNPKG

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