mirror of
https://github.com/bodyrep/DemoApp.git
synced 2026-03-15 09:25:27 +00:00
migrating repo to Bodyrep org
This commit is contained in:
177
node_modules/mongoose/lib/collection.js
generated
vendored
Normal file
177
node_modules/mongoose/lib/collection.js
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var STATES = require('./connectionstate')
|
||||
|
||||
/**
|
||||
* Abstract Collection constructor
|
||||
*
|
||||
* This is the base class that drivers inherit from and implement.
|
||||
*
|
||||
* @param {String} name name of the collection
|
||||
* @param {Connection} conn A MongooseConnection instance
|
||||
* @param {Object} opts optional collection options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Collection (name, conn, opts) {
|
||||
this.name = name;
|
||||
this.conn = conn;
|
||||
this.buffer = true;
|
||||
this.queue = [];
|
||||
|
||||
if ('number' == typeof opts) opts = { size: opts };
|
||||
this.opts = opts || {};
|
||||
|
||||
if (STATES.connected == this.conn.readyState) {
|
||||
this.onOpen();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The collection name
|
||||
*
|
||||
* @api public
|
||||
* @property name
|
||||
*/
|
||||
|
||||
Collection.prototype.name;
|
||||
|
||||
/**
|
||||
* The Connection instance
|
||||
*
|
||||
* @api public
|
||||
* @property conn
|
||||
*/
|
||||
|
||||
Collection.prototype.conn;
|
||||
|
||||
/**
|
||||
* Called when the database connects
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onOpen = function () {
|
||||
var self = this;
|
||||
this.buffer = false;
|
||||
self.doQueue();
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the database disconnects
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onClose = function () {
|
||||
this.buffer = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Queues a method for later execution when its
|
||||
* database connection opens.
|
||||
*
|
||||
* @param {String} name name of the method to queue
|
||||
* @param {Array} args arguments to pass to the method when executed
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.addQueue = function (name, args) {
|
||||
this.queue.push([name, args]);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes all queued methods and clears the queue.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.doQueue = function () {
|
||||
for (var i = 0, l = this.queue.length; i < l; i++){
|
||||
this[this.queue[i][0]].apply(this, this.queue[i][1]);
|
||||
}
|
||||
this.queue = [];
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.ensureIndex = function(){
|
||||
throw new Error('Collection#ensureIndex unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findAndModify = function(){
|
||||
throw new Error('Collection#findAndModify unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOne = function(){
|
||||
throw new Error('Collection#findOne unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.find = function(){
|
||||
throw new Error('Collection#find unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.insert = function(){
|
||||
throw new Error('Collection#insert unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.save = function(){
|
||||
throw new Error('Collection#save unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.update = function(){
|
||||
throw new Error('Collection#update unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.getIndexes = function(){
|
||||
throw new Error('Collection#getIndexes unimplemented by driver');
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.mapReduce = function(){
|
||||
throw new Error('Collection#mapReduce unimplemented by driver');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Collection;
|
||||
680
node_modules/mongoose/lib/connection.js
generated
vendored
Normal file
680
node_modules/mongoose/lib/connection.js
generated
vendored
Normal file
@@ -0,0 +1,680 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var url = require('url')
|
||||
, utils = require('./utils')
|
||||
, EventEmitter = utils.EventEmitter
|
||||
, driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native'
|
||||
, Model = require('./model')
|
||||
, Schema = require('./schema')
|
||||
, Collection = require(driver + '/collection')
|
||||
, STATES = require('./connectionstate')
|
||||
, MongooseError = require('./error')
|
||||
, assert =require('assert')
|
||||
, muri = require('muri')
|
||||
|
||||
/*!
|
||||
* Protocol prefix regexp.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var rgxProtocol = /^(?:.)+:\/\//;
|
||||
|
||||
/**
|
||||
* Connection constructor
|
||||
*
|
||||
* For practical reasons, a Connection equals a Db.
|
||||
*
|
||||
* @param {Mongoose} base a mongoose instance
|
||||
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
|
||||
* @event `connecting`: Emitted when `connection.{open,openSet}()` is executed on this connection.
|
||||
* @event `connected`: Emitted when this connection successfully connects to the db. May be emitted _multiple_ times in `reconnected` scenarios.
|
||||
* @event `open`: Emitted after we `connected` and `onOpen` is executed on all of this connections models.
|
||||
* @event `disconnecting`: Emitted when `connection.close()` was executed.
|
||||
* @event `disconnected`: Emitted after getting disconnected from the db.
|
||||
* @event `close`: Emitted after we `disconnected` and `onClose` executed on all of this connections models.
|
||||
* @event `reconnected`: Emitted after we `connected` and subsequently `disconnected`, followed by successfully another successfull connection.
|
||||
* @event `error`: Emitted when an error occurs on this connection.
|
||||
* @event `fullsetup`: Emitted in a replica-set scenario, when all nodes specified in the connection string are connected.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Connection (base) {
|
||||
this.base = base;
|
||||
this.collections = {};
|
||||
this.models = {};
|
||||
this.replica = false;
|
||||
this.hosts = null;
|
||||
this.host = null;
|
||||
this.port = null;
|
||||
this.user = null;
|
||||
this.pass = null;
|
||||
this.name = null;
|
||||
this.options = null;
|
||||
this._readyState = STATES.disconnected;
|
||||
this._closeCalled = false;
|
||||
this._hasOpened = false;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from EventEmitter
|
||||
*/
|
||||
|
||||
Connection.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
/**
|
||||
* Connection ready state
|
||||
*
|
||||
* - 0 = disconnected
|
||||
* - 1 = connected
|
||||
* - 2 = connecting
|
||||
* - 3 = disconnecting
|
||||
*
|
||||
* Each state change emits its associated event name.
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* conn.on('connected', callback);
|
||||
* conn.on('disconnected', callback);
|
||||
*
|
||||
* @property readyState
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Object.defineProperty(Connection.prototype, 'readyState', {
|
||||
get: function(){ return this._readyState; }
|
||||
, set: function (val) {
|
||||
if (!(val in STATES)) {
|
||||
throw new Error('Invalid connection state: ' + val);
|
||||
}
|
||||
|
||||
if (this._readyState !== val) {
|
||||
this._readyState = val;
|
||||
|
||||
if (STATES.connected === val)
|
||||
this._hasOpened = true;
|
||||
|
||||
this.emit(STATES[val]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* A hash of the collections associated with this connection
|
||||
*
|
||||
* @property collections
|
||||
*/
|
||||
|
||||
Connection.prototype.collections;
|
||||
|
||||
/**
|
||||
* The mongodb.Db instance, set when the connection is opened
|
||||
*
|
||||
* @property db
|
||||
*/
|
||||
|
||||
Connection.prototype.db;
|
||||
|
||||
/**
|
||||
* Opens the connection to MongoDB.
|
||||
*
|
||||
* `options` is a hash with the following possible properties:
|
||||
*
|
||||
* db - passed to the connection db instance
|
||||
* server - passed to the connection server instance(s)
|
||||
* replset - passed to the connection ReplSet instance
|
||||
* user - username for authentication
|
||||
* pass - password for authentication
|
||||
*
|
||||
* ####Notes:
|
||||
*
|
||||
* Mongoose forces the db option `forceServerObjectId` false and cannot be overridden.
|
||||
* Mongoose defaults the server `auto_reconnect` options to true which can be overridden.
|
||||
* See the node-mongodb-native driver instance for options that it understands.
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
* @param {String} connection_string mongodb://uri or the host to which you are connecting
|
||||
* @param {String} [database] database name
|
||||
* @param {Number} [port] database port
|
||||
* @param {Object} [options] options
|
||||
* @param {Function} [callback]
|
||||
* @see node-mongodb-native https://github.com/mongodb/node-mongodb-native
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.open = function (host, database, port, options, callback) {
|
||||
var self = this
|
||||
, parsed
|
||||
, uri;
|
||||
|
||||
if ('string' === typeof database) {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
port = 27017;
|
||||
case 3:
|
||||
switch (typeof port) {
|
||||
case 'function':
|
||||
callback = port, port = 27017;
|
||||
break;
|
||||
case 'object':
|
||||
options = port, port = 27017;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ('function' === typeof options)
|
||||
callback = options, options = {};
|
||||
}
|
||||
} else {
|
||||
switch (typeof database) {
|
||||
case 'function':
|
||||
callback = database, database = undefined;
|
||||
break;
|
||||
case 'object':
|
||||
options = database;
|
||||
database = undefined;
|
||||
callback = port;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rgxProtocol.test(host)) {
|
||||
host = 'mongodb://' + host;
|
||||
}
|
||||
|
||||
try {
|
||||
parsed = muri(host);
|
||||
} catch (err) {
|
||||
this.error(err, callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
database = parsed.db;
|
||||
host = parsed.hosts[0].host || parsed.hosts[0].ipc;
|
||||
port = parsed.hosts[0].port || 27017;
|
||||
}
|
||||
|
||||
this.options = this.parseOptions(options, parsed && parsed.options);
|
||||
|
||||
// make sure we can open
|
||||
if (STATES.disconnected !== this.readyState) {
|
||||
var err = new Error('Trying to open unclosed connection.');
|
||||
err.state = this.readyState;
|
||||
this.error(err, callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!host) {
|
||||
this.error(new Error('Missing hostname.'), callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!database) {
|
||||
this.error(new Error('Missing database name.'), callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
// authentication
|
||||
if (options && options.user && options.pass) {
|
||||
this.user = options.user;
|
||||
this.pass = options.pass;
|
||||
|
||||
} else if (parsed && parsed.auth) {
|
||||
this.user = parsed.auth.user;
|
||||
this.pass = parsed.auth.pass;
|
||||
|
||||
// Check hostname for user/pass
|
||||
} else if (/@/.test(host) && /:/.test(host.split('@')[0])) {
|
||||
host = host.split('@');
|
||||
var auth = host.shift().split(':');
|
||||
host = host.pop();
|
||||
this.user = auth[0];
|
||||
this.pass = auth[1];
|
||||
|
||||
} else {
|
||||
this.user = this.pass = undefined;
|
||||
}
|
||||
|
||||
this.name = database;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
this._open(callback);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connects to a replica set.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var db = mongoose.createConnection();
|
||||
* db.openSet("mongodb://user:pwd@localhost:27020/testing,mongodb://example.com:27020,mongodb://localhost:27019");
|
||||
*
|
||||
* The database name and/or auth need only be included in one URI.
|
||||
* The `options` is a hash which is passed to the internal driver connection object.
|
||||
*
|
||||
* Valid `options`
|
||||
*
|
||||
* db - passed to the connection db instance
|
||||
* server - passed to the connection server instance(s)
|
||||
* replset - passed to the connection ReplSetServer instance
|
||||
* user - username for authentication
|
||||
* pass - password for authentication
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
* @param {String} uris comma-separated mongodb:// `URI`s
|
||||
* @param {String} [database] database name if not included in `uris`
|
||||
* @param {Object} [options] passed to the internal driver
|
||||
* @param {Function} [callback]
|
||||
* @see node-mongodb-native https://github.com/mongodb/node-mongodb-native
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
if (!rgxProtocol.test(uris)) {
|
||||
uris = 'mongodb://' + uris;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
|
||||
switch (arguments.length) {
|
||||
case 3:
|
||||
switch (typeof database) {
|
||||
case 'string':
|
||||
this.name = database;
|
||||
break;
|
||||
case 'object':
|
||||
callback = options;
|
||||
options = database;
|
||||
database = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if ('function' === typeof options) {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (typeof database) {
|
||||
case 'string':
|
||||
this.name = database;
|
||||
break;
|
||||
case 'function':
|
||||
callback = database, database = null;
|
||||
break;
|
||||
case 'object':
|
||||
options = database, database = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var parsed;
|
||||
try {
|
||||
parsed = muri(uris);
|
||||
} catch (err) {
|
||||
this.error(err, callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!this.name) {
|
||||
this.name = parsed.db;
|
||||
}
|
||||
|
||||
this.hosts = parsed.hosts;
|
||||
this.options = this.parseOptions(options, parsed && parsed.options);
|
||||
this.replica = true;
|
||||
|
||||
if (!this.name) {
|
||||
this.error(new Error('No database name provided for replica set'), callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
// authentication
|
||||
if (options && options.user && options.pass) {
|
||||
this.user = options.user;
|
||||
this.pass = options.pass;
|
||||
|
||||
} else if (parsed && parsed.auth) {
|
||||
this.user = parsed.auth.user;
|
||||
this.pass = parsed.auth.pass;
|
||||
|
||||
} else {
|
||||
this.user = this.pass = undefined;
|
||||
}
|
||||
|
||||
this._open(callback);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* error
|
||||
*
|
||||
* Graceful error handling, passes error to callback
|
||||
* if available, else emits error on the connection.
|
||||
*
|
||||
* @param {Error} err
|
||||
* @param {Function} callback optional
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.error = function (err, callback) {
|
||||
if (callback) return callback(err);
|
||||
this.emit('error', err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles opening the connection with the appropriate method based on connection type.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype._open = function (callback) {
|
||||
this.readyState = STATES.connecting;
|
||||
this._closeCalled = false;
|
||||
|
||||
var self = this;
|
||||
|
||||
var method = this.replica
|
||||
? 'doOpenSet'
|
||||
: 'doOpen';
|
||||
|
||||
// open connection
|
||||
this[method](function (err) {
|
||||
if (err) {
|
||||
self.readyState = STATES.disconnected;
|
||||
if (self._hasOpened) {
|
||||
if (callback) callback(err);
|
||||
} else {
|
||||
self.error(err, callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.onOpen(callback);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the connection is opened
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.onOpen = function (callback) {
|
||||
var self = this;
|
||||
|
||||
function open (err) {
|
||||
if (err) {
|
||||
self.readyState = STATES.disconnected;
|
||||
if (self._hasOpened) {
|
||||
if (callback) callback(err);
|
||||
} else {
|
||||
self.error(err, callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.readyState = STATES.connected;
|
||||
|
||||
// avoid having the collection subscribe to our event emitter
|
||||
// to prevent 0.3 warning
|
||||
for (var i in self.collections)
|
||||
self.collections[i].onOpen();
|
||||
|
||||
callback && callback();
|
||||
self.emit('open');
|
||||
};
|
||||
|
||||
// re-authenticate
|
||||
if (self.user && self.pass) {
|
||||
self.db.authenticate(self.user, self.pass, open);
|
||||
}
|
||||
else
|
||||
open();
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the connection
|
||||
*
|
||||
* @param {Function} [callback] optional
|
||||
* @return {Connection} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.close = function (callback) {
|
||||
var self = this;
|
||||
this._closeCalled = true;
|
||||
|
||||
switch (this.readyState){
|
||||
case 0: // disconnected
|
||||
callback && callback();
|
||||
break;
|
||||
|
||||
case 1: // connected
|
||||
this.readyState = STATES.disconnecting;
|
||||
this.doClose(function(err){
|
||||
if (err){
|
||||
self.error(err, callback);
|
||||
} else {
|
||||
self.onClose();
|
||||
callback && callback();
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case 2: // connecting
|
||||
this.once('open', function(){
|
||||
self.close(callback);
|
||||
});
|
||||
break;
|
||||
|
||||
case 3: // disconnecting
|
||||
if (!callback) break;
|
||||
this.once('close', function () {
|
||||
callback();
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the connection closes
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.onClose = function () {
|
||||
this.readyState = STATES.disconnected;
|
||||
|
||||
// avoid having the collection subscribe to our event emitter
|
||||
// to prevent 0.3 warning
|
||||
for (var i in this.collections)
|
||||
this.collections[i].onClose();
|
||||
|
||||
this.emit('close');
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a collection, creating it if not cached.
|
||||
*
|
||||
* @param {String} name of the collection
|
||||
* @param {Object} [options] optional collection options
|
||||
* @return {Collection} collection instance
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.collection = function (name, options) {
|
||||
if (!(name in this.collections))
|
||||
this.collections[name] = new Collection(name, this, options);
|
||||
return this.collections[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines or retrieves a model.
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var db = mongoose.createConnection(..);
|
||||
* db.model('Venue', new Schema(..));
|
||||
* var Ticket = db.model('Ticket', new Schema(..));
|
||||
* var Venue = db.model('Venue');
|
||||
*
|
||||
* _When no `collection` argument is passed, Mongoose produces a collection name by passing the model `name` to the [utils.toCollectionName](#utils.toCollectionName) method. This method pluralizes the name. If you don't like this behavior, either pass a collection name or set your schemas collection name option._
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var schema = new Schema({ name: String }, { collection: 'actor' });
|
||||
*
|
||||
* // or
|
||||
*
|
||||
* schema.set('collection', 'actor');
|
||||
*
|
||||
* // or
|
||||
*
|
||||
* var collectionName = 'actor'
|
||||
* var M = conn.model('Actor', schema, collectionName)
|
||||
*
|
||||
* @param {String} name the model name
|
||||
* @param {Schema} [schema] a schema. necessary when defining a model
|
||||
* @param {String} [collection] name of mongodb collection (optional) if not given it will be induced from model name
|
||||
* @see Mongoose#model #index_Mongoose-model
|
||||
* @return {Model} The compiled model
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.model = function (name, schema, collection) {
|
||||
// collection name discovery
|
||||
if ('string' == typeof schema) {
|
||||
collection = schema;
|
||||
schema = false;
|
||||
}
|
||||
|
||||
if (this.models[name] && !collection) {
|
||||
// model exists but we are not subclassing with custom collection
|
||||
if (schema instanceof Schema && schema != this.models[name].schema) {
|
||||
throw new MongooseError.OverwriteModelError(name);
|
||||
}
|
||||
return this.models[name];
|
||||
}
|
||||
|
||||
var opts = { cache: false, connection: this }
|
||||
var model;
|
||||
|
||||
if (schema instanceof Schema) {
|
||||
// compile a model
|
||||
model = this.base.model(name, schema, collection, opts)
|
||||
|
||||
// only the first model with this name is cached to allow
|
||||
// for one-offs with custom collection names etc.
|
||||
if (!this.models[name]) {
|
||||
this.models[name] = model;
|
||||
}
|
||||
|
||||
model.init();
|
||||
return model;
|
||||
}
|
||||
|
||||
if (this.models[name] && collection) {
|
||||
// subclassing current model with alternate collection
|
||||
model = this.models[name];
|
||||
schema = model.prototype.schema;
|
||||
var sub = model.__subclass(this, schema, collection);
|
||||
// do not cache the sub model
|
||||
return sub;
|
||||
}
|
||||
|
||||
// lookup model in mongoose module
|
||||
model = this.base.models[name];
|
||||
|
||||
if (!model) {
|
||||
throw new MongooseError.MissingSchemaError(name);
|
||||
}
|
||||
|
||||
if (this == model.prototype.db
|
||||
&& (!collection || collection == model.collection.name)) {
|
||||
// model already uses this connection.
|
||||
|
||||
// only the first model with this name is cached to allow
|
||||
// for one-offs with custom collection names etc.
|
||||
if (!this.models[name]) {
|
||||
this.models[name] = model;
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
return this.models[name] = model.__subclass(this, schema, collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set profiling level.
|
||||
*
|
||||
* @param {Number|String} level either off (0), slow (1), or all (2)
|
||||
* @param {Number} [ms] the threshold in milliseconds above which queries will be logged when in `slow` mode. defaults to 100.
|
||||
* @param {Function} callback
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.setProfiling = function (level, ms, callback) {
|
||||
if (STATES.connected !== this.readyState) {
|
||||
return this.on('open', this.setProfiling.bind(this, level, ms, callback));
|
||||
}
|
||||
|
||||
if (!callback) callback = ms, ms = 100;
|
||||
|
||||
var cmd = {};
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
case 'off':
|
||||
cmd.profile = 0;
|
||||
break;
|
||||
case 1:
|
||||
case 'slow':
|
||||
cmd.profile = 1;
|
||||
if ('number' !== typeof ms) {
|
||||
ms = parseInt(ms, 10);
|
||||
if (isNaN(ms)) ms = 100;
|
||||
}
|
||||
cmd.slowms = ms;
|
||||
break;
|
||||
case 2:
|
||||
case 'all':
|
||||
cmd.profile = 2;
|
||||
break;
|
||||
default:
|
||||
return callback(new Error('Invalid profiling level: '+ level));
|
||||
}
|
||||
|
||||
this.db.executeDbCommand(cmd, function (err, resp) {
|
||||
if (err) return callback(err);
|
||||
|
||||
var doc = resp.documents[0];
|
||||
|
||||
err = 1 === doc.ok
|
||||
? null
|
||||
: new Error('Could not set profiling level to: '+ level)
|
||||
|
||||
callback(err, doc);
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Noop.
|
||||
*/
|
||||
|
||||
function noop () {}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
Connection.STATES = STATES;
|
||||
module.exports = Connection;
|
||||
24
node_modules/mongoose/lib/connectionstate.js
generated
vendored
Normal file
24
node_modules/mongoose/lib/connectionstate.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
/*!
|
||||
* Connection states
|
||||
*/
|
||||
|
||||
var STATES = module.exports = exports = Object.create(null);
|
||||
|
||||
var disconnected = 'disconnected';
|
||||
var connected = 'connected';
|
||||
var connecting = 'connecting';
|
||||
var disconnecting = 'disconnecting';
|
||||
var uninitialized = 'uninitialized';
|
||||
|
||||
STATES[0] = disconnected;
|
||||
STATES[1] = connected;
|
||||
STATES[2] = connecting;
|
||||
STATES[3] = disconnecting;
|
||||
STATES[99] = uninitialized;
|
||||
|
||||
STATES[disconnected] = 0;
|
||||
STATES[connected] = 1;
|
||||
STATES[connecting] = 2;
|
||||
STATES[disconnecting] = 3;
|
||||
STATES[uninitialized] = 99;
|
||||
1520
node_modules/mongoose/lib/document.js
generated
vendored
Normal file
1520
node_modules/mongoose/lib/document.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
generated
vendored
Normal file
8
node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Binary = require('mongodb').BSONPure.Binary;
|
||||
|
||||
module.exports = exports = Binary;
|
||||
212
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
Normal file
212
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseCollection = require('../../collection')
|
||||
, Collection = require('mongodb').Collection
|
||||
, STATES = require('../../connectionstate')
|
||||
, utils = require('../../utils')
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
|
||||
*
|
||||
* All methods methods from the [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver are copied and wrapped in queue management.
|
||||
*
|
||||
* @inherits Collection
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function NativeCollection () {
|
||||
this.collection = null;
|
||||
MongooseCollection.apply(this, arguments);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from abstract Collection.
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.__proto__ = MongooseCollection.prototype;
|
||||
|
||||
/**
|
||||
* Called when the connection opens.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onOpen = function () {
|
||||
var self = this;
|
||||
|
||||
if (this.collection) {
|
||||
return MongooseCollection.prototype.onOpen.call(self);
|
||||
}
|
||||
|
||||
if (!self.opts.size) {
|
||||
// non-capped
|
||||
return self.conn.db.collection(self.name, callback);
|
||||
}
|
||||
|
||||
// capped
|
||||
return self.conn.db.collection(self.name, function (err, c) {
|
||||
if (err) return callback(err);
|
||||
|
||||
// discover if this collection exists and if it is capped
|
||||
c.options(function (err, exists) {
|
||||
if (err) return callback(err);
|
||||
|
||||
if (exists) {
|
||||
if (exists.capped) {
|
||||
callback(null, c);
|
||||
} else {
|
||||
var msg = 'A non-capped collection exists with this name.\n\n'
|
||||
+ ' To use this collection as a capped collection, please '
|
||||
+ 'first convert it.\n'
|
||||
+ ' http://www.mongodb.org/display/DOCS/Capped+Collections#CappedCollections-Convertingacollectiontocapped'
|
||||
err = new Error(msg);
|
||||
callback(err);
|
||||
}
|
||||
} else {
|
||||
// create
|
||||
var opts = utils.clone(self.opts);
|
||||
opts.capped = true;
|
||||
self.conn.db.createCollection(self.name, opts, callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function callback (err, collection) {
|
||||
if (err) {
|
||||
// likely a strict mode error
|
||||
self.conn.emit('error', err);
|
||||
} else {
|
||||
self.collection = collection;
|
||||
MongooseCollection.prototype.onOpen.call(self);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the connection closes
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onClose = function () {
|
||||
MongooseCollection.prototype.onClose.call(this);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Copy the collection methods and make them subject to queues
|
||||
*/
|
||||
|
||||
for (var i in Collection.prototype) {
|
||||
(function(i){
|
||||
NativeCollection.prototype[i] = function () {
|
||||
if (this.buffer) {
|
||||
this.addQueue(i, arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
var collection = this.collection
|
||||
, args = arguments
|
||||
, self = this
|
||||
, debug = self.conn.base.options.debug;
|
||||
|
||||
if (debug) {
|
||||
if ('function' === typeof debug) {
|
||||
debug.apply(debug
|
||||
, [self.name, i].concat(utils.args(args, 0, args.length-1)));
|
||||
} else {
|
||||
console.error('\x1B[0;36mMongoose:\x1B[0m %s.%s(%s) %s %s %s'
|
||||
, self.name
|
||||
, i
|
||||
, print(args[0])
|
||||
, print(args[1])
|
||||
, print(args[2])
|
||||
, print(args[3]))
|
||||
}
|
||||
}
|
||||
|
||||
collection[i].apply(collection, args);
|
||||
};
|
||||
})(i);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Debug print helper
|
||||
*/
|
||||
|
||||
function print (arg) {
|
||||
var type = typeof arg;
|
||||
if ('function' === type || 'undefined' === type) return '';
|
||||
return format(arg);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Debug print helper
|
||||
*/
|
||||
|
||||
function format (obj, sub) {
|
||||
var x = utils.clone(obj);
|
||||
if (x) {
|
||||
if ('Binary' === x.constructor.name) {
|
||||
x = '[object Buffer]';
|
||||
} else if ('ObjectID' === x.constructor.name) {
|
||||
var representation = 'ObjectId("' + x.toHexString() + '")';
|
||||
x = { inspect: function() { return representation; } };
|
||||
} else if ('Date' === x.constructor.name) {
|
||||
var representation = 'new Date("' + x.toUTCString() + '")';
|
||||
x = { inspect: function() { return representation; } };
|
||||
} else if ('Object' === x.constructor.name) {
|
||||
var keys = Object.keys(x)
|
||||
, i = keys.length
|
||||
, key
|
||||
while (i--) {
|
||||
key = keys[i];
|
||||
if (x[key]) {
|
||||
if ('Binary' === x[key].constructor.name) {
|
||||
x[key] = '[object Buffer]';
|
||||
} else if ('Object' === x[key].constructor.name) {
|
||||
x[key] = format(x[key], true);
|
||||
} else if ('ObjectID' === x[key].constructor.name) {
|
||||
;(function(x){
|
||||
var representation = 'ObjectId("' + x[key].toHexString() + '")';
|
||||
x[key] = { inspect: function() { return representation; } };
|
||||
})(x)
|
||||
} else if ('Date' === x[key].constructor.name) {
|
||||
;(function(x){
|
||||
var representation = 'new Date("' + x[key].toUTCString() + '")';
|
||||
x[key] = { inspect: function() { return representation; } };
|
||||
})(x)
|
||||
} else if (Array.isArray(x[key])) {
|
||||
x[key] = x[key].map(function (o) {
|
||||
return format(o, true)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sub) return x;
|
||||
}
|
||||
|
||||
return require('util')
|
||||
.inspect(x, false, 10, true)
|
||||
.replace(/\n/g, '')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreives information about this collections indexes.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @method getIndexes
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.getIndexes = NativeCollection.prototype.indexInformation;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = NativeCollection;
|
||||
267
node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
Normal file
267
node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseConnection = require('../../connection')
|
||||
, mongo = require('mongodb')
|
||||
, Server = mongo.Server
|
||||
, STATES = require('../../connectionstate')
|
||||
, ReplSetServers = mongo.ReplSetServers;
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation.
|
||||
*
|
||||
* @inherits Connection
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function NativeConnection() {
|
||||
MongooseConnection.apply(this, arguments);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from Connection.
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.__proto__ = MongooseConnection.prototype;
|
||||
|
||||
/**
|
||||
* Opens the connection to MongoDB.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Connection} this
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doOpen = function (fn) {
|
||||
var server
|
||||
, self = this;
|
||||
|
||||
if (!this.db) {
|
||||
server = new mongo.Server(this.host, this.port, this.options.server);
|
||||
this.db = new mongo.Db(this.name, server, this.options.db);
|
||||
}
|
||||
|
||||
this.db.open(function (err) {
|
||||
if (err) return fn(err);
|
||||
fn();
|
||||
listen(self);
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
function listen (conn) {
|
||||
if (conn._listening) return;
|
||||
conn._listening = true;
|
||||
|
||||
conn.db.on('close', function(){
|
||||
if (conn._closeCalled) return;
|
||||
|
||||
// the driver never emits an `open` event. auto_reconnect still
|
||||
// emits a `close` event but since we never get another
|
||||
// `open` we can't emit close
|
||||
if (conn.db.serverConfig.autoReconnect) {
|
||||
conn.readyState = STATES.disconnected;
|
||||
conn.emit('close');
|
||||
return;
|
||||
}
|
||||
conn.onClose();
|
||||
});
|
||||
conn.db.on('error', function(err){
|
||||
conn.emit('error', err);
|
||||
});
|
||||
conn.db.on('timeout', function(err){
|
||||
var error = new Error(err && err.err || 'connection timeout');
|
||||
conn.emit('error', error);
|
||||
});
|
||||
conn.db.on('open', function (err, db) {
|
||||
if (STATES.disconnected === conn.readyState && db && db.databaseName) {
|
||||
conn.readyState = STATES.connected;
|
||||
conn.emit('reconnected')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a connection to a MongoDB ReplicaSet.
|
||||
*
|
||||
* See description of [doOpen](#NativeConnection-doOpen) for server options. In this case `options.replset` is also passed to ReplSetServers.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @api private
|
||||
* @return {Connection} this
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doOpenSet = function (fn) {
|
||||
var servers = []
|
||||
, self = this;
|
||||
|
||||
if (!this.db) {
|
||||
this.hosts.forEach(function (server) {
|
||||
var host = server.host || server.ipc;
|
||||
var port = server.port || 27017;
|
||||
servers.push(new mongo.Server(host, port, self.options.server));
|
||||
})
|
||||
|
||||
var server = new ReplSetServers(servers, this.options.replset);
|
||||
this.db = new mongo.Db(this.name, server, this.options.db);
|
||||
|
||||
this.db.on('fullsetup', function () {
|
||||
self.emit('fullsetup')
|
||||
});
|
||||
}
|
||||
|
||||
this.db.open(function (err) {
|
||||
if (err) return fn(err);
|
||||
fn();
|
||||
listen(self);
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes the connection
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Connection} this
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doClose = function (fn) {
|
||||
this.db.close();
|
||||
if (fn) fn();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares default connection options for the node-mongodb-native driver.
|
||||
*
|
||||
* _NOTE: `passed` options take precedence over connection string options._
|
||||
*
|
||||
* @param {Object} passed options that were passed directly during connection
|
||||
* @param {Object} [connStrOptions] options that were passed in the connection string
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
|
||||
var o = passed || {};
|
||||
o.db || (o.db = {});
|
||||
o.server || (o.server = {});
|
||||
o.replset || (o.replset = {});
|
||||
o.server.socketOptions || (o.server.socketOptions = {});
|
||||
o.replset.socketOptions || (o.replset.socketOptions = {});
|
||||
|
||||
var opts = connStrOpts || {};
|
||||
Object.keys(opts).forEach(function (name) {
|
||||
switch (name) {
|
||||
case 'poolSize':
|
||||
if ('undefined' == typeof o.server.poolSize) {
|
||||
o.server.poolSize = o.replset.poolSize = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'slaveOk':
|
||||
if ('undefined' == typeof o.server.slave_ok) {
|
||||
o.server.slave_ok = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'autoReconnect':
|
||||
if ('undefined' == typeof o.server.auto_reconnect) {
|
||||
o.server.auto_reconnect = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'ssl':
|
||||
case 'socketTimeoutMS':
|
||||
case 'connectTimeoutMS':
|
||||
if ('undefined' == typeof o.server.socketOptions[name]) {
|
||||
o.server.socketOptions[name] = o.replset.socketOptions[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'retries':
|
||||
case 'reconnectWait':
|
||||
case 'rs_name':
|
||||
if ('undefined' == typeof o.replset[name]) {
|
||||
o.replset[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'replicaSet':
|
||||
if ('undefined' == typeof o.replset.rs_name) {
|
||||
o.replset.rs_name = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readSecondary':
|
||||
if ('undefined' == typeof o.replset.read_secondary) {
|
||||
o.replset.read_secondary = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'nativeParser':
|
||||
if ('undefined' == typeof o.db.native_parser) {
|
||||
o.db.native_parser = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'w':
|
||||
case 'safe':
|
||||
case 'fsync':
|
||||
case 'journal':
|
||||
case 'wtimeoutMS':
|
||||
if ('undefined' == typeof o.db[name]) {
|
||||
o.db[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readPreference':
|
||||
if ('undefined' == typeof o.db.read_preference) {
|
||||
o.db.read_preference = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readPreferenceTags':
|
||||
if ('undefined' == typeof o.db.read_preference_tags) {
|
||||
o.db.read_preference_tags = opts[name];
|
||||
}
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
if (!('auto_reconnect' in o.server)) {
|
||||
o.server.auto_reconnect = true;
|
||||
}
|
||||
|
||||
if (!o.db.read_preference) {
|
||||
// read from primaries by default
|
||||
o.db.read_preference = 'primary';
|
||||
}
|
||||
|
||||
// mongoose creates its own ObjectIds
|
||||
o.db.forceServerObjectId = false;
|
||||
|
||||
// default safe using new nomenclature
|
||||
if (!('journal' in o.db || 'j' in o.db ||
|
||||
'fsync' in o.db || 'safe' in o.db || 'w' in o.db)) {
|
||||
o.db.w = 1;
|
||||
}
|
||||
|
||||
validate(o);
|
||||
return o;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Validates the driver db options.
|
||||
*
|
||||
* @param {Object} o
|
||||
*/
|
||||
|
||||
function validate (o) {
|
||||
if (-1 === o.db.w || 0 === o.db.w) {
|
||||
if (o.db.journal || o.db.fsync || o.db.safe) {
|
||||
throw new Error(
|
||||
'Invalid writeConcern: '
|
||||
+ 'w set to -1 or 0 cannot be combined with safe|fsync|journal');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = NativeConnection;
|
||||
29
node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
generated
vendored
Normal file
29
node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
/*!
|
||||
* [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) ObjectId
|
||||
* @constructor NodeMongoDbObjectId
|
||||
* @see ObjectId
|
||||
*/
|
||||
|
||||
var ObjectId = require('mongodb').BSONPure.ObjectID;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
var ObjectIdToString = ObjectId.toString.bind(ObjectId);
|
||||
module.exports = exports = ObjectId;
|
||||
|
||||
ObjectId.fromString = function(str){
|
||||
// patch native driver bug in V0.9.6.4
|
||||
if (!('string' === typeof str && 24 === str.length)) {
|
||||
throw new Error("Invalid ObjectId");
|
||||
}
|
||||
|
||||
return ObjectId.createFromHexString(str);
|
||||
};
|
||||
|
||||
ObjectId.toString = function(oid){
|
||||
if (!arguments.length) return ObjectIdToString();
|
||||
return oid.toHexString();
|
||||
};
|
||||
38
node_modules/mongoose/lib/error.js
generated
vendored
Normal file
38
node_modules/mongoose/lib/error.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
/**
|
||||
* Mongoose error
|
||||
*
|
||||
* @api private
|
||||
* @inherits Error https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
|
||||
*/
|
||||
|
||||
function MongooseError (msg) {
|
||||
Error.call(this);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.message = msg;
|
||||
this.name = 'MongooseError';
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from Error.
|
||||
*/
|
||||
|
||||
MongooseError.prototype.__proto__ = Error.prototype;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = MongooseError;
|
||||
|
||||
/*!
|
||||
* Expose subclasses
|
||||
*/
|
||||
|
||||
MongooseError.CastError = require('./errors/cast');
|
||||
MongooseError.DocumentError = require('./errors/document');
|
||||
MongooseError.ValidationError = require('./errors/validation')
|
||||
MongooseError.ValidatorError = require('./errors/validator')
|
||||
MongooseError.VersionError =require('./errors/version')
|
||||
MongooseError.OverwriteModelError = require('./errors/overwriteModel')
|
||||
MongooseError.MissingSchemaError = require('./errors/missingSchema')
|
||||
35
node_modules/mongoose/lib/errors/cast.js
generated
vendored
Normal file
35
node_modules/mongoose/lib/errors/cast.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/**
|
||||
* Casting Error constructor.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} value
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function CastError (type, value, path) {
|
||||
MongooseError.call(this, 'Cast to ' + type + ' failed for value "' + value + '" at path "' + path + '"');
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'CastError';
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
this.path = path;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
CastError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = CastError;
|
||||
32
node_modules/mongoose/lib/errors/document.js
generated
vendored
Normal file
32
node_modules/mongoose/lib/errors/document.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
/*!
|
||||
* Module requirements
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error')
|
||||
|
||||
/**
|
||||
* Document Error
|
||||
*
|
||||
* @param {String} msg
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function DocumentError (msg) {
|
||||
MongooseError.call(this, msg);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'DocumentError';
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
DocumentError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = DocumentError;
|
||||
32
node_modules/mongoose/lib/errors/missingSchema.js
generated
vendored
Normal file
32
node_modules/mongoose/lib/errors/missingSchema.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/*!
|
||||
* MissingSchema Error constructor.
|
||||
*
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function MissingSchemaError (name) {
|
||||
var msg = 'Schema hasn\'t been registered for model "' + name + '".\n'
|
||||
+ 'Use mongoose.model(name, schema)';
|
||||
MongooseError.call(this, msg);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'MissingSchemaError';
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
MissingSchemaError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MissingSchemaError;
|
||||
30
node_modules/mongoose/lib/errors/overwriteModel.js
generated
vendored
Normal file
30
node_modules/mongoose/lib/errors/overwriteModel.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/*!
|
||||
* OverwriteModel Error constructor.
|
||||
*
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function OverwriteModelError (name) {
|
||||
MongooseError.call(this, 'Cannot overwrite `' + name + '` model once compiled.');
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'OverwriteModelError';
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
OverwriteModelError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = OverwriteModelError;
|
||||
43
node_modules/mongoose/lib/errors/validation.js
generated
vendored
Normal file
43
node_modules/mongoose/lib/errors/validation.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
/*!
|
||||
* Module requirements
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error')
|
||||
|
||||
/**
|
||||
* Document Validation Error
|
||||
*
|
||||
* @api private
|
||||
* @param {Document} instance
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function ValidationError (instance) {
|
||||
MongooseError.call(this, "Validation failed");
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'ValidationError';
|
||||
this.errors = instance.errors = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Console.log helper
|
||||
*/
|
||||
|
||||
ValidationError.prototype.toString = function () {
|
||||
return this.name + ': ' + Object.keys(this.errors).map(function (key) {
|
||||
return String(this.errors[key]);
|
||||
}, this).join(', ');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
ValidationError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = exports = ValidationError;
|
||||
45
node_modules/mongoose/lib/errors/validator.js
generated
vendored
Normal file
45
node_modules/mongoose/lib/errors/validator.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/**
|
||||
* Schema validator error
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String} msg
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function ValidatorError (path, type) {
|
||||
var msg = type
|
||||
? '"' + type + '" '
|
||||
: '';
|
||||
MongooseError.call(this, 'Validator ' + msg + 'failed for path ' + path);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'ValidatorError';
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
};
|
||||
|
||||
/*!
|
||||
* toString helper
|
||||
*/
|
||||
|
||||
ValidatorError.prototype.toString = function () {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError
|
||||
*/
|
||||
|
||||
ValidatorError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = ValidatorError;
|
||||
31
node_modules/mongoose/lib/errors/version.js
generated
vendored
Normal file
31
node_modules/mongoose/lib/errors/version.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/**
|
||||
* Version Error constructor.
|
||||
*
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function VersionError () {
|
||||
MongooseError.call(this, 'No matching document found.');
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'VersionError';
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
VersionError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = VersionError;
|
||||
547
node_modules/mongoose/lib/index.js
generated
vendored
Normal file
547
node_modules/mongoose/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,547 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Schema = require('./schema')
|
||||
, SchemaType = require('./schematype')
|
||||
, VirtualType = require('./virtualtype')
|
||||
, SchemaTypes = Schema.Types
|
||||
, SchemaDefaults = require('./schemadefault')
|
||||
, Types = require('./types')
|
||||
, Query = require('./query')
|
||||
, Promise = require('./promise')
|
||||
, Model = require('./model')
|
||||
, Document = require('./document')
|
||||
, utils = require('./utils')
|
||||
, format = utils.toCollectionName
|
||||
, mongodb = require('mongodb')
|
||||
|
||||
/**
|
||||
* Mongoose constructor.
|
||||
*
|
||||
* The exports object of the `mongoose` module is an instance of this class.
|
||||
* Most apps will only use this one instance.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Mongoose () {
|
||||
this.connections = [];
|
||||
this.plugins = [];
|
||||
this.models = {};
|
||||
this.modelSchemas = {};
|
||||
this.options = {};
|
||||
this.createConnection(); // default connection
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets mongoose options
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* mongoose.set('test', value) // sets the 'test' option to `value`
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {String} value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.set = function (key, value) {
|
||||
if (arguments.length == 1)
|
||||
return this.options[key];
|
||||
this.options[key] = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets mongoose options
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* mongoose.get('test') // returns the 'test' value
|
||||
*
|
||||
* @param {String} key
|
||||
* @method get
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.get = Mongoose.prototype.set;
|
||||
|
||||
/*!
|
||||
* ReplSet connection string check.
|
||||
*/
|
||||
|
||||
var rgxReplSet = /^.+,.+$/;
|
||||
|
||||
/**
|
||||
* Creates a Connection instance.
|
||||
*
|
||||
* Each `connection` instance maps to a single database. This method is helpful when mangaging multiple db connections.
|
||||
*
|
||||
* If arguments are passed, they are proxied to either [Connection#open](#connection_Connection-open) or [Connection#openSet](#connection_Connection-openSet) appropriately. This means we can pass `db`, `server`, and `replset` options to the driver.
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* // with mongodb:// URI
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port/database');
|
||||
*
|
||||
* // and options
|
||||
* var opts = { db: { native_parser: true }}
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', opts);
|
||||
*
|
||||
* // replica sets
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port');
|
||||
*
|
||||
* // and options
|
||||
* var opts = { replset: { strategy: 'ping', rs_name: 'testSet' }}
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port', opts);
|
||||
*
|
||||
* // with [host, database_name[, port] signature
|
||||
* db = mongoose.createConnection('localhost', 'database', port)
|
||||
*
|
||||
* // and options
|
||||
* var opts = { server: { auto_reconnect: false }, user: 'username', pass: 'mypassword' }
|
||||
* db = mongoose.createConnection('localhost', 'database', port, opts)
|
||||
*
|
||||
* // initialize now, connect later
|
||||
* db = mongoose.createConnection();
|
||||
* db.open('localhost', 'database', port, [opts]);
|
||||
*
|
||||
* @param {String} [uri] a mongodb:// URI
|
||||
* @param {Object} [options] options to pass to the driver
|
||||
* @see Connection#open #connection_Connection-open
|
||||
* @see Connection#openSet #connection_Connection-openSet
|
||||
* @return {Connection} the created Connection object
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.createConnection = function () {
|
||||
var conn = new Connection(this);
|
||||
this.connections.push(conn);
|
||||
|
||||
if (arguments.length) {
|
||||
if (rgxReplSet.test(arguments[0])) {
|
||||
conn.openSet.apply(conn, arguments);
|
||||
} else {
|
||||
conn.open.apply(conn, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
return conn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opens the default mongoose connection.
|
||||
*
|
||||
* If arguments are passed, they are proxied to either [Connection#open](#connection_Connection-open) or [Connection#openSet](#connection_Connection-openSet) appropriately.
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
* @see Mongoose#createConnection #index_Mongoose-createConnection
|
||||
* @api public
|
||||
* @return {Mongoose} this
|
||||
*/
|
||||
|
||||
Mongoose.prototype.connect = function () {
|
||||
var conn = this.connection;
|
||||
|
||||
if (rgxReplSet.test(arguments[0])) {
|
||||
conn.openSet.apply(conn, arguments);
|
||||
} else {
|
||||
conn.open.apply(conn, arguments);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Disconnects all connections.
|
||||
*
|
||||
* @param {Function} [fn] called after all connection close.
|
||||
* @return {Mongoose} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.disconnect = function (fn) {
|
||||
var count = this.connections.length
|
||||
, error
|
||||
|
||||
this.connections.forEach(function(conn){
|
||||
conn.close(function(err){
|
||||
if (error) return;
|
||||
|
||||
if (err) {
|
||||
error = err;
|
||||
if (fn) return fn(err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (fn)
|
||||
--count || fn();
|
||||
});
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a model or retrieves it.
|
||||
*
|
||||
* Models defined on the `mongoose` instance are available to all connection created by the same `mongoose` instance.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
*
|
||||
* // define an Actor model with this mongoose instance
|
||||
* mongoose.model('Actor', new Schema({ name: String }));
|
||||
*
|
||||
* // create a new connection
|
||||
* var conn = mongoose.createConnection(..);
|
||||
*
|
||||
* // retrieve the Actor model
|
||||
* var Actor = conn.model('Actor');
|
||||
*
|
||||
* _When no `collection` argument is passed, Mongoose produces a collection name by passing the model `name` to the [utils.toCollectionName](#utils.toCollectionName) method. This method pluralizes the name. If you don't like this behavior, either pass a collection name or set your schemas collection name option._
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var schema = new Schema({ name: String }, { collection: 'actor' });
|
||||
*
|
||||
* // or
|
||||
*
|
||||
* schema.set('collection', 'actor');
|
||||
*
|
||||
* // or
|
||||
*
|
||||
* var collectionName = 'actor'
|
||||
* var M = mongoose.model('Actor', schema, collectionName)
|
||||
*
|
||||
* @param {String} name model name
|
||||
* @param {Schema} [schema]
|
||||
* @param {String} [collection] name (optional, induced from model name)
|
||||
* @param {Boolean} [skipInit] whether to skip initialization (defaults to false)
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
if (!(schema instanceof Schema)) {
|
||||
collection = schema;
|
||||
schema = false;
|
||||
}
|
||||
|
||||
if ('boolean' === typeof collection) {
|
||||
skipInit = collection;
|
||||
collection = null;
|
||||
}
|
||||
|
||||
// handle internal options from connection.model()
|
||||
var options;
|
||||
if (skipInit && utils.isObject(skipInit)) {
|
||||
options = skipInit;
|
||||
skipInit = true;
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
// look up schema for the collection. this might be a
|
||||
// default schema like system.indexes stored in SchemaDefaults.
|
||||
if (!this.modelSchemas[name]) {
|
||||
if (!schema && name in SchemaDefaults) {
|
||||
schema = SchemaDefaults[name];
|
||||
}
|
||||
|
||||
if (schema) {
|
||||
// cache it so we only apply plugins once
|
||||
this.modelSchemas[name] = schema;
|
||||
this._applyPlugins(schema);
|
||||
} else {
|
||||
throw new mongoose.Error.MissingSchemaError(name);
|
||||
}
|
||||
}
|
||||
|
||||
var model;
|
||||
var sub;
|
||||
|
||||
// connection.model() may be passing a different schema for
|
||||
// an existing model name. in this case don't read from cache.
|
||||
if (this.models[name] && false !== options.cache) {
|
||||
if (schema instanceof Schema && schema != this.models[name].schema) {
|
||||
throw new mongoose.Error.OverwriteModelError(name);
|
||||
}
|
||||
|
||||
if (collection) {
|
||||
// subclass current model with alternate collection
|
||||
model = this.models[name];
|
||||
schema = model.prototype.schema;
|
||||
sub = model.__subclass(this.connection, schema, collection);
|
||||
// do not cache the sub model
|
||||
return sub;
|
||||
}
|
||||
|
||||
return this.models[name];
|
||||
}
|
||||
|
||||
// ensure a schema exists
|
||||
if (!schema) {
|
||||
schema = this.modelSchemas[name];
|
||||
if (!schema) {
|
||||
throw new mongoose.Error.MissingSchemaError(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!collection) {
|
||||
collection = schema.get('collection') || format(name);
|
||||
}
|
||||
|
||||
var connection = options.connection || this.connection;
|
||||
model = Model.compile(name, schema, collection, connection, this);
|
||||
|
||||
if (!skipInit) {
|
||||
model.init();
|
||||
}
|
||||
|
||||
if (false === options.cache) {
|
||||
return model;
|
||||
}
|
||||
|
||||
return this.models[name] = model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies global plugins to `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mongoose.prototype._applyPlugins = function (schema) {
|
||||
for (var i = 0, l = this.plugins.length; i < l; i++) {
|
||||
schema.plugin(this.plugins[i][0], this.plugins[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares a global plugin executed on all Schemas.
|
||||
*
|
||||
* Equivalent to calling `.plugin(fn)` on each Schema you create.
|
||||
*
|
||||
* @param {Function} fn plugin callback
|
||||
* @param {Object} [opts] optional options
|
||||
* @return {Mongoose} this
|
||||
* @see plugins ./plugins.html
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.plugin = function (fn, opts) {
|
||||
this.plugins.push([fn, opts]);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* The default connection of the mongoose module.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* mongoose.connect(...);
|
||||
* mongoose.connection.on('error', cb);
|
||||
*
|
||||
* This is the connection used by default for every model created using [mongoose.model](#index_Mongoose-model).
|
||||
*
|
||||
* @property connection
|
||||
* @return {Connection}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.__defineGetter__('connection', function(){
|
||||
return this.connections[0];
|
||||
});
|
||||
|
||||
/*!
|
||||
* Driver depentend APIs
|
||||
*/
|
||||
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
|
||||
|
||||
/*!
|
||||
* Connection
|
||||
*/
|
||||
|
||||
var Connection = require(driver + '/connection');
|
||||
|
||||
/*!
|
||||
* Collection
|
||||
*/
|
||||
|
||||
var Collection = require(driver + '/collection');
|
||||
|
||||
/**
|
||||
* The exports object is an instance of Mongoose.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = exports = new Mongoose;
|
||||
var mongoose = module.exports;
|
||||
|
||||
/**
|
||||
* The Mongoose Collection constructor
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Collection = Collection;
|
||||
|
||||
/**
|
||||
* The Mongoose Connection constructor
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Connection = Connection;
|
||||
|
||||
/**
|
||||
* Mongoose version
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.version = JSON.parse(
|
||||
require('fs').readFileSync(__dirname + '/../package.json', 'utf8')
|
||||
).version;
|
||||
|
||||
/**
|
||||
* The Mongoose constructor
|
||||
*
|
||||
* The exports of the mongoose module is an instance of this class.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var mongoose2 = new mongoose.Mongoose();
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Mongoose = Mongoose;
|
||||
|
||||
/**
|
||||
* The Mongoose Schema constructor
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var Schema = mongoose.Schema;
|
||||
* var CatSchema = new Schema(..);
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Schema = Schema;
|
||||
|
||||
/**
|
||||
* The Mongoose SchemaType constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.SchemaType = SchemaType;
|
||||
|
||||
/**
|
||||
* The various Mongoose SchemaTypes.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _Alias of mongoose.Schema.Types for backwards compatibility._
|
||||
*
|
||||
* @see Schema.SchemaTypes #schema_Schema-Types
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.SchemaTypes = Schema.Types;
|
||||
|
||||
/**
|
||||
* The Mongoose VirtualType constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.VirtualType = VirtualType;
|
||||
|
||||
/**
|
||||
* The various Mongoose Types.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var array = mongoose.Types.Array;
|
||||
*
|
||||
* ####Types:
|
||||
*
|
||||
* - Array
|
||||
* - Buffer
|
||||
* - Document
|
||||
* - Embedded
|
||||
* - DocumentArray
|
||||
* - ObjectId
|
||||
*
|
||||
* Using this exposed access to the `ObjectId` type, we can construct ids on demand.
|
||||
*
|
||||
* var ObjectId = mongoose.Types.ObjectId;
|
||||
* var id1 = new ObjectId;
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Types = Types;
|
||||
|
||||
/**
|
||||
* The Mongoose Query constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Query = Query;
|
||||
|
||||
/**
|
||||
* The Mongoose Promise constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Promise = Promise;
|
||||
|
||||
/**
|
||||
* The Mongoose Model constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Model = Model;
|
||||
|
||||
/**
|
||||
* The Mongoose Document constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Document = Document;
|
||||
|
||||
/**
|
||||
* The MongooseError constructor.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.Error = require('./error');
|
||||
|
||||
/**
|
||||
* The node-mongodb-native driver Mongoose uses.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
mongoose.mongo = require('mongodb');
|
||||
1745
node_modules/mongoose/lib/model.js
generated
vendored
Normal file
1745
node_modules/mongoose/lib/model.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
70
node_modules/mongoose/lib/namedscope.js
generated
vendored
Normal file
70
node_modules/mongoose/lib/namedscope.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
var Query = require('./query');
|
||||
function NamedScope () {}
|
||||
|
||||
NamedScope.prototype.query;
|
||||
|
||||
NamedScope.prototype.where = function () {
|
||||
var q = this.query || (this.query = new Query());
|
||||
q.where.apply(q, arguments);
|
||||
return q;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decorate
|
||||
*
|
||||
* @param {NamedScope} target
|
||||
* @param {Object} getters
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NamedScope.prototype.decorate = function (target, getters) {
|
||||
var name = this.name
|
||||
, block = this.block
|
||||
, query = this.query;
|
||||
if (block) {
|
||||
if (block.length === 0) {
|
||||
Object.defineProperty(target, name, {
|
||||
get: getters.block0(block)
|
||||
});
|
||||
} else {
|
||||
target[name] = getters.blockN(block);
|
||||
}
|
||||
} else {
|
||||
Object.defineProperty(target, name, {
|
||||
get: getters.basic(query)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
NamedScope.prototype.compile = function (model) {
|
||||
var allScopes = this.scopesByName
|
||||
, scope;
|
||||
for (var k in allScopes) {
|
||||
scope = allScopes[k];
|
||||
scope.decorate(model, {
|
||||
block0: function (block) {
|
||||
return function () {
|
||||
var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
|
||||
block.call(cquery);
|
||||
return this;
|
||||
};
|
||||
},
|
||||
blockN: function (block) {
|
||||
return function () {
|
||||
var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
|
||||
block.apply(cquery, arguments);
|
||||
return this;
|
||||
};
|
||||
},
|
||||
basic: function (query) {
|
||||
return function () {
|
||||
var cquery = this._cumulativeQuery || (this._cumulativeQuery = new Query().bind(this));
|
||||
cquery.find(query);
|
||||
return this;
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = NamedScope;
|
||||
151
node_modules/mongoose/lib/promise.js
generated
vendored
Normal file
151
node_modules/mongoose/lib/promise.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var util = require('./utils');
|
||||
var EventEmitter = util.EventEmitter;
|
||||
|
||||
/**
|
||||
* Promise constructor.
|
||||
*
|
||||
* @param {Function} back a callback+errback that accepts `fn(err, ...){}` as signature
|
||||
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
|
||||
* @event `err`: Emits when the promise resolves to an error.
|
||||
* @event `complete`: Emits when the promise resolves sucessfully.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Promise (back) {
|
||||
this.emitted = {};
|
||||
if ('function' == typeof back)
|
||||
this.addBack(back);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from EventEmitter.
|
||||
*/
|
||||
|
||||
Promise.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
/**
|
||||
* Adds `listener` to the `event`.
|
||||
*
|
||||
* If `event` is either `error` or `complete` and the event has already been emitted, the`listener` is called immediately and passed the results of the original emitted event.
|
||||
*
|
||||
* @param {Event} event
|
||||
* @param {Function} callback
|
||||
* @return {Promise} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.on = function (event, callback) {
|
||||
if (this.emitted[event])
|
||||
callback.apply(this, this.emitted[event]);
|
||||
else
|
||||
EventEmitter.prototype.on.call(this, event, callback);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Keeps track of emitted events to run them on `on`.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Promise.prototype.emit = function (event) {
|
||||
// ensures a promise can't be complete() or error() twice
|
||||
if (event == 'err' || event == 'complete'){
|
||||
if (this.emitted.err || this.emitted.complete) {
|
||||
return this;
|
||||
}
|
||||
this.emitted[event] = util.args(arguments, 1);
|
||||
}
|
||||
|
||||
return EventEmitter.prototype.emit.apply(this, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut for emitting the `complete` event.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.complete = function () {
|
||||
var args = util.args(arguments);
|
||||
return this.emit.apply(this, ['complete'].concat(args));
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut for emitting the `err` event.
|
||||
*
|
||||
* @api public
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
Promise.prototype.error = function (err) {
|
||||
if (!(err instanceof Error)) err = new Error(err);
|
||||
return this.emit('err', err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut for `.on('complete', fn)`.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.addCallback = function (fn) {
|
||||
return this.on('complete', fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut for `.on('err', fn)`.
|
||||
*
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.addErrback = function (fn) {
|
||||
return this.on('err', fn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a single function that's both a callback and errback.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
Promise.prototype.addBack = function (fn) {
|
||||
this.on('err', function(err){
|
||||
fn.call(this, err);
|
||||
});
|
||||
|
||||
this.on('complete', function(){
|
||||
var args = util.args(arguments);
|
||||
fn.apply(this, [null].concat(args));
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sugar for handling cases where you may be resolving to either an error condition or a success condition.
|
||||
*
|
||||
* @param {Error} err optional error or null
|
||||
* @param {Object} val value to complete the promise with
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.resolve = function (err, val) {
|
||||
if (err) return this.error(err);
|
||||
return this.complete(val);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Promise;
|
||||
2395
node_modules/mongoose/lib/query.js
generated
vendored
Normal file
2395
node_modules/mongoose/lib/query.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
313
node_modules/mongoose/lib/querystream.js
generated
vendored
Normal file
313
node_modules/mongoose/lib/querystream.js
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Stream = require('stream').Stream
|
||||
var utils = require('./utils')
|
||||
|
||||
/**
|
||||
* Provides a [ReadStream](http://nodejs.org/api/stream.html#stream_readable_stream) interface for Queries.
|
||||
*
|
||||
* var stream = Model.find().stream();
|
||||
*
|
||||
* stream.on('data', function (doc) {
|
||||
* // do something with the mongoose document
|
||||
* }).on('error', function (err) {
|
||||
* // handle the error
|
||||
* }).on('close', function () {
|
||||
* // the stream is closed
|
||||
* });
|
||||
*
|
||||
*
|
||||
* The stream interface allows us to simply "plug-in" to other Node.js write streams (fs.createWriteStream) so everything "just works" out of the box.
|
||||
*
|
||||
* Model.where('created').gte(twoWeeksAgo).stream().pipe(writeStream);
|
||||
*
|
||||
* _NOTE: plugging into an HTTP response will *not* work out of the box. Those streams expect only strings or buffers to be emitted, so first formatting our documents as strings/buffers is necessary._
|
||||
*
|
||||
* @param {Query} query
|
||||
* @inherits NodeJS Stream http://nodejs.org/api/stream.html
|
||||
* @event `data`: emits a single Mongoose document
|
||||
* @event `error`: emits when an error occurs during streaming. This will emit _before_ the `close` event.
|
||||
* @event `close`: emits when the stream reaches the end of the cursor or an error occurs, or the stream is manually `destroy`ed. After this event, no more events are emitted.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function QueryStream (query) {
|
||||
Stream.call(this);
|
||||
|
||||
this.query = query;
|
||||
this.readable = true;
|
||||
this.paused = false;
|
||||
this._cursor = null;
|
||||
this._destroyed = null;
|
||||
this._fields = null;
|
||||
this._buffer = null;
|
||||
this._inline = T_INIT;
|
||||
this._running = false;
|
||||
|
||||
// give time to hook up events
|
||||
var self = this;
|
||||
process.nextTick(function () {
|
||||
self._init();
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from Stream
|
||||
*/
|
||||
|
||||
QueryStream.prototype.__proto__ = Stream.prototype;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is readable.
|
||||
*
|
||||
* @property readable
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.readable;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is paused.
|
||||
*
|
||||
* @property paused
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.paused;
|
||||
|
||||
// trampoline flags
|
||||
var T_INIT = 0;
|
||||
var T_IDLE = 1;
|
||||
var T_CONT = 2;
|
||||
|
||||
/**
|
||||
* Initializes the query.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._init = function () {
|
||||
if (this._destroyed) return;
|
||||
|
||||
var query = this.query
|
||||
, model = query.model
|
||||
, options = query._optionsForExec(model)
|
||||
, self = this
|
||||
|
||||
try {
|
||||
query.cast(model);
|
||||
} catch (err) {
|
||||
return self.destroy(err);
|
||||
}
|
||||
|
||||
self._fields = utils.clone(query._fields);
|
||||
options.fields = query._castFields(self._fields);
|
||||
|
||||
model.collection.find(query._conditions, options, function (err, cursor) {
|
||||
if (err) return self.destroy(err);
|
||||
self._cursor = cursor;
|
||||
self._next();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trampoline for pulling the next doc from cursor.
|
||||
*
|
||||
* @see QueryStream#__next #querystream_QueryStream-__next
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._next = function _next () {
|
||||
if (this.paused || this._destroyed) {
|
||||
return this._running = false;
|
||||
}
|
||||
|
||||
this._running = true;
|
||||
|
||||
if (this._buffer && this._buffer.length) {
|
||||
var arg;
|
||||
while (!this.paused && !this._destroyed && (arg = this._buffer.shift())) {
|
||||
this._onNextObject.apply(this, arg);
|
||||
}
|
||||
}
|
||||
|
||||
// avoid stack overflows with large result sets.
|
||||
// trampoline instead of recursion.
|
||||
while (this.__next()) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls the next doc from the cursor.
|
||||
*
|
||||
* @see QueryStream#_next #querystream_QueryStream-_next
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype.__next = function () {
|
||||
if (this.paused || this._destroyed)
|
||||
return this._running = false;
|
||||
|
||||
var self = this;
|
||||
self._inline = T_INIT;
|
||||
|
||||
self._cursor.nextObject(function cursorcb (err, doc) {
|
||||
self._onNextObject(err, doc);
|
||||
});
|
||||
|
||||
// if onNextObject() was already called in this tick
|
||||
// return ourselves to the trampoline.
|
||||
if (T_CONT === this._inline) {
|
||||
return true;
|
||||
} else {
|
||||
// onNextObject() hasn't fired yet. tell onNextObject
|
||||
// that its ok to call _next b/c we are not within
|
||||
// the trampoline anymore.
|
||||
this._inline = T_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms raw `doc`s returned from the cursor into a model instance.
|
||||
*
|
||||
* @param {Error|null} err
|
||||
* @param {Object} doc
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
|
||||
if (this._destroyed) return;
|
||||
|
||||
if (this.paused) {
|
||||
this._buffer || (this._buffer = []);
|
||||
this._buffer.push([err, doc]);
|
||||
return this._running = false;
|
||||
}
|
||||
|
||||
if (err) return this.destroy(err);
|
||||
|
||||
// when doc is null we hit the end of the cursor
|
||||
if (!doc) {
|
||||
this.emit('end');
|
||||
return this.destroy();
|
||||
}
|
||||
|
||||
if (this.query.options && true === this.query.options.lean) {
|
||||
this.emit('data', doc);
|
||||
|
||||
// trampoline management
|
||||
if (T_IDLE === this._inline) {
|
||||
// no longer in trampoline. restart it.
|
||||
this._next();
|
||||
} else {
|
||||
// in a trampoline. tell __next that its
|
||||
// ok to continue jumping.
|
||||
this._inline = T_CONT;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = new this.query.model(undefined, this._fields, true);
|
||||
|
||||
var self = this;
|
||||
instance.init(doc, this.query, function (err) {
|
||||
if (err) return self.destroy(err);
|
||||
self.emit('data', instance);
|
||||
|
||||
// trampoline management
|
||||
if (T_IDLE === self._inline) {
|
||||
// no longer in trampoline. restart it.
|
||||
self._next();
|
||||
} else
|
||||
// in a trampoline. tell __next that its
|
||||
// ok to continue jumping.
|
||||
self._inline = T_CONT;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses this stream.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.pause = function () {
|
||||
this.paused = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes this stream.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.resume = function () {
|
||||
this.paused = false;
|
||||
|
||||
if (!this._cursor) {
|
||||
// cannot start if not initialized
|
||||
return;
|
||||
}
|
||||
|
||||
// are we within the trampoline?
|
||||
if (T_INIT === this._inline) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._running) {
|
||||
// outside QueryStream control, need manual restart
|
||||
return this._next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the stream, closing the underlying cursor. No more events will be emitted.
|
||||
*
|
||||
* @param {Error} [err]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.destroy = function (err) {
|
||||
if (this._destroyed) return;
|
||||
this._destroyed = true;
|
||||
this._running = false;
|
||||
this.readable = false;
|
||||
|
||||
if (this._cursor) {
|
||||
this._cursor.close();
|
||||
}
|
||||
|
||||
if (err) {
|
||||
this.emit('error', err);
|
||||
}
|
||||
|
||||
this.emit('close');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipes this query stream into another stream. This method is inherited from NodeJS Streams.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* query.stream().pipe(writeStream [, options])
|
||||
*
|
||||
* This could be particularily useful if you are, for example, setting up an API for a service and want to stream out the docs based on some criteria. We could first pipe the QueryStream into a sort of filter that formats the stream as an array before passing on the document to an http response.
|
||||
*
|
||||
* var format = new ArrayFormatter;
|
||||
* Events.find().stream().pipe(format).pipe(res);
|
||||
*
|
||||
* As long as ArrayFormat implements the WriteStream API we can stream large formatted result sets out to the client. See this [gist](https://gist.github.com/1403797) for a hacked example.
|
||||
*
|
||||
* @method pipe
|
||||
* @memberOf QueryStream
|
||||
* @see NodeJS http://nodejs.org/api/stream.html
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = exports = QueryStream;
|
||||
869
node_modules/mongoose/lib/schema.js
generated
vendored
Normal file
869
node_modules/mongoose/lib/schema.js
generated
vendored
Normal file
@@ -0,0 +1,869 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
, VirtualType = require('./virtualtype')
|
||||
, utils = require('./utils')
|
||||
, NamedScope
|
||||
, Query
|
||||
, Types
|
||||
|
||||
/**
|
||||
* Schema constructor.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var child = new Schema({ name: String });
|
||||
* var schema = new Schema({ name: String, age: Number, children: [child] });
|
||||
* var Tree = mongoose.model('Tree', schema);
|
||||
*
|
||||
* // setting schema options
|
||||
* new Schema({ name: String }, { _id: false, autoIndex: false })
|
||||
*
|
||||
* ####Options:
|
||||
*
|
||||
* - [autoIndex](/docs/guide.html#autoIndex): bool - defaults to true
|
||||
* - [capped](/docs/guide.html#capped): bool - defaults to false
|
||||
* - [collection](/docs/guide.html#collection): string - no default
|
||||
* - [id](/docs/guide.html#id): bool - defaults to true
|
||||
* - [_id](/docs/guide.html#_id): bool - defaults to true
|
||||
* - [read](/docs/guide.html#read): string
|
||||
* - [safe](/docs/guide.html#safe): bool - defaults to true.
|
||||
* - [shardKey](/docs/guide.html#shardKey): bool - defaults to `null`
|
||||
* - [strict](/docs/guide.html#strict): bool - defaults to true
|
||||
* - [toJSON](/docs/guide.html#toJSON) - object - no default
|
||||
* - [toObject](/docs/guide.html#toObject) - object - no default
|
||||
* - [versionKey](/docs/guide.html#versionKey): bool - defaults to "__v"
|
||||
* - `minimize`: bool - controls [document#toObject](#document_Document-toObject) behavior when called manually - defaults to true
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _When nesting schemas, (`children` in the example above), always declare the child schema first before passing it into is parent._
|
||||
*
|
||||
* @param {Object} definition
|
||||
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
|
||||
* @event `init`: Emitted after the schema is compiled into a `Model`.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Schema (obj, options) {
|
||||
if (!(this instanceof Schema))
|
||||
return new Schema(obj, options);
|
||||
|
||||
this.paths = {};
|
||||
this.subpaths = {};
|
||||
this.virtuals = {};
|
||||
this.nested = {};
|
||||
this.inherits = {};
|
||||
this.callQueue = [];
|
||||
this._indexes = [];
|
||||
this.methods = {};
|
||||
this.statics = {};
|
||||
this.tree = {};
|
||||
this._requiredpaths = undefined;
|
||||
|
||||
this.options = this.defaultOptions(options);
|
||||
|
||||
// build paths
|
||||
if (obj) {
|
||||
this.add(obj);
|
||||
}
|
||||
|
||||
// ensure the documents get an auto _id unless disabled
|
||||
var auto_id = !this.paths['_id'] && (!this.options.noId && this.options._id);
|
||||
if (auto_id) {
|
||||
this.add({ _id: {type: Schema.ObjectId, auto: true} });
|
||||
}
|
||||
|
||||
// ensure the documents receive an id getter unless disabled
|
||||
var autoid = !this.paths['id'] && (!this.options.noVirtualId && this.options.id);
|
||||
if (autoid) {
|
||||
this.virtual('id').get(idGetter);
|
||||
}
|
||||
|
||||
// versioning not directly added to schema b/c we only want
|
||||
// it in the top level document, not embedded ones.
|
||||
};
|
||||
|
||||
/*!
|
||||
* Returns this documents _id cast to a string.
|
||||
*/
|
||||
|
||||
function idGetter () {
|
||||
if (this.__id) {
|
||||
return this.__id;
|
||||
}
|
||||
|
||||
return this.__id = null == this._id
|
||||
? null
|
||||
: String(this._id);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from EventEmitter.
|
||||
*/
|
||||
|
||||
Schema.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
/**
|
||||
* Schema as flat paths
|
||||
*
|
||||
* ####Example:
|
||||
* {
|
||||
* '_id' : SchemaType,
|
||||
* , 'nested.key' : SchemaType,
|
||||
* }
|
||||
*
|
||||
* @api private
|
||||
* @property paths
|
||||
*/
|
||||
|
||||
Schema.prototype.paths;
|
||||
|
||||
/**
|
||||
* Schema as a tree
|
||||
*
|
||||
* ####Example:
|
||||
* {
|
||||
* '_id' : ObjectId
|
||||
* , 'nested' : {
|
||||
* 'key' : String
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @api private
|
||||
* @property tree
|
||||
*/
|
||||
|
||||
Schema.prototype.tree;
|
||||
|
||||
/**
|
||||
* Returns default options for this schema, merged with `options`.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Schema.prototype.defaultOptions = function (options) {
|
||||
if (options && false === options.safe) {
|
||||
options.safe = { w: 0 };
|
||||
}
|
||||
|
||||
options = utils.options({
|
||||
strict: true
|
||||
, capped: false // { size, max, autoIndexId }
|
||||
, versionKey: '__v'
|
||||
, minimize: true
|
||||
, autoIndex: true
|
||||
, shardKey: null
|
||||
, read: null
|
||||
// the following are only applied at construction time
|
||||
, noId: false // deprecated, use { _id: false }
|
||||
, _id: true
|
||||
, noVirtualId: false // deprecated, use { id: false }
|
||||
, id: true
|
||||
}, options);
|
||||
|
||||
if (options.read)
|
||||
options.read = utils.readPref(options.read);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds key path / schema type pairs to this schema.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var ToySchema = new Schema;
|
||||
* ToySchema.add({ name: 'string', color: 'string', price: 'number' });
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {String} prefix
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.add = function add (obj, prefix) {
|
||||
prefix = prefix || '';
|
||||
for (var i in obj) {
|
||||
if (null == obj[i]) {
|
||||
throw new TypeError('Invalid value for schema path `'+ prefix + i +'`');
|
||||
}
|
||||
|
||||
if (obj[i].constructor.name == 'Object' && (!obj[i].type || obj[i].type.type)) {
|
||||
if (Object.keys(obj[i]).length) {
|
||||
// nested object { last: { name: String }}
|
||||
this.nested[prefix + i] = true;
|
||||
this.add(obj[i], prefix + i + '.');
|
||||
} else {
|
||||
this.path(prefix + i, obj[i]); // mixed type
|
||||
}
|
||||
} else {
|
||||
this.path(prefix + i, obj[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Reserved document keys.
|
||||
*
|
||||
* Keys in this object are names that are rejected in schema declarations b/c they conflict with mongoose functionality. Using these key name will throw an error.
|
||||
*
|
||||
* on, db, init, isNew, errors, schema, options, modelName, collection
|
||||
*
|
||||
* _NOTE:_ Use of these terms as method names is permitted, but play at your own risk, as they may be existing mongoose document methods you are stomping on.
|
||||
*
|
||||
* var schema = new Schema(..);
|
||||
* schema.methods.init = function () {} // potentially breaking
|
||||
*/
|
||||
|
||||
Schema.reserved = Object.create(null);
|
||||
var reserved = Schema.reserved;
|
||||
reserved.on =
|
||||
reserved.db =
|
||||
reserved.init =
|
||||
reserved.isNew =
|
||||
reserved.errors =
|
||||
reserved.schema =
|
||||
reserved.options =
|
||||
reserved.modelName =
|
||||
reserved._pres = reserved._posts = // hooks.js
|
||||
reserved.collection = 1;
|
||||
|
||||
/**
|
||||
* Gets/sets schema paths.
|
||||
*
|
||||
* Sets a path (if arity 2)
|
||||
* Gets a path (if arity 1)
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* schema.path('name') // returns a SchemaType
|
||||
* schema.path('name', Number) // changes the schemaType of `name` to Number
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} constructor
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.path = function (path, obj) {
|
||||
if (obj == undefined) {
|
||||
if (this.paths[path]) return this.paths[path];
|
||||
if (this.subpaths[path]) return this.subpaths[path];
|
||||
|
||||
// subpaths?
|
||||
return /\.\d+\.?$/.test(path)
|
||||
? getPositionalPath(this, path)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
// some path names conflict with document methods
|
||||
if (reserved[path]) {
|
||||
throw new Error("`" + path + "` may not be used as a schema pathname");
|
||||
}
|
||||
|
||||
// update the tree
|
||||
var subpaths = path.split(/\./)
|
||||
, last = subpaths.pop()
|
||||
, branch = this.tree;
|
||||
|
||||
subpaths.forEach(function(sub, i) {
|
||||
if (!branch[sub]) branch[sub] = {};
|
||||
if ('object' != typeof branch[sub]) {
|
||||
var msg = 'Cannot set nested path `' + path + '`. '
|
||||
+ 'Parent path `'
|
||||
+ subpaths.slice(0, i).concat([sub]).join('.')
|
||||
+ '` already set to type ' + branch[sub].name
|
||||
+ '.';
|
||||
throw new Error(msg);
|
||||
}
|
||||
branch = branch[sub];
|
||||
});
|
||||
|
||||
branch[last] = utils.clone(obj);
|
||||
|
||||
this.paths[path] = Schema.interpretAsType(path, obj);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts type arguments into Mongoose Types.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} obj constructor
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Schema.interpretAsType = function (path, obj) {
|
||||
if (obj.constructor.name != 'Object')
|
||||
obj = { type: obj };
|
||||
|
||||
// Get the type making sure to allow keys named "type"
|
||||
// and default to mixed if not specified.
|
||||
// { type: { type: String, default: 'freshcut' } }
|
||||
var type = obj.type && !obj.type.type
|
||||
? obj.type
|
||||
: {};
|
||||
|
||||
if ('Object' == type.constructor.name || 'mixed' == type) {
|
||||
return new Types.Mixed(path, obj);
|
||||
}
|
||||
|
||||
if (Array.isArray(type) || Array == type || 'array' == type) {
|
||||
// if it was specified through { type } look for `cast`
|
||||
var cast = (Array == type || 'array' == type)
|
||||
? obj.cast
|
||||
: type[0];
|
||||
|
||||
if (cast instanceof Schema) {
|
||||
return new Types.DocumentArray(path, cast, obj);
|
||||
}
|
||||
|
||||
if ('string' == typeof cast) {
|
||||
cast = Types[cast.charAt(0).toUpperCase() + cast.substring(1)];
|
||||
} else if (cast && (!cast.type || cast.type.type)
|
||||
&& 'Object' == cast.constructor.name
|
||||
&& Object.keys(cast).length) {
|
||||
return new Types.DocumentArray(path, new Schema(cast), obj);
|
||||
}
|
||||
|
||||
return new Types.Array(path, cast || Types.Mixed, obj);
|
||||
}
|
||||
|
||||
var name = 'string' == typeof type
|
||||
? type
|
||||
: type.name;
|
||||
|
||||
if (name) {
|
||||
name = name.charAt(0).toUpperCase() + name.substring(1);
|
||||
}
|
||||
|
||||
if (undefined == Types[name]) {
|
||||
throw new TypeError('Undefined type at `' + path +
|
||||
'`\n Did you try nesting Schemas? ' +
|
||||
'You can only nest using refs or arrays.');
|
||||
}
|
||||
|
||||
return new Types[name](path, obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterates the schemas paths similar to Array#forEach.
|
||||
*
|
||||
* The callback is passed the pathname and schemaType as arguments on each iteration.
|
||||
*
|
||||
* @param {Function} fn callback function
|
||||
* @return {Schema} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.eachPath = function (fn) {
|
||||
var keys = Object.keys(this.paths)
|
||||
, len = keys.length;
|
||||
|
||||
for (var i = 0; i < len; ++i) {
|
||||
fn(keys[i], this.paths[keys[i]]);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an Array of path strings that are required by this schema.
|
||||
*
|
||||
* @api public
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
Schema.prototype.requiredPaths = function requiredPaths () {
|
||||
if (this._requiredpaths) return this._requiredpaths;
|
||||
|
||||
var paths = Object.keys(this.paths)
|
||||
, i = paths.length
|
||||
, ret = [];
|
||||
|
||||
while (i--) {
|
||||
var path = paths[i];
|
||||
if (this.paths[path].isRequired) ret.push(path);
|
||||
}
|
||||
|
||||
return this._requiredpaths = ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pathType of `path` for this schema.
|
||||
*
|
||||
* Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.pathType = function (path) {
|
||||
if (path in this.paths) return 'real';
|
||||
if (path in this.virtuals) return 'virtual';
|
||||
if (path in this.nested) return 'nested';
|
||||
if (path in this.subpaths) return 'real';
|
||||
|
||||
if (/\.\d+\.?/.test(path) && getPositionalPath(this, path)) {
|
||||
return 'real';
|
||||
} else {
|
||||
return 'adhocOrUndefined'
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function getPositionalPath (self, path) {
|
||||
var subpaths = path.split(/\.(\d+)\.?/).filter(Boolean);
|
||||
if (subpaths.length < 2) {
|
||||
return self.paths[subpaths[0]];
|
||||
}
|
||||
|
||||
var val = self.path(subpaths[0]);
|
||||
if (!val) return val;
|
||||
|
||||
var last = subpaths.length - 1
|
||||
, subpath
|
||||
, i = 1;
|
||||
|
||||
for (; i < subpaths.length; ++i) {
|
||||
subpath = subpaths[i];
|
||||
|
||||
if (i === last &&
|
||||
val &&
|
||||
!val.schema &&
|
||||
!/\D/.test(subpath) &&
|
||||
val instanceof Types.Array) {
|
||||
// StringSchema, NumberSchema, etc
|
||||
val = val.caster;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 'path.0.subpath'
|
||||
if (!/\D/.test(subpath)) continue;
|
||||
val = val.schema.path(subpath);
|
||||
}
|
||||
|
||||
return self.subpaths[path] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a method call to the queue.
|
||||
*
|
||||
* @param {String} name name of the document method to call later
|
||||
* @param {Array} args arguments to pass to the method
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Schema.prototype.queue = function(name, args){
|
||||
this.callQueue.push([name, args]);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a pre hook for the document.
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* var toySchema = new Schema(..);
|
||||
*
|
||||
* toySchema.pre('save', function (next) {
|
||||
* if (!this.created) this.created = new Date;
|
||||
* next();
|
||||
* })
|
||||
*
|
||||
* toySchema.pre('validate', function (next) {
|
||||
* if (this.name != 'Woody') this.name = 'Woody';
|
||||
* next();
|
||||
* })
|
||||
*
|
||||
* @param {String} method
|
||||
* @param {Function} callback
|
||||
* @see hooks.js https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.pre = function(){
|
||||
return this.queue('pre', arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a post for the document
|
||||
*
|
||||
* Post hooks fire `on` the event emitted from document instances of Models compiled from this schema.
|
||||
*
|
||||
* var schema = new Schema(..);
|
||||
* schema.post('save', function (doc) {
|
||||
* console.log('this fired after a document was saved');
|
||||
* });
|
||||
*
|
||||
* var Model = mongoose.model('Model', schema);
|
||||
*
|
||||
* var m = new Model(..);
|
||||
* m.save(function (err) {
|
||||
* console.log('this fires after the `post` hook');
|
||||
* });
|
||||
*
|
||||
* @param {String} method name of the method to hook
|
||||
* @param {Function} fn callback
|
||||
* @see hooks.js https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.post = function(method, fn){
|
||||
return this.queue('on', arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers a plugin for this schema.
|
||||
*
|
||||
* @param {Function} plugin callback
|
||||
* @param {Object} opts
|
||||
* @see plugins
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.plugin = function (fn, opts) {
|
||||
fn(this, opts);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an instance method to documents constructed from Models compiled from this schema.
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* var schema = kittySchema = new Schema(..);
|
||||
*
|
||||
* schema.methods.meow = function () {
|
||||
* console.log('meeeeeoooooooooooow');
|
||||
* })
|
||||
*
|
||||
* var Kitty = mongoose.model('Kitty', schema);
|
||||
*
|
||||
* var fizz = new Kitty;
|
||||
* fizz.meow(); // meeeeeooooooooooooow
|
||||
*
|
||||
* If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as methods.
|
||||
*
|
||||
* schema.method({
|
||||
* purr: function () {}
|
||||
* , scratch: function () {}
|
||||
* });
|
||||
*
|
||||
* // later
|
||||
* fizz.purr();
|
||||
* fizz.scratch();
|
||||
*
|
||||
* @param {String|Object} method name
|
||||
* @param {Function} [fn]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.method = function (name, fn) {
|
||||
if ('string' != typeof name)
|
||||
for (var i in name)
|
||||
this.methods[i] = name[i];
|
||||
else
|
||||
this.methods[name] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds static "class" methods to Models compiled from this schema.
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* var schema = new Schema(..);
|
||||
* schema.static('findByName', function (name, callback) {
|
||||
* return this.find({ name: name }, callback);
|
||||
* });
|
||||
*
|
||||
* var Drink = mongoose.model('Drink', schema);
|
||||
* Drink.findByName('sanpellegrino', function (err, drinks) {
|
||||
* //
|
||||
* });
|
||||
*
|
||||
* If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as statics.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} fn
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.static = function(name, fn) {
|
||||
if ('string' != typeof name)
|
||||
for (var i in name)
|
||||
this.statics[i] = name[i];
|
||||
else
|
||||
this.statics[name] = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines an index (most likely compound) for this schema.
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* schema.index({ first: 1, last: -1 })
|
||||
*
|
||||
* @param {Object} fields
|
||||
* @param {Object} [options]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.index = function (fields, options) {
|
||||
options || (options = {});
|
||||
|
||||
if (options.expires)
|
||||
utils.expires(options);
|
||||
|
||||
this._indexes.push([fields, options]);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets/gets a schema option.
|
||||
*
|
||||
* @param {String} key option name
|
||||
* @param {Object} [value] if not passed, the current option value is returned
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.set = function (key, value, _tags) {
|
||||
if (1 === arguments.length) {
|
||||
return this.options[key];
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 'read':
|
||||
this.options[key] = utils.readPref(value, _tags)
|
||||
break;
|
||||
case 'safe':
|
||||
this.options[key] = false === value
|
||||
? { w: 0 }
|
||||
: value
|
||||
break;
|
||||
default:
|
||||
this.options[key] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a schema option.
|
||||
*
|
||||
* @param {String} key option name
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.get = function (key) {
|
||||
return this.options[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles indexes from fields and schema-level indexes
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.prototype.indexes = function () {
|
||||
var indexes = []
|
||||
, seenSchemas = [];
|
||||
|
||||
collectIndexes(this);
|
||||
|
||||
return indexes;
|
||||
|
||||
function collectIndexes (schema, prefix) {
|
||||
if (~seenSchemas.indexOf(schema)) return;
|
||||
seenSchemas.push(schema);
|
||||
|
||||
var index;
|
||||
var paths = schema.paths;
|
||||
prefix = prefix || '';
|
||||
|
||||
for (var i in paths) {
|
||||
if (paths[i]) {
|
||||
if (paths[i] instanceof Types.DocumentArray) {
|
||||
collectIndexes(paths[i].schema, i + '.');
|
||||
} else {
|
||||
index = paths[i]._index;
|
||||
|
||||
if (index !== false && index !== null){
|
||||
var field = {};
|
||||
field[prefix + i] = '2d' === index ? index : 1;
|
||||
var options = 'Object' === index.constructor.name ? index : {};
|
||||
if (!('background' in options)) options.background = true;
|
||||
indexes.push([field, options]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix) {
|
||||
fixSubIndexPaths(schema, prefix);
|
||||
} else {
|
||||
schema._indexes.forEach(function (index) {
|
||||
if (!('background' in index[1])) index[1].background = true;
|
||||
});
|
||||
indexes = indexes.concat(schema._indexes);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checks for indexes added to subdocs using Schema.index().
|
||||
* These indexes need their paths prefixed properly.
|
||||
*
|
||||
* schema._indexes = [ [indexObj, options], [indexObj, options] ..]
|
||||
*/
|
||||
|
||||
function fixSubIndexPaths (schema, prefix) {
|
||||
var subindexes = schema._indexes
|
||||
, len = subindexes.length
|
||||
, indexObj
|
||||
, newindex
|
||||
, klen
|
||||
, keys
|
||||
, key
|
||||
, i = 0
|
||||
, j
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
indexObj = subindexes[i][0];
|
||||
keys = Object.keys(indexObj);
|
||||
klen = keys.length;
|
||||
newindex = {};
|
||||
|
||||
// use forward iteration, order matters
|
||||
for (j = 0; j < klen; ++j) {
|
||||
key = keys[j];
|
||||
newindex[prefix + key] = indexObj[key];
|
||||
}
|
||||
|
||||
indexes.push([newindex, subindexes[i][1]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a virtual type with the given name.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} [options]
|
||||
* @return {VirtualType}
|
||||
*/
|
||||
|
||||
Schema.prototype.virtual = function (name, options) {
|
||||
var virtuals = this.virtuals;
|
||||
var parts = name.split('.');
|
||||
return virtuals[name] = parts.reduce(function (mem, part, i) {
|
||||
mem[part] || (mem[part] = (i === parts.length-1)
|
||||
? new VirtualType(options, name)
|
||||
: {});
|
||||
return mem[part];
|
||||
}, this.tree);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the virtual type with the given `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {VirtualType}
|
||||
*/
|
||||
|
||||
Schema.prototype.virtualpath = function (name) {
|
||||
return this.virtuals[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* These still haven't been fixed. Once they're working we'll make them public again.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Schema.prototype.namedScope = function (name, fn) {
|
||||
var namedScopes = this.namedScopes || (this.namedScopes = new NamedScope)
|
||||
, newScope = Object.create(namedScopes)
|
||||
, allScopes = namedScopes.scopesByName || (namedScopes.scopesByName = {});
|
||||
allScopes[name] = newScope;
|
||||
newScope.name = name;
|
||||
newScope.block = fn;
|
||||
newScope.query = new Query();
|
||||
newScope.decorate(namedScopes, {
|
||||
block0: function (block) {
|
||||
return function () {
|
||||
block.call(this.query);
|
||||
return this;
|
||||
};
|
||||
},
|
||||
blockN: function (block) {
|
||||
return function () {
|
||||
block.apply(this.query, arguments);
|
||||
return this;
|
||||
};
|
||||
},
|
||||
basic: function (query) {
|
||||
return function () {
|
||||
this.query.find(query);
|
||||
return this;
|
||||
};
|
||||
}
|
||||
});
|
||||
return newScope;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = Schema;
|
||||
|
||||
// require down here because of reference issues
|
||||
|
||||
/**
|
||||
* The various Mongoose Schema Types.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var ObjectId = mongoose.Schema.Types.ObjectId;
|
||||
*
|
||||
* ####Types:
|
||||
*
|
||||
* - String
|
||||
* - Number
|
||||
* - Boolean | Bool
|
||||
* - Array
|
||||
* - Buffer
|
||||
* - Date
|
||||
* - ObjectId | Oid
|
||||
* - Mixed
|
||||
*
|
||||
* Using this exposed access to the `Mixed` SchemaType, we can use them in our schema.
|
||||
*
|
||||
* var Mixed = mongoose.Schema.Types.Mixed;
|
||||
* new mongoose.Schema({ _user: Mixed })
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Schema.Types = require('./schema/index');
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
Types = Schema.Types;
|
||||
NamedScope = require('./namedscope')
|
||||
Query = require('./query');
|
||||
var ObjectId = exports.ObjectId = Types.ObjectId;
|
||||
|
||||
261
node_modules/mongoose/lib/schema/array.js
generated
vendored
Normal file
261
node_modules/mongoose/lib/schema/array.js
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, NumberSchema = require('./number')
|
||||
, Types = {
|
||||
Boolean: require('./boolean')
|
||||
, Date: require('./date')
|
||||
, Number: require('./number')
|
||||
, String: require('./string')
|
||||
, ObjectId: require('./objectid')
|
||||
, Buffer: require('./buffer')
|
||||
}
|
||||
, MongooseArray = require('../types').Array
|
||||
, EmbeddedDoc = require('../types').Embedded
|
||||
, Mixed = require('./mixed')
|
||||
, Query = require('../query')
|
||||
, isMongooseObject = require('../utils').isMongooseObject
|
||||
|
||||
/**
|
||||
* Array SchemaType constructor
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {SchemaType} cast
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaArray (key, cast, options) {
|
||||
if (cast) {
|
||||
var castOptions = {};
|
||||
|
||||
if ('Object' === cast.constructor.name) {
|
||||
if (cast.type) {
|
||||
// support { type: Woot }
|
||||
castOptions = cast;
|
||||
cast = cast.type;
|
||||
delete castOptions.type;
|
||||
} else {
|
||||
cast = Mixed;
|
||||
}
|
||||
}
|
||||
|
||||
var caster = cast.name in Types ? Types[cast.name] : cast;
|
||||
this.casterConstructor = caster;
|
||||
this.caster = new caster(null, castOptions);
|
||||
if (!(this.caster instanceof EmbeddedDoc)) {
|
||||
this.caster.path = key;
|
||||
}
|
||||
}
|
||||
|
||||
SchemaType.call(this, key, options);
|
||||
|
||||
var self = this
|
||||
, defaultArr
|
||||
, fn;
|
||||
|
||||
if (this.defaultValue) {
|
||||
defaultArr = this.defaultValue;
|
||||
fn = 'function' == typeof defaultArr;
|
||||
}
|
||||
|
||||
this.default(function(){
|
||||
var arr = fn ? defaultArr() : defaultArr || [];
|
||||
return new MongooseArray(arr, self.path, this);
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Check required
|
||||
*
|
||||
* @param {Array} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.checkRequired = function (value) {
|
||||
return !!(value && value.length);
|
||||
};
|
||||
|
||||
/**
|
||||
* Overrides the getters application for the population special-case
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.applyGetters = function (value, scope) {
|
||||
if (this.caster.options && this.caster.options.ref) {
|
||||
// means the object id was populated
|
||||
return value;
|
||||
}
|
||||
|
||||
return SchemaType.prototype.applyGetters.call(this, value, scope);
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Document} doc document that triggers the casting
|
||||
* @param {Boolean} init whether this is an initialization cast
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.cast = function (value, doc, init) {
|
||||
if (Array.isArray(value)) {
|
||||
if (!(value instanceof MongooseArray)) {
|
||||
value = new MongooseArray(value, this.path, doc);
|
||||
}
|
||||
|
||||
if (this.caster) {
|
||||
try {
|
||||
for (var i = 0, l = value.length; i < l; i++) {
|
||||
value[i] = this.caster.cast(value[i], doc, init);
|
||||
}
|
||||
} catch (e) {
|
||||
// rethrow
|
||||
throw new CastError(e.type, value, this.path);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
} else {
|
||||
return this.cast([value], doc, init);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [value]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.castForQuery = function ($conditional, value) {
|
||||
var handler
|
||||
, val;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler)
|
||||
throw new Error("Can't use " + $conditional + " with Array.");
|
||||
val = handler.call(this, value);
|
||||
} else {
|
||||
val = $conditional;
|
||||
var proto = this.casterConstructor.prototype;
|
||||
var method = proto.castForQuery || proto.cast;
|
||||
|
||||
var caster = this.caster;
|
||||
if (Array.isArray(val)) {
|
||||
val = val.map(function (v) {
|
||||
if (method) v = method.call(caster, v);
|
||||
|
||||
return isMongooseObject(v)
|
||||
? v.toObject()
|
||||
: v;
|
||||
});
|
||||
} else if (method) {
|
||||
val = method.call(caster, val);
|
||||
}
|
||||
}
|
||||
return val && isMongooseObject(val)
|
||||
? val.toObject()
|
||||
: val;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
function castToNumber (val) {
|
||||
return Types.Number.prototype.cast.call(this, val);
|
||||
}
|
||||
|
||||
SchemaArray.prototype.$conditionalHandlers = {
|
||||
'$all': function handle$all (val) {
|
||||
if (!Array.isArray(val)) {
|
||||
val = [val];
|
||||
}
|
||||
|
||||
val = val.map(function (v) {
|
||||
if (v && 'Object' === v.constructor.name) {
|
||||
var o = {};
|
||||
o[this.path] = v;
|
||||
var query = new Query(o);
|
||||
query.cast(this.casterConstructor);
|
||||
return query._conditions[this.path];
|
||||
}
|
||||
return v;
|
||||
}, this);
|
||||
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
, '$elemMatch': function (val) {
|
||||
if (val.$in) {
|
||||
val.$in = this.castForQuery('$in', val.$in);
|
||||
return val;
|
||||
}
|
||||
|
||||
var query = new Query(val);
|
||||
query.cast(this.casterConstructor);
|
||||
return query._conditions;
|
||||
}
|
||||
, '$size': castToNumber
|
||||
, '$ne': SchemaArray.prototype.castForQuery
|
||||
, '$in': SchemaArray.prototype.castForQuery
|
||||
, '$nin': SchemaArray.prototype.castForQuery
|
||||
, '$regex': SchemaArray.prototype.castForQuery
|
||||
, '$near': SchemaArray.prototype.castForQuery
|
||||
, '$nearSphere': SchemaArray.prototype.castForQuery
|
||||
, '$gt': SchemaArray.prototype.castForQuery
|
||||
, '$gte': SchemaArray.prototype.castForQuery
|
||||
, '$lt': SchemaArray.prototype.castForQuery
|
||||
, '$lte': SchemaArray.prototype.castForQuery
|
||||
, '$within': function (val) {
|
||||
var self = this;
|
||||
|
||||
if (val.$maxDistance) {
|
||||
val.$maxDistance = castToNumber.call(this, val.$maxDistance);
|
||||
}
|
||||
|
||||
if (val.$box || val.$polygon) {
|
||||
var type = val.$box ? '$box' : '$polygon';
|
||||
val[type].forEach(function (arr) {
|
||||
arr.forEach(function (v, i) {
|
||||
arr[i] = castToNumber.call(this, v);
|
||||
});
|
||||
})
|
||||
} else if (val.$center || val.$centerSphere) {
|
||||
var type = val.$center ? '$center' : '$centerSphere';
|
||||
val[type].forEach(function (item, i) {
|
||||
if (Array.isArray(item)) {
|
||||
item.forEach(function (v, j) {
|
||||
item[j] = castToNumber.call(this, v);
|
||||
});
|
||||
} else {
|
||||
val[type][i] = castToNumber.call(this, item);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
, '$maxDistance': castToNumber
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaArray;
|
||||
91
node_modules/mongoose/lib/schema/boolean.js
generated
vendored
Normal file
91
node_modules/mongoose/lib/schema/boolean.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype');
|
||||
|
||||
/**
|
||||
* Boolean SchemaType constructor.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaBoolean (path, options) {
|
||||
SchemaType.call(this, path, options);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
SchemaBoolean.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Required validator
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.checkRequired = function (value) {
|
||||
return value === true || value === false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to boolean
|
||||
*
|
||||
* @param {Object} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.cast = function (value) {
|
||||
if (value === null) return value;
|
||||
if (value === '0') return false;
|
||||
return !!value;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaBoolean.$conditionalHandlers = {
|
||||
'$in': handleArray
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
if (2 === arguments.length) {
|
||||
handler = SchemaBoolean.$conditionalHandlers[$conditional];
|
||||
|
||||
if (handler) {
|
||||
return handler.call(this, val);
|
||||
}
|
||||
|
||||
return this.cast(val);
|
||||
}
|
||||
|
||||
return this.cast($conditional);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaBoolean;
|
||||
118
node_modules/mongoose/lib/schema/buffer.js
generated
vendored
Normal file
118
node_modules/mongoose/lib/schema/buffer.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, MongooseBuffer = require('../types').Buffer
|
||||
, Binary = MongooseBuffer.Binary
|
||||
, Query = require('../query');
|
||||
|
||||
/**
|
||||
* Buffer SchemaType constructor
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {SchemaType} cast
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaBuffer (key, options) {
|
||||
SchemaType.call(this, key, options, 'Buffer');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Check required
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.checkRequired = function (value) {
|
||||
return !!(value && value.length);
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Document} doc document that triggers the casting
|
||||
* @param {Boolean} init
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.cast = function (value, doc, init) {
|
||||
if (SchemaType._isRef(this, value, init)) return value;
|
||||
|
||||
if (Buffer.isBuffer(value)) {
|
||||
if (!(value instanceof MongooseBuffer)) {
|
||||
value = new MongooseBuffer(value, [this.path, doc]);
|
||||
}
|
||||
|
||||
return value;
|
||||
} else if (value instanceof Binary) {
|
||||
return new MongooseBuffer(value.value(true), [this.path, doc]);
|
||||
}
|
||||
|
||||
if ('string' === typeof value || Array.isArray(value)) {
|
||||
return new MongooseBuffer(value, [this.path, doc]);
|
||||
}
|
||||
|
||||
throw new CastError('buffer', value, this.path);
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
function handleSingle (val) {
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map( function (m) {
|
||||
return self.castForQuery(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaBuffer.prototype.$conditionalHandlers = {
|
||||
'$ne' : handleSingle
|
||||
, '$in' : handleArray
|
||||
, '$nin': handleArray
|
||||
, '$gt' : handleSingle
|
||||
, '$lt' : handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$lte': handleSingle
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [value]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler)
|
||||
throw new Error("Can't use " + $conditional + " with Buffer.");
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
val = $conditional;
|
||||
return this.cast(val).toObject();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaBuffer;
|
||||
126
node_modules/mongoose/lib/schema/date.js
generated
vendored
Normal file
126
node_modules/mongoose/lib/schema/date.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
|
||||
/*!
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError;
|
||||
|
||||
/**
|
||||
* Date SchemaType constructor.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaDate (key, options) {
|
||||
SchemaType.call(this, key, options);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Required validator for date
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.checkRequired = function (value) {
|
||||
return value instanceof Date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to date
|
||||
*
|
||||
* @param {Object} value to cast
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.cast = function (value) {
|
||||
if (value === null || value === '')
|
||||
return null;
|
||||
|
||||
if (value instanceof Date)
|
||||
return value;
|
||||
|
||||
var date;
|
||||
|
||||
// support for timestamps
|
||||
if (value instanceof Number || 'number' == typeof value
|
||||
|| String(value) == Number(value))
|
||||
date = new Date(Number(value));
|
||||
|
||||
// support for date strings
|
||||
else if (value.toString)
|
||||
date = new Date(value.toString());
|
||||
|
||||
if (date.toString() != 'Invalid Date')
|
||||
return date;
|
||||
|
||||
throw new CastError('date', value, this.path);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Date Query casting.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
return this.cast(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map( function (m) {
|
||||
return self.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaDate.prototype.$conditionalHandlers = {
|
||||
'$lt': handleSingle
|
||||
, '$lte': handleSingle
|
||||
, '$gt': handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$ne': handleSingle
|
||||
, '$in': handleArray
|
||||
, '$nin': handleArray
|
||||
, '$all': handleArray
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [value]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
|
||||
if (2 !== arguments.length) {
|
||||
return this.cast($conditional);
|
||||
}
|
||||
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
|
||||
if (!handler) {
|
||||
throw new Error("Can't use " + $conditional + " with Date.");
|
||||
}
|
||||
|
||||
return handler.call(this, val);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaDate;
|
||||
189
node_modules/mongoose/lib/schema/documentarray.js
generated
vendored
Normal file
189
node_modules/mongoose/lib/schema/documentarray.js
generated
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, ArrayType = require('./array')
|
||||
, MongooseDocumentArray = require('../types/documentarray')
|
||||
, Subdocument = require('../types/embedded')
|
||||
, Document = require('../document');
|
||||
|
||||
/**
|
||||
* SubdocsArray SchemaType constructor
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Schema} schema
|
||||
* @param {Object} options
|
||||
* @inherits SchemaArray
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function DocumentArray (key, schema, options) {
|
||||
|
||||
// compile an embedded document for this schema
|
||||
function EmbeddedDocument () {
|
||||
Subdocument.apply(this, arguments);
|
||||
}
|
||||
|
||||
EmbeddedDocument.prototype.__proto__ = Subdocument.prototype;
|
||||
EmbeddedDocument.prototype._setSchema(schema);
|
||||
EmbeddedDocument.schema = schema;
|
||||
|
||||
// apply methods
|
||||
for (var i in schema.methods) {
|
||||
EmbeddedDocument.prototype[i] = schema.methods[i];
|
||||
}
|
||||
|
||||
// apply statics
|
||||
for (var i in schema.statics)
|
||||
EmbeddedDocument[i] = schema.statics[i];
|
||||
|
||||
EmbeddedDocument.options = options;
|
||||
this.schema = schema;
|
||||
|
||||
ArrayType.call(this, key, EmbeddedDocument, options);
|
||||
|
||||
this.schema = schema;
|
||||
var path = this.path;
|
||||
var fn = this.defaultValue;
|
||||
|
||||
this.default(function(){
|
||||
var arr = fn.call(this);
|
||||
if (!Array.isArray(arr)) arr = [arr];
|
||||
return new MongooseDocumentArray(arr, path, this);
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from ArrayType.
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.__proto__ = ArrayType.prototype;
|
||||
|
||||
/**
|
||||
* Performs local validations first, then validations on each embedded doc
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.doValidate = function (array, fn, scope) {
|
||||
var self = this;
|
||||
|
||||
SchemaType.prototype.doValidate.call(this, array, function (err) {
|
||||
if (err) return fn(err);
|
||||
|
||||
var count = array && array.length
|
||||
, error;
|
||||
|
||||
if (!count) return fn();
|
||||
|
||||
// handle sparse arrays, do not use array.forEach which does not
|
||||
// iterate over sparse elements yet reports array.length including
|
||||
// them :(
|
||||
|
||||
for (var i = 0, len = count; i < len; ++i) {
|
||||
// sidestep sparse entries
|
||||
var doc = array[i];
|
||||
if (!doc) {
|
||||
--count || fn();
|
||||
continue;
|
||||
}
|
||||
|
||||
;(function (i) {
|
||||
doc.validate(function (err) {
|
||||
if (err && !error) {
|
||||
// rewrite the key
|
||||
err.key = self.key + '.' + i + '.' + err.key;
|
||||
return fn(error = err);
|
||||
}
|
||||
--count || fn();
|
||||
});
|
||||
})(i);
|
||||
}
|
||||
}, scope);
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Document} document that triggers the casting
|
||||
* @api private
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.cast = function (value, doc, init, prev) {
|
||||
var selected
|
||||
, subdoc
|
||||
, i
|
||||
|
||||
if (!Array.isArray(value)) {
|
||||
return this.cast([value], doc, init, prev);
|
||||
}
|
||||
|
||||
if (!(value instanceof MongooseDocumentArray)) {
|
||||
value = new MongooseDocumentArray(value, this.path, doc);
|
||||
}
|
||||
|
||||
i = value.length;
|
||||
|
||||
while (i--) {
|
||||
if (!(value[i] instanceof Subdocument) && value[i]) {
|
||||
if (init) {
|
||||
selected || (selected = scopePaths(this, doc._selected, init));
|
||||
subdoc = new this.casterConstructor(null, value, true, selected);
|
||||
value[i] = subdoc.init(value[i]);
|
||||
} else {
|
||||
if (prev && (subdoc = prev.id(value[i]._id))) {
|
||||
// handle resetting doc with existing id but differing data
|
||||
// doc.array = [{ doc: 'val' }]
|
||||
subdoc.set(value[i]);
|
||||
} else {
|
||||
subdoc = new this.casterConstructor(value[i], value);
|
||||
}
|
||||
|
||||
// if set() is hooked it will have no return value
|
||||
// see gh-746
|
||||
value[i] = subdoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Scopes paths selected in a query to this array.
|
||||
* Necessary for proper default application of subdocument values.
|
||||
*
|
||||
* @param {DocumentArray} array - the array to scope `fields` paths
|
||||
* @param {Object|undefined} fields - the root fields selected in the query
|
||||
* @param {Boolean|undefined} init - if we are being created part of a query result
|
||||
*/
|
||||
|
||||
function scopePaths (array, fields, init) {
|
||||
if (!(init && fields)) return undefined;
|
||||
|
||||
var path = array.path + '.'
|
||||
, keys = Object.keys(fields)
|
||||
, i = keys.length
|
||||
, selected = {}
|
||||
, hasKeys
|
||||
, key
|
||||
|
||||
while (i--) {
|
||||
key = keys[i];
|
||||
if (0 === key.indexOf(path)) {
|
||||
hasKeys || (hasKeys = true);
|
||||
selected[key.substring(path.length)] = fields[key];
|
||||
}
|
||||
}
|
||||
|
||||
return hasKeys && selected || undefined;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = DocumentArray;
|
||||
28
node_modules/mongoose/lib/schema/index.js
generated
vendored
Normal file
28
node_modules/mongoose/lib/schema/index.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
exports.String = require('./string');
|
||||
|
||||
exports.Number = require('./number');
|
||||
|
||||
exports.Boolean = require('./boolean');
|
||||
|
||||
exports.DocumentArray = require('./documentarray');
|
||||
|
||||
exports.Array = require('./array');
|
||||
|
||||
exports.Buffer = require('./buffer');
|
||||
|
||||
exports.Date = require('./date');
|
||||
|
||||
exports.ObjectId = require('./objectid');
|
||||
|
||||
exports.Mixed = require('./mixed');
|
||||
|
||||
// alias
|
||||
|
||||
exports.Oid = exports.ObjectId;
|
||||
exports.Object = exports.Mixed;
|
||||
exports.Bool = exports.Boolean;
|
||||
75
node_modules/mongoose/lib/schema/mixed.js
generated
vendored
Normal file
75
node_modules/mongoose/lib/schema/mixed.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype');
|
||||
|
||||
/**
|
||||
* Mixed SchemaType constructor.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Mixed (path, options) {
|
||||
// make sure empty array defaults are handled
|
||||
if (options &&
|
||||
options.default &&
|
||||
Array.isArray(options.default) &&
|
||||
0 === options.default.length) {
|
||||
options.default = Array;
|
||||
}
|
||||
|
||||
SchemaType.call(this, path, options);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
Mixed.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Required validator
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.checkRequired = function (val) {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts `val` for Mixed.
|
||||
*
|
||||
* _this is a no-op_
|
||||
*
|
||||
* @param {Object} value to cast
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.cast = function (val) {
|
||||
return val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $cond
|
||||
* @param {any} [val]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.castForQuery = function ($cond, val) {
|
||||
if (arguments.length === 2) return val;
|
||||
return $cond;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = Mixed;
|
||||
182
node_modules/mongoose/lib/schema/number.js
generated
vendored
Normal file
182
node_modules/mongoose/lib/schema/number.js
generated
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/*!
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
|
||||
/**
|
||||
* Number SchemaType constructor.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaNumber (key, options) {
|
||||
SchemaType.call(this, key, options, 'Number');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Required validator for number
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.checkRequired = function checkRequired (value) {
|
||||
if (SchemaType._isRef(this, value, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return typeof value == 'number' || value instanceof Number;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a maximum number validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ n: { type: Number, min: 10 })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ n: 9 })
|
||||
* m.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* m.n = 10;
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* @param {Number} value minimum number
|
||||
* @param {String} message
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.min = function (value, message) {
|
||||
if (this.minValidator)
|
||||
this.validators = this.validators.filter(function(v){
|
||||
return v[1] != 'min';
|
||||
});
|
||||
if (value != null)
|
||||
this.validators.push([function(v){
|
||||
return v === null || v >= value;
|
||||
}, 'min']);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a maximum number validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ n: { type: Number, max: 10 })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ n: 11 })
|
||||
* m.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* m.n = 10;
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* @param {Number} maximum number
|
||||
* @param {String} message
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.max = function (value, message) {
|
||||
if (this.maxValidator)
|
||||
this.validators = this.validators.filter(function(v){
|
||||
return v[1] != 'max';
|
||||
});
|
||||
if (value != null)
|
||||
this.validators.push([this.maxValidator = function(v){
|
||||
return v === null || v <= value;
|
||||
}, 'max']);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to number
|
||||
*
|
||||
* @param {Object} value value to cast
|
||||
* @param {Document} doc document that triggers the casting
|
||||
* @param {Boolean} init
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.cast = function (value, doc, init) {
|
||||
if (SchemaType._isRef(this, value, init)) return value;
|
||||
|
||||
if (!isNaN(value)){
|
||||
if (null === value) return value;
|
||||
if ('' === value) return null;
|
||||
if ('string' == typeof value) value = Number(value);
|
||||
if (value instanceof Number) return value
|
||||
if ('number' == typeof value) return value;
|
||||
if (value.toString && !Array.isArray(value) &&
|
||||
value.toString() == Number(value)) {
|
||||
return new Number(value)
|
||||
}
|
||||
}
|
||||
|
||||
throw new CastError('number', value, this.path);
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
return this.cast(val)
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map( function (m) {
|
||||
return self.cast(m)
|
||||
});
|
||||
}
|
||||
|
||||
SchemaNumber.prototype.$conditionalHandlers = {
|
||||
'$lt' : handleSingle
|
||||
, '$lte': handleSingle
|
||||
, '$gt' : handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$ne' : handleSingle
|
||||
, '$in' : handleArray
|
||||
, '$nin': handleArray
|
||||
, '$mod': handleArray
|
||||
, '$all': handleArray
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [value]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler)
|
||||
throw new Error("Can't use " + $conditional + " with Number.");
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
val = this.cast($conditional);
|
||||
return val == null ? val : val
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaNumber;
|
||||
151
node_modules/mongoose/lib/schema/objectid.js
generated
vendored
Normal file
151
node_modules/mongoose/lib/schema/objectid.js
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, driver = global.MONGOOSE_DRIVER_PATH || './../drivers/node-mongodb-native'
|
||||
, oid = require('../types/objectid');
|
||||
|
||||
|
||||
/**
|
||||
* ObjectId SchemaType constructor.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function ObjectId (key, options) {
|
||||
SchemaType.call(this, key, options, 'ObjectID');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
ObjectId.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Check required
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.checkRequired = function checkRequired (value) {
|
||||
if (SchemaType._isRef(this, value, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return value instanceof oid;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to ObjectId
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @param {Boolean} init whether this is an initialization cast
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.cast = function (value, scope, init) {
|
||||
if (SchemaType._isRef(this, value, init)) return value;
|
||||
|
||||
if (value === null) return value;
|
||||
|
||||
if (value instanceof oid)
|
||||
return value;
|
||||
|
||||
if (value._id && value._id instanceof oid)
|
||||
return value._id;
|
||||
|
||||
if (value.toString) {
|
||||
try {
|
||||
return oid.fromString(value.toString());
|
||||
} catch (err) {
|
||||
throw new CastError('ObjectId', value, this.path);
|
||||
}
|
||||
}
|
||||
|
||||
throw new CastError('ObjectId', value, this.path);
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
return this.cast(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
ObjectId.prototype.$conditionalHandlers = {
|
||||
'$ne': handleSingle
|
||||
, '$in': handleArray
|
||||
, '$nin': handleArray
|
||||
, '$gt': handleSingle
|
||||
, '$lt': handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$lte': handleSingle
|
||||
, '$all': handleArray
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [val]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler)
|
||||
throw new Error("Can't use " + $conditional + " with ObjectId.");
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
return this.cast($conditional);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an auto-generated ObjectId default if turnOn is true.
|
||||
* @param {Boolean} turnOn auto generated ObjectId defaults
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.auto = function (turnOn) {
|
||||
if (turnOn) {
|
||||
this.default(defaultId);
|
||||
this.set(resetId)
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function defaultId () {
|
||||
return new oid();
|
||||
};
|
||||
|
||||
function resetId (v) {
|
||||
this.__id = null;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = ObjectId;
|
||||
255
node_modules/mongoose/lib/schema/string.js
generated
vendored
Normal file
255
node_modules/mongoose/lib/schema/string.js
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError;
|
||||
|
||||
/**
|
||||
* String SchemaType constructor.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaString (key, options) {
|
||||
this.enumValues = [];
|
||||
this.regExp = null;
|
||||
SchemaType.call(this, key, options, 'String');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaString.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Adds enumeration values and a coinciding validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var states = 'opening open closing closed'.split(' ')
|
||||
* var s = new Schema({ state: { type: String, enum: states })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ state: 'invalid' })
|
||||
* m.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* m.state = 'open'
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* @param {String} [args...] enumeration values
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.enum = function () {
|
||||
var len = arguments.length;
|
||||
if (!len || undefined === arguments[0] || false === arguments[0]) {
|
||||
if (this.enumValidator){
|
||||
this.enumValidator = false;
|
||||
this.validators = this.validators.filter(function(v){
|
||||
return v[1] != 'enum';
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (undefined !== arguments[i]) {
|
||||
this.enumValues.push(this.cast(arguments[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.enumValidator) {
|
||||
var values = this.enumValues;
|
||||
this.enumValidator = function(v){
|
||||
return undefined === v || ~values.indexOf(v);
|
||||
};
|
||||
this.validators.push([this.enumValidator, 'enum']);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a lowercase setter.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ email: { type: String, lowercase: true }})
|
||||
* var M = db.model('M', s);
|
||||
* var m = new M({ email: 'SomeEmail@example.COM' });
|
||||
* console.log(m.email) // someemail@example.com
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.lowercase = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.toLowerCase();
|
||||
return v;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an uppercase setter.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ caps: { type: String, uppercase: true }})
|
||||
* var M = db.model('M', s);
|
||||
* var m = new M({ caps: 'an example' });
|
||||
* console.log(m.caps) // AN EXAMPLE
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.uppercase = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.toUpperCase();
|
||||
return v;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a trim setter.
|
||||
*
|
||||
* The string value will be trimmed when set.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, trim: true }})
|
||||
* var M = db.model('M', s)
|
||||
* var string = ' some name '
|
||||
* console.log(string.length) // 11
|
||||
* var m = new M({ name: string })
|
||||
* console.log(m.name.length) // 9
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.trim = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.trim();
|
||||
return v;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a regexp validator.
|
||||
*
|
||||
* Any value that does not pass `regExp`.test(val) will fail validation.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, match: /^a/ }})
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ name: 'invalid' })
|
||||
* m.validate(function (err) {
|
||||
* console.error(err) // validation error
|
||||
* m.name = 'apples'
|
||||
* m.validate(function (err) {
|
||||
* assert.ok(err) // success
|
||||
* })
|
||||
* })
|
||||
*
|
||||
* @param {RegExp} regExp regular expression to test against
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.match = function match (regExp) {
|
||||
this.validators.push([function(v){
|
||||
return null != v && '' !== v
|
||||
? regExp.test(v)
|
||||
: true
|
||||
}, 'regexp']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check required
|
||||
*
|
||||
* @param {String|null|undefined} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaString.prototype.checkRequired = function checkRequired (value) {
|
||||
if (SchemaType._isRef(this, value, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return (value instanceof String || typeof value == 'string') && value.length;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to String
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaString.prototype.cast = function (value, scope, init) {
|
||||
if (SchemaType._isRef(this, value, init)) return value;
|
||||
if (value === null) return value;
|
||||
if ('undefined' !== typeof value && value.toString) return value.toString();
|
||||
throw new CastError('string', value, this.path);
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.castForQuery(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaString.prototype.$conditionalHandlers = {
|
||||
'$ne' : handleSingle
|
||||
, '$in' : handleArray
|
||||
, '$nin': handleArray
|
||||
, '$gt' : handleSingle
|
||||
, '$lt' : handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$lte': handleSingle
|
||||
, '$all': handleArray
|
||||
, '$regex': handleSingle
|
||||
, '$options': handleSingle
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [val]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaString.prototype.castForQuery = function ($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler)
|
||||
throw new Error("Can't use " + $conditional + " with String.");
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
val = $conditional;
|
||||
if (val instanceof RegExp) return val;
|
||||
return this.cast(val);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = SchemaString;
|
||||
34
node_modules/mongoose/lib/schemadefault.js
generated
vendored
Normal file
34
node_modules/mongoose/lib/schemadefault.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Schema = require('./schema')
|
||||
|
||||
/**
|
||||
* Default model for querying the system.profiles collection.
|
||||
*
|
||||
* @property system.profile
|
||||
* @receiver exports
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports['system.profile'] = new Schema({
|
||||
ts: Date
|
||||
, info: String // deprecated
|
||||
, millis: Number
|
||||
, op: String
|
||||
, ns: String
|
||||
, query: Schema.Types.Mixed
|
||||
, updateobj: Schema.Types.Mixed
|
||||
, ntoreturn: Number
|
||||
, nreturned: Number
|
||||
, nscanned: Number
|
||||
, responseLength: Number
|
||||
, client: String
|
||||
, user: String
|
||||
, idhack: Boolean
|
||||
, scanAndOrder: Boolean
|
||||
, keyUpdates: Number
|
||||
, cursorid: Number
|
||||
}, { noVirtualId: true, noId: true });
|
||||
657
node_modules/mongoose/lib/schematype.js
generated
vendored
Normal file
657
node_modules/mongoose/lib/schematype.js
generated
vendored
Normal file
@@ -0,0 +1,657 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
var CastError = require('./error').CastError;
|
||||
var ValidatorError = require('./error').ValidatorError;
|
||||
|
||||
/**
|
||||
* SchemaType constructor
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Object} [options]
|
||||
* @param {String} [instance]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaType (path, options, instance) {
|
||||
this.path = path;
|
||||
this.instance = instance;
|
||||
this.validators = [];
|
||||
this.setters = [];
|
||||
this.getters = [];
|
||||
this.options = options;
|
||||
this._index = null;
|
||||
this.selected;
|
||||
|
||||
for (var i in options) if (this[i] && 'function' == typeof this[i]) {
|
||||
// { unique: true, index: true }
|
||||
if ('index' == i && this._index) continue;
|
||||
|
||||
var opts = Array.isArray(options[i])
|
||||
? options[i]
|
||||
: [options[i]];
|
||||
|
||||
this[i].apply(this, opts);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a default value for this SchemaType.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var schema = new Schema({ n: { type: Number, default: 10 })
|
||||
* var M = db.model('M', schema)
|
||||
* var m = new M;
|
||||
* console.log(m.n) // 10
|
||||
*
|
||||
* Defaults can be either `functions` which return the value to use as the default or the literal value itself. Either way, the value will be cast based on its schema type before being set during document creation.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* // values are cast:
|
||||
* var schema = new Schema({ aNumber: Number, default: "4.815162342" })
|
||||
* var M = db.model('M', schema)
|
||||
* var m = new M;
|
||||
* console.log(m.aNumber) // 4.815162342
|
||||
*
|
||||
* // default unique objects for Mixed types:
|
||||
* var schema = new Schema({ mixed: Schema.Types.Mixed });
|
||||
* schema.path('mixed').default(function () {
|
||||
* return {};
|
||||
* });
|
||||
*
|
||||
* // if we don't use a function to return object literals for Mixed defaults,
|
||||
* // each document will receive a reference to the same object literal creating
|
||||
* // a "shared" object instance:
|
||||
* var schema = new Schema({ mixed: Schema.Types.Mixed });
|
||||
* schema.path('mixed').default({});
|
||||
* var M = db.model('M', schema);
|
||||
* var m1 = new M;
|
||||
* m1.mixed.added = 1;
|
||||
* console.log(m1.mixed); // { added: 1 }
|
||||
* var m2 = new M;
|
||||
* console.log(m2.mixed); // { added: 1 }
|
||||
*
|
||||
* @param {Function|any} val the default value
|
||||
* @return {defaultValue}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.default = function (val) {
|
||||
if (1 === arguments.length) {
|
||||
this.defaultValue = typeof val === 'function'
|
||||
? val
|
||||
: this.cast(val);
|
||||
return this;
|
||||
} else if (arguments.length > 1) {
|
||||
this.defaultValue = utils.args(arguments);
|
||||
}
|
||||
return this.defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares the index options for this schematype.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, index: true })
|
||||
* var s = new Schema({ date: { type: Date, index: { unique: true, expires: '1d' }})
|
||||
* Schema.path('my.path').index(true);
|
||||
* Schema.path('my.date').index({ expires: 60 });
|
||||
* Schema.path('my.path').index({ unique: true, sparse: true });
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _Indexes are created in the background by default. Specify `background: false` to override._
|
||||
*
|
||||
* [Direction doesn't matter for single key indexes](http://www.mongodb.org/display/DOCS/Indexes#Indexes-CompoundKeysIndexes)
|
||||
*
|
||||
* @param {Object|Boolean} options
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.index = function (options) {
|
||||
this._index = options;
|
||||
utils.expires(this._index);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares an unique index.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, unique: true })
|
||||
* Schema.path('name').index({ unique: true });
|
||||
*
|
||||
* _NOTE: violating the constraint returns an `E11000` error from MongoDB when saving, not a Mongoose validation error._
|
||||
*
|
||||
* @param {Boolean} bool
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.unique = function (bool) {
|
||||
if (!this._index || 'Object' !== this._index.constructor.name) {
|
||||
this._index = {};
|
||||
}
|
||||
|
||||
this._index.unique = bool;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares a sparse index.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, sparse: true })
|
||||
* Schema.path('name').index({ sparse: true });
|
||||
*
|
||||
* @param {Boolean} bool
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.sparse = function (bool) {
|
||||
if (!this._index || 'Object' !== this._index.constructor.name) {
|
||||
this._index = {};
|
||||
}
|
||||
|
||||
this._index.sparse = bool;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares a TTL index (rounded to the nearest second) for _Date_ types only.
|
||||
*
|
||||
* This sets the `expiresAfterSeconds` index option available in MongoDB >= 2.1.2.
|
||||
* This index type is only compatible with Date types.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* // expire in 24 hours
|
||||
* new Schema({ createdAt: { type: Date, expires: 60*60*24 }});
|
||||
*
|
||||
* `expires` utilizes the `ms` module from [guille](https://github.com/guille/) allowing us to use a friendlier syntax:
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* // expire in 24 hours
|
||||
* new Schema({ createdAt: { type: Date, expires: '24h' }});
|
||||
*
|
||||
* // expire in 1.5 hours
|
||||
* new Schema({ createdAt: { type: Date, expires: '1.5h' }});
|
||||
*
|
||||
* // expire in 7 days
|
||||
* var schema = new Schema({ createdAt: Date });
|
||||
* schema.path('createdAt').expires('7d');
|
||||
*
|
||||
* @param {Number|String} when
|
||||
* @added 3.0.0
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.expires = function (when) {
|
||||
if (!this._index || 'Object' !== this._index.constructor.name) {
|
||||
this._index = {};
|
||||
}
|
||||
|
||||
this._index.expires = when;
|
||||
utils.expires(this._index);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a setter to this schematype.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* function capitalize (val) {
|
||||
* if ('string' != typeof val) val = '';
|
||||
* return val.charAt(0).toUpperCase() + val.substring(1);
|
||||
* }
|
||||
*
|
||||
* // defining within the schema
|
||||
* var s = new Schema({ name: { type: String, set: capitalize }})
|
||||
*
|
||||
* // or by retreiving its SchemaType
|
||||
* var s = new Schema({ name: String })
|
||||
* s.path('name').set(capitalize)
|
||||
*
|
||||
* Setters allow you to transform the data before it gets to the raw mongodb document and is set as a value on an actual key.
|
||||
*
|
||||
* Suppose you are implementing user registration for a website. Users provide an email and password, which gets saved to mongodb. The email is a string that you will want to normalize to lower case, in order to avoid one email having more than one account -- e.g., otherwise, avenue@q.com can be registered for 2 accounts via avenue@q.com and AvEnUe@Q.CoM.
|
||||
*
|
||||
* You can set up email lower case normalization easily via a Mongoose setter.
|
||||
*
|
||||
* function toLower (v) {
|
||||
* return v.toLowerCase();
|
||||
* }
|
||||
*
|
||||
* var UserSchema = new Schema({
|
||||
* email: { type: String, set: toLower }
|
||||
* })
|
||||
*
|
||||
* var User = db.model('User', UserSchema)
|
||||
*
|
||||
* var user = new User({email: 'AVENUE@Q.COM'})
|
||||
* console.log(user.email); // 'avenue@q.com'
|
||||
*
|
||||
* // or
|
||||
* var user = new User
|
||||
* user.email = 'Avenue@Q.com'
|
||||
* console.log(user.email) // 'avenue@q.com'
|
||||
*
|
||||
* As you can see above, setters allow you to transform the data before it gets to the raw mongodb document and is set as a value on an actual key.
|
||||
*
|
||||
* _NOTE: we could have also just used the built-in `lowercase: true` SchemaType option instead of defining our own function._
|
||||
*
|
||||
* new Schema({ email: { type: String, lowercase: true }})
|
||||
*
|
||||
* Setters are also passed a second argument, the schematype on which the setter was defined. This allows for tailored behavior based on options passed in the schema.
|
||||
*
|
||||
* function inspector (val, schematype) {
|
||||
* if (schematype.options.required) {
|
||||
* return schematype.path + ' is required';
|
||||
* } else {
|
||||
* return val;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* var VirusSchema = new Schema({
|
||||
* name: { type: String, required: true, set: inspector },
|
||||
* taxonomy: { type: String, set: inspector }
|
||||
* })
|
||||
*
|
||||
* var Virus = db.model('Virus', VirusSchema);
|
||||
* var v = new Virus({ name: 'Parvoviridae', taxonomy: 'Parvovirinae' });
|
||||
*
|
||||
* console.log(v.name); // name is required
|
||||
* console.log(v.taxonomy); // Parvovirinae
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.set = function (fn) {
|
||||
if ('function' != typeof fn)
|
||||
throw new Error('A setter must be a function.');
|
||||
this.setters.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a getter to this schematype.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* function dob (val) {
|
||||
* if (!val) return val;
|
||||
* return (val.getMonth() + 1) + "/" + val.getDate() + "/" + val.getFullYear();
|
||||
* }
|
||||
*
|
||||
* // defining within the schema
|
||||
* var s = new Schema({ born: { type: Date, get: dob })
|
||||
*
|
||||
* // or by retreiving its SchemaType
|
||||
* var s = new Schema({ born: Date })
|
||||
* s.path('born').get(dob)
|
||||
*
|
||||
* Getters allow you to transform the representation of the data as it travels from the raw mongodb document to the value that you see.
|
||||
*
|
||||
* Suppose you are storing credit card numbers and you want to hide everything except the last 4 digits to the mongoose user. You can do so by defining a getter in the following way:
|
||||
*
|
||||
* function obfuscate (cc) {
|
||||
* return '****-****-****-' + cc.slice(cc.length-4, cc.length);
|
||||
* }
|
||||
*
|
||||
* var AccountSchema = new Schema({
|
||||
* creditCardNumber: { type: String, get: obfuscate }
|
||||
* });
|
||||
*
|
||||
* var Account = db.model('Account', AccountSchema);
|
||||
*
|
||||
* Account.findById(id, function (err, found) {
|
||||
* console.log(found.creditCardNumber); // '****-****-****-1234'
|
||||
* });
|
||||
*
|
||||
* Getters are also passed a second argument, the schematype on which the getter was defined. This allows for tailored behavior based on options passed in the schema.
|
||||
*
|
||||
* function inspector (val, schematype) {
|
||||
* if (schematype.options.required) {
|
||||
* return schematype.path + ' is required';
|
||||
* } else {
|
||||
* return schematype.path + ' is not';
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* var VirusSchema = new Schema({
|
||||
* name: { type: String, required: true, get: inspector },
|
||||
* taxonomy: { type: String, get: inspector }
|
||||
* })
|
||||
*
|
||||
* var Virus = db.model('Virus', VirusSchema);
|
||||
*
|
||||
* Virus.findById(id, function (err, virus) {
|
||||
* console.log(virus.name); // name is required
|
||||
* console.log(virus.taxonomy); // taxonomy is not
|
||||
* })
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.get = function (fn) {
|
||||
if ('function' != typeof fn)
|
||||
throw new Error('A getter must be a function.');
|
||||
this.getters.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds validator(s) for this document path.
|
||||
*
|
||||
* Validators always receive the value to validate as their first argument and must return `Boolean`. Returning false is interpreted as validation failure.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* function validator (val) {
|
||||
* return val == 'something';
|
||||
* }
|
||||
*
|
||||
* new Schema({ name: { type: String, validate: validator }});
|
||||
*
|
||||
* // with a custom error message
|
||||
*
|
||||
* var custom = [validator, 'validation failed']
|
||||
* new Schema({ name: { type: String, validate: custom }});
|
||||
*
|
||||
* var many = [
|
||||
* { validator: validator, msg: 'uh oh' }
|
||||
* , { validator: fn, msg: 'failed' }
|
||||
* ]
|
||||
* new Schema({ name: { type: String, validate: many }});
|
||||
*
|
||||
* // or utilizing SchemaType methods directly:
|
||||
*
|
||||
* var schema = new Schema({ name: 'string' });
|
||||
* schema.path('name').validate(validator, 'validation failed');
|
||||
*
|
||||
* ####Asynchronous validation:
|
||||
*
|
||||
* Passing a validator function that receives two arguments tells mongoose that the validator is an asynchronous validator. The second argument is an callback function that must be passed either `true` or `false` when validation is complete.
|
||||
*
|
||||
* schema.path('name').validate(function (value, respond) {
|
||||
* doStuff(value, function () {
|
||||
* ...
|
||||
* respond(false); // validation failed
|
||||
* })
|
||||
* }, 'my error type');
|
||||
*
|
||||
* You might use asynchronous validators to retreive other documents from the database to validate against or to meet other I/O bound validation needs.
|
||||
*
|
||||
* Validation occurs `pre('save')` or whenever you manually execute [document#validate](#document_Document-validate).
|
||||
*
|
||||
* If validation fails during `pre('save')` and no callback was passed to receive the error, an `error` event will be emitted on your Models associated db [connection](#connection_Connection), passing the validation error object along.
|
||||
*
|
||||
* var conn = mongoose.createConnection(..);
|
||||
* conn.on('error', handleError);
|
||||
*
|
||||
* var Product = conn.model('Product', yourSchema);
|
||||
* var dvd = new Product(..);
|
||||
* dvd.save(); // emits error on the `conn` above
|
||||
*
|
||||
* If you desire handling these errors at the Model level, attach an `error` listener to your Model and the event will instead be emitted there.
|
||||
*
|
||||
* // registering an error listener on the Model lets us handle errors more locally
|
||||
* Product.on('error', handleError);
|
||||
*
|
||||
* @param {RegExp|Function|Object} obj validator
|
||||
* @param {String} [error] optional error message
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.validate = function (obj, error) {
|
||||
if ('function' == typeof obj || obj && 'RegExp' === obj.constructor.name) {
|
||||
this.validators.push([obj, error]);
|
||||
return this;
|
||||
}
|
||||
|
||||
var i = arguments.length
|
||||
, arg
|
||||
|
||||
while (i--) {
|
||||
arg = arguments[i];
|
||||
if (!(arg && 'Object' == arg.constructor.name)) {
|
||||
var msg = 'Invalid validator. Received (' + typeof arg + ') '
|
||||
+ arg
|
||||
+ '. See http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate';
|
||||
|
||||
throw new Error(msg);
|
||||
}
|
||||
this.validate(arg.validator, arg.msg);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a required validator to this schematype.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ born: { type: Date, required: true })
|
||||
* // or
|
||||
* Schema.path('name').required(true);
|
||||
*
|
||||
*
|
||||
* @param {Boolean} required enable/disable the validator
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.required = function (required) {
|
||||
var self = this;
|
||||
|
||||
function __checkRequired (v) {
|
||||
// in here, `this` refers to the validating document.
|
||||
// no validation when this path wasn't selected in the query.
|
||||
if ('isSelected' in this &&
|
||||
!this.isSelected(self.path) &&
|
||||
!this.isModified(self.path)) return true;
|
||||
return self.checkRequired(v);
|
||||
}
|
||||
|
||||
if (false === required) {
|
||||
this.isRequired = false;
|
||||
this.validators = this.validators.filter(function (v) {
|
||||
return v[0].name !== '__checkRequired';
|
||||
});
|
||||
} else {
|
||||
this.isRequired = true;
|
||||
this.validators.push([__checkRequired, 'required']);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the default value
|
||||
*
|
||||
* @param {Object} scope the scope which callback are executed
|
||||
* @param {Boolean} init
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.getDefault = function (scope, init) {
|
||||
var ret = 'function' === typeof this.defaultValue
|
||||
? this.defaultValue.call(scope)
|
||||
: this.defaultValue;
|
||||
|
||||
if (null !== ret && undefined !== ret) {
|
||||
return this.cast(ret, scope, init);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies setters
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @param {Boolean} init
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
|
||||
if (SchemaType._isRef(this, value, init)) return value;
|
||||
|
||||
var v = value
|
||||
, setters = this.setters
|
||||
, len = setters.length
|
||||
|
||||
if (!len) {
|
||||
if (null === v || undefined === v) return v;
|
||||
return init
|
||||
? v // if we just initialized we dont recast
|
||||
: this.cast(v, scope, init, priorVal)
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
v = setters[len].call(scope, v, this);
|
||||
}
|
||||
|
||||
if (null === v || undefined === v) return v;
|
||||
|
||||
// do not cast until all setters are applied #665
|
||||
v = this.cast(v, scope, init, priorVal);
|
||||
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies getters to a value
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.applyGetters = function (value, scope) {
|
||||
if (SchemaType._isRef(this, value, true)) return value;
|
||||
|
||||
var v = value
|
||||
, getters = this.getters
|
||||
, len = getters.length;
|
||||
|
||||
if (!len) {
|
||||
return v;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
v = getters[len].call(scope, v, this);
|
||||
}
|
||||
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets default `select()` behavior for this path.
|
||||
*
|
||||
* Set to `true` if this path should always be included in the results, `false` if it should be excluded by default. This setting can be overridden at the query level.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* T = db.model('T', new Schema({ x: { type: String, select: true }}));
|
||||
* T.find(..); // field x will always be selected ..
|
||||
* // .. unless overridden;
|
||||
* T.find().select('-x').exec(callback);
|
||||
*
|
||||
* @param {Boolean} val
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.select = function select (val) {
|
||||
this.selected = !! val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a validation of `value` using the validators declared for this SchemaType.
|
||||
*
|
||||
* @param {any} value
|
||||
* @param {Function} callback
|
||||
* @param {Object} scope
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.doValidate = function (value, fn, scope) {
|
||||
var err = false
|
||||
, path = this.path
|
||||
, count = this.validators.length;
|
||||
|
||||
if (!count) return fn(null);
|
||||
|
||||
function validate (val, msg) {
|
||||
if (err) return;
|
||||
if (val === undefined || val) {
|
||||
--count || fn(null);
|
||||
} else {
|
||||
fn(err = new ValidatorError(path, msg));
|
||||
}
|
||||
}
|
||||
|
||||
this.validators.forEach(function (v) {
|
||||
var validator = v[0]
|
||||
, message = v[1];
|
||||
|
||||
if (validator instanceof RegExp) {
|
||||
validate(validator.test(value), message);
|
||||
} else if ('function' === typeof validator) {
|
||||
if (2 === validator.length) {
|
||||
validator.call(scope, value, function (val) {
|
||||
validate(val, message);
|
||||
});
|
||||
} else {
|
||||
validate(validator.call(scope, value), message);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if value is a valid Reference.
|
||||
*
|
||||
* @param {SchemaType} self
|
||||
* @param {Object} value
|
||||
* @param {Boolean} init
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType._isRef = function (self, value, init) {
|
||||
if (init && self.options && self.options.ref) {
|
||||
if (null == value) return true;
|
||||
if (value._id && value._id.constructor.name === self.instance) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = SchemaType;
|
||||
|
||||
exports.CastError = CastError;
|
||||
|
||||
exports.ValidatorError = ValidatorError;
|
||||
179
node_modules/mongoose/lib/statemachine.js
generated
vendored
Normal file
179
node_modules/mongoose/lib/statemachine.js
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
/*!
|
||||
* StateMachine represents a minimal `interface` for the
|
||||
* constructors it builds via StateMachine.ctor(...).
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var StateMachine = module.exports = exports = function StateMachine () {
|
||||
this.paths = {};
|
||||
this.states = {};
|
||||
}
|
||||
|
||||
/*!
|
||||
* StateMachine.ctor('state1', 'state2', ...)
|
||||
* A factory method for subclassing StateMachine.
|
||||
* The arguments are a list of states. For each state,
|
||||
* the constructor's prototype gets state transition
|
||||
* methods named after each state. These transition methods
|
||||
* place their path argument into the given state.
|
||||
*
|
||||
* @param {String} state
|
||||
* @param {String} [state]
|
||||
* @return {Function} subclass constructor
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.ctor = function () {
|
||||
var states = utils.args(arguments);
|
||||
|
||||
var ctor = function () {
|
||||
StateMachine.apply(this, arguments);
|
||||
this.stateNames = states;
|
||||
|
||||
var i = states.length
|
||||
, state;
|
||||
|
||||
while (i--) {
|
||||
state = states[i];
|
||||
this.states[state] = {};
|
||||
}
|
||||
};
|
||||
|
||||
ctor.prototype.__proto__ = StateMachine.prototype;
|
||||
|
||||
states.forEach(function (state) {
|
||||
// Changes the `path`'s state to `state`.
|
||||
ctor.prototype[state] = function (path) {
|
||||
this._changeState(path, state);
|
||||
}
|
||||
});
|
||||
|
||||
return ctor;
|
||||
};
|
||||
|
||||
/*!
|
||||
* This function is wrapped by the state change functions:
|
||||
*
|
||||
* - `require(path)`
|
||||
* - `modify(path)`
|
||||
* - `init(path)`
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
StateMachine.prototype._changeState = function _changeState (path, nextState) {
|
||||
var prevBucket = this.states[this.paths[path]];
|
||||
if (prevBucket) delete prevBucket[path];
|
||||
|
||||
this.paths[path] = nextState;
|
||||
this.states[nextState][path] = true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
StateMachine.prototype.clear = function clear (state) {
|
||||
var keys = Object.keys(this.states[state])
|
||||
, i = keys.length
|
||||
, path
|
||||
|
||||
while (i--) {
|
||||
path = keys[i];
|
||||
delete this.states[state][path];
|
||||
delete this.paths[path];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Checks to see if at least one path is in the states passed in via `arguments`
|
||||
* e.g., this.some('required', 'inited')
|
||||
*
|
||||
* @param {String} state that we want to check for.
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.some = function some () {
|
||||
var self = this;
|
||||
var what = arguments.length ? arguments : this.stateNames;
|
||||
return Array.prototype.some.call(what, function (state) {
|
||||
return Object.keys(self.states[state]).length;
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* This function builds the functions that get assigned to `forEach` and `map`,
|
||||
* since both of those methods share a lot of the same logic.
|
||||
*
|
||||
* @param {String} iterMethod is either 'forEach' or 'map'
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
StateMachine.prototype._iter = function _iter (iterMethod) {
|
||||
return function () {
|
||||
var numArgs = arguments.length
|
||||
, states = utils.args(arguments, 0, numArgs-1)
|
||||
, callback = arguments[numArgs-1];
|
||||
|
||||
if (!states.length) states = this.stateNames;
|
||||
|
||||
var self = this;
|
||||
|
||||
var paths = states.reduce(function (paths, state) {
|
||||
return paths.concat(Object.keys(self.states[state]));
|
||||
}, []);
|
||||
|
||||
return paths[iterMethod](function (path, i, paths) {
|
||||
return callback(path, i, paths);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Iterates over the paths that belong to one of the parameter states.
|
||||
*
|
||||
* The function profile can look like:
|
||||
* this.forEach(state1, fn); // iterates over all paths in state1
|
||||
* this.forEach(state1, state2, fn); // iterates over all paths in state1 or state2
|
||||
* this.forEach(fn); // iterates over all paths in all states
|
||||
*
|
||||
* @param {String} [state]
|
||||
* @param {String} [state]
|
||||
* @param {Function} callback
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.forEach = function forEach () {
|
||||
this.forEach = this._iter('forEach');
|
||||
return this.forEach.apply(this, arguments);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Maps over the paths that belong to one of the parameter states.
|
||||
*
|
||||
* The function profile can look like:
|
||||
* this.forEach(state1, fn); // iterates over all paths in state1
|
||||
* this.forEach(state1, state2, fn); // iterates over all paths in state1 or state2
|
||||
* this.forEach(fn); // iterates over all paths in all states
|
||||
*
|
||||
* @param {String} [state]
|
||||
* @param {String} [state]
|
||||
* @param {Function} callback
|
||||
* @return {Array}
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.map = function map () {
|
||||
this.map = this._iter('map');
|
||||
return this.map.apply(this, arguments);
|
||||
}
|
||||
|
||||
598
node_modules/mongoose/lib/types/array.js
generated
vendored
Normal file
598
node_modules/mongoose/lib/types/array.js
generated
vendored
Normal file
@@ -0,0 +1,598 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var EmbeddedDocument = require('./embedded');
|
||||
var Document = require('../document');
|
||||
var ObjectId = require('./objectid');
|
||||
|
||||
/**
|
||||
* Mongoose Array constructor.
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _Values always have to be passed to the constructor to initialize, otherwise `MongooseArray#push` will mark the array as modified._
|
||||
*
|
||||
* @param {Array} values
|
||||
* @param {String} path
|
||||
* @param {Document} doc parent document
|
||||
* @api private
|
||||
* @inherits Array
|
||||
* @see http://bit.ly/f6CnZU
|
||||
*/
|
||||
|
||||
function MongooseArray (values, path, doc) {
|
||||
var arr = [];
|
||||
arr.push.apply(arr, values);
|
||||
arr.__proto__ = MongooseArray.prototype;
|
||||
|
||||
arr._atomics = {};
|
||||
arr.validators = [];
|
||||
arr._path = path;
|
||||
|
||||
if (doc) {
|
||||
arr._parent = doc;
|
||||
arr._schema = doc.schema.path(path);
|
||||
}
|
||||
|
||||
return arr;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from Array
|
||||
*/
|
||||
|
||||
MongooseArray.prototype = new Array;
|
||||
|
||||
/**
|
||||
* Stores a queue of atomic operations to perform
|
||||
*
|
||||
* @property _atomics
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseArray.prototype._atomics;
|
||||
|
||||
/**
|
||||
* Parent owner document
|
||||
*
|
||||
* @property _parent
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseArray.prototype._parent;
|
||||
|
||||
/**
|
||||
* Casts a member based on this arrays schema.
|
||||
*
|
||||
* @param {any} value
|
||||
* @return value the casted value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseArray.prototype._cast = function (value) {
|
||||
var cast = this._schema.caster.cast
|
||||
, doc = this._parent;
|
||||
|
||||
return cast.call(null, value, doc);
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this array as modified.
|
||||
*
|
||||
* If it bubbles up from an embedded document change, then it takes the following arguments (otherwise, takes 0 arguments)
|
||||
*
|
||||
* @param {EmbeddedDocument} embeddedDoc the embedded doc that invoked this method on the Array
|
||||
* @param {String} embeddedPath the path which changed in the embeddedDoc
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseArray.prototype._markModified = function (elem, embeddedPath) {
|
||||
var parent = this._parent
|
||||
, dirtyPath;
|
||||
|
||||
if (parent) {
|
||||
dirtyPath = this._path;
|
||||
|
||||
if (arguments.length) {
|
||||
if (null != embeddedPath) {
|
||||
// an embedded doc bubbled up the change
|
||||
dirtyPath = dirtyPath + '.' + this.indexOf(elem) + '.' + embeddedPath;
|
||||
} else {
|
||||
// directly set an index
|
||||
dirtyPath = dirtyPath + '.' + elem;
|
||||
}
|
||||
|
||||
}
|
||||
parent.markModified(dirtyPath);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register an atomic operation with the parent.
|
||||
*
|
||||
* @param {Array} op operation
|
||||
* @param {any} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseArray.prototype._registerAtomic = function (op, val) {
|
||||
if ('$set' == op) {
|
||||
// $set takes precedence over all other ops.
|
||||
// mark entire array modified.
|
||||
this._atomics = { $set: val };
|
||||
return this;
|
||||
}
|
||||
|
||||
var atomics = this._atomics;
|
||||
|
||||
// reset pop/shift after save
|
||||
if ('$pop' == op && !('$pop' in atomics)) {
|
||||
var self = this;
|
||||
this._parent.once('save', function () {
|
||||
self._popped = self._shifted = null;
|
||||
});
|
||||
}
|
||||
|
||||
// check for impossible $atomic combos (Mongo denies more than one
|
||||
// $atomic op on a single path
|
||||
if (this._atomics.$set ||
|
||||
Object.keys(atomics).length && !(op in atomics)) {
|
||||
// a different op was previously registered.
|
||||
// save the entire thing.
|
||||
this._atomics = { $set: this };
|
||||
return this;
|
||||
}
|
||||
|
||||
if (op === '$pullAll' || op === '$pushAll' || op === '$addToSet') {
|
||||
atomics[op] || (atomics[op] = []);
|
||||
atomics[op] = atomics[op].concat(val);
|
||||
} else if (op === '$pullDocs') {
|
||||
var pullOp = atomics['$pull'] || (atomics['$pull'] = {})
|
||||
, selector = pullOp['_id'] || (pullOp['_id'] = {'$in' : [] });
|
||||
selector['$in'] = selector['$in'].concat(val);
|
||||
} else {
|
||||
atomics[op] = val;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the number of pending atomic operations to send to the db for this array.
|
||||
*
|
||||
* @api private
|
||||
* @return {Number}
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.hasAtomics = function hasAtomics () {
|
||||
if (!(this._atomics && 'Object' === this._atomics.constructor.name)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Object.keys(this._atomics).length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps [`Array#push`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/push) with proper change tracking.
|
||||
*
|
||||
* @param {Object} [args...]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.push = function () {
|
||||
var values = [].map.call(arguments, this._cast, this)
|
||||
, ret = [].push.apply(this, values);
|
||||
|
||||
// $pushAll might be fibbed (could be $push). But it makes it easier to
|
||||
// handle what could have been $push, $pushAll combos
|
||||
this._registerAtomic('$pushAll', values);
|
||||
this._markModified();
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pushes items to the array non-atomically.
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @param {any} [args...]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.nonAtomicPush = function () {
|
||||
var values = [].map.call(arguments, this._cast, this)
|
||||
, ret = [].push.apply(this, values);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pops the array atomically at most one time per document `save()`.
|
||||
*
|
||||
* #### NOTE:
|
||||
*
|
||||
* _Calling this mulitple times on an array before saving sends the same command as calling it once._
|
||||
* _This update is implemented using the MongoDB [$pop](http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop) method which enforces this restriction._
|
||||
*
|
||||
* doc.array = [1,2,3];
|
||||
*
|
||||
* var popped = doc.array.$pop();
|
||||
* console.log(popped); // 3
|
||||
* console.log(doc.array); // [1,2]
|
||||
*
|
||||
* // no affect
|
||||
* popped = doc.array.$pop();
|
||||
* console.log(doc.array); // [1,2]
|
||||
*
|
||||
* doc.save(function (err) {
|
||||
* if (err) return handleError(err);
|
||||
*
|
||||
* // we saved, now $pop works again
|
||||
* popped = doc.array.$pop();
|
||||
* console.log(popped); // 2
|
||||
* console.log(doc.array); // [1]
|
||||
* })
|
||||
*
|
||||
* @api public
|
||||
* @method $pop
|
||||
* @memberOf MongooseArray
|
||||
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.$pop = function () {
|
||||
this._registerAtomic('$pop', 1);
|
||||
this._markModified();
|
||||
|
||||
// only allow popping once
|
||||
if (this._popped) return;
|
||||
this._popped = true;
|
||||
|
||||
return [].pop.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps [`Array#pop`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/pop) with proper change tracking.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _marks the entire array as modified which will pass the entire thing to $set potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @see MongooseArray#$pop #types_array_MongooseArray-%24pop
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.pop = function () {
|
||||
var ret = [].pop.call(this);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Atomically shifts the array at most one time per document `save()`.
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _Calling this mulitple times on an array before saving sends the same command as calling it once._
|
||||
* _This update is implemented using the MongoDB [$pop](http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop) method which enforces this restriction._
|
||||
*
|
||||
* doc.array = [1,2,3];
|
||||
*
|
||||
* var shifted = doc.array.$shift();
|
||||
* console.log(shifted); // 1
|
||||
* console.log(doc.array); // [2,3]
|
||||
*
|
||||
* // no affect
|
||||
* shifted = doc.array.$shift();
|
||||
* console.log(doc.array); // [2,3]
|
||||
*
|
||||
* doc.save(function (err) {
|
||||
* if (err) return handleError(err);
|
||||
*
|
||||
* // we saved, now $shift works again
|
||||
* shifted = doc.array.$shift();
|
||||
* console.log(shifted ); // 2
|
||||
* console.log(doc.array); // [3]
|
||||
* })
|
||||
*
|
||||
* @api public
|
||||
* @memberOf MongooseArray
|
||||
* @method $shift
|
||||
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pop
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.$shift = function $shift () {
|
||||
this._registerAtomic('$pop', -1);
|
||||
this._markModified();
|
||||
|
||||
// only allow shifting once
|
||||
if (this._shifted) return;
|
||||
this._shifted = true;
|
||||
|
||||
return [].shift.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps [`Array#shift`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/unshift) with proper change tracking.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* doc.array = [2,3];
|
||||
* var res = doc.array.shift();
|
||||
* console.log(res) // 2
|
||||
* console.log(doc.array) // [3]
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.shift = function () {
|
||||
var ret = [].shift.call(this);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes items from an array atomically
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* doc.array.remove(ObjectId)
|
||||
* doc.array.remove('tag 1', 'tag 2')
|
||||
*
|
||||
* @param {Object} [args...] values to remove
|
||||
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pull
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.remove = function () {
|
||||
var args = [].map.call(arguments, this._cast, this);
|
||||
if (args.length == 1)
|
||||
this.pull(args[0]);
|
||||
else
|
||||
this.pull.apply(this, args);
|
||||
return args;
|
||||
};
|
||||
|
||||
/**
|
||||
* Pulls items from the array atomically.
|
||||
*
|
||||
* @param {any} [args...]
|
||||
* @see mongodb http://www.mongodb.org/display/DOCS/Updating/#Updating-%24pull
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.pull = function () {
|
||||
var values = [].map.call(arguments, this._cast, this)
|
||||
, cur = this._parent.get(this._path)
|
||||
, i = cur.length
|
||||
, mem;
|
||||
|
||||
while (i--) {
|
||||
mem = cur[i];
|
||||
if (mem instanceof EmbeddedDocument) {
|
||||
if (values.some(function (v) { return v.equals(mem); } )) {
|
||||
[].splice.call(cur, i, 1);
|
||||
}
|
||||
} else if (~cur.indexOf.call(values, mem)) {
|
||||
[].splice.call(cur, i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (values[0] instanceof EmbeddedDocument) {
|
||||
this._registerAtomic('$pullDocs', values.map( function (v) { return v._id; } ));
|
||||
} else {
|
||||
this._registerAtomic('$pullAll', values);
|
||||
}
|
||||
|
||||
this._markModified();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps [`Array#splice`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice) with proper change tracking and casting.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.splice = function splice () {
|
||||
var ret, vals, i;
|
||||
|
||||
if (arguments.length) {
|
||||
vals = [];
|
||||
for (i = 0; i < arguments.length; ++i) {
|
||||
vals[i] = i < 2
|
||||
? arguments[i]
|
||||
: this._cast(arguments[i]);
|
||||
}
|
||||
ret = [].splice.apply(this, vals);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps [`Array#unshift`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/unshift) with proper change tracking.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.unshift = function () {
|
||||
var values = [].map.call(arguments, this._cast, this);
|
||||
[].unshift.apply(this, values);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
return this.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps [`Array#sort`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort) with proper change tracking.
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _marks the entire array as modified, which if saved, will store it as a `$set` operation, potentially overwritting any changes that happen between when you retrieved the object and when you save it._
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.sort = function () {
|
||||
var ret = [].sort.apply(this, arguments);
|
||||
this._registerAtomic('$set', this);
|
||||
this._markModified();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds values to the array if not already present.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* console.log(doc.array) // [2,3,4]
|
||||
* var added = doc.array.addToSet(4,5);
|
||||
* console.log(doc.array) // [2,3,4,5]
|
||||
* console.log(added) // [5]
|
||||
*
|
||||
* @param {any} [args...]
|
||||
* @return {Array} the values that were added
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.addToSet = function addToSet () {
|
||||
var values = [].map.call(arguments, this._cast, this)
|
||||
, added = []
|
||||
, type = values[0] instanceof EmbeddedDocument ? 'doc' :
|
||||
values[0] instanceof Date ? 'date' :
|
||||
'';
|
||||
|
||||
values.forEach(function (v) {
|
||||
var found;
|
||||
switch (type) {
|
||||
case 'doc':
|
||||
found = this.some(function(doc){ return doc.equals(v) });
|
||||
break;
|
||||
case 'date':
|
||||
var val = +v;
|
||||
found = this.some(function(d){ return +d === val });
|
||||
break;
|
||||
default:
|
||||
found = ~this.indexOf(v);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
[].push.call(this, v);
|
||||
this._registerAtomic('$addToSet', v);
|
||||
this._markModified();
|
||||
[].push.call(added, v);
|
||||
}
|
||||
}, this);
|
||||
|
||||
return added;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the casted `val` at index `i` and marks the array modified.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* // given documents based on the following
|
||||
* var Doc = mongoose.model('Doc', new Schema({ array: [Number] }));
|
||||
*
|
||||
* var doc = new Doc({ array: [2,3,4] })
|
||||
*
|
||||
* console.log(doc.array) // [2,3,4]
|
||||
*
|
||||
* doc.array.set(1,"5");
|
||||
* console.log(doc.array); // [2,5,4] // properly cast to number
|
||||
* doc.save() // the change is saved
|
||||
*
|
||||
* // VS not using array#set
|
||||
* doc.array[1] = "5";
|
||||
* console.log(doc.array); // [2,"5",4] // no casting
|
||||
* doc.save() // change is not saved
|
||||
*
|
||||
* @return {Array} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.set = function set (i, val) {
|
||||
this[i] = this._cast(val);
|
||||
this._markModified(i);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a native js Array.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.toObject = function (options) {
|
||||
if (options && options.depopulate && this[0] instanceof Document) {
|
||||
return this.map(function (doc) {
|
||||
return doc._id;
|
||||
});
|
||||
}
|
||||
|
||||
// return this.slice()?
|
||||
return this.map(function (doc) {
|
||||
return doc;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper for console.log
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.inspect = function () {
|
||||
return '[' + this.map(function (doc) {
|
||||
return ' ' + doc;
|
||||
}) + ' ]';
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the index of `obj` or `-1` if not found.
|
||||
*
|
||||
* @param {Object} obj the item to look for
|
||||
* @return {Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseArray.prototype.indexOf = function indexOf (obj) {
|
||||
if (obj instanceof ObjectId) obj = obj.toString();
|
||||
for (var i = 0, len = this.length; i < len; ++i) {
|
||||
if (obj == this[i])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = MongooseArray;
|
||||
185
node_modules/mongoose/lib/types/buffer.js
generated
vendored
Normal file
185
node_modules/mongoose/lib/types/buffer.js
generated
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
/*!
|
||||
* Access driver.
|
||||
*/
|
||||
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Binary = require(driver + '/binary');
|
||||
|
||||
/**
|
||||
* Mongoose Buffer constructor.
|
||||
*
|
||||
* Values always have to be passed to the constructor to initialize.
|
||||
*
|
||||
* @param {Buffer} value
|
||||
* @param {String} encode
|
||||
* @param {Number} offset
|
||||
* @api private
|
||||
* @inherits Buffer
|
||||
* @see http://bit.ly/f6CnZU
|
||||
*/
|
||||
|
||||
function MongooseBuffer (value, encode, offset) {
|
||||
var length = arguments.length;
|
||||
var val;
|
||||
|
||||
if (0 === length || null === arguments[0] || undefined === arguments[0]) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = value;
|
||||
}
|
||||
|
||||
var encoding;
|
||||
var path;
|
||||
var doc;
|
||||
|
||||
if (Array.isArray(encode)) {
|
||||
// internal casting
|
||||
path = encode[0];
|
||||
doc = encode[1];
|
||||
} else {
|
||||
encoding = encode;
|
||||
}
|
||||
|
||||
var buf = new Buffer(val, encoding, offset);
|
||||
buf.__proto__ = MongooseBuffer.prototype;
|
||||
|
||||
// make sure these internal props don't show up in Object.keys()
|
||||
Object.defineProperties(buf, {
|
||||
validators: { value: [] }
|
||||
, _path: { value: path }
|
||||
, _parent: { value: doc }
|
||||
});
|
||||
|
||||
if (doc && "string" === typeof path) {
|
||||
Object.defineProperty(buf, '_schema', {
|
||||
value: doc.schema.path(path)
|
||||
});
|
||||
}
|
||||
|
||||
return buf;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from Buffer.
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype = new Buffer(0);
|
||||
|
||||
/**
|
||||
* Parent owner document
|
||||
*
|
||||
* @api private
|
||||
* @property _parent
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype._parent;
|
||||
|
||||
/**
|
||||
* Marks this buffer as modified.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype._markModified = function () {
|
||||
var parent = this._parent;
|
||||
|
||||
if (parent) {
|
||||
parent.markModified(this._path);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes the buffer.
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype.write = function () {
|
||||
var written = Buffer.prototype.write.apply(this, arguments);
|
||||
|
||||
if (written > 0) {
|
||||
this._markModified();
|
||||
}
|
||||
|
||||
return written;
|
||||
};
|
||||
|
||||
/**
|
||||
* Copies the buffer.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* `Buffer#copy` does not mark `target` as modified so you must copy from a `MongooseBuffer` for it to work as expected. This is a work around since `copy` modifies the target, not this.
|
||||
*
|
||||
* @return {MongooseBuffer}
|
||||
* @param {Buffer} target
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype.copy = function (target) {
|
||||
var ret = Buffer.prototype.copy.apply(this, arguments);
|
||||
|
||||
if (target instanceof MongooseBuffer) {
|
||||
target._markModified();
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Compile other Buffer methods marking this buffer as modified.
|
||||
*/
|
||||
|
||||
;(
|
||||
// node < 0.5
|
||||
'writeUInt8 writeUInt16 writeUInt32 writeInt8 writeInt16 writeInt32 ' +
|
||||
'writeFloat writeDouble fill ' +
|
||||
'utf8Write binaryWrite asciiWrite set ' +
|
||||
|
||||
// node >= 0.5
|
||||
'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
|
||||
'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' +
|
||||
'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE'
|
||||
).split(' ').forEach(function (method) {
|
||||
if (!Buffer.prototype[method]) return;
|
||||
MongooseBuffer.prototype[method] = new Function(
|
||||
'var ret = Buffer.prototype.'+method+'.apply(this, arguments);' +
|
||||
'this._markModified();' +
|
||||
'return ret;'
|
||||
)
|
||||
});
|
||||
|
||||
/**
|
||||
* Converts this buffer to its Binary type representation.
|
||||
*
|
||||
* ####SubTypes:
|
||||
*
|
||||
* - 0x00: Binary/Generic
|
||||
* - 0x01: Function
|
||||
* - 0x02: Binary (Deprecated, 0x00 is new default)
|
||||
* - 0x03: UUID
|
||||
* - 0x04: MD5
|
||||
* - 0x80: User Defined
|
||||
*
|
||||
* @see http://bsonspec.org/#/specification
|
||||
* @param {Hex} [subtype]
|
||||
* @return {Binary}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype.toObject = function (subtype) {
|
||||
subtype = typeof subtype !== 'undefined' ? subtype : 0x00
|
||||
return new Binary(this, subtype);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
MongooseBuffer.Binary = Binary;
|
||||
|
||||
module.exports = MongooseBuffer;
|
||||
171
node_modules/mongoose/lib/types/documentarray.js
generated
vendored
Normal file
171
node_modules/mongoose/lib/types/documentarray.js
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseArray = require('./array')
|
||||
, driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native'
|
||||
, ObjectId = require(driver + '/objectid')
|
||||
, ObjectIdSchema = require('../schema/objectid')
|
||||
, util = require('util')
|
||||
|
||||
/**
|
||||
* DocumentArray constructor
|
||||
*
|
||||
* @param {Array} values
|
||||
* @param {String} path the path to this array
|
||||
* @param {Document} doc parent document
|
||||
* @api private
|
||||
* @return {MongooseDocumentArray}
|
||||
* @inherits MongooseArray
|
||||
* @see http://bit.ly/f6CnZU
|
||||
*/
|
||||
|
||||
function MongooseDocumentArray (values, path, doc) {
|
||||
var arr = [];
|
||||
|
||||
// Values always have to be passed to the constructor to initialize, since
|
||||
// otherwise MongooseArray#push will mark the array as modified to the parent.
|
||||
arr.push.apply(arr, values);
|
||||
arr.__proto__ = MongooseDocumentArray.prototype;
|
||||
|
||||
arr._atomics = {};
|
||||
arr.validators = [];
|
||||
arr._path = path;
|
||||
|
||||
if (doc) {
|
||||
arr._parent = doc;
|
||||
arr._schema = doc.schema.path(path);
|
||||
doc.on('save', arr.notify('save'));
|
||||
doc.on('isNew', arr.notify('isNew'));
|
||||
}
|
||||
|
||||
return arr;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseArray
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.__proto__ = MongooseArray.prototype;
|
||||
|
||||
/**
|
||||
* Overrides MongooseArray#cast
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype._cast = function (value) {
|
||||
if (value instanceof this._schema.casterConstructor)
|
||||
return value;
|
||||
|
||||
return new this._schema.casterConstructor(value, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Searches array items for the first document with a matching id.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var embeddedDoc = m.array.id(some_id);
|
||||
*
|
||||
* @return {EmbeddedDocument|null} the subdocuent or null if not found.
|
||||
* @param {ObjectId|String|Number|Buffer} id
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.id = function (id) {
|
||||
var casted
|
||||
, _id;
|
||||
|
||||
try {
|
||||
casted = ObjectId.toString(ObjectIdSchema.prototype.cast.call({}, id));
|
||||
} catch (e) {
|
||||
casted = null;
|
||||
}
|
||||
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
_id = this[i].get('_id');
|
||||
if (!(_id instanceof ObjectId)) {
|
||||
if (String(id) == _id)
|
||||
return this[i];
|
||||
} else {
|
||||
if (casted == _id)
|
||||
return this[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a native js Array of plain js objects
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _Each sub-document is converted to a plain object by calling its `#toObject` method._
|
||||
*
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.toObject = function () {
|
||||
return this.map(function (doc) {
|
||||
return doc && doc.toObject() || null;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper for console.log
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.inspect = function () {
|
||||
return '[' + this.map(function (doc) {
|
||||
if (doc) {
|
||||
return doc.inspect
|
||||
? doc.inspect()
|
||||
: util.inspect(doc)
|
||||
}
|
||||
return 'null'
|
||||
}).join('\n') + ']';
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a subdocument casted to this schema.
|
||||
*
|
||||
* This is the same subdocument constructor used for casting.
|
||||
*
|
||||
* @param {Object} obj the value to cast to this arrays SubDocument schema
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.create = function (obj) {
|
||||
return new this._schema.casterConstructor(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fn that notifies all child docs of `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Function}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.notify = function notify (event) {
|
||||
var self = this;
|
||||
return function notify (val) {
|
||||
var i = self.length;
|
||||
while (i--) {
|
||||
if (!self[i]) continue;
|
||||
self[i].emit(event, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = MongooseDocumentArray;
|
||||
199
node_modules/mongoose/lib/types/embedded.js
generated
vendored
Normal file
199
node_modules/mongoose/lib/types/embedded.js
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Document = require('../document')
|
||||
, inspect = require('util').inspect;
|
||||
|
||||
/**
|
||||
* EmbeddedDocument constructor.
|
||||
*
|
||||
* @param {Object} obj js object returned from the db
|
||||
* @param {MongooseDocumentArray} parentArr the parent array of this document
|
||||
* @param {Boolean} skipId
|
||||
* @inherits Document
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function EmbeddedDocument (obj, parentArr, skipId, fields) {
|
||||
if (parentArr) {
|
||||
this.__parentArray = parentArr;
|
||||
this.__parent = parentArr._parent;
|
||||
} else {
|
||||
this.__parentArray = undefined;
|
||||
this.__parent = undefined;
|
||||
}
|
||||
|
||||
Document.call(this, obj, fields, skipId);
|
||||
|
||||
var self = this;
|
||||
this.on('isNew', function (val) {
|
||||
self.isNew = val;
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from Document
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.__proto__ = Document.prototype;
|
||||
|
||||
/**
|
||||
* Marks the embedded doc modified.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var doc = blogpost.comments.id(hexstring);
|
||||
* doc.mixed.type = 'changed';
|
||||
* doc.markModified('mixed.type');
|
||||
*
|
||||
* @param {String} path the path which changed
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.markModified = function (path) {
|
||||
if (!this.__parentArray) return;
|
||||
|
||||
this._activePaths.modify(path);
|
||||
|
||||
if (this.isNew) {
|
||||
// Mark the WHOLE parent array as modified
|
||||
// if this is a new document (i.e., we are initializing
|
||||
// a document),
|
||||
this.__parentArray._markModified();
|
||||
} else
|
||||
this.__parentArray._markModified(this, path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Used as a stub for [hooks.js](https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3)
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* _This is a no-op. Does not actually save the doc to the db._
|
||||
*
|
||||
* @param {Function} [fn]
|
||||
* @return {EmbeddedDocument} this
|
||||
* @api private
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.save = function(fn) {
|
||||
if (fn)
|
||||
fn(null);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the subdocument from its parent array.
|
||||
*
|
||||
* @param {Function} [fn]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.remove = function (fn) {
|
||||
if (!this.__parentArray) return this;
|
||||
|
||||
var _id;
|
||||
if (!this.willRemove) {
|
||||
_id = this._doc._id;
|
||||
if (!_id) {
|
||||
throw new Error('For your own good, Mongoose does not know ' +
|
||||
'how to remove an EmbeddedDocument that has no _id');
|
||||
}
|
||||
this.__parentArray.pull({ _id: _id });
|
||||
this.willRemove = true;
|
||||
}
|
||||
|
||||
if (fn)
|
||||
fn(null);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override #update method of parent documents.
|
||||
* @api private
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.update = function () {
|
||||
throw new Error('The #update method is not available on EmbeddedDocuments');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for console.log
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.inspect = function () {
|
||||
return inspect(this.toObject());
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks a path as invalid, causing validation to fail.
|
||||
*
|
||||
* @param {String} path the field to invalidate
|
||||
* @param {String|Error} err error which states the reason `path` was invalid
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.invalidate = function (path, err, first) {
|
||||
if (!this.__parent) return false;
|
||||
var index = this.__parentArray.indexOf(this);
|
||||
var parentPath = this.__parentArray._path;
|
||||
var fullPath = [parentPath, index, path].join('.');
|
||||
this.__parent.invalidate(fullPath, err);
|
||||
if (first)
|
||||
this._validationError = ownerDocument(this)._validationError;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the top level document of this sub-document.
|
||||
*
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.ownerDocument = function () {
|
||||
return ownerDocument(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the top level document of this sub-document.
|
||||
*
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
function ownerDocument (self) {
|
||||
var parent = self.__parent;
|
||||
while (parent.__parent)
|
||||
parent = parent.__parent;
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this sub-documents parent document.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.parent = function () {
|
||||
return this.__parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this sub-documents parent array.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.parentArray = function () {
|
||||
return this.__parentArray;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = EmbeddedDocument;
|
||||
13
node_modules/mongoose/lib/types/index.js
generated
vendored
Normal file
13
node_modules/mongoose/lib/types/index.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
exports.Array = require('./array');
|
||||
exports.Buffer = require('./buffer');
|
||||
|
||||
exports.Document = // @deprecate
|
||||
exports.Embedded = require('./embedded');
|
||||
|
||||
exports.DocumentArray = require('./documentarray');
|
||||
exports.ObjectId = require('./objectid');
|
||||
43
node_modules/mongoose/lib/types/objectid.js
generated
vendored
Normal file
43
node_modules/mongoose/lib/types/objectid.js
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
/*!
|
||||
* Access driver.
|
||||
*/
|
||||
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
|
||||
|
||||
/**
|
||||
* ObjectId type constructor
|
||||
*
|
||||
* ####Example
|
||||
*
|
||||
* var id = new mongoose.Types.ObjectId;
|
||||
*
|
||||
* @constructor ObjectId
|
||||
*/
|
||||
|
||||
var ObjectId = require(driver + '/objectid');
|
||||
module.exports = ObjectId;
|
||||
|
||||
/**
|
||||
* Creates an ObjectId from `str`
|
||||
*
|
||||
* @param {ObjectId|HexString} str
|
||||
* @static fromString
|
||||
* @receiver ObjectId
|
||||
* @return {ObjectId}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.fromString;
|
||||
|
||||
/**
|
||||
* Converts `oid` to a string.
|
||||
*
|
||||
* @param {ObjectId} oid ObjectId instance
|
||||
* @static toString
|
||||
* @receiver ObjectId
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.toString;
|
||||
506
node_modules/mongoose/lib/utils.js
generated
vendored
Normal file
506
node_modules/mongoose/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,506 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
, ReadPref = require('mongodb').ReadPreference
|
||||
, ObjectId = require('./types/objectid')
|
||||
, ms = require('ms')
|
||||
, sliced = require('sliced')
|
||||
, MongooseBuffer
|
||||
, MongooseArray
|
||||
, Document
|
||||
|
||||
/**
|
||||
* Produces a collection name from model `name`.
|
||||
*
|
||||
* @param {String} name a model name
|
||||
* @return {String} a collection name
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.toCollectionName = function (name) {
|
||||
if ('system.profile' === name) return name;
|
||||
if ('system.indexes' === name) return name;
|
||||
return pluralize(name.toLowerCase());
|
||||
};
|
||||
|
||||
/**
|
||||
* Pluralization rules.
|
||||
*
|
||||
* These rules are applied while processing the argument to `toCollectionName`.
|
||||
*/
|
||||
|
||||
exports.pluralization = [
|
||||
[/(m)an$/gi, '$1en'],
|
||||
[/(pe)rson$/gi, '$1ople'],
|
||||
[/(child)$/gi, '$1ren'],
|
||||
[/^(ox)$/gi, '$1en'],
|
||||
[/(ax|test)is$/gi, '$1es'],
|
||||
[/(octop|vir)us$/gi, '$1i'],
|
||||
[/(alias|status)$/gi, '$1es'],
|
||||
[/(bu)s$/gi, '$1ses'],
|
||||
[/(buffal|tomat|potat)o$/gi, '$1oes'],
|
||||
[/([ti])um$/gi, '$1a'],
|
||||
[/sis$/gi, 'ses'],
|
||||
[/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'],
|
||||
[/(hive)$/gi, '$1s'],
|
||||
[/([^aeiouy]|qu)y$/gi, '$1ies'],
|
||||
[/(x|ch|ss|sh)$/gi, '$1es'],
|
||||
[/(matr|vert|ind)ix|ex$/gi, '$1ices'],
|
||||
[/([m|l])ouse$/gi, '$1ice'],
|
||||
[/(quiz)$/gi, '$1zes'],
|
||||
[/s$/gi, 's'],
|
||||
[/$/gi, 's']
|
||||
];
|
||||
var rules = exports.pluralization;
|
||||
|
||||
/**
|
||||
* Uncountable words.
|
||||
*
|
||||
* These words are applied while processing the argument to `toCollectionName`.
|
||||
*/
|
||||
|
||||
exports.uncountables = [
|
||||
'advice',
|
||||
'energy',
|
||||
'excretion',
|
||||
'digestion',
|
||||
'cooperation',
|
||||
'health',
|
||||
'justice',
|
||||
'labour',
|
||||
'machinery',
|
||||
'equipment',
|
||||
'information',
|
||||
'pollution',
|
||||
'sewage',
|
||||
'paper',
|
||||
'money',
|
||||
'species',
|
||||
'series',
|
||||
'rain',
|
||||
'rice',
|
||||
'fish',
|
||||
'sheep',
|
||||
'moose',
|
||||
'deer',
|
||||
'news',
|
||||
'expertise',
|
||||
'status',
|
||||
'media'
|
||||
];
|
||||
var uncountables = exports.uncountables;
|
||||
|
||||
/*!
|
||||
* Pluralize function.
|
||||
*
|
||||
* @author TJ Holowaychuk (extracted from _ext.js_)
|
||||
* @param {String} string to pluralize
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function pluralize (str) {
|
||||
var rule, found;
|
||||
if (!~uncountables.indexOf(str.toLowerCase())){
|
||||
found = rules.filter(function(rule){
|
||||
return str.match(rule[0]);
|
||||
});
|
||||
if (found[0]) return str.replace(found[0][0], found[0][1]);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Add `once` to EventEmitter if absent
|
||||
*
|
||||
* @param {String} event name
|
||||
* @param {Function} listener
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var Events = EventEmitter;
|
||||
|
||||
if (!('once' in EventEmitter.prototype)){
|
||||
|
||||
Events = function () {
|
||||
EventEmitter.apply(this, arguments);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from EventEmitter.
|
||||
*/
|
||||
|
||||
Events.prototype.__proto__ = EventEmitter.prototype;
|
||||
|
||||
/*!
|
||||
* Add `once`.
|
||||
*/
|
||||
|
||||
Events.prototype.once = function (type, listener) {
|
||||
var self = this;
|
||||
self.on(type, function g(){
|
||||
self.removeListener(type, g);
|
||||
listener.apply(this, arguments);
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.EventEmitter = Events;
|
||||
|
||||
/**
|
||||
* Determines if `a` and `b` are deep equal.
|
||||
*
|
||||
* Modified from node/lib/assert.js
|
||||
*
|
||||
* @param {any} a a value to compare to `b`
|
||||
* @param {any} b a value to compare to `a`
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.deepEqual = function deepEqual (a, b) {
|
||||
if (a === b) return true;
|
||||
|
||||
if (a instanceof Date && b instanceof Date)
|
||||
return a.getTime() === b.getTime();
|
||||
|
||||
if (a instanceof ObjectId && b instanceof ObjectId) {
|
||||
return a.toString() === b.toString();
|
||||
}
|
||||
|
||||
if (typeof a !== 'object' && typeof b !== 'object')
|
||||
return a == b;
|
||||
|
||||
if (a === null || b === null || a === undefined || b === undefined)
|
||||
return false
|
||||
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
|
||||
// Handle MongooseNumbers
|
||||
if (a instanceof Number && b instanceof Number) {
|
||||
return a.valueOf() === b.valueOf();
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(a)) {
|
||||
if (!Buffer.isBuffer(b)) return false;
|
||||
if (a.length !== b.length) return false;
|
||||
for (var i = 0, len = a.length; i < len; ++i) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isMongooseObject(a)) a = a.toObject();
|
||||
if (isMongooseObject(b)) b = b.toObject();
|
||||
|
||||
try {
|
||||
var ka = Object.keys(a),
|
||||
kb = Object.keys(b),
|
||||
key, i;
|
||||
} catch (e) {//happens when one is a string literal and the other isn't
|
||||
return false;
|
||||
}
|
||||
|
||||
// having the same number of owned properties (keys incorporates
|
||||
// hasOwnProperty)
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
|
||||
//~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!deepEqual(a[key], b[key])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Object clone with Mongoose natives support.
|
||||
*
|
||||
* If options.minimize is true, creates a minimal data object. Empty objects and undefined values will not be cloned. This makes the data payload sent to MongoDB as small as possible.
|
||||
*
|
||||
* Functions are never cloned.
|
||||
*
|
||||
* @param {Object} obj the object to clone
|
||||
* @param {Object} options
|
||||
* @return {Object} the cloned object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.clone = function clone (obj, options) {
|
||||
if (obj === undefined || obj === null)
|
||||
return obj;
|
||||
|
||||
if (Array.isArray(obj))
|
||||
return cloneArray(obj, options);
|
||||
|
||||
if (isMongooseObject(obj)) {
|
||||
if (options && options.json && 'function' === typeof obj.toJSON) {
|
||||
return obj.toJSON(options);
|
||||
} else {
|
||||
return obj.toObject(options);
|
||||
}
|
||||
}
|
||||
|
||||
if ('Object' === obj.constructor.name)
|
||||
return cloneObject(obj, options);
|
||||
|
||||
if ('Date' === obj.constructor.name)
|
||||
return new obj.constructor(+obj);
|
||||
|
||||
if ('RegExp' === obj.constructor.name)
|
||||
return new RegExp(obj.source);
|
||||
|
||||
if (obj instanceof ObjectId)
|
||||
return new ObjectId(obj.id);
|
||||
|
||||
if (obj.valueOf)
|
||||
return obj.valueOf();
|
||||
};
|
||||
var clone = exports.clone;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function cloneObject (obj, options) {
|
||||
var retainKeyOrder = options && options.retainKeyOrder
|
||||
, minimize = options && options.minimize
|
||||
, ret = {}
|
||||
, hasKeys
|
||||
, keys
|
||||
, val
|
||||
, k
|
||||
, i
|
||||
|
||||
if (retainKeyOrder) {
|
||||
for (k in obj) {
|
||||
val = clone(obj[k], options);
|
||||
|
||||
if (!minimize || ('undefined' !== typeof val)) {
|
||||
hasKeys || (hasKeys = true);
|
||||
ret[k] = val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// faster
|
||||
|
||||
keys = Object.keys(obj);
|
||||
i = keys.length;
|
||||
|
||||
while (i--) {
|
||||
k = keys[i];
|
||||
val = clone(obj[k], options);
|
||||
|
||||
if (!minimize || ('undefined' !== typeof val)) {
|
||||
if (!hasKeys) hasKeys = true;
|
||||
ret[k] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minimize
|
||||
? hasKeys && ret
|
||||
: ret;
|
||||
};
|
||||
|
||||
function cloneArray (arr, options) {
|
||||
var ret = [];
|
||||
for (var i = 0, l = arr.length; i < l; i++)
|
||||
ret.push(clone(arr[i], options));
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Copies and merges options with defaults.
|
||||
*
|
||||
* @param {Object} defaults
|
||||
* @param {Object} options
|
||||
* @return {Object} the merged object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.options = function (defaults, options) {
|
||||
var keys = Object.keys(defaults)
|
||||
, i = keys.length
|
||||
, k ;
|
||||
|
||||
options = options || {};
|
||||
|
||||
while (i--) {
|
||||
k = keys[i];
|
||||
if (!(k in options)) {
|
||||
options[k] = defaults[k];
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a random string
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.random = function () {
|
||||
return Math.random().toString().substr(3);
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges `from` into `to` without overwriting existing properties.
|
||||
*
|
||||
* @param {Object} to
|
||||
* @param {Object} from
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.merge = function merge (to, from) {
|
||||
var keys = Object.keys(from)
|
||||
, i = keys.length
|
||||
, key
|
||||
|
||||
while (i--) {
|
||||
key = keys[i];
|
||||
if ('undefined' === typeof to[key]) {
|
||||
to[key] = from[key];
|
||||
} else {
|
||||
if (exports.isObject(from[key])) {
|
||||
merge(to[key], from[key]);
|
||||
} else {
|
||||
to[key] = from[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* toString helper
|
||||
*/
|
||||
|
||||
var toString = Object.prototype.toString;
|
||||
|
||||
/**
|
||||
* Determines if `arg` is an object.
|
||||
*
|
||||
* @param {Object|Array|String|Function|RegExp|any} arg
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
exports.isObject = function (arg) {
|
||||
return '[object Object]' == toString.call(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* A faster Array.prototype.slice.call(arguments) alternative
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.args = sliced;
|
||||
|
||||
/**
|
||||
* process.nextTick helper.
|
||||
*
|
||||
* Wraps `callback` in a try/catch + nextTick.
|
||||
*
|
||||
* node-mongodb-native has a habit of state corruption when an error is immediately thrown from within a collection callback.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.tick = function tick (callback) {
|
||||
if ('function' !== typeof callback) return;
|
||||
return function () {
|
||||
try {
|
||||
callback.apply(this, arguments);
|
||||
} catch (err) {
|
||||
// only nextTick on err to get out of
|
||||
// the event loop and avoid state corruption.
|
||||
process.nextTick(function () {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if `v` is a mongoose object that has a `toObject()` method we can use.
|
||||
*
|
||||
* This is for compatibility with libs like Date.js which do foolish things to Natives.
|
||||
*
|
||||
* @param {any} v
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.isMongooseObject = function (v) {
|
||||
Document || (Document = require('./document'));
|
||||
MongooseArray || (MongooseArray = require('./types').Array);
|
||||
MongooseBuffer || (MongooseBuffer = require('./types').Buffer);
|
||||
|
||||
return v instanceof Document ||
|
||||
v instanceof MongooseArray ||
|
||||
v instanceof MongooseBuffer
|
||||
}
|
||||
var isMongooseObject = exports.isMongooseObject;
|
||||
|
||||
/**
|
||||
* Converts `expires` options of index objects to `expiresAfterSeconds` options for MongoDB.
|
||||
*
|
||||
* @param {Object} object
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.expires = function expires (object) {
|
||||
if (!(object && 'Object' == object.constructor.name)) return;
|
||||
if (!('expires' in object)) return;
|
||||
|
||||
var when;
|
||||
if ('string' != typeof object.expires) {
|
||||
when = object.expires;
|
||||
} else {
|
||||
when = Math.round(ms(object.expires) / 1000);
|
||||
}
|
||||
object.expireAfterSeconds = when;
|
||||
delete object.expires;
|
||||
}
|
||||
|
||||
exports.readPref = function readPref (pref, tags) {
|
||||
if (Array.isArray(pref)) {
|
||||
tags = pref[1];
|
||||
pref = pref[0];
|
||||
}
|
||||
|
||||
switch (pref) {
|
||||
case 'p':
|
||||
pref = 'primary';
|
||||
break;
|
||||
case 'pp':
|
||||
pref = 'primaryPrefered';
|
||||
break;
|
||||
case 's':
|
||||
pref = 'secondary';
|
||||
break;
|
||||
case 'sp':
|
||||
pref = 'secondaryPrefered';
|
||||
break;
|
||||
case 'n':
|
||||
pref = 'nearest';
|
||||
break;
|
||||
}
|
||||
|
||||
return new ReadPref(pref, tags);
|
||||
}
|
||||
103
node_modules/mongoose/lib/virtualtype.js
generated
vendored
Normal file
103
node_modules/mongoose/lib/virtualtype.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
/**
|
||||
* VirtualType constructor
|
||||
*
|
||||
* This is what mongoose uses to define virtual attributes via `Schema.prototype.virtual`.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var fullname = schema.virtual('fullname');
|
||||
* fullname instanceof mongoose.VirtualType // true
|
||||
*
|
||||
* @parma {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function VirtualType (options, name) {
|
||||
this.path = name;
|
||||
this.getters = [];
|
||||
this.setters = [];
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a getter.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var virtual = schema.virtual('fullname');
|
||||
* virtual.get(function () {
|
||||
* return this.name.first + ' ' + this.name.last;
|
||||
* });
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {VirtualType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.get = function (fn) {
|
||||
this.getters.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines a setter.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var virtual = schema.virtual('fullname');
|
||||
* virtual.set(function (v) {
|
||||
* var parts = v.split(' ');
|
||||
* this.name.first = parts[0];
|
||||
* this.name.last = parts[1];
|
||||
* });
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {VirtualType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.set = function (fn) {
|
||||
this.setters.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies getters to `value` using optional `scope`.
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @return {any} the value after applying all getters
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.applyGetters = function (value, scope) {
|
||||
var v = value;
|
||||
for (var l = this.getters.length - 1; l >= 0; l--) {
|
||||
v = this.getters[l].call(scope, v, this);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies setters to `value` using optional `scope`.
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Object} scope
|
||||
* @return {any} the value after applying all setters
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.applySetters = function (value, scope) {
|
||||
var v = value;
|
||||
for (var l = this.setters.length - 1; l >= 0; l--) {
|
||||
v = this.setters[l].call(scope, v, this);
|
||||
}
|
||||
return v;
|
||||
};
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = VirtualType;
|
||||
Reference in New Issue
Block a user