index.js 42 KB

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