mirror of
https://github.com/arnaucube/thoughts.git
synced 2026-02-07 11:46:52 +01:00
database externa
This commit is contained in:
26
node_modules/mongoose/lib/ES6Promise.js
generated
vendored
Normal file
26
node_modules/mongoose/lib/ES6Promise.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* ES6 Promise wrapper constructor.
|
||||
*
|
||||
* Promises are returned from executed queries. Example:
|
||||
*
|
||||
* var query = Candy.find({ bar: true });
|
||||
* var promise = query.exec();
|
||||
*
|
||||
* DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird,
|
||||
* if native promises are not present) but still
|
||||
* support plugging in your own ES6-compatible promises library. Mongoose 5.0
|
||||
* will **not** support mpromise.
|
||||
*
|
||||
* @param {Function} fn a function which will be called when the promise is resolved that accepts `fn(err, ...){}` as signature
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function ES6Promise() {
|
||||
throw new Error('Can\'t use ES6 promise with mpromise style constructor');
|
||||
}
|
||||
|
||||
ES6Promise.use = function(Promise) {
|
||||
ES6Promise.ES6 = Promise;
|
||||
};
|
||||
|
||||
module.exports = ES6Promise;
|
||||
685
node_modules/mongoose/lib/aggregate.js
generated
vendored
Normal file
685
node_modules/mongoose/lib/aggregate.js
generated
vendored
Normal file
@@ -0,0 +1,685 @@
|
||||
/*!
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var util = require('util');
|
||||
var utils = require('./utils');
|
||||
var PromiseProvider = require('./promise_provider');
|
||||
var Query = require('./query');
|
||||
var read = Query.prototype.read;
|
||||
|
||||
/**
|
||||
* Aggregate constructor used for building aggregation pipelines.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* new Aggregate();
|
||||
* new Aggregate({ $project: { a: 1, b: 1 } });
|
||||
* new Aggregate({ $project: { a: 1, b: 1 } }, { $skip: 5 });
|
||||
* new Aggregate([{ $project: { a: 1, b: 1 } }, { $skip: 5 }]);
|
||||
*
|
||||
* Returned when calling Model.aggregate().
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* Model
|
||||
* .aggregate({ $match: { age: { $gte: 21 }}})
|
||||
* .unwind('tags')
|
||||
* .exec(callback)
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* - The documents returned are plain javascript objects, not mongoose documents (since any shape of document can be returned).
|
||||
* - Requires MongoDB >= 2.1
|
||||
* - Mongoose does **not** cast pipeline stages. `new Aggregate({ $match: { _id: '00000000000000000000000a' } });` will not work unless `_id` is a string in the database. Use `new Aggregate({ $match: { _id: mongoose.Types.ObjectId('00000000000000000000000a') } });` instead.
|
||||
*
|
||||
* @see MongoDB http://docs.mongodb.org/manual/applications/aggregation/
|
||||
* @see driver http://mongodb.github.com/node-mongodb-native/api-generated/collection.html#aggregate
|
||||
* @param {Object|Array} [ops] aggregation operator(s) or operator array
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Aggregate() {
|
||||
this._pipeline = [];
|
||||
this._model = undefined;
|
||||
this.options = undefined;
|
||||
|
||||
if (arguments.length === 1 && util.isArray(arguments[0])) {
|
||||
this.append.apply(this, arguments[0]);
|
||||
} else {
|
||||
this.append.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this aggregate to a model.
|
||||
*
|
||||
* @param {Model} model the model to which the aggregate is to be bound
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.model = function(model) {
|
||||
this._model = model;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends new operators to this aggregate pipeline
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.append({ $project: { field: 1 }}, { $limit: 2 });
|
||||
*
|
||||
* // or pass an array
|
||||
* var pipeline = [{ $match: { daw: 'Logic Audio X' }} ];
|
||||
* aggregate.append(pipeline);
|
||||
*
|
||||
* @param {Object} ops operator(s) to append
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.append = function() {
|
||||
var args = (arguments.length === 1 && util.isArray(arguments[0]))
|
||||
? arguments[0]
|
||||
: utils.args(arguments);
|
||||
|
||||
if (!args.every(isOperator)) {
|
||||
throw new Error('Arguments must be aggregate pipeline operators');
|
||||
}
|
||||
|
||||
this._pipeline = this._pipeline.concat(args);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a new $project operator to this aggregate pipeline.
|
||||
*
|
||||
* Mongoose query [selection syntax](#query_Query-select) is also supported.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* // include a, include b, exclude _id
|
||||
* aggregate.project("a b -_id");
|
||||
*
|
||||
* // or you may use object notation, useful when
|
||||
* // you have keys already prefixed with a "-"
|
||||
* aggregate.project({a: 1, b: 1, _id: 0});
|
||||
*
|
||||
* // reshaping documents
|
||||
* aggregate.project({
|
||||
* newField: '$b.nested'
|
||||
* , plusTen: { $add: ['$val', 10]}
|
||||
* , sub: {
|
||||
* name: '$a'
|
||||
* }
|
||||
* })
|
||||
*
|
||||
* // etc
|
||||
* aggregate.project({ salary_k: { $divide: [ "$salary", 1000 ] } });
|
||||
*
|
||||
* @param {Object|String} arg field specification
|
||||
* @see projection http://docs.mongodb.org/manual/reference/aggregation/project/
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.project = function(arg) {
|
||||
var fields = {};
|
||||
|
||||
if (typeof arg === 'object' && !util.isArray(arg)) {
|
||||
Object.keys(arg).forEach(function(field) {
|
||||
fields[field] = arg[field];
|
||||
});
|
||||
} else if (arguments.length === 1 && typeof arg === 'string') {
|
||||
arg.split(/\s+/).forEach(function(field) {
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
var include = field[0] === '-' ? 0 : 1;
|
||||
if (include === 0) {
|
||||
field = field.substring(1);
|
||||
}
|
||||
fields[field] = include;
|
||||
});
|
||||
} else {
|
||||
throw new Error('Invalid project() argument. Must be string or object');
|
||||
}
|
||||
|
||||
return this.append({$project: fields});
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a new custom $group operator to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.group({ _id: "$department" });
|
||||
*
|
||||
* @see $group http://docs.mongodb.org/manual/reference/aggregation/group/
|
||||
* @method group
|
||||
* @memberOf Aggregate
|
||||
* @param {Object} arg $group operator contents
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Appends a new custom $match operator to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.match({ department: { $in: [ "sales", "engineering" } } });
|
||||
*
|
||||
* @see $match http://docs.mongodb.org/manual/reference/aggregation/match/
|
||||
* @method match
|
||||
* @memberOf Aggregate
|
||||
* @param {Object} arg $match operator contents
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Appends a new $skip operator to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.skip(10);
|
||||
*
|
||||
* @see $skip http://docs.mongodb.org/manual/reference/aggregation/skip/
|
||||
* @method skip
|
||||
* @memberOf Aggregate
|
||||
* @param {Number} num number of records to skip before next stage
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Appends a new $limit operator to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.limit(10);
|
||||
*
|
||||
* @see $limit http://docs.mongodb.org/manual/reference/aggregation/limit/
|
||||
* @method limit
|
||||
* @memberOf Aggregate
|
||||
* @param {Number} num maximum number of records to pass to the next stage
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
/**
|
||||
* Appends a new $geoNear operator to this aggregate pipeline.
|
||||
*
|
||||
* ####NOTE:
|
||||
*
|
||||
* **MUST** be used as the first operator in the pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.near({
|
||||
* near: [40.724, -73.997],
|
||||
* distanceField: "dist.calculated", // required
|
||||
* maxDistance: 0.008,
|
||||
* query: { type: "public" },
|
||||
* includeLocs: "dist.location",
|
||||
* uniqueDocs: true,
|
||||
* num: 5
|
||||
* });
|
||||
*
|
||||
* @see $geoNear http://docs.mongodb.org/manual/reference/aggregation/geoNear/
|
||||
* @method near
|
||||
* @memberOf Aggregate
|
||||
* @param {Object} parameters
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.near = function(arg) {
|
||||
var op = {};
|
||||
op.$geoNear = arg;
|
||||
return this.append(op);
|
||||
};
|
||||
|
||||
/*!
|
||||
* define methods
|
||||
*/
|
||||
|
||||
'group match skip limit out'.split(' ').forEach(function($operator) {
|
||||
Aggregate.prototype[$operator] = function(arg) {
|
||||
var op = {};
|
||||
op['$' + $operator] = arg;
|
||||
return this.append(op);
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Appends new custom $unwind operator(s) to this aggregate pipeline.
|
||||
*
|
||||
* Note that the `$unwind` operator requires the path name to start with '$'.
|
||||
* Mongoose will prepend '$' if the specified field doesn't start '$'.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.unwind("tags");
|
||||
* aggregate.unwind("a", "b", "c");
|
||||
*
|
||||
* @see $unwind http://docs.mongodb.org/manual/reference/aggregation/unwind/
|
||||
* @param {String} fields the field(s) to unwind
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.unwind = function() {
|
||||
var args = utils.args(arguments);
|
||||
|
||||
var res = [];
|
||||
for (var i = 0; i < args.length; ++i) {
|
||||
var arg = args[i];
|
||||
if (arg && typeof arg === 'object') {
|
||||
res.push({ $unwind: arg });
|
||||
} else if (typeof arg === 'string') {
|
||||
res.push({
|
||||
$unwind: (arg && arg.charAt(0) === '$') ? arg : '$' + arg
|
||||
});
|
||||
} else {
|
||||
throw new Error('Invalid arg "' + arg + '" to unwind(), ' +
|
||||
'must be string or object');
|
||||
}
|
||||
}
|
||||
|
||||
return this.append.apply(this, res);
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends new custom $lookup operator(s) to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.lookup({ from: 'users', localField: 'userId', foreignField: '_id', as: 'users' });
|
||||
*
|
||||
* @see $lookup https://docs.mongodb.org/manual/reference/operator/aggregation/lookup/#pipe._S_lookup
|
||||
* @param {Object} options to $lookup as described in the above link
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.lookup = function(options) {
|
||||
return this.append({$lookup: options});
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends new custom $sample operator(s) to this aggregate pipeline.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* aggregate.sample(3); // Add a pipeline that picks 3 random documents
|
||||
*
|
||||
* @see $sample https://docs.mongodb.org/manual/reference/operator/aggregation/sample/#pipe._S_sample
|
||||
* @param {Number} size number of random documents to pick
|
||||
* @return {Aggregate}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.sample = function(size) {
|
||||
return this.append({$sample: {size: size}});
|
||||
};
|
||||
|
||||
/**
|
||||
* Appends a new $sort operator to this aggregate pipeline.
|
||||
*
|
||||
* If an object is passed, values allowed are `asc`, `desc`, `ascending`, `descending`, `1`, and `-1`.
|
||||
*
|
||||
* If a string is passed, it must be a space delimited list of path names. The sort order of each path is ascending unless the path name is prefixed with `-` which will be treated as descending.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* // these are equivalent
|
||||
* aggregate.sort({ field: 'asc', test: -1 });
|
||||
* aggregate.sort('field -test');
|
||||
*
|
||||
* @see $sort http://docs.mongodb.org/manual/reference/aggregation/sort/
|
||||
* @param {Object|String} arg
|
||||
* @return {Aggregate} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.sort = function(arg) {
|
||||
// TODO refactor to reuse the query builder logic
|
||||
|
||||
var sort = {};
|
||||
|
||||
if (arg.constructor.name === 'Object') {
|
||||
var desc = ['desc', 'descending', -1];
|
||||
Object.keys(arg).forEach(function(field) {
|
||||
sort[field] = desc.indexOf(arg[field]) === -1 ? 1 : -1;
|
||||
});
|
||||
} else if (arguments.length === 1 && typeof arg === 'string') {
|
||||
arg.split(/\s+/).forEach(function(field) {
|
||||
if (!field) {
|
||||
return;
|
||||
}
|
||||
var ascend = field[0] === '-' ? -1 : 1;
|
||||
if (ascend === -1) {
|
||||
field = field.substring(1);
|
||||
}
|
||||
sort[field] = ascend;
|
||||
});
|
||||
} else {
|
||||
throw new TypeError('Invalid sort() argument. Must be a string or object.');
|
||||
}
|
||||
|
||||
return this.append({$sort: sort});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the readPreference option for the aggregation query.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* Model.aggregate(..).read('primaryPreferred').exec(callback)
|
||||
*
|
||||
* @param {String} pref one of the listed preference options or their aliases
|
||||
* @param {Array} [tags] optional tags for this query
|
||||
* @see mongodb http://docs.mongodb.org/manual/applications/replication/#read-preference
|
||||
* @see driver http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences
|
||||
*/
|
||||
|
||||
Aggregate.prototype.read = function(pref, tags) {
|
||||
if (!this.options) {
|
||||
this.options = {};
|
||||
}
|
||||
read.call(this, pref, tags);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute the aggregation with explain
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* Model.aggregate(..).explain(callback)
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
Aggregate.prototype.explain = function(callback) {
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
if (!_this._pipeline.length) {
|
||||
var err = new Error('Aggregate has empty pipeline');
|
||||
if (callback) {
|
||||
callback(err);
|
||||
}
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
prepareDiscriminatorPipeline(_this);
|
||||
|
||||
_this._model
|
||||
.collection
|
||||
.aggregate(_this._pipeline, _this.options || {})
|
||||
.explain(function(error, result) {
|
||||
if (error) {
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(null, result);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0)
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* Model.aggregate(..).allowDiskUse(true).exec(callback)
|
||||
*
|
||||
* @param {Boolean} value Should tell server it can use hard drive to store data during aggregation.
|
||||
* @param {Array} [tags] optional tags for this query
|
||||
* @see mongodb http://docs.mongodb.org/manual/reference/command/aggregate/
|
||||
*/
|
||||
|
||||
Aggregate.prototype.allowDiskUse = function(value) {
|
||||
if (!this.options) {
|
||||
this.options = {};
|
||||
}
|
||||
this.options.allowDiskUse = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor option option for the aggregation query (ignored for < 2.6.0).
|
||||
* Note the different syntax below: .exec() returns a cursor object, and no callback
|
||||
* is necessary.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
|
||||
* cursor.each(function(error, doc) {
|
||||
* // use doc
|
||||
* });
|
||||
*
|
||||
* @param {Object} options set the cursor batch size
|
||||
* @see mongodb http://mongodb.github.io/node-mongodb-native/2.0/api/AggregationCursor.html
|
||||
*/
|
||||
|
||||
Aggregate.prototype.cursor = function(options) {
|
||||
if (!this.options) {
|
||||
this.options = {};
|
||||
}
|
||||
this.options.cursor = options || {};
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a [cursor flag](http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#addCursorFlag)
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var cursor = Model.aggregate(..).cursor({ batchSize: 1000 }).exec();
|
||||
* cursor.each(function(error, doc) {
|
||||
* // use doc
|
||||
* });
|
||||
*
|
||||
* @param {String} flag
|
||||
* @param {Boolean} value
|
||||
* @see mongodb http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#addCursorFlag
|
||||
*/
|
||||
|
||||
Aggregate.prototype.addCursorFlag = function(flag, value) {
|
||||
if (!this.options) {
|
||||
this.options = {};
|
||||
}
|
||||
this.options[flag] = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes the aggregate pipeline on the currently bound Model.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* aggregate.exec(callback);
|
||||
*
|
||||
* // Because a promise is returned, the `callback` is optional.
|
||||
* var promise = aggregate.exec();
|
||||
* promise.then(..);
|
||||
*
|
||||
* @see Promise #promise_Promise
|
||||
* @param {Function} [callback]
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Aggregate.prototype.exec = function(callback) {
|
||||
if (!this._model) {
|
||||
throw new Error('Aggregate not bound to any Model');
|
||||
}
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
var options = utils.clone(this.options);
|
||||
|
||||
if (options && options.cursor) {
|
||||
if (options.cursor.async) {
|
||||
delete options.cursor.async;
|
||||
return new Promise.ES6(function(resolve) {
|
||||
if (!_this._model.collection.buffer) {
|
||||
process.nextTick(function() {
|
||||
var cursor = _this._model.collection.
|
||||
aggregate(_this._pipeline, options || {});
|
||||
resolve(cursor);
|
||||
callback && callback(null, cursor);
|
||||
});
|
||||
return;
|
||||
}
|
||||
_this._model.collection.emitter.once('queue', function() {
|
||||
var cursor = _this._model.collection.
|
||||
aggregate(_this._pipeline, options || {});
|
||||
resolve(cursor);
|
||||
callback && callback(null, cursor);
|
||||
});
|
||||
});
|
||||
}
|
||||
return this._model.collection.
|
||||
aggregate(this._pipeline, this.options || {});
|
||||
}
|
||||
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
if (!_this._pipeline.length) {
|
||||
var err = new Error('Aggregate has empty pipeline');
|
||||
if (callback) {
|
||||
callback(err);
|
||||
}
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
prepareDiscriminatorPipeline(_this);
|
||||
|
||||
_this._model
|
||||
.collection
|
||||
.aggregate(_this._pipeline, _this.options || {}, function(error, result) {
|
||||
if (error) {
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(null, result);
|
||||
}
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides promise for aggregate.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* Model.aggregate(..).then(successCallback, errorCallback);
|
||||
*
|
||||
* @see Promise #promise_Promise
|
||||
* @param {Function} [resolve] successCallback
|
||||
* @param {Function} [reject] errorCallback
|
||||
* @return {Promise}
|
||||
*/
|
||||
Aggregate.prototype.then = function(resolve, reject) {
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
var promise = new Promise.ES6(function(success, error) {
|
||||
_this.exec(function(err, val) {
|
||||
if (err) error(err);
|
||||
else success(val);
|
||||
});
|
||||
});
|
||||
return promise.then(resolve, reject);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks whether an object is likely a pipeline operator
|
||||
*
|
||||
* @param {Object} obj object to check
|
||||
* @return {Boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function isOperator(obj) {
|
||||
var k;
|
||||
|
||||
if (typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
k = Object.keys(obj);
|
||||
|
||||
return k.length === 1 && k
|
||||
.some(function(key) {
|
||||
return key[0] === '$';
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* Adds the appropriate `$match` pipeline step to the top of an aggregate's
|
||||
* pipeline, should it's model is a non-root discriminator type. This is
|
||||
* analogous to the `prepareDiscriminatorCriteria` function in `lib/query.js`.
|
||||
*
|
||||
* @param {Aggregate} aggregate Aggregate to prepare
|
||||
*/
|
||||
|
||||
function prepareDiscriminatorPipeline(aggregate) {
|
||||
var schema = aggregate._model.schema,
|
||||
discriminatorMapping = schema && schema.discriminatorMapping;
|
||||
|
||||
if (discriminatorMapping && !discriminatorMapping.isRoot) {
|
||||
var originalPipeline = aggregate._pipeline,
|
||||
discriminatorKey = discriminatorMapping.key,
|
||||
discriminatorValue = discriminatorMapping.value;
|
||||
|
||||
// If the first pipeline stage is a match and it doesn't specify a `__t`
|
||||
// key, add the discriminator key to it. This allows for potential
|
||||
// aggregation query optimizations not to be disturbed by this feature.
|
||||
if (originalPipeline[0] && originalPipeline[0].$match && !originalPipeline[0].$match[discriminatorKey]) {
|
||||
originalPipeline[0].$match[discriminatorKey] = discriminatorValue;
|
||||
// `originalPipeline` is a ref, so there's no need for
|
||||
// aggregate._pipeline = originalPipeline
|
||||
} else if (originalPipeline[0] && originalPipeline[0].$geoNear) {
|
||||
originalPipeline[0].$geoNear.query =
|
||||
originalPipeline[0].$geoNear.query || {};
|
||||
originalPipeline[0].$geoNear.query[discriminatorKey] = discriminatorValue;
|
||||
} else {
|
||||
var match = {};
|
||||
match[discriminatorKey] = discriminatorValue;
|
||||
aggregate._pipeline = [{$match: match}].concat(originalPipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Exports
|
||||
*/
|
||||
|
||||
module.exports = Aggregate;
|
||||
99
node_modules/mongoose/lib/browser.js
generated
vendored
Normal file
99
node_modules/mongoose/lib/browser.js
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
/**
|
||||
* The [MongooseError](#error_MongooseError) constructor.
|
||||
*
|
||||
* @method Error
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.Error = require('./error');
|
||||
|
||||
/**
|
||||
* The Mongoose [Schema](#schema_Schema) constructor
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var Schema = mongoose.Schema;
|
||||
* var CatSchema = new Schema(..);
|
||||
*
|
||||
* @method Schema
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.Schema = require('./schema');
|
||||
|
||||
/**
|
||||
* The various Mongoose Types.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var mongoose = require('mongoose');
|
||||
* var array = mongoose.Types.Array;
|
||||
*
|
||||
* ####Types:
|
||||
*
|
||||
* - [ObjectId](#types-objectid-js)
|
||||
* - [Buffer](#types-buffer-js)
|
||||
* - [SubDocument](#types-embedded-js)
|
||||
* - [Array](#types-array-js)
|
||||
* - [DocumentArray](#types-documentarray-js)
|
||||
*
|
||||
* Using this exposed access to the `ObjectId` type, we can construct ids on demand.
|
||||
*
|
||||
* var ObjectId = mongoose.Types.ObjectId;
|
||||
* var id1 = new ObjectId;
|
||||
*
|
||||
* @property Types
|
||||
* @api public
|
||||
*/
|
||||
exports.Types = require('./types');
|
||||
|
||||
/**
|
||||
* The Mongoose [VirtualType](#virtualtype_VirtualType) constructor
|
||||
*
|
||||
* @method VirtualType
|
||||
* @api public
|
||||
*/
|
||||
exports.VirtualType = require('./virtualtype');
|
||||
|
||||
/**
|
||||
* The various Mongoose SchemaTypes.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* _Alias of mongoose.Schema.Types for backwards compatibility._
|
||||
*
|
||||
* @property SchemaTypes
|
||||
* @see Schema.SchemaTypes #schema_Schema.Types
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.SchemaType = require('./schematype.js');
|
||||
|
||||
/**
|
||||
* Internal utils
|
||||
*
|
||||
* @property utils
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.utils = require('./utils.js');
|
||||
|
||||
/**
|
||||
* The Mongoose browser [Document](#document-js) constructor.
|
||||
*
|
||||
* @method Document
|
||||
* @api public
|
||||
*/
|
||||
exports.Document = require('./document_provider.js')();
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.mongoose = module.exports;
|
||||
window.Buffer = Buffer;
|
||||
}
|
||||
103
node_modules/mongoose/lib/browserDocument.js
generated
vendored
Normal file
103
node_modules/mongoose/lib/browserDocument.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var NodeJSDocument = require('./document'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
MongooseError = require('./error'),
|
||||
Schema = require('./schema'),
|
||||
ObjectId = require('./types/objectid'),
|
||||
utils = require('./utils'),
|
||||
ValidationError = MongooseError.ValidationError,
|
||||
InternalCache = require('./internal');
|
||||
|
||||
/**
|
||||
* Document constructor.
|
||||
*
|
||||
* @param {Object} obj the values to set
|
||||
* @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
|
||||
* @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
|
||||
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
|
||||
* @event `init`: Emitted on a document after it has was retrieved from the db and fully hydrated by Mongoose.
|
||||
* @event `save`: Emitted when the document is successfully saved
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Document(obj, schema, fields, skipId, skipInit) {
|
||||
if (!(this instanceof Document)) {
|
||||
return new Document(obj, schema, fields, skipId, skipInit);
|
||||
}
|
||||
|
||||
|
||||
if (utils.isObject(schema) && !schema.instanceOfSchema) {
|
||||
schema = new Schema(schema);
|
||||
}
|
||||
|
||||
// When creating EmbeddedDocument, it already has the schema and he doesn't need the _id
|
||||
schema = this.schema || schema;
|
||||
|
||||
// Generate ObjectId if it is missing, but it requires a scheme
|
||||
if (!this.schema && schema.options._id) {
|
||||
obj = obj || {};
|
||||
|
||||
if (obj._id === undefined) {
|
||||
obj._id = new ObjectId();
|
||||
}
|
||||
}
|
||||
|
||||
if (!schema) {
|
||||
throw new MongooseError.MissingSchemaError();
|
||||
}
|
||||
|
||||
this.$__setSchema(schema);
|
||||
|
||||
this.$__ = new InternalCache;
|
||||
this.$__.emitter = new EventEmitter();
|
||||
this.isNew = true;
|
||||
this.errors = undefined;
|
||||
|
||||
// var schema = this.schema;
|
||||
|
||||
if (typeof fields === 'boolean') {
|
||||
this.$__.strictMode = fields;
|
||||
fields = undefined;
|
||||
} else {
|
||||
this.$__.strictMode = this.schema.options && this.schema.options.strict;
|
||||
this.$__.selected = fields;
|
||||
}
|
||||
|
||||
var required = this.schema.requiredPaths();
|
||||
for (var i = 0; i < required.length; ++i) {
|
||||
this.$__.activePaths.require(required[i]);
|
||||
}
|
||||
|
||||
this.$__.emitter.setMaxListeners(0);
|
||||
this._doc = this.$__buildDoc(obj, fields, skipId);
|
||||
|
||||
if (!skipInit && obj) {
|
||||
this.init(obj);
|
||||
}
|
||||
|
||||
this.$__registerHooksFromSchema();
|
||||
|
||||
// apply methods
|
||||
for (var m in schema.methods) {
|
||||
this[m] = schema.methods[m];
|
||||
}
|
||||
// apply statics
|
||||
for (var s in schema.statics) {
|
||||
this[s] = schema.statics[s];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from the NodeJS document
|
||||
*/
|
||||
Document.prototype = Object.create(NodeJSDocument.prototype);
|
||||
Document.prototype.constructor = Document;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
Document.ValidationError = ValidationError;
|
||||
module.exports = exports = Document;
|
||||
238
node_modules/mongoose/lib/cast.js
generated
vendored
Normal file
238
node_modules/mongoose/lib/cast.js
generated
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
var Types = require('./schema/index');
|
||||
|
||||
var ALLOWED_GEOWITHIN_GEOJSON_TYPES = ['Polygon', 'MultiPolygon'];
|
||||
|
||||
/**
|
||||
* Handles internal casting for queries
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {Object} obj Object to cast
|
||||
* @api private
|
||||
*/
|
||||
module.exports = function cast(schema, obj) {
|
||||
var paths = Object.keys(obj),
|
||||
i = paths.length,
|
||||
any$conditionals,
|
||||
schematype,
|
||||
nested,
|
||||
path,
|
||||
type,
|
||||
val;
|
||||
|
||||
while (i--) {
|
||||
path = paths[i];
|
||||
val = obj[path];
|
||||
|
||||
if (path === '$or' || path === '$nor' || path === '$and') {
|
||||
var k = val.length;
|
||||
|
||||
while (k--) {
|
||||
val[k] = cast(schema, val[k]);
|
||||
}
|
||||
} else if (path === '$where') {
|
||||
type = typeof val;
|
||||
|
||||
if (type !== 'string' && type !== 'function') {
|
||||
throw new Error('Must have a string or function for $where');
|
||||
}
|
||||
|
||||
if (type === 'function') {
|
||||
obj[path] = val.toString();
|
||||
}
|
||||
|
||||
continue;
|
||||
} else if (path === '$elemMatch') {
|
||||
val = cast(schema, val);
|
||||
} else {
|
||||
if (!schema) {
|
||||
// no casting for Mixed types
|
||||
continue;
|
||||
}
|
||||
|
||||
schematype = schema.path(path);
|
||||
|
||||
if (!schematype) {
|
||||
// Handle potential embedded array queries
|
||||
var split = path.split('.'),
|
||||
j = split.length,
|
||||
pathFirstHalf,
|
||||
pathLastHalf,
|
||||
remainingConds;
|
||||
|
||||
// Find the part of the var path that is a path of the Schema
|
||||
while (j--) {
|
||||
pathFirstHalf = split.slice(0, j).join('.');
|
||||
schematype = schema.path(pathFirstHalf);
|
||||
if (schematype) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If a substring of the input path resolves to an actual real path...
|
||||
if (schematype) {
|
||||
// Apply the casting; similar code for $elemMatch in schema/array.js
|
||||
if (schematype.caster && schematype.caster.schema) {
|
||||
remainingConds = {};
|
||||
pathLastHalf = split.slice(j).join('.');
|
||||
remainingConds[pathLastHalf] = val;
|
||||
obj[path] = cast(schematype.caster.schema, remainingConds)[pathLastHalf];
|
||||
} else {
|
||||
obj[path] = val;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils.isObject(val)) {
|
||||
// handle geo schemas that use object notation
|
||||
// { loc: { long: Number, lat: Number }
|
||||
|
||||
var geo = '';
|
||||
if (val.$near) {
|
||||
geo = '$near';
|
||||
} else if (val.$nearSphere) {
|
||||
geo = '$nearSphere';
|
||||
} else if (val.$within) {
|
||||
geo = '$within';
|
||||
} else if (val.$geoIntersects) {
|
||||
geo = '$geoIntersects';
|
||||
} else if (val.$geoWithin) {
|
||||
geo = '$geoWithin';
|
||||
}
|
||||
|
||||
if (!geo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var numbertype = new Types.Number('__QueryCasting__');
|
||||
var value = val[geo];
|
||||
|
||||
if (val.$maxDistance != null) {
|
||||
val.$maxDistance = numbertype.castForQuery(val.$maxDistance);
|
||||
}
|
||||
if (val.$minDistance != null) {
|
||||
val.$minDistance = numbertype.castForQuery(val.$minDistance);
|
||||
}
|
||||
|
||||
if (geo === '$within') {
|
||||
var withinType = value.$center
|
||||
|| value.$centerSphere
|
||||
|| value.$box
|
||||
|| value.$polygon;
|
||||
|
||||
if (!withinType) {
|
||||
throw new Error('Bad $within paramater: ' + JSON.stringify(val));
|
||||
}
|
||||
|
||||
value = withinType;
|
||||
} else if (geo === '$near' &&
|
||||
typeof value.type === 'string' && Array.isArray(value.coordinates)) {
|
||||
// geojson; cast the coordinates
|
||||
value = value.coordinates;
|
||||
} else if ((geo === '$near' || geo === '$nearSphere' || geo === '$geoIntersects') &&
|
||||
value.$geometry && typeof value.$geometry.type === 'string' &&
|
||||
Array.isArray(value.$geometry.coordinates)) {
|
||||
if (value.$maxDistance != null) {
|
||||
value.$maxDistance = numbertype.castForQuery(value.$maxDistance);
|
||||
}
|
||||
if (value.$minDistance != null) {
|
||||
value.$minDistance = numbertype.castForQuery(value.$minDistance);
|
||||
}
|
||||
if (utils.isMongooseObject(value.$geometry)) {
|
||||
value.$geometry = value.$geometry.toObject({ virtuals: false });
|
||||
}
|
||||
value = value.$geometry.coordinates;
|
||||
} else if (geo === '$geoWithin') {
|
||||
if (!value.$geometry) {
|
||||
throw new Error('$geoWithin must specify $geometry');
|
||||
}
|
||||
if (utils.isMongooseObject(value.$geometry)) {
|
||||
value.$geometry = value.$geometry.toObject({ virtuals: false });
|
||||
}
|
||||
var geoWithinType = value.$geometry.type;
|
||||
if (ALLOWED_GEOWITHIN_GEOJSON_TYPES.indexOf(geoWithinType) === -1) {
|
||||
throw new Error('Invalid geoJSON type for $geoWithin "' +
|
||||
geoWithinType + '", must be "Polygon" or "MultiPolygon"');
|
||||
}
|
||||
value = value.$geometry.coordinates;
|
||||
}
|
||||
|
||||
_cast(value, numbertype);
|
||||
}
|
||||
} else if (val === null || val === undefined) {
|
||||
obj[path] = null;
|
||||
continue;
|
||||
} else if (val.constructor.name === 'Object') {
|
||||
any$conditionals = Object.keys(val).some(function(k) {
|
||||
return k.charAt(0) === '$' && k !== '$id' && k !== '$ref';
|
||||
});
|
||||
|
||||
if (!any$conditionals) {
|
||||
obj[path] = schematype.castForQuery(val);
|
||||
} else {
|
||||
var ks = Object.keys(val),
|
||||
$cond;
|
||||
|
||||
k = ks.length;
|
||||
|
||||
while (k--) {
|
||||
$cond = ks[k];
|
||||
nested = val[$cond];
|
||||
|
||||
if ($cond === '$exists') {
|
||||
if (typeof nested !== 'boolean') {
|
||||
throw new Error('$exists parameter must be Boolean');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($cond === '$type') {
|
||||
if (typeof nested !== 'number' && typeof nested !== 'string') {
|
||||
throw new Error('$type parameter must be number or string');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($cond === '$not') {
|
||||
cast(schema, nested);
|
||||
} else {
|
||||
val[$cond] = schematype.castForQuery($cond, nested);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
obj[path] = schematype.castForQuery(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
function _cast(val, numbertype) {
|
||||
if (Array.isArray(val)) {
|
||||
val.forEach(function(item, i) {
|
||||
if (Array.isArray(item) || utils.isObject(item)) {
|
||||
return _cast(item, numbertype);
|
||||
}
|
||||
val[i] = numbertype.castForQuery(item);
|
||||
});
|
||||
} else {
|
||||
var nearKeys = Object.keys(val);
|
||||
var nearLen = nearKeys.length;
|
||||
while (nearLen--) {
|
||||
var nkey = nearKeys[nearLen];
|
||||
var item = val[nkey];
|
||||
if (Array.isArray(item) || utils.isObject(item)) {
|
||||
_cast(item, numbertype);
|
||||
val[nkey] = item;
|
||||
} else {
|
||||
val[nkey] = numbertype.castForQuery(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
node_modules/mongoose/lib/collection.js
generated
vendored
72
node_modules/mongoose/lib/collection.js
generated
vendored
@@ -1,9 +1,9 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var STATES = require('./connectionstate')
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var STATES = require('./connectionstate');
|
||||
|
||||
/**
|
||||
* Abstract Collection constructor
|
||||
@@ -16,28 +16,34 @@ var STATES = require('./connectionstate')
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Collection (name, conn, opts) {
|
||||
if (undefined === opts) opts = {};
|
||||
if (undefined === opts.capped) opts.capped = {};
|
||||
function Collection(name, conn, opts) {
|
||||
if (opts === void 0) {
|
||||
opts = {};
|
||||
}
|
||||
if (opts.capped === void 0) {
|
||||
opts.capped = {};
|
||||
}
|
||||
|
||||
opts.bufferCommands = undefined === opts.bufferCommands
|
||||
? true
|
||||
: opts.bufferCommands;
|
||||
? true
|
||||
: opts.bufferCommands;
|
||||
|
||||
if ('number' == typeof opts.capped) {
|
||||
opts.capped = { size: opts.capped };
|
||||
if (typeof opts.capped === 'number') {
|
||||
opts.capped = {size: opts.capped};
|
||||
}
|
||||
|
||||
this.opts = opts;
|
||||
this.name = name;
|
||||
this.collectionName = name;
|
||||
this.conn = conn;
|
||||
this.queue = [];
|
||||
this.buffer = this.opts.bufferCommands;
|
||||
this.emitter = new EventEmitter();
|
||||
|
||||
if (STATES.connected == this.conn.readyState) {
|
||||
if (STATES.connected === this.conn.readyState) {
|
||||
this.onOpen();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection name
|
||||
@@ -48,6 +54,15 @@ function Collection (name, conn, opts) {
|
||||
|
||||
Collection.prototype.name;
|
||||
|
||||
/**
|
||||
* The collection name
|
||||
*
|
||||
* @api public
|
||||
* @property collectionName
|
||||
*/
|
||||
|
||||
Collection.prototype.collectionName;
|
||||
|
||||
/**
|
||||
* The Connection instance
|
||||
*
|
||||
@@ -63,10 +78,9 @@ Collection.prototype.conn;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onOpen = function () {
|
||||
var self = this;
|
||||
Collection.prototype.onOpen = function() {
|
||||
this.buffer = false;
|
||||
self.doQueue();
|
||||
this.doQueue();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -75,7 +89,7 @@ Collection.prototype.onOpen = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.onClose = function () {
|
||||
Collection.prototype.onClose = function() {
|
||||
if (this.opts.bufferCommands) {
|
||||
this.buffer = true;
|
||||
}
|
||||
@@ -90,7 +104,7 @@ Collection.prototype.onClose = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.addQueue = function (name, args) {
|
||||
Collection.prototype.addQueue = function(name, args) {
|
||||
this.queue.push([name, args]);
|
||||
return this;
|
||||
};
|
||||
@@ -101,11 +115,15 @@ Collection.prototype.addQueue = function (name, args) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Collection.prototype.doQueue = function () {
|
||||
for (var i = 0, l = this.queue.length; i < l; i++){
|
||||
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 = [];
|
||||
var _this = this;
|
||||
process.nextTick(function() {
|
||||
_this.emitter.emit('queue');
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -113,7 +131,7 @@ Collection.prototype.doQueue = function () {
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.ensureIndex = function(){
|
||||
Collection.prototype.ensureIndex = function() {
|
||||
throw new Error('Collection#ensureIndex unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -121,7 +139,7 @@ Collection.prototype.ensureIndex = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findAndModify = function(){
|
||||
Collection.prototype.findAndModify = function() {
|
||||
throw new Error('Collection#findAndModify unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -129,7 +147,7 @@ Collection.prototype.findAndModify = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.findOne = function(){
|
||||
Collection.prototype.findOne = function() {
|
||||
throw new Error('Collection#findOne unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -137,7 +155,7 @@ Collection.prototype.findOne = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.find = function(){
|
||||
Collection.prototype.find = function() {
|
||||
throw new Error('Collection#find unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -145,7 +163,7 @@ Collection.prototype.find = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.insert = function(){
|
||||
Collection.prototype.insert = function() {
|
||||
throw new Error('Collection#insert unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -153,7 +171,7 @@ Collection.prototype.insert = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.save = function(){
|
||||
Collection.prototype.save = function() {
|
||||
throw new Error('Collection#save unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -161,7 +179,7 @@ Collection.prototype.save = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.update = function(){
|
||||
Collection.prototype.update = function() {
|
||||
throw new Error('Collection#update unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -169,7 +187,7 @@ Collection.prototype.update = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.getIndexes = function(){
|
||||
Collection.prototype.getIndexes = function() {
|
||||
throw new Error('Collection#getIndexes unimplemented by driver');
|
||||
};
|
||||
|
||||
@@ -177,7 +195,7 @@ Collection.prototype.getIndexes = function(){
|
||||
* Abstract method that drivers must implement.
|
||||
*/
|
||||
|
||||
Collection.prototype.mapReduce = function(){
|
||||
Collection.prototype.mapReduce = function() {
|
||||
throw new Error('Collection#mapReduce unimplemented by driver');
|
||||
};
|
||||
|
||||
|
||||
429
node_modules/mongoose/lib/connection.js
generated
vendored
429
node_modules/mongoose/lib/connection.js
generated
vendored
@@ -2,17 +2,15 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var url = require('url')
|
||||
, utils = require('./utils')
|
||||
, EventEmitter = require('events').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')
|
||||
var utils = require('./utils');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || './drivers/node-mongodb-native';
|
||||
var Schema = require('./schema');
|
||||
var Collection = require(driver + '/collection');
|
||||
var STATES = require('./connectionstate');
|
||||
var MongooseError = require('./error');
|
||||
var muri = require('muri');
|
||||
var PromiseProvider = require('./promise_provider');
|
||||
|
||||
/*!
|
||||
* Protocol prefix regexp.
|
||||
@@ -22,6 +20,16 @@ var url = require('url')
|
||||
|
||||
var rgxProtocol = /^(?:.)+:\/\//;
|
||||
|
||||
/*!
|
||||
* A list of authentication mechanisms that don't require a password for authentication.
|
||||
* This is used by the authMechanismDoesNotRequirePassword method.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
var authMechanismsWhichDontRequirePassword = [
|
||||
'MONGODB-X509'
|
||||
];
|
||||
|
||||
/**
|
||||
* Connection constructor
|
||||
*
|
||||
@@ -37,14 +45,16 @@ var rgxProtocol = /^(?:.)+:\/\//;
|
||||
* @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.
|
||||
* @event `fullsetup`: Emitted in a replica-set scenario, when primary and at least one seconaries specified in the connection string are connected.
|
||||
* @event `all`: Emitted in a replica-set scenario, when all nodes specified in the connection string are connected.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Connection (base) {
|
||||
function Connection(base) {
|
||||
this.base = base;
|
||||
this.collections = {};
|
||||
this.models = {};
|
||||
this.config = {autoIndex: true};
|
||||
this.replica = false;
|
||||
this.hosts = null;
|
||||
this.host = null;
|
||||
@@ -53,10 +63,11 @@ function Connection (base) {
|
||||
this.pass = null;
|
||||
this.name = null;
|
||||
this.options = null;
|
||||
this.otherDbs = [];
|
||||
this._readyState = STATES.disconnected;
|
||||
this._closeCalled = false;
|
||||
this._hasOpened = false;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from EventEmitter
|
||||
@@ -84,21 +95,28 @@ Connection.prototype.__proto__ = EventEmitter.prototype;
|
||||
*/
|
||||
|
||||
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]);
|
||||
}
|
||||
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;
|
||||
// loop over the otherDbs on this connection and change their state
|
||||
for (var i = 0; i < this.otherDbs.length; i++) {
|
||||
this.otherDbs[i].readyState = val;
|
||||
}
|
||||
|
||||
if (STATES.connected === val) {
|
||||
this._hasOpened = true;
|
||||
}
|
||||
|
||||
this.emit(STATES[val]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -117,11 +135,20 @@ Connection.prototype.collections;
|
||||
|
||||
Connection.prototype.db;
|
||||
|
||||
/**
|
||||
* A hash of the global options that are associated with this connection
|
||||
*
|
||||
* @property config
|
||||
*/
|
||||
|
||||
Connection.prototype.config;
|
||||
|
||||
/**
|
||||
* Opens the connection to MongoDB.
|
||||
*
|
||||
* `options` is a hash with the following possible properties:
|
||||
*
|
||||
* config - passed to the connection config instance
|
||||
* db - passed to the connection db instance
|
||||
* server - passed to the connection server instance(s)
|
||||
* replset - passed to the connection ReplSet instance
|
||||
@@ -147,33 +174,37 @@ Connection.prototype.db;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.open = function (host, database, port, options, callback) {
|
||||
var self = this
|
||||
, parsed
|
||||
, uri;
|
||||
Connection.prototype.open = function(host, database, port, options, callback) {
|
||||
var parsed;
|
||||
|
||||
if ('string' === typeof database) {
|
||||
if (typeof database === 'string') {
|
||||
switch (arguments.length) {
|
||||
case 2:
|
||||
port = 27017;
|
||||
break;
|
||||
case 3:
|
||||
switch (typeof port) {
|
||||
case 'function':
|
||||
callback = port, port = 27017;
|
||||
callback = port;
|
||||
port = 27017;
|
||||
break;
|
||||
case 'object':
|
||||
options = port, port = 27017;
|
||||
options = port;
|
||||
port = 27017;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if ('function' === typeof options)
|
||||
callback = options, options = {};
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (typeof database) {
|
||||
case 'function':
|
||||
callback = database, database = undefined;
|
||||
callback = database;
|
||||
database = undefined;
|
||||
break;
|
||||
case 'object':
|
||||
options = database;
|
||||
@@ -219,32 +250,49 @@ Connection.prototype.open = function (host, database, port, options, callback) {
|
||||
}
|
||||
|
||||
// authentication
|
||||
if (options && options.user && options.pass) {
|
||||
if (this.optionsProvideAuthenticationData(options)) {
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
// global configuration options
|
||||
if (options && options.config) {
|
||||
this.config.autoIndex = options.config.autoIndex !== false;
|
||||
}
|
||||
|
||||
this.name = database;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
this._open(callback);
|
||||
return this;
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
var promise = new Promise.ES6(function(resolve, reject) {
|
||||
_this._open(true, function(error) {
|
||||
callback && callback(error);
|
||||
if (error) {
|
||||
reject(error);
|
||||
if (!callback && !promise.$hasHandler) {
|
||||
_this.emit('error', error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -268,6 +316,8 @@ Connection.prototype.open = function (host, database, port, options, callback) {
|
||||
* auth - options for authentication (see http://mongodb.github.com/node-mongodb-native/api-generated/db.html#authenticate)
|
||||
* mongos - Boolean - if true, enables High Availability support for mongos
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
* ####Notes:
|
||||
*
|
||||
* _If connecting to multiple mongos servers, set the `mongos` option to true._
|
||||
@@ -289,13 +339,11 @@ Connection.prototype.open = function (host, database, port, options, callback) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
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) {
|
||||
@@ -309,7 +357,7 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ('function' === typeof options) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
@@ -320,10 +368,12 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
this.name = database;
|
||||
break;
|
||||
case 'function':
|
||||
callback = database, database = null;
|
||||
callback = database;
|
||||
database = null;
|
||||
break;
|
||||
case 'object':
|
||||
options = database, database = null;
|
||||
options = database;
|
||||
database = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -350,20 +400,37 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
}
|
||||
|
||||
// authentication
|
||||
if (options && options.user && options.pass) {
|
||||
if (this.optionsProvideAuthenticationData(options)) {
|
||||
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;
|
||||
// global configuration options
|
||||
if (options && options.config) {
|
||||
this.config.autoIndex = options.config.autoIndex !== false;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
var promise = new Promise.ES6(function(resolve, reject) {
|
||||
_this._open(true, function(error) {
|
||||
callback && callback(error);
|
||||
if (error) {
|
||||
reject(error);
|
||||
if (!callback && !promise.$hasHandler) {
|
||||
_this.emit('error', error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -377,10 +444,12 @@ Connection.prototype.openSet = function (uris, database, options, callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.error = function (err, callback) {
|
||||
if (callback) return callback(err);
|
||||
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.
|
||||
@@ -389,31 +458,33 @@ Connection.prototype.error = function (err, callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype._open = function (callback) {
|
||||
Connection.prototype._open = function(emit, callback) {
|
||||
this.readyState = STATES.connecting;
|
||||
this._closeCalled = false;
|
||||
|
||||
var self = this;
|
||||
var _this = this;
|
||||
|
||||
var method = this.replica
|
||||
? 'doOpenSet'
|
||||
: 'doOpen';
|
||||
? 'doOpenSet'
|
||||
: 'doOpen';
|
||||
|
||||
// open connection
|
||||
this[method](function (err) {
|
||||
this[method](function(err) {
|
||||
if (err) {
|
||||
self.readyState = STATES.disconnected;
|
||||
if (self._hasOpened) {
|
||||
if (callback) callback(err);
|
||||
_this.readyState = STATES.disconnected;
|
||||
if (_this._hasOpened) {
|
||||
if (callback) {
|
||||
callback(err);
|
||||
}
|
||||
} else {
|
||||
self.error(err, callback);
|
||||
_this.error(err, emit && callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.onOpen(callback);
|
||||
_this.onOpen(callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the connection is opened
|
||||
@@ -421,37 +492,38 @@ Connection.prototype._open = function (callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.onOpen = function (callback) {
|
||||
var self = this;
|
||||
Connection.prototype.onOpen = function(callback) {
|
||||
var _this = this;
|
||||
|
||||
function open (err) {
|
||||
function open(err, isAuth) {
|
||||
if (err) {
|
||||
self.readyState = STATES.disconnected;
|
||||
if (self._hasOpened) {
|
||||
if (callback) callback(err);
|
||||
} else {
|
||||
self.error(err, callback);
|
||||
}
|
||||
_this.readyState = isAuth ? STATES.unauthorized : STATES.disconnected;
|
||||
_this.error(err, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
self.readyState = STATES.connected;
|
||||
_this.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();
|
||||
for (var i in _this.collections) {
|
||||
if (utils.object.hasOwnProperty(_this.collections, i)) {
|
||||
_this.collections[i].onOpen();
|
||||
}
|
||||
}
|
||||
|
||||
callback && callback();
|
||||
self.emit('open');
|
||||
};
|
||||
|
||||
// re-authenticate
|
||||
if (self.user && self.pass) {
|
||||
self.db.authenticate(self.user, self.pass, self.options.auth, open);
|
||||
_this.emit('open');
|
||||
}
|
||||
else
|
||||
|
||||
// re-authenticate if we're not already connected #3871
|
||||
if (this._readyState !== STATES.connected && this.shouldAuthenticate()) {
|
||||
_this.db.authenticate(_this.user, _this.pass, _this.options.auth, function(err) {
|
||||
open(err, true);
|
||||
});
|
||||
} else {
|
||||
open();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -462,36 +534,60 @@ Connection.prototype.onOpen = function (callback) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.close = function (callback) {
|
||||
var self = this;
|
||||
Connection.prototype.close = function(callback) {
|
||||
var _this = this;
|
||||
var Promise = PromiseProvider.get();
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
_this._close(function(error) {
|
||||
callback && callback(error);
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles closing the connection
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @api private
|
||||
*/
|
||||
Connection.prototype._close = function(callback) {
|
||||
var _this = this;
|
||||
this._closeCalled = true;
|
||||
|
||||
switch (this.readyState){
|
||||
switch (this.readyState) {
|
||||
case 0: // disconnected
|
||||
callback && callback();
|
||||
break;
|
||||
|
||||
case 1: // connected
|
||||
case 4: // unauthorized
|
||||
this.readyState = STATES.disconnecting;
|
||||
this.doClose(function(err){
|
||||
if (err){
|
||||
self.error(err, callback);
|
||||
this.doClose(function(err) {
|
||||
if (err) {
|
||||
_this.error(err, callback);
|
||||
} else {
|
||||
self.onClose();
|
||||
_this.onClose();
|
||||
callback && callback();
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case 2: // connecting
|
||||
this.once('open', function(){
|
||||
self.close(callback);
|
||||
this.once('open', function() {
|
||||
_this.close(callback);
|
||||
});
|
||||
break;
|
||||
|
||||
case 3: // disconnecting
|
||||
if (!callback) break;
|
||||
this.once('close', function () {
|
||||
if (!callback) {
|
||||
break;
|
||||
}
|
||||
this.once('close', function() {
|
||||
callback();
|
||||
});
|
||||
break;
|
||||
@@ -506,13 +602,16 @@ Connection.prototype.close = function (callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Connection.prototype.onClose = function () {
|
||||
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();
|
||||
for (var i in this.collections) {
|
||||
if (utils.object.hasOwnProperty(this.collections, i)) {
|
||||
this.collections[i].onClose();
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('close');
|
||||
};
|
||||
@@ -528,9 +627,10 @@ Connection.prototype.onClose = function () {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.collection = function (name, options) {
|
||||
if (!(name in this.collections))
|
||||
Connection.prototype.collection = function(name, options) {
|
||||
if (!(name in this.collections)) {
|
||||
this.collections[name] = new Collection(name, this, options);
|
||||
}
|
||||
return this.collections[name];
|
||||
};
|
||||
|
||||
@@ -566,31 +666,31 @@ Connection.prototype.collection = function (name, options) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Connection.prototype.model = function (name, schema, collection) {
|
||||
Connection.prototype.model = function(name, schema, collection) {
|
||||
// collection name discovery
|
||||
if ('string' == typeof schema) {
|
||||
if (typeof schema === 'string') {
|
||||
collection = schema;
|
||||
schema = false;
|
||||
}
|
||||
|
||||
if (utils.isObject(schema) && !(schema instanceof Schema)) {
|
||||
if (utils.isObject(schema) && !schema.instanceOfSchema) {
|
||||
schema = new Schema(schema);
|
||||
}
|
||||
|
||||
if (this.models[name] && !collection) {
|
||||
// model exists but we are not subclassing with custom collection
|
||||
if (schema instanceof Schema && schema != this.models[name].schema) {
|
||||
if (schema && schema.instanceOfSchema && schema !== this.models[name].schema) {
|
||||
throw new MongooseError.OverwriteModelError(name);
|
||||
}
|
||||
return this.models[name];
|
||||
}
|
||||
|
||||
var opts = { cache: false, connection: this }
|
||||
var opts = {cache: false, connection: this};
|
||||
var model;
|
||||
|
||||
if (schema instanceof Schema) {
|
||||
if (schema && schema.instanceOfSchema) {
|
||||
// compile a model
|
||||
model = this.base.model(name, schema, collection, opts)
|
||||
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.
|
||||
@@ -618,8 +718,8 @@ Connection.prototype.model = function (name, schema, collection) {
|
||||
throw new MongooseError.MissingSchemaError(name);
|
||||
}
|
||||
|
||||
if (this == model.prototype.db
|
||||
&& (!collection || collection == model.collection.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
|
||||
@@ -630,9 +730,9 @@ Connection.prototype.model = function (name, schema, collection) {
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
return this.models[name] = model.__subclass(this, schema, collection);
|
||||
}
|
||||
this.models[name] = model.__subclass(this, schema, collection);
|
||||
return this.models[name];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of model names created on this connection.
|
||||
@@ -640,68 +740,51 @@ Connection.prototype.model = function (name, schema, collection) {
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
Connection.prototype.modelNames = function () {
|
||||
Connection.prototype.modelNames = function() {
|
||||
return Object.keys(this.models);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
/**
|
||||
* @brief Returns if the connection requires authentication after it is opened. Generally if a
|
||||
* username and password are both provided than authentication is needed, but in some cases a
|
||||
* password is not required.
|
||||
* @api private
|
||||
* @return {Boolean} true if the connection should be authenticated after it is opened, otherwise false.
|
||||
*/
|
||||
Connection.prototype.shouldAuthenticate = function() {
|
||||
return (this.user !== null && this.user !== void 0) &&
|
||||
((this.pass !== null || this.pass !== void 0) || this.authMechanismDoesNotRequirePassword());
|
||||
};
|
||||
|
||||
function noop () {}
|
||||
/**
|
||||
* @brief Returns a boolean value that specifies if the current authentication mechanism needs a
|
||||
* password to authenticate according to the auth objects passed into the open/openSet methods.
|
||||
* @api private
|
||||
* @return {Boolean} true if the authentication mechanism specified in the options object requires
|
||||
* a password, otherwise false.
|
||||
*/
|
||||
Connection.prototype.authMechanismDoesNotRequirePassword = function() {
|
||||
if (this.options && this.options.auth) {
|
||||
return authMechanismsWhichDontRequirePassword.indexOf(this.options.auth.authMechanism) >= 0;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns a boolean value that specifies if the provided objects object provides enough
|
||||
* data to authenticate with. Generally this is true if the username and password are both specified
|
||||
* but in some authentication methods, a password is not required for authentication so only a username
|
||||
* is required.
|
||||
* @param {Object} [options] the options object passed into the open/openSet methods.
|
||||
* @api private
|
||||
* @return {Boolean} true if the provided options object provides enough data to authenticate with,
|
||||
* otherwise false.
|
||||
*/
|
||||
Connection.prototype.optionsProvideAuthenticationData = function(options) {
|
||||
return (options) &&
|
||||
(options.user) &&
|
||||
((options.pass) || this.authMechanismDoesNotRequirePassword());
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
|
||||
3
node_modules/mongoose/lib/connectionstate.js
generated
vendored
3
node_modules/mongoose/lib/connectionstate.js
generated
vendored
@@ -9,16 +9,19 @@ var disconnected = 'disconnected';
|
||||
var connected = 'connected';
|
||||
var connecting = 'connecting';
|
||||
var disconnecting = 'disconnecting';
|
||||
var unauthorized = 'unauthorized';
|
||||
var uninitialized = 'uninitialized';
|
||||
|
||||
STATES[0] = disconnected;
|
||||
STATES[1] = connected;
|
||||
STATES[2] = connecting;
|
||||
STATES[3] = disconnecting;
|
||||
STATES[4] = unauthorized;
|
||||
STATES[99] = uninitialized;
|
||||
|
||||
STATES[disconnected] = 0;
|
||||
STATES[connected] = 1;
|
||||
STATES[connecting] = 2;
|
||||
STATES[disconnecting] = 3;
|
||||
STATES[unauthorized] = 4;
|
||||
STATES[uninitialized] = 99;
|
||||
|
||||
2000
node_modules/mongoose/lib/document.js
generated
vendored
2000
node_modules/mongoose/lib/document.js
generated
vendored
File diff suppressed because it is too large
Load Diff
21
node_modules/mongoose/lib/document_provider.js
generated
vendored
Normal file
21
node_modules/mongoose/lib/document_provider.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint-env browser */
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
var Document = require('./document.js');
|
||||
var BrowserDocument = require('./browserDocument.js');
|
||||
|
||||
/**
|
||||
* Returns the Document constructor for the current context
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
module.exports = function() {
|
||||
if (typeof window !== 'undefined' && typeof document !== 'undefined' && document === window.document) {
|
||||
return BrowserDocument;
|
||||
}
|
||||
return Document;
|
||||
};
|
||||
5
node_modules/mongoose/lib/drivers/browser/ReadPreference.js
generated
vendored
Normal file
5
node_modules/mongoose/lib/drivers/browser/ReadPreference.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = function() {};
|
||||
12
node_modules/mongoose/lib/drivers/browser/binary.js
generated
vendored
Normal file
12
node_modules/mongoose/lib/drivers/browser/binary.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Binary = require('bson').Binary;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
module.exports = exports = Binary;
|
||||
7
node_modules/mongoose/lib/drivers/browser/index.js
generated
vendored
Normal file
7
node_modules/mongoose/lib/drivers/browser/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
exports.Binary = require('./binary');
|
||||
exports.ObjectId = require('./objectid');
|
||||
exports.ReadPreference = require('./ReadPreference');
|
||||
14
node_modules/mongoose/lib/drivers/browser/objectid.js
generated
vendored
Normal file
14
node_modules/mongoose/lib/drivers/browser/objectid.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
/*!
|
||||
* [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) ObjectId
|
||||
* @constructor NodeMongoDbObjectId
|
||||
* @see ObjectId
|
||||
*/
|
||||
|
||||
var ObjectId = require('bson').ObjectID;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = exports = ObjectId;
|
||||
17
node_modules/mongoose/lib/drivers/index.js
generated
vendored
Normal file
17
node_modules/mongoose/lib/drivers/index.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
var driver;
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
driver = require(global.MONGOOSE_DRIVER_PATH || './node-mongodb-native');
|
||||
} else {
|
||||
driver = require('./browser');
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
module.exports = driver;
|
||||
45
node_modules/mongoose/lib/drivers/node-mongodb-native/ReadPreference.js
generated
vendored
Normal file
45
node_modules/mongoose/lib/drivers/node-mongodb-native/ReadPreference.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var mongodb = require('mongodb');
|
||||
var ReadPref = mongodb.ReadPreference;
|
||||
|
||||
/*!
|
||||
* Converts arguments to ReadPrefs the driver
|
||||
* can understand.
|
||||
*
|
||||
* @param {String|Array} pref
|
||||
* @param {Array} [tags]
|
||||
*/
|
||||
|
||||
module.exports = function readPref(pref, tags) {
|
||||
if (Array.isArray(pref)) {
|
||||
tags = pref[1];
|
||||
pref = pref[0];
|
||||
}
|
||||
|
||||
if (pref instanceof ReadPref) {
|
||||
return pref;
|
||||
}
|
||||
|
||||
switch (pref) {
|
||||
case 'p':
|
||||
pref = 'primary';
|
||||
break;
|
||||
case 'pp':
|
||||
pref = 'primaryPreferred';
|
||||
break;
|
||||
case 's':
|
||||
pref = 'secondary';
|
||||
break;
|
||||
case 'sp':
|
||||
pref = 'secondaryPreferred';
|
||||
break;
|
||||
case 'n':
|
||||
pref = 'nearest';
|
||||
break;
|
||||
}
|
||||
|
||||
return new ReadPref(pref, tags);
|
||||
};
|
||||
2
node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
generated
vendored
2
node_modules/mongoose/lib/drivers/node-mongodb-native/binary.js
generated
vendored
@@ -3,6 +3,6 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Binary = require('mongodb').BSONPure.Binary;
|
||||
var Binary = require('mongodb').Binary;
|
||||
|
||||
module.exports = exports = Binary;
|
||||
|
||||
232
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
232
node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js
generated
vendored
@@ -1,12 +1,10 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseCollection = require('../../collection')
|
||||
, Collection = require('mongodb').Collection
|
||||
, STATES = require('../../connectionstate')
|
||||
, utils = require('../../utils')
|
||||
var MongooseCollection = require('../../collection'),
|
||||
Collection = require('mongodb').Collection,
|
||||
utils = require('../../utils');
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) collection implementation.
|
||||
@@ -17,7 +15,7 @@ var MongooseCollection = require('../../collection')
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function NativeCollection () {
|
||||
function NativeCollection() {
|
||||
this.collection = null;
|
||||
MongooseCollection.apply(this, arguments);
|
||||
}
|
||||
@@ -34,54 +32,58 @@ NativeCollection.prototype.__proto__ = MongooseCollection.prototype;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onOpen = function () {
|
||||
var self = this;
|
||||
NativeCollection.prototype.onOpen = function() {
|
||||
var _this = this;
|
||||
|
||||
// always get a new collection in case the user changed host:port
|
||||
// of parent db instance when re-opening the connection.
|
||||
|
||||
if (!self.opts.capped.size) {
|
||||
if (!_this.opts.capped.size) {
|
||||
// non-capped
|
||||
return self.conn.db.collection(self.name, callback);
|
||||
return _this.conn.db.collection(_this.name, callback);
|
||||
}
|
||||
|
||||
// capped
|
||||
return self.conn.db.collection(self.name, function (err, c) {
|
||||
return _this.conn.db.collection(_this.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);
|
||||
_this.conn.db.listCollections({name: _this.name}).toArray(function(err, docs) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var doc = docs[0];
|
||||
var exists = !!doc;
|
||||
|
||||
if (exists) {
|
||||
if (exists.capped) {
|
||||
if (doc.options && doc.options.capped) {
|
||||
callback(null, c);
|
||||
} else {
|
||||
var msg = 'A non-capped collection exists with the name: '+ self.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'
|
||||
var msg = 'A non-capped collection exists with the name: ' + _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.capped);
|
||||
var opts = utils.clone(_this.opts.capped);
|
||||
opts.capped = true;
|
||||
self.conn.db.createCollection(self.name, opts, callback);
|
||||
_this.conn.db.createCollection(_this.name, opts, callback);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function callback (err, collection) {
|
||||
function callback(err, collection) {
|
||||
if (err) {
|
||||
// likely a strict mode error
|
||||
self.conn.emit('error', err);
|
||||
_this.conn.emit('error', err);
|
||||
} else {
|
||||
self.collection = collection;
|
||||
MongooseCollection.prototype.onOpen.call(self);
|
||||
_this.collection = collection;
|
||||
MongooseCollection.prototype.onOpen.call(_this);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -90,7 +92,7 @@ NativeCollection.prototype.onOpen = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.onClose = function () {
|
||||
NativeCollection.prototype.onClose = function() {
|
||||
MongooseCollection.prototype.onClose.call(this);
|
||||
};
|
||||
|
||||
@@ -98,89 +100,135 @@ NativeCollection.prototype.onClose = function () {
|
||||
* Copy the collection methods and make them subject to queues
|
||||
*/
|
||||
|
||||
function iter(i) {
|
||||
NativeCollection.prototype[i] = function() {
|
||||
if (this.buffer) {
|
||||
this.addQueue(i, arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
var collection = this.collection,
|
||||
args = arguments,
|
||||
_this = this,
|
||||
debug = _this.conn.base.options.debug;
|
||||
|
||||
if (debug) {
|
||||
if (typeof debug === 'function') {
|
||||
debug.apply(debug,
|
||||
[_this.name, i].concat(utils.args(args, 0, args.length - 1)));
|
||||
} else {
|
||||
this.$print(_this.name, i, args);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return collection[i].apply(collection, args);
|
||||
} catch (error) {
|
||||
// Collection operation may throw because of max bson size, catch it here
|
||||
// See gh-3906
|
||||
if (args.length > 0 &&
|
||||
typeof args[args.length - 1] === 'function') {
|
||||
args[args.length - 1](error);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for (var i in Collection.prototype) {
|
||||
(function(i){
|
||||
NativeCollection.prototype[i] = function () {
|
||||
if (this.buffer) {
|
||||
this.addQueue(i, arguments);
|
||||
return;
|
||||
}
|
||||
// Janky hack to work around gh-3005 until we can get rid of the mongoose
|
||||
// collection abstraction
|
||||
try {
|
||||
if (typeof Collection.prototype[i] !== 'function') {
|
||||
continue;
|
||||
}
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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);
|
||||
iter(i);
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Debug print helper
|
||||
*
|
||||
* @api public
|
||||
* @method $print
|
||||
*/
|
||||
|
||||
function print (arg) {
|
||||
NativeCollection.prototype.$print = function(name, i, args) {
|
||||
var moduleName = '\x1B[0;36mMongoose:\x1B[0m ';
|
||||
var functionCall = [name, i].join('.');
|
||||
var _args = [];
|
||||
for (var j = args.length - 1; j >= 0; --j) {
|
||||
if (this.$format(args[j]) || _args.length) {
|
||||
_args.unshift(this.$format(args[j]));
|
||||
}
|
||||
}
|
||||
var params = '(' + _args.join(', ') + ')';
|
||||
|
||||
console.error(moduleName + functionCall + params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for debug print args
|
||||
*
|
||||
* @api public
|
||||
* @method $format
|
||||
*/
|
||||
|
||||
NativeCollection.prototype.$format = function(arg) {
|
||||
var type = typeof arg;
|
||||
if ('function' === type || 'undefined' === type) return '';
|
||||
if (type === 'function' || type === 'undefined') return '';
|
||||
return format(arg);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Debug print helper
|
||||
*/
|
||||
|
||||
function format (obj, sub) {
|
||||
var x = utils.clone(obj);
|
||||
if (x) {
|
||||
if ('Binary' === x.constructor.name) {
|
||||
function map(o) {
|
||||
return format(o, true);
|
||||
}
|
||||
function formatObjectId(x, key) {
|
||||
var representation = 'ObjectId("' + x[key].toHexString() + '")';
|
||||
x[key] = {inspect: function() { return representation; }};
|
||||
}
|
||||
function formatDate(x, key) {
|
||||
var representation = 'new Date("' + x[key].toUTCString() + '")';
|
||||
x[key] = {inspect: function() { return representation; }};
|
||||
}
|
||||
function format(obj, sub) {
|
||||
var x = utils.clone(obj, {retainKeyOrder: 1});
|
||||
var representation;
|
||||
|
||||
if (x != null) {
|
||||
if (x.constructor.name === 'Binary') {
|
||||
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--) {
|
||||
} else if (x.constructor.name === 'ObjectID') {
|
||||
representation = 'ObjectId("' + x.toHexString() + '")';
|
||||
x = {inspect: function() { return representation; }};
|
||||
} else if (x.constructor.name === 'Date') {
|
||||
representation = 'new Date("' + x.toUTCString() + '")';
|
||||
x = {inspect: function() { return representation; }};
|
||||
} else if (x.constructor.name === 'Object') {
|
||||
var keys = Object.keys(x);
|
||||
var numKeys = keys.length;
|
||||
var key;
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
key = keys[i];
|
||||
if (x[key]) {
|
||||
if ('Binary' === x[key].constructor.name) {
|
||||
if (x[key].constructor.name === 'Binary') {
|
||||
x[key] = '[object Buffer]';
|
||||
} else if ('Object' === x[key].constructor.name) {
|
||||
} else if (x[key].constructor.name === 'Object') {
|
||||
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 (x[key].constructor.name === 'ObjectID') {
|
||||
formatObjectId(x, key);
|
||||
} else if (x[key].constructor.name === 'Date') {
|
||||
formatDate(x, key);
|
||||
} else if (Array.isArray(x[key])) {
|
||||
x[key] = x[key].map(function (o) {
|
||||
return format(o, true)
|
||||
});
|
||||
x[key] = x[key].map(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,9 +237,9 @@ function format (obj, sub) {
|
||||
}
|
||||
|
||||
return require('util')
|
||||
.inspect(x, false, 10, true)
|
||||
.replace(/\n/g, '')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.inspect(x, false, 10, true)
|
||||
.replace(/\n/g, '')
|
||||
.replace(/\s{2,}/g, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
248
node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
248
node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js
generated
vendored
@@ -2,13 +2,14 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseConnection = require('../../connection')
|
||||
, mongo = require('mongodb')
|
||||
, Db = mongo.Db
|
||||
, Server = mongo.Server
|
||||
, Mongos = mongo.Mongos
|
||||
, STATES = require('../../connectionstate')
|
||||
, ReplSetServers = mongo.ReplSetServers;
|
||||
var MongooseConnection = require('../../connection');
|
||||
var mongo = require('mongodb');
|
||||
var Db = mongo.Db;
|
||||
var Server = mongo.Server;
|
||||
var Mongos = mongo.Mongos;
|
||||
var STATES = require('../../connectionstate');
|
||||
var ReplSetServers = mongo.ReplSet;
|
||||
var DisconnectedError = require('../../error/disconnected');
|
||||
|
||||
/**
|
||||
* A [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) connection implementation.
|
||||
@@ -20,7 +21,7 @@ var MongooseConnection = require('../../connection')
|
||||
function NativeConnection() {
|
||||
MongooseConnection.apply(this, arguments);
|
||||
this._listening = false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the possible connection states.
|
||||
@@ -43,33 +44,107 @@ NativeConnection.prototype.__proto__ = MongooseConnection.prototype;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doOpen = function (fn) {
|
||||
if (this.db) {
|
||||
mute(this);
|
||||
NativeConnection.prototype.doOpen = function(fn) {
|
||||
var _this = this;
|
||||
var server = new Server(this.host, this.port, this.options.server);
|
||||
|
||||
if (this.options && this.options.mongos) {
|
||||
var mongos = new Mongos([server], this.options.mongos);
|
||||
this.db = new Db(this.name, mongos, this.options.db);
|
||||
} else {
|
||||
this.db = new Db(this.name, server, this.options.db);
|
||||
}
|
||||
|
||||
var server = new Server(this.host, this.port, this.options.server);
|
||||
this.db = new Db(this.name, server, this.options.db);
|
||||
this.db.open(function(err) {
|
||||
listen(_this);
|
||||
|
||||
if (!mongos) {
|
||||
server.s.server.on('error', function(error) {
|
||||
if (/after \d+ retries/.test(error.message)) {
|
||||
_this.emit('error', new DisconnectedError(server.s.server.name));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.db.open(function (err) {
|
||||
if (err) return fn(err);
|
||||
listen(self);
|
||||
|
||||
fn();
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Switches to a different database using the same connection pool.
|
||||
*
|
||||
* Returns a new connection object, with the new db.
|
||||
*
|
||||
* @param {String} name The database name
|
||||
* @return {Connection} New Connection Object
|
||||
* @api public
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.useDb = function(name) {
|
||||
// we have to manually copy all of the attributes...
|
||||
var newConn = new this.constructor();
|
||||
newConn.name = name;
|
||||
newConn.base = this.base;
|
||||
newConn.collections = {};
|
||||
newConn.models = {};
|
||||
newConn.replica = this.replica;
|
||||
newConn.hosts = this.hosts;
|
||||
newConn.host = this.host;
|
||||
newConn.port = this.port;
|
||||
newConn.user = this.user;
|
||||
newConn.pass = this.pass;
|
||||
newConn.options = this.options;
|
||||
newConn._readyState = this._readyState;
|
||||
newConn._closeCalled = this._closeCalled;
|
||||
newConn._hasOpened = this._hasOpened;
|
||||
newConn._listening = false;
|
||||
|
||||
// First, when we create another db object, we are not guaranteed to have a
|
||||
// db object to work with. So, in the case where we have a db object and it
|
||||
// is connected, we can just proceed with setting everything up. However, if
|
||||
// we do not have a db or the state is not connected, then we need to wait on
|
||||
// the 'open' event of the connection before doing the rest of the setup
|
||||
// the 'connected' event is the first time we'll have access to the db object
|
||||
|
||||
var _this = this;
|
||||
|
||||
if (this.db && this._readyState === STATES.connected) {
|
||||
wireup();
|
||||
} else {
|
||||
this.once('connected', wireup);
|
||||
}
|
||||
|
||||
function wireup() {
|
||||
newConn.db = _this.db.db(name);
|
||||
newConn.onOpen();
|
||||
// setup the events appropriately
|
||||
listen(newConn);
|
||||
}
|
||||
|
||||
newConn.name = name;
|
||||
|
||||
// push onto the otherDbs stack, this is used when state changes
|
||||
this.otherDbs.push(newConn);
|
||||
newConn.otherDbs.push(this);
|
||||
|
||||
return newConn;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Register listeners for important events and bubble appropriately.
|
||||
*/
|
||||
|
||||
function listen (conn) {
|
||||
if (conn._listening) return;
|
||||
conn._listening = true;
|
||||
function listen(conn) {
|
||||
if (conn.db._listening) {
|
||||
return;
|
||||
}
|
||||
conn.db._listening = true;
|
||||
|
||||
conn.db.on('close', function(){
|
||||
conn.db.on('close', function() {
|
||||
if (conn._closeCalled) return;
|
||||
|
||||
// the driver never emits an `open` event. auto_reconnect still
|
||||
@@ -82,33 +157,26 @@ function listen (conn) {
|
||||
}
|
||||
conn.onClose();
|
||||
});
|
||||
conn.db.on('error', function(err){
|
||||
conn.db.on('error', function(err) {
|
||||
conn.emit('error', err);
|
||||
});
|
||||
conn.db.on('timeout', function(err){
|
||||
conn.db.on('reconnect', function() {
|
||||
conn.readyState = STATES.connected;
|
||||
conn.emit('reconnected');
|
||||
});
|
||||
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) {
|
||||
conn.db.on('open', function(err, db) {
|
||||
if (STATES.disconnected === conn.readyState && db && db.databaseName) {
|
||||
conn.readyState = STATES.connected;
|
||||
conn.emit('reconnected')
|
||||
conn.emit('reconnected');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/*!
|
||||
* Remove listeners registered in `listen`
|
||||
*/
|
||||
|
||||
function mute (conn) {
|
||||
if (!conn.db) throw new Error('missing db');
|
||||
conn.db.removeAllListeners("close");
|
||||
conn.db.removeAllListeners("error");
|
||||
conn.db.removeAllListeners("timeout");
|
||||
conn.db.removeAllListeners("open");
|
||||
conn.db.removeAllListeners("fullsetup");
|
||||
conn._listening = false;
|
||||
});
|
||||
conn.db.on('parseError', function(err) {
|
||||
conn.emit('parseError', err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,33 +189,33 @@ function mute (conn) {
|
||||
* @return {Connection} this
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doOpenSet = function (fn) {
|
||||
if (this.db) {
|
||||
mute(this);
|
||||
}
|
||||
NativeConnection.prototype.doOpenSet = function(fn) {
|
||||
var servers = [],
|
||||
_this = this;
|
||||
|
||||
var servers = []
|
||||
, self = this;
|
||||
|
||||
this.hosts.forEach(function (server) {
|
||||
this.hosts.forEach(function(server) {
|
||||
var host = server.host || server.ipc;
|
||||
var port = server.port || 27017;
|
||||
servers.push(new Server(host, port, self.options.server));
|
||||
})
|
||||
servers.push(new Server(host, port, _this.options.server));
|
||||
});
|
||||
|
||||
var server = this.options.mongos
|
||||
? new Mongos(servers, this.options.mongos)
|
||||
: new ReplSetServers(servers, this.options.replset);
|
||||
: new ReplSetServers(servers, this.options.replset || this.options.replSet);
|
||||
this.db = new Db(this.name, server, this.options.db);
|
||||
|
||||
this.db.on('fullsetup', function () {
|
||||
self.emit('fullsetup')
|
||||
this.db.on('fullsetup', function() {
|
||||
_this.emit('fullsetup');
|
||||
});
|
||||
|
||||
this.db.open(function (err) {
|
||||
this.db.on('all', function() {
|
||||
_this.emit('all');
|
||||
});
|
||||
|
||||
this.db.open(function(err) {
|
||||
if (err) return fn(err);
|
||||
fn();
|
||||
listen(self);
|
||||
listen(_this);
|
||||
});
|
||||
|
||||
return this;
|
||||
@@ -161,11 +229,10 @@ NativeConnection.prototype.doOpenSet = function (fn) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.doClose = function (fn) {
|
||||
this.db.close();
|
||||
if (fn) fn();
|
||||
NativeConnection.prototype.doClose = function(fn) {
|
||||
this.db.close(fn);
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepares default connection options for the node-mongodb-native driver.
|
||||
@@ -177,69 +244,75 @@ NativeConnection.prototype.doClose = function (fn) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
|
||||
NativeConnection.prototype.parseOptions = function(passed, connStrOpts) {
|
||||
var o = passed || {};
|
||||
o.db || (o.db = {});
|
||||
o.auth || (o.auth = {});
|
||||
o.server || (o.server = {});
|
||||
o.replset || (o.replset = {});
|
||||
o.replset || (o.replset = o.replSet) || (o.replset = {});
|
||||
o.server.socketOptions || (o.server.socketOptions = {});
|
||||
o.replset.socketOptions || (o.replset.socketOptions = {});
|
||||
o.mongos || (o.mongos = (connStrOpts && connStrOpts.mongos));
|
||||
(o.mongos === true) && (o.mongos = {});
|
||||
|
||||
var opts = connStrOpts || {};
|
||||
Object.keys(opts).forEach(function (name) {
|
||||
Object.keys(opts).forEach(function(name) {
|
||||
switch (name) {
|
||||
case 'ssl':
|
||||
o.server.ssl = opts.ssl;
|
||||
o.replset.ssl = opts.ssl;
|
||||
o.mongos && (o.mongos.ssl = opts.ssl);
|
||||
break;
|
||||
case 'poolSize':
|
||||
if ('undefined' == typeof o.server.poolSize) {
|
||||
o.server.poolSize = o.replset.poolSize = opts[name];
|
||||
if (typeof o.server[name] === 'undefined') {
|
||||
o.server[name] = o.replset[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'slaveOk':
|
||||
if ('undefined' == typeof o.server.slave_ok) {
|
||||
if (typeof o.server.slave_ok === 'undefined') {
|
||||
o.server.slave_ok = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'autoReconnect':
|
||||
if ('undefined' == typeof o.server.auto_reconnect) {
|
||||
if (typeof o.server.auto_reconnect === 'undefined') {
|
||||
o.server.auto_reconnect = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'ssl':
|
||||
case 'socketTimeoutMS':
|
||||
case 'connectTimeoutMS':
|
||||
if ('undefined' == typeof o.server.socketOptions[name]) {
|
||||
if (typeof o.server.socketOptions[name] === 'undefined') {
|
||||
o.server.socketOptions[name] = o.replset.socketOptions[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'authdb':
|
||||
if ('undefined' == typeof o.auth.authdb) {
|
||||
if (typeof o.auth.authdb === 'undefined') {
|
||||
o.auth.authdb = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'authSource':
|
||||
if ('undefined' == typeof o.auth.authSource) {
|
||||
if (typeof o.auth.authSource === 'undefined') {
|
||||
o.auth.authSource = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'retries':
|
||||
case 'reconnectWait':
|
||||
case 'rs_name':
|
||||
if ('undefined' == typeof o.replset[name]) {
|
||||
if (typeof o.replset[name] === 'undefined') {
|
||||
o.replset[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'replicaSet':
|
||||
if ('undefined' == typeof o.replset.rs_name) {
|
||||
if (typeof o.replset.rs_name === 'undefined') {
|
||||
o.replset.rs_name = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readSecondary':
|
||||
if ('undefined' == typeof o.replset.read_secondary) {
|
||||
if (typeof o.replset.read_secondary === 'undefined') {
|
||||
o.replset.read_secondary = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'nativeParser':
|
||||
if ('undefined' == typeof o.db.native_parser) {
|
||||
if (typeof o.db.native_parser === 'undefined') {
|
||||
o.db.native_parser = opts[name];
|
||||
}
|
||||
break;
|
||||
@@ -248,32 +321,31 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
|
||||
case 'fsync':
|
||||
case 'journal':
|
||||
case 'wtimeoutMS':
|
||||
if ('undefined' == typeof o.db[name]) {
|
||||
if (typeof o.db[name] === 'undefined') {
|
||||
o.db[name] = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readPreference':
|
||||
if ('undefined' == typeof o.db.read_preference) {
|
||||
o.db.read_preference = opts[name];
|
||||
if (typeof o.db.readPreference === 'undefined') {
|
||||
o.db.readPreference = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'readPreferenceTags':
|
||||
if ('undefined' == typeof o.db.read_preference_tags) {
|
||||
if (typeof o.db.read_preference_tags === 'undefined') {
|
||||
o.db.read_preference_tags = opts[name];
|
||||
}
|
||||
break;
|
||||
case 'sslValidate':
|
||||
o.server.sslValidate = opts.sslValidate;
|
||||
o.replset.sslValidate = opts.sslValidate;
|
||||
o.mongos && (o.mongos.sslValidate = opts.sslValidate);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
@@ -283,9 +355,13 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
|
||||
o.db.w = 1;
|
||||
}
|
||||
|
||||
if (o.promiseLibrary) {
|
||||
o.db.promiseLibrary = o.promiseLibrary;
|
||||
}
|
||||
|
||||
validate(o);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Validates the driver db options.
|
||||
@@ -293,8 +369,8 @@ NativeConnection.prototype.parseOptions = function (passed, connStrOpts) {
|
||||
* @param {Object} o
|
||||
*/
|
||||
|
||||
function validate (o) {
|
||||
if (-1 === o.db.w || 0 === o.db.w) {
|
||||
function validate(o) {
|
||||
if (o.db.w === -1 || o.db.w === 0) {
|
||||
if (o.db.journal || o.db.fsync || o.db.safe) {
|
||||
throw new Error(
|
||||
'Invalid writeConcern: '
|
||||
|
||||
7
node_modules/mongoose/lib/drivers/node-mongodb-native/index.js
generated
vendored
Normal file
7
node_modules/mongoose/lib/drivers/node-mongodb-native/index.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
exports.Binary = require('./binary');
|
||||
exports.ObjectId = require('./objectid');
|
||||
exports.ReadPreference = require('./ReadPreference');
|
||||
17
node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
generated
vendored
17
node_modules/mongoose/lib/drivers/node-mongodb-native/objectid.js
generated
vendored
@@ -5,25 +5,10 @@
|
||||
* @see ObjectId
|
||||
*/
|
||||
|
||||
var ObjectId = require('mongodb').BSONPure.ObjectID;
|
||||
var ObjectId = require('mongodb').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();
|
||||
};
|
||||
|
||||
40
node_modules/mongoose/lib/error.js
generated
vendored
40
node_modules/mongoose/lib/error.js
generated
vendored
@@ -6,18 +6,23 @@
|
||||
* @inherits Error https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error
|
||||
*/
|
||||
|
||||
function MongooseError (msg) {
|
||||
function MongooseError(msg) {
|
||||
Error.call(this);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.message = msg;
|
||||
this.name = 'MongooseError';
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from Error.
|
||||
*/
|
||||
|
||||
MongooseError.prototype.__proto__ = Error.prototype;
|
||||
MongooseError.prototype = Object.create(Error.prototype);
|
||||
MongooseError.prototype.constructor = Error;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
@@ -25,15 +30,26 @@ MongooseError.prototype.__proto__ = Error.prototype;
|
||||
|
||||
module.exports = exports = MongooseError;
|
||||
|
||||
/**
|
||||
* The default built-in validator error messages.
|
||||
*
|
||||
* @see Error.messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseError.messages = require('./error/messages');
|
||||
|
||||
// backward compat
|
||||
MongooseError.Messages = MongooseError.messages;
|
||||
|
||||
/*!
|
||||
* 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')
|
||||
MongooseError.DivergentArrayError = require('./errors/divergentArray')
|
||||
MongooseError.CastError = require('./error/cast');
|
||||
MongooseError.ValidationError = require('./error/validation');
|
||||
MongooseError.ValidatorError = require('./error/validator');
|
||||
MongooseError.VersionError = require('./error/version');
|
||||
MongooseError.OverwriteModelError = require('./error/overwriteModel');
|
||||
MongooseError.MissingSchemaError = require('./error/missingSchema');
|
||||
MongooseError.DivergentArrayError = require('./error/divergentArray');
|
||||
|
||||
32
node_modules/mongoose/lib/error/browserMissingSchema.js
generated
vendored
Normal file
32
node_modules/mongoose/lib/error/browserMissingSchema.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/*!
|
||||
* MissingSchema Error constructor.
|
||||
*
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function MissingSchemaError() {
|
||||
var msg = 'Schema hasn\'t been registered for document.\n'
|
||||
+ 'Use mongoose.Document(name, schema)';
|
||||
MongooseError.call(this, msg);
|
||||
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'MissingSchemaError';
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
MissingSchemaError.prototype = Object.create(MongooseError.prototype);
|
||||
MissingSchemaError.prototype.constructor = MongooseError;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = MissingSchemaError;
|
||||
19
node_modules/mongoose/lib/errors/cast.js → node_modules/mongoose/lib/error/cast.js
generated
vendored
19
node_modules/mongoose/lib/errors/cast.js → node_modules/mongoose/lib/error/cast.js
generated
vendored
@@ -2,7 +2,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Casting Error constructor.
|
||||
@@ -13,20 +13,27 @@ var MongooseError = require('../error');
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function CastError (type, value, path) {
|
||||
function CastError(type, value, path, reason) {
|
||||
MongooseError.call(this, 'Cast to ' + type + ' failed for value "' + value + '" at path "' + path + '"');
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.name = 'CastError';
|
||||
this.type = type;
|
||||
this.kind = type;
|
||||
this.value = value;
|
||||
this.path = path;
|
||||
};
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
CastError.prototype.__proto__ = MongooseError.prototype;
|
||||
CastError.prototype = Object.create(MongooseError.prototype);
|
||||
CastError.prototype.constructor = MongooseError;
|
||||
|
||||
|
||||
/*!
|
||||
* exports
|
||||
40
node_modules/mongoose/lib/error/disconnected.js
generated
vendored
Normal file
40
node_modules/mongoose/lib/error/disconnected.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Casting Error constructor.
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} value
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function DisconnectedError(connectionString) {
|
||||
MongooseError.call(this, 'Ran out of retries trying to reconnect to "' +
|
||||
connectionString + '". Try setting `server.reconnectTries` and ' +
|
||||
'`server.reconnectInterval` to something higher.');
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.name = 'DisconnectedError';
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
DisconnectedError.prototype = Object.create(MongooseError.prototype);
|
||||
DisconnectedError.prototype.constructor = MongooseError;
|
||||
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = DisconnectedError;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/*!
|
||||
* DivergentArrayError constructor.
|
||||
@@ -11,7 +11,7 @@ var MongooseError = require('../error');
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function DivergentArrayError (paths) {
|
||||
function DivergentArrayError(paths) {
|
||||
var msg = 'For your own good, using `document.save()` to update an array '
|
||||
+ 'which was selected using an $elemMatch projection OR '
|
||||
+ 'populated using skip, limit, query conditions, or exclusion of '
|
||||
@@ -19,19 +19,21 @@ function DivergentArrayError (paths) {
|
||||
+ 'the entire array is not supported. The following '
|
||||
+ 'path(s) would have been modified unsafely:\n'
|
||||
+ ' ' + paths.join('\n ') + '\n'
|
||||
+ 'Use Model.update() to update these arrays instead.'
|
||||
+ 'Use Model.update() to update these arrays instead.';
|
||||
// TODO write up a docs page (FAQ) and link to it
|
||||
|
||||
MongooseError.call(this, msg);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'DivergentArrayError';
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
DivergentArrayError.prototype.__proto__ = MongooseError.prototype;
|
||||
DivergentArrayError.prototype = Object.create(MongooseError.prototype);
|
||||
DivergentArrayError.prototype.constructor = MongooseError;
|
||||
|
||||
|
||||
/*!
|
||||
* exports
|
||||
42
node_modules/mongoose/lib/error/messages.js
generated
vendored
Normal file
42
node_modules/mongoose/lib/error/messages.js
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
/**
|
||||
* The default built-in validator error messages. These may be customized.
|
||||
*
|
||||
* // customize within each schema or globally like so
|
||||
* var mongoose = require('mongoose');
|
||||
* mongoose.Error.messages.String.enum = "Your custom message for {PATH}.";
|
||||
*
|
||||
* As you might have noticed, error messages support basic templating
|
||||
*
|
||||
* - `{PATH}` is replaced with the invalid document path
|
||||
* - `{VALUE}` is replaced with the invalid value
|
||||
* - `{TYPE}` is replaced with the validator type such as "regexp", "min", or "user defined"
|
||||
* - `{MIN}` is replaced with the declared min value for the Number.min validator
|
||||
* - `{MAX}` is replaced with the declared max value for the Number.max validator
|
||||
*
|
||||
* Click the "show code" link below to see all defaults.
|
||||
*
|
||||
* @static messages
|
||||
* @receiver MongooseError
|
||||
* @api public
|
||||
*/
|
||||
|
||||
var msg = module.exports = exports = {};
|
||||
|
||||
msg.general = {};
|
||||
msg.general.default = 'Validator failed for path `{PATH}` with value `{VALUE}`';
|
||||
msg.general.required = 'Path `{PATH}` is required.';
|
||||
|
||||
msg.Number = {};
|
||||
msg.Number.min = 'Path `{PATH}` ({VALUE}) is less than minimum allowed value ({MIN}).';
|
||||
msg.Number.max = 'Path `{PATH}` ({VALUE}) is more than maximum allowed value ({MAX}).';
|
||||
|
||||
msg.Date = {};
|
||||
msg.Date.min = 'Path `{PATH}` ({VALUE}) is before minimum allowed value ({MIN}).';
|
||||
msg.Date.max = 'Path `{PATH}` ({VALUE}) is after maximum allowed value ({MAX}).';
|
||||
|
||||
msg.String = {};
|
||||
msg.String.enum = '`{VALUE}` is not a valid enum value for path `{PATH}`.';
|
||||
msg.String.match = 'Path `{PATH}` is invalid ({VALUE}).';
|
||||
msg.String.minlength = 'Path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).';
|
||||
msg.String.maxlength = 'Path `{PATH}` (`{VALUE}`) is longer than the maximum allowed length ({MAXLENGTH}).';
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/*!
|
||||
* MissingSchema Error constructor.
|
||||
@@ -11,19 +11,20 @@ var MongooseError = require('../error');
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function MissingSchemaError (name) {
|
||||
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);
|
||||
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'MissingSchemaError';
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
MissingSchemaError.prototype.__proto__ = MongooseError.prototype;
|
||||
MissingSchemaError.prototype = Object.create(MongooseError.prototype);
|
||||
MissingSchemaError.prototype.constructor = MongooseError;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
35
node_modules/mongoose/lib/error/objectExpected.js
generated
vendored
Normal file
35
node_modules/mongoose/lib/error/objectExpected.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Strict mode error constructor
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} value
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function ObjectExpectedError(path, val) {
|
||||
MongooseError.call(this, 'Tried to set nested object field `' + path +
|
||||
'` to primitive value `' + val + '` and strict mode is set to throw.');
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.name = 'ObjectExpectedError';
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
ObjectExpectedError.prototype = Object.create(MongooseError.prototype);
|
||||
ObjectExpectedError.prototype.constructor = MongooseError;
|
||||
|
||||
module.exports = ObjectExpectedError;
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/*!
|
||||
* OverwriteModel Error constructor.
|
||||
@@ -11,17 +11,18 @@ var MongooseError = require('../error');
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function OverwriteModelError (name) {
|
||||
function OverwriteModelError(name) {
|
||||
MongooseError.call(this, 'Cannot overwrite `' + name + '` model once compiled.');
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
Error.captureStackTrace && Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'OverwriteModelError';
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
OverwriteModelError.prototype.__proto__ = MongooseError.prototype;
|
||||
OverwriteModelError.prototype = Object.create(MongooseError.prototype);
|
||||
OverwriteModelError.prototype.constructor = MongooseError;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
35
node_modules/mongoose/lib/error/strict.js
generated
vendored
Normal file
35
node_modules/mongoose/lib/error/strict.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Strict mode error constructor
|
||||
*
|
||||
* @param {String} type
|
||||
* @param {String} value
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function StrictModeError(path) {
|
||||
MongooseError.call(this, 'Field `' + path + '` is not in schema and strict ' +
|
||||
'mode is set to throw.');
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.name = 'StrictModeError';
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
StrictModeError.prototype = Object.create(MongooseError.prototype);
|
||||
StrictModeError.prototype.constructor = MongooseError;
|
||||
|
||||
module.exports = StrictModeError;
|
||||
63
node_modules/mongoose/lib/error/validation.js
generated
vendored
Normal file
63
node_modules/mongoose/lib/error/validation.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*!
|
||||
* Module requirements
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Document Validation Error
|
||||
*
|
||||
* @api private
|
||||
* @param {Document} instance
|
||||
* @inherits MongooseError
|
||||
*/
|
||||
|
||||
function ValidationError(instance) {
|
||||
if (instance && instance.constructor.name === 'model') {
|
||||
MongooseError.call(this, instance.constructor.modelName + ' validation failed');
|
||||
} else {
|
||||
MongooseError.call(this, 'Validation failed');
|
||||
}
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.name = 'ValidationError';
|
||||
this.errors = {};
|
||||
if (instance) {
|
||||
instance.errors = this.errors;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
ValidationError.prototype = Object.create(MongooseError.prototype);
|
||||
ValidationError.prototype.constructor = MongooseError;
|
||||
|
||||
|
||||
/**
|
||||
* Console.log helper
|
||||
*/
|
||||
|
||||
ValidationError.prototype.toString = function() {
|
||||
var ret = this.name + ': ';
|
||||
var msgs = [];
|
||||
|
||||
Object.keys(this.errors).forEach(function(key) {
|
||||
if (this === this.errors[key]) {
|
||||
return;
|
||||
}
|
||||
msgs.push(String(this.errors[key]));
|
||||
}, this);
|
||||
|
||||
return ret + msgs.join(', ');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = exports = ValidationError;
|
||||
81
node_modules/mongoose/lib/error/validator.js
generated
vendored
Normal file
81
node_modules/mongoose/lib/error/validator.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Schema validator error
|
||||
*
|
||||
* @param {Object} properties
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function ValidatorError(properties) {
|
||||
var msg = properties.message;
|
||||
if (!msg) {
|
||||
msg = MongooseError.messages.general.default;
|
||||
}
|
||||
|
||||
var message = this.formatMessage(msg, properties);
|
||||
MongooseError.call(this, message);
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this);
|
||||
} else {
|
||||
this.stack = new Error().stack;
|
||||
}
|
||||
this.properties = properties;
|
||||
this.name = 'ValidatorError';
|
||||
this.kind = properties.type;
|
||||
this.path = properties.path;
|
||||
this.value = properties.value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError
|
||||
*/
|
||||
|
||||
ValidatorError.prototype = Object.create(MongooseError.prototype);
|
||||
ValidatorError.prototype.constructor = MongooseError;
|
||||
|
||||
/*!
|
||||
* The object used to define this validator. Not enumerable to hide
|
||||
* it from `require('util').inspect()` output re: gh-3925
|
||||
*/
|
||||
|
||||
Object.defineProperty(ValidatorError.prototype, 'properties', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: null
|
||||
});
|
||||
|
||||
/*!
|
||||
* Formats error messages
|
||||
*/
|
||||
|
||||
ValidatorError.prototype.formatMessage = function(msg, properties) {
|
||||
var propertyNames = Object.keys(properties);
|
||||
for (var i = 0; i < propertyNames.length; ++i) {
|
||||
var propertyName = propertyNames[i];
|
||||
if (propertyName === 'message') {
|
||||
continue;
|
||||
}
|
||||
msg = msg.replace('{' + propertyName.toUpperCase() + '}', properties[propertyName]);
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
/*!
|
||||
* toString helper
|
||||
*/
|
||||
|
||||
ValidatorError.prototype.toString = function() {
|
||||
return this.message;
|
||||
};
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = ValidatorError;
|
||||
33
node_modules/mongoose/lib/error/version.js
generated
vendored
Normal file
33
node_modules/mongoose/lib/error/version.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error.js');
|
||||
|
||||
/**
|
||||
* Version Error constructor.
|
||||
*
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function VersionError(doc) {
|
||||
MongooseError.call(this, 'No matching document found for id "' + doc._id +
|
||||
'"');
|
||||
this.name = 'VersionError';
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
VersionError.prototype = Object.create(MongooseError.prototype);
|
||||
VersionError.prototype.constructor = MongooseError;
|
||||
|
||||
/*!
|
||||
* exports
|
||||
*/
|
||||
|
||||
module.exports = VersionError;
|
||||
32
node_modules/mongoose/lib/errors/document.js
generated
vendored
32
node_modules/mongoose/lib/errors/document.js
generated
vendored
@@ -1,32 +0,0 @@
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
49
node_modules/mongoose/lib/errors/validation.js
generated
vendored
49
node_modules/mongoose/lib/errors/validation.js
generated
vendored
@@ -1,49 +0,0 @@
|
||||
|
||||
/*!
|
||||
* 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 () {
|
||||
var ret = this.name + ': ';
|
||||
var msgs = [];
|
||||
|
||||
Object.keys(this.errors).forEach(function (key) {
|
||||
if (this == this.errors[key]) return;
|
||||
msgs.push(String(this.errors[key]));
|
||||
}, this)
|
||||
|
||||
return ret + msgs.join(', ');
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseError.
|
||||
*/
|
||||
|
||||
ValidationError.prototype.__proto__ = MongooseError.prototype;
|
||||
|
||||
/*!
|
||||
* Module exports
|
||||
*/
|
||||
|
||||
module.exports = exports = ValidationError;
|
||||
51
node_modules/mongoose/lib/errors/validator.js
generated
vendored
51
node_modules/mongoose/lib/errors/validator.js
generated
vendored
@@ -1,51 +0,0 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseError = require('../error');
|
||||
|
||||
/**
|
||||
* Schema validator error
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String} msg
|
||||
* @param {String|Number|any} val
|
||||
* @inherits MongooseError
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function ValidatorError (path, type, val) {
|
||||
var msg = type
|
||||
? '"' + type + '" '
|
||||
: '';
|
||||
|
||||
var message = 'Validator ' + msg + 'failed for path ' + path
|
||||
if (2 < arguments.length) message += ' with value `' + String(val) + '`';
|
||||
|
||||
MongooseError.call(this, message);
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
this.name = 'ValidatorError';
|
||||
this.path = path;
|
||||
this.type = type;
|
||||
this.value = val;
|
||||
};
|
||||
|
||||
/*!
|
||||
* 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
31
node_modules/mongoose/lib/errors/version.js
generated
vendored
@@ -1,31 +0,0 @@
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
370
node_modules/mongoose/lib/index.js
generated
vendored
370
node_modules/mongoose/lib/index.js
generated
vendored
@@ -4,43 +4,22 @@
|
||||
* 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')
|
||||
, pkg = require('../package.json')
|
||||
var Schema = require('./schema'),
|
||||
SchemaType = require('./schematype'),
|
||||
VirtualType = require('./virtualtype'),
|
||||
STATES = require('./connectionstate'),
|
||||
Types = require('./types'),
|
||||
Query = require('./query'),
|
||||
Model = require('./model'),
|
||||
Document = require('./document'),
|
||||
utils = require('./utils'),
|
||||
format = utils.toCollectionName,
|
||||
pkg = require('../package.json');
|
||||
|
||||
/*!
|
||||
* Warn users if they are running an unstable release.
|
||||
*
|
||||
* Disable the warning by setting the MONGOOSE_DISABLE_STABILITY_WARNING
|
||||
* environment variable.
|
||||
*/
|
||||
var querystring = require('querystring');
|
||||
|
||||
if (pkg.publishConfig && 'unstable' == pkg.publishConfig.tag) {
|
||||
if (!process.env.MONGOOSE_DISABLE_STABILITY_WARNING) {
|
||||
console.log('\u001b[33m');
|
||||
console.log('##############################################################');
|
||||
console.log('#');
|
||||
console.log('# !!! MONGOOSE WARNING !!!');
|
||||
console.log('#');
|
||||
console.log('# This is an UNSTABLE release of Mongoose.');
|
||||
console.log('# Unstable releases are available for preview/testing only.');
|
||||
console.log('# DO NOT run this in production.');
|
||||
console.log('#');
|
||||
console.log('##############################################################');
|
||||
console.log('\u001b[0m');
|
||||
}
|
||||
}
|
||||
var Aggregate = require('./aggregate');
|
||||
var PromiseProvider = require('./promise_provider');
|
||||
|
||||
/**
|
||||
* Mongoose constructor.
|
||||
@@ -51,14 +30,24 @@ if (pkg.publishConfig && 'unstable' == pkg.publishConfig.tag) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Mongoose () {
|
||||
function Mongoose() {
|
||||
this.connections = [];
|
||||
this.plugins = [];
|
||||
this.models = {};
|
||||
this.modelSchemas = {};
|
||||
this.options = {};
|
||||
this.createConnection(); // default connection
|
||||
};
|
||||
// default global options
|
||||
this.options = {
|
||||
pluralization: true
|
||||
};
|
||||
var conn = this.createConnection(); // default connection
|
||||
conn.models = this.models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose connection states for user-land
|
||||
*
|
||||
*/
|
||||
Mongoose.prototype.STATES = STATES;
|
||||
|
||||
/**
|
||||
* Sets mongoose options
|
||||
@@ -69,17 +58,22 @@ function Mongoose () {
|
||||
*
|
||||
* mongoose.set('debug', true) // enable logging collection methods + arguments to the console
|
||||
*
|
||||
* mongoose.set('debug', function(collectionName, methodName, arg1, arg2...) {}); // use custom function to log collection methods + arguments
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {String} value
|
||||
* @param {String|Function} value
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.set = function (key, value) {
|
||||
if (arguments.length == 1)
|
||||
Mongoose.prototype.set = function(key, value) {
|
||||
if (arguments.length === 1) {
|
||||
return this.options[key];
|
||||
}
|
||||
|
||||
this.options[key] = value;
|
||||
return this;
|
||||
};
|
||||
Mongoose.prototype.set.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Gets mongoose options
|
||||
@@ -101,12 +95,45 @@ Mongoose.prototype.get = Mongoose.prototype.set;
|
||||
|
||||
var rgxReplSet = /^.+,.+$/;
|
||||
|
||||
/**
|
||||
* Checks if ?replicaSet query parameter is specified in URI
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* checkReplicaSetInUri('localhost:27000?replicaSet=rs0'); // true
|
||||
*
|
||||
* @param {String} uri
|
||||
* @return {boolean}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var checkReplicaSetInUri = function(uri) {
|
||||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var queryStringStart = uri.indexOf('?');
|
||||
var isReplicaSet = false;
|
||||
if (queryStringStart !== -1) {
|
||||
try {
|
||||
var obj = querystring.parse(uri.substr(queryStringStart + 1));
|
||||
if (obj && obj.replicaSet) {
|
||||
isReplicaSet = true;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return isReplicaSet;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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. _Note that the `safe` option specified in your schema will overwrite the `safe` db option specified here unless you set your schemas `safe` option to `undefined`. See [this](/docs/guide.html#safe) for more information._
|
||||
*
|
||||
* _Options passed take precedence over options included in connection strings._
|
||||
*
|
||||
@@ -120,11 +147,11 @@ var rgxReplSet = /^.+,.+$/;
|
||||
* 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');
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database');
|
||||
*
|
||||
* // 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);
|
||||
* db = mongoose.createConnection('mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/database', opts);
|
||||
*
|
||||
* // with [host, database_name[, port] signature
|
||||
* db = mongoose.createConnection('localhost', 'database', port)
|
||||
@@ -139,18 +166,23 @@ var rgxReplSet = /^.+,.+$/;
|
||||
*
|
||||
* @param {String} [uri] a mongodb:// URI
|
||||
* @param {Object} [options] options to pass to the driver
|
||||
* @param {Object} [options.config] mongoose-specific options
|
||||
* @param {Boolean} [options.config.autoIndex] set to false to disable automatic index creation for all models associated with this connection.
|
||||
* @see Connection#open #connection_Connection-open
|
||||
* @see Connection#openSet #connection_Connection-openSet
|
||||
* @return {Connection} the created Connection object
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.createConnection = function () {
|
||||
Mongoose.prototype.createConnection = function(uri, options) {
|
||||
var conn = new Connection(this);
|
||||
this.connections.push(conn);
|
||||
|
||||
if (arguments.length) {
|
||||
if (rgxReplSet.test(arguments[0])) {
|
||||
if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
|
||||
conn.openSet.apply(conn, arguments);
|
||||
} else if (options && options.replset &&
|
||||
(options.replset.replicaSet || options.replset.rs_name)) {
|
||||
conn.openSet.apply(conn, arguments);
|
||||
} else {
|
||||
conn.open.apply(conn, arguments);
|
||||
@@ -159,11 +191,14 @@ Mongoose.prototype.createConnection = function () {
|
||||
|
||||
return conn;
|
||||
};
|
||||
Mongoose.prototype.createConnection.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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._
|
||||
*
|
||||
@@ -172,7 +207,7 @@ Mongoose.prototype.createConnection = function () {
|
||||
* mongoose.connect('mongodb://user:pass@localhost:port/database');
|
||||
*
|
||||
* // replica sets
|
||||
* var uri = 'mongodb://user:pass@localhost:port/database,mongodb://anotherhost:port,mongodb://yetanother:port';
|
||||
* var uri = 'mongodb://user:pass@localhost:port,anotherhost:port,yetanother:port/mydatabase';
|
||||
* mongoose.connect(uri);
|
||||
*
|
||||
* // with options
|
||||
@@ -183,54 +218,62 @@ Mongoose.prototype.createConnection = function () {
|
||||
* var opts = { mongos: true };
|
||||
* mongoose.connect(uri, opts);
|
||||
*
|
||||
* // optional callback that gets fired when initial connection completed
|
||||
* var uri = 'mongodb://nonexistent.domain:27000';
|
||||
* mongoose.connect(uri, function(error) {
|
||||
* // if error is truthy, the initial connection failed.
|
||||
* })
|
||||
*
|
||||
* @param {String} uri(s)
|
||||
* @param {Object} [options]
|
||||
* @param {Function} [callback]
|
||||
* @see Mongoose#createConnection #index_Mongoose-createConnection
|
||||
* @api public
|
||||
* @return {Mongoose} this
|
||||
* @return {MongooseThenable} pseudo-promise wrapper around this
|
||||
*/
|
||||
|
||||
Mongoose.prototype.connect = function () {
|
||||
Mongoose.prototype.connect = function() {
|
||||
var conn = this.connection;
|
||||
|
||||
if (rgxReplSet.test(arguments[0])) {
|
||||
conn.openSet.apply(conn, arguments);
|
||||
} else {
|
||||
conn.open.apply(conn, arguments);
|
||||
if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
|
||||
return new MongooseThenable(this, conn.openSet.apply(conn, arguments));
|
||||
}
|
||||
|
||||
return this;
|
||||
return new MongooseThenable(this, conn.open.apply(conn, arguments));
|
||||
};
|
||||
Mongoose.prototype.connect.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Disconnects all connections.
|
||||
*
|
||||
* @param {Function} [fn] called after all connection close.
|
||||
* @return {Mongoose} this
|
||||
* @return {MongooseThenable} pseudo-promise wrapper around 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;
|
||||
|
||||
Mongoose.prototype.disconnect = function(fn) {
|
||||
var 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;
|
||||
|
||||
var Promise = PromiseProvider.get();
|
||||
return new MongooseThenable(this, new Promise.ES6(function(resolve, reject) {
|
||||
fn && fn(error);
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
}));
|
||||
};
|
||||
Mongoose.prototype.disconnect.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Defines a model or retrieves it.
|
||||
@@ -272,17 +315,17 @@ Mongoose.prototype.disconnect = function (fn) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
if ('string' == typeof schema) {
|
||||
Mongoose.prototype.model = function(name, schema, collection, skipInit) {
|
||||
if (typeof schema === 'string') {
|
||||
collection = schema;
|
||||
schema = false;
|
||||
}
|
||||
|
||||
if (utils.isObject(schema) && !(schema instanceof Schema)) {
|
||||
if (utils.isObject(schema) && !(schema.instanceOfSchema)) {
|
||||
schema = new Schema(schema);
|
||||
}
|
||||
|
||||
if ('boolean' === typeof collection) {
|
||||
if (typeof collection === 'boolean') {
|
||||
skipInit = collection;
|
||||
collection = null;
|
||||
}
|
||||
@@ -296,13 +339,8 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
// look up schema for the collection. this might be a
|
||||
// default schema like system.indexes stored in SchemaDefaults.
|
||||
// look up schema for the collection.
|
||||
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;
|
||||
@@ -317,8 +355,8 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
|
||||
// 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) {
|
||||
if (this.models[name] && options.cache !== false) {
|
||||
if (schema && schema.instanceOfSchema && schema !== this.models[name].schema) {
|
||||
throw new mongoose.Error.OverwriteModelError(name);
|
||||
}
|
||||
|
||||
@@ -342,8 +380,12 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply relevant "global" options to the schema
|
||||
if (!('pluralization' in schema.options)) schema.options.pluralization = this.options.pluralization;
|
||||
|
||||
|
||||
if (!collection) {
|
||||
collection = schema.get('collection') || format(name);
|
||||
collection = schema.get('collection') || format(name, schema.options);
|
||||
}
|
||||
|
||||
var connection = options.connection || this.connection;
|
||||
@@ -353,12 +395,14 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
model.init();
|
||||
}
|
||||
|
||||
if (false === options.cache) {
|
||||
if (options.cache === false) {
|
||||
return model;
|
||||
}
|
||||
|
||||
return this.models[name] = model;
|
||||
}
|
||||
this.models[name] = model;
|
||||
return this.models[name];
|
||||
};
|
||||
Mongoose.prototype.model.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Returns an array of model names created on this instance of Mongoose.
|
||||
@@ -371,10 +415,11 @@ Mongoose.prototype.model = function (name, schema, collection, skipInit) {
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
Mongoose.prototype.modelNames = function () {
|
||||
Mongoose.prototype.modelNames = function() {
|
||||
var names = Object.keys(this.models);
|
||||
return names;
|
||||
}
|
||||
};
|
||||
Mongoose.prototype.modelNames.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Applies global plugins to `schema`.
|
||||
@@ -383,11 +428,21 @@ Mongoose.prototype.modelNames = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mongoose.prototype._applyPlugins = function (schema) {
|
||||
for (var i = 0, l = this.plugins.length; i < l; i++) {
|
||||
Mongoose.prototype._applyPlugins = function(schema) {
|
||||
if (schema.$globalPluginsApplied) {
|
||||
return;
|
||||
}
|
||||
var i;
|
||||
var len;
|
||||
for (i = 0, len = this.plugins.length; i < len; ++i) {
|
||||
schema.plugin(this.plugins[i][0], this.plugins[i][1]);
|
||||
}
|
||||
}
|
||||
schema.$globalPluginsApplied = true;
|
||||
for (i = 0, len = schema.childSchemas.length; i < len; ++i) {
|
||||
this._applyPlugins(schema.childSchemas[i]);
|
||||
}
|
||||
};
|
||||
Mongoose.prototype._applyPlugins.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* Declares a global plugin executed on all Schemas.
|
||||
@@ -401,10 +456,11 @@ Mongoose.prototype._applyPlugins = function (schema) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.plugin = function (fn, opts) {
|
||||
Mongoose.prototype.plugin = function(fn, opts) {
|
||||
this.plugins.push([fn, opts]);
|
||||
return this;
|
||||
};
|
||||
Mongoose.prototype.plugin.$hasSideEffects = true;
|
||||
|
||||
/**
|
||||
* The default connection of the mongoose module.
|
||||
@@ -422,10 +478,14 @@ Mongoose.prototype.plugin = function (fn, opts) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.__defineGetter__('connection', function(){
|
||||
Mongoose.prototype.__defineGetter__('connection', function() {
|
||||
return this.connections[0];
|
||||
});
|
||||
|
||||
Mongoose.prototype.__defineSetter__('connection', function(v) {
|
||||
this.connections[0] = v;
|
||||
});
|
||||
|
||||
/*!
|
||||
* Driver depentend APIs
|
||||
*/
|
||||
@@ -444,6 +504,15 @@ var Connection = require(driver + '/connection');
|
||||
|
||||
var Collection = require(driver + '/collection');
|
||||
|
||||
/**
|
||||
* The Mongoose Aggregate constructor
|
||||
*
|
||||
* @method Aggregate
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.Aggregate = Aggregate;
|
||||
|
||||
/**
|
||||
* The Mongoose Collection constructor
|
||||
*
|
||||
@@ -577,7 +646,23 @@ Mongoose.prototype.Query = Query;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.Promise = Promise;
|
||||
Object.defineProperty(Mongoose.prototype, 'Promise', {
|
||||
get: function() {
|
||||
return PromiseProvider.get();
|
||||
},
|
||||
set: function(lib) {
|
||||
PromiseProvider.set(lib);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Storage layer for mongoose promises
|
||||
*
|
||||
* @method PromiseProvider
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.PromiseProvider = PromiseProvider;
|
||||
|
||||
/**
|
||||
* The Mongoose [Model](#model_Model) constructor.
|
||||
@@ -597,6 +682,15 @@ Mongoose.prototype.Model = Model;
|
||||
|
||||
Mongoose.prototype.Document = Document;
|
||||
|
||||
/**
|
||||
* The Mongoose DocumentProvider constructor.
|
||||
*
|
||||
* @method DocumentProvider
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.DocumentProvider = require('./document_provider');
|
||||
|
||||
/**
|
||||
* The [MongooseError](#error_MongooseError) constructor.
|
||||
*
|
||||
@@ -606,6 +700,19 @@ Mongoose.prototype.Document = Document;
|
||||
|
||||
Mongoose.prototype.Error = require('./error');
|
||||
|
||||
/**
|
||||
* The Mongoose CastError constructor
|
||||
*
|
||||
* @method CastError
|
||||
* @param {String} type The name of the type
|
||||
* @param {Any} value The value that failed to cast
|
||||
* @param {String} path The path `a.b.c` in the doc where this cast error occurred
|
||||
* @param {Error} [reason] The original error that was thrown
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.CastError = require('./error/cast');
|
||||
|
||||
/**
|
||||
* The [node-mongodb-native](https://github.com/mongodb/node-mongodb-native) driver Mongoose uses.
|
||||
*
|
||||
@@ -615,6 +722,77 @@ Mongoose.prototype.Error = require('./error');
|
||||
|
||||
Mongoose.prototype.mongo = require('mongodb');
|
||||
|
||||
/**
|
||||
* The [mquery](https://github.com/aheckmann/mquery) query builder Mongoose uses.
|
||||
*
|
||||
* @property mquery
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Mongoose.prototype.mquery = require('mquery');
|
||||
|
||||
/**
|
||||
* Wraps the given Mongoose instance into a thenable (pseudo-promise). This
|
||||
* is so `connect()` and `disconnect()` can return a thenable while maintaining
|
||||
* backwards compatibility.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function MongooseThenable(mongoose, promise) {
|
||||
var _this = this;
|
||||
for (var key in mongoose) {
|
||||
if (typeof mongoose[key] === 'function' && mongoose[key].$hasSideEffects) {
|
||||
(function(key) {
|
||||
_this[key] = function() {
|
||||
return mongoose[key].apply(mongoose, arguments);
|
||||
};
|
||||
})(key);
|
||||
} else if (['connection', 'connections'].indexOf(key) !== -1) {
|
||||
_this[key] = mongoose[key];
|
||||
}
|
||||
}
|
||||
this.$opPromise = promise;
|
||||
}
|
||||
|
||||
MongooseThenable.prototype = new Mongoose;
|
||||
|
||||
/**
|
||||
* Ability to use mongoose object as a pseudo-promise so `.connect().then()`
|
||||
* and `.disconnect().then()` are viable.
|
||||
*
|
||||
* @param {Function} onFulfilled
|
||||
* @param {Function} onRejected
|
||||
* @return {Promise}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseThenable.prototype.then = function(onFulfilled, onRejected) {
|
||||
var Promise = PromiseProvider.get();
|
||||
if (!this.$opPromise) {
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
reject(new Error('Can only call `.then()` if connect() or disconnect() ' +
|
||||
'has been called'));
|
||||
}).then(onFulfilled, onRejected);
|
||||
}
|
||||
this.$opPromise.$hasHandler = true;
|
||||
return this.$opPromise.then(onFulfilled, onRejected);
|
||||
};
|
||||
|
||||
/**
|
||||
* Ability to use mongoose object as a pseudo-promise so `.connect().then()`
|
||||
* and `.disconnect().then()` are viable.
|
||||
*
|
||||
* @param {Function} onFulfilled
|
||||
* @param {Function} onRejected
|
||||
* @return {Promise}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseThenable.prototype.catch = function(onRejected) {
|
||||
return this.then(null, onRejected);
|
||||
};
|
||||
|
||||
/*!
|
||||
* The exports object is an instance of Mongoose.
|
||||
*
|
||||
|
||||
6
node_modules/mongoose/lib/internal.js
generated
vendored
6
node_modules/mongoose/lib/internal.js
generated
vendored
@@ -2,12 +2,12 @@
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var StateMachine = require('./statemachine')
|
||||
var ActiveRoster = StateMachine.ctor('require', 'modify', 'init', 'default')
|
||||
var StateMachine = require('./statemachine');
|
||||
var ActiveRoster = StateMachine.ctor('require', 'modify', 'init', 'default', 'ignore');
|
||||
|
||||
module.exports = exports = InternalCache;
|
||||
|
||||
function InternalCache () {
|
||||
function InternalCache() {
|
||||
this.strictMode = undefined;
|
||||
this.selected = undefined;
|
||||
this.shardval = undefined;
|
||||
|
||||
2757
node_modules/mongoose/lib/model.js
generated
vendored
2757
node_modules/mongoose/lib/model.js
generated
vendored
File diff suppressed because it is too large
Load Diff
70
node_modules/mongoose/lib/namedscope.js
generated
vendored
70
node_modules/mongoose/lib/namedscope.js
generated
vendored
@@ -1,70 +0,0 @@
|
||||
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;
|
||||
119
node_modules/mongoose/lib/promise.js
generated
vendored
119
node_modules/mongoose/lib/promise.js
generated
vendored
@@ -1,9 +1,9 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var MPromise = require('mpromise');
|
||||
var util = require('util');
|
||||
|
||||
/**
|
||||
* Promise constructor.
|
||||
@@ -13,31 +13,82 @@ var MPromise = require('mpromise');
|
||||
* var query = Candy.find({ bar: true });
|
||||
* var promise = query.exec();
|
||||
*
|
||||
* DEPRECATED. Mongoose 5.0 will use native promises by default (or bluebird,
|
||||
* if native promises are not present) but still
|
||||
* support plugging in your own ES6-compatible promises library. Mongoose 5.0
|
||||
* will **not** support mpromise.
|
||||
*
|
||||
* @param {Function} fn a function which will be called when the promise is resolved that accepts `fn(err, ...){}` as signature
|
||||
* @inherits mpromise https://github.com/aheckmann/mpromise
|
||||
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
|
||||
* @event `err`: Emits when the promise is rejected
|
||||
* @event `complete`: Emits when the promise is fulfilled
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
function Promise (fn) {
|
||||
function Promise(fn) {
|
||||
MPromise.call(this, fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* ES6-style promise constructor wrapper around mpromise.
|
||||
*
|
||||
* @param {Function} resolver
|
||||
* @return {Promise} new promise
|
||||
* @api public
|
||||
*/
|
||||
Promise.ES6 = function(resolver) {
|
||||
var promise = new Promise();
|
||||
|
||||
// No try/catch for backwards compatibility
|
||||
resolver(
|
||||
function() {
|
||||
promise.complete.apply(promise, arguments);
|
||||
},
|
||||
function(e) {
|
||||
promise.error(e);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherit from mpromise
|
||||
*/
|
||||
|
||||
Promise.prototype = Object.create(MPromise.prototype, {
|
||||
constructor: {
|
||||
value: Promise
|
||||
, enumerable: false
|
||||
, writable: true
|
||||
, configurable: true
|
||||
}
|
||||
constructor: {
|
||||
value: Promise,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
Promise.prototype.then = util.deprecate(Promise.prototype.then,
|
||||
'Mongoose: mpromise (mongoose\'s default promise library) is deprecated, ' +
|
||||
'plug in your own promise library instead: ' +
|
||||
'http://mongoosejs.com/docs/promises.html');
|
||||
|
||||
/**
|
||||
* ES6-style `.catch()` shorthand
|
||||
*
|
||||
* @method catch
|
||||
* @memberOf Promise
|
||||
* @param {Function} onReject
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Promise.prototype.catch = function(onReject) {
|
||||
return this.then(null, onReject);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Override event names for backward compatibility.
|
||||
*/
|
||||
@@ -84,10 +135,15 @@ Promise.FAILURE = 'err';
|
||||
* @return {Promise} this
|
||||
*/
|
||||
|
||||
Promise.prototype.error = function (err) {
|
||||
if (!(err instanceof Error)) err = new Error(err);
|
||||
Promise.prototype.error = function(err) {
|
||||
if (!(err instanceof Error)) {
|
||||
if (err instanceof Object) {
|
||||
err = util.inspect(err);
|
||||
}
|
||||
err = new Error(err);
|
||||
}
|
||||
return this.reject(err);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves this promise to a rejected state if `err` is passed or a fulfilled state if no `err` is passed.
|
||||
@@ -101,17 +157,18 @@ Promise.prototype.error = function (err) {
|
||||
* @param {Error} [err] error or null
|
||||
* @param {Object} [val] value to fulfill the promise with
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
Promise.prototype.resolve = function (err, val) {
|
||||
Promise.prototype.resolve = function(err) {
|
||||
if (err) return this.error(err);
|
||||
return this.fulfill(val);
|
||||
}
|
||||
return this.fulfill.apply(this, Array.prototype.slice.call(arguments, 1));
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a single function as a listener to both err and complete.
|
||||
*
|
||||
* It will be executed with traditional node.js argument position when the promise is resolved.
|
||||
* It will be executed with traditional node.js argument position when the promise is resolved.
|
||||
*
|
||||
* promise.addBack(function (err, args...) {
|
||||
* if (err) return handleError(err);
|
||||
@@ -120,9 +177,12 @@ Promise.prototype.resolve = function (err, val) {
|
||||
*
|
||||
* Alias of [mpromise#onResolve](https://github.com/aheckmann/mpromise#onresolve).
|
||||
*
|
||||
* _Deprecated. Use `onResolve` instead._
|
||||
*
|
||||
* @method addBack
|
||||
* @param {Function} listener
|
||||
* @return {Promise} this
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
Promise.prototype.addBack = Promise.prototype.onResolve;
|
||||
@@ -130,11 +190,26 @@ Promise.prototype.addBack = Promise.prototype.onResolve;
|
||||
/**
|
||||
* Fulfills this promise with passed arguments.
|
||||
*
|
||||
* Alias of [mpromise#fulfill](https://github.com/aheckmann/mpromise#fulfill).
|
||||
*
|
||||
* @method complete
|
||||
* @method fulfill
|
||||
* @receiver Promise
|
||||
* @see https://github.com/aheckmann/mpromise#fulfill
|
||||
* @param {any} args
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fulfills this promise with passed arguments.
|
||||
*
|
||||
* Alias of [mpromise#fulfill](https://github.com/aheckmann/mpromise#fulfill).
|
||||
*
|
||||
* _Deprecated. Use `fulfill` instead._
|
||||
*
|
||||
* @method complete
|
||||
* @receiver Promise
|
||||
* @param {any} args
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
Promise.prototype.complete = MPromise.prototype.fulfill;
|
||||
@@ -144,10 +219,13 @@ Promise.prototype.complete = MPromise.prototype.fulfill;
|
||||
*
|
||||
* Alias of [mpromise#onFulfill](https://github.com/aheckmann/mpromise#onfulfill).
|
||||
*
|
||||
* _Deprecated. Use `onFulfill` instead._
|
||||
*
|
||||
* @method addCallback
|
||||
* @param {Function} listener
|
||||
* @return {Promise} this
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
Promise.prototype.addCallback = Promise.prototype.onFulfill;
|
||||
@@ -157,10 +235,13 @@ Promise.prototype.addCallback = Promise.prototype.onFulfill;
|
||||
*
|
||||
* Alias of [mpromise#onReject](https://github.com/aheckmann/mpromise#onreject).
|
||||
*
|
||||
* _Deprecated. Use `onReject` instead._
|
||||
*
|
||||
* @method addErrback
|
||||
* @param {Function} listener
|
||||
* @return {Promise} this
|
||||
* @api public
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
Promise.prototype.addErrback = Promise.prototype.onReject;
|
||||
@@ -195,6 +276,7 @@ Promise.prototype.addErrback = Promise.prototype.onReject;
|
||||
* @param {Function} onFulFill
|
||||
* @param {Function} onReject
|
||||
* @return {Promise} newPromise
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -222,6 +304,7 @@ Promise.prototype.addErrback = Promise.prototype.onReject;
|
||||
* @see mpromise#end https://github.com/aheckmann/mpromise#end
|
||||
* @method end
|
||||
* @memberOf Promise
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
||||
51
node_modules/mongoose/lib/promise_provider.js
generated
vendored
Normal file
51
node_modules/mongoose/lib/promise_provider.js
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MPromise = require('./promise');
|
||||
|
||||
/**
|
||||
* Helper for multiplexing promise implementations
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var Promise = {
|
||||
_promise: MPromise
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current promise constructor
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
Promise.get = function() {
|
||||
return Promise._promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the current promise constructor
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Promise.set = function(lib) {
|
||||
if (lib === MPromise) {
|
||||
return Promise.reset();
|
||||
}
|
||||
Promise._promise = require('./ES6Promise');
|
||||
Promise._promise.use(lib);
|
||||
require('mquery').Promise = Promise._promise.ES6;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets to using mpromise
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Promise.reset = function() {
|
||||
Promise._promise = MPromise;
|
||||
};
|
||||
|
||||
module.exports = Promise;
|
||||
4193
node_modules/mongoose/lib/query.js
generated
vendored
4193
node_modules/mongoose/lib/query.js
generated
vendored
File diff suppressed because it is too large
Load Diff
262
node_modules/mongoose/lib/querycursor.js
generated
vendored
Normal file
262
node_modules/mongoose/lib/querycursor.js
generated
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var PromiseProvider = require('./promise_provider');
|
||||
var Readable = require('stream').Readable;
|
||||
var helpers = require('./queryhelpers');
|
||||
var util = require('util');
|
||||
|
||||
/**
|
||||
* A QueryCursor is a concurrency primitive for processing query results
|
||||
* one document at a time. A QueryCursor fulfills the [Node.js streams3 API](https://strongloop.com/strongblog/whats-new-io-js-beta-streams3/),
|
||||
* in addition to several other mechanisms for loading documents from MongoDB
|
||||
* one at a time.
|
||||
*
|
||||
* Unless you're an advanced user, do **not** instantiate this class directly.
|
||||
* Use [`Query#cursor()`](/api.html#query_Query-cursor) instead.
|
||||
*
|
||||
* @param {Query} query
|
||||
* @param {Object} options query options passed to `.find()`
|
||||
* @inherits Readable
|
||||
* @event `cursor`: Emitted when the cursor is created
|
||||
* @event `error`: Emitted when an error occurred
|
||||
* @event `data`: Emitted when the stream is flowing and the next doc is ready
|
||||
* @event `end`: Emitted when the stream is exhausted
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function QueryCursor(query, options) {
|
||||
Readable.call(this, { objectMode: true });
|
||||
|
||||
this.cursor = null;
|
||||
this.query = query;
|
||||
var _this = this;
|
||||
var model = query.model;
|
||||
model.collection.find(query._conditions, options, function(err, cursor) {
|
||||
if (_this._error) {
|
||||
cursor.close(function() {});
|
||||
_this.listeners('error').length > 0 && _this.emit('error', _this._error);
|
||||
}
|
||||
if (err) {
|
||||
return _this.emit('error', err);
|
||||
}
|
||||
_this.cursor = cursor;
|
||||
_this.emit('cursor', cursor);
|
||||
});
|
||||
}
|
||||
|
||||
util.inherits(QueryCursor, Readable);
|
||||
|
||||
/*!
|
||||
* Necessary to satisfy the Readable API
|
||||
*/
|
||||
|
||||
QueryCursor.prototype._read = function() {
|
||||
var _this = this;
|
||||
_next(this, function(error, doc) {
|
||||
if (error) {
|
||||
return _this.emit('error', error);
|
||||
}
|
||||
if (!doc) {
|
||||
_this.push(null);
|
||||
return _this.cursor.close(function(error) {
|
||||
if (error) {
|
||||
return _this.emit('error', error);
|
||||
}
|
||||
_this.emit('close');
|
||||
});
|
||||
}
|
||||
_this.push(doc);
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Marks this cursor as errored
|
||||
*/
|
||||
|
||||
QueryCursor.prototype._markError = function(error) {
|
||||
this._error = error;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks this cursor as closed. Will stop streaming and subsequent calls to
|
||||
* `next()` will error.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method close
|
||||
* @emits close
|
||||
* @see MongoDB driver cursor#close http://mongodb.github.io/node-mongodb-native/2.1/api/Cursor.html#close
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.close = function(callback) {
|
||||
var Promise = PromiseProvider.get();
|
||||
var _this = this;
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
_this.cursor.close(function(error) {
|
||||
if (error) {
|
||||
callback && callback(error);
|
||||
reject(error);
|
||||
return _this.listeners('error').length > 0 &&
|
||||
_this.emit('error', error);
|
||||
}
|
||||
_this.emit('close');
|
||||
resolve();
|
||||
callback && callback();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the next document from this cursor. Will return `null` when there are
|
||||
* no documents left.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method next
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.next = function(callback) {
|
||||
var Promise = PromiseProvider.get();
|
||||
var _this = this;
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
_next(_this, function(error, doc) {
|
||||
if (error) {
|
||||
callback && callback(error);
|
||||
return reject(error);
|
||||
}
|
||||
callback && callback(null, doc);
|
||||
resolve(doc);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute `fn` for every document in the cursor. If `fn` returns a promise,
|
||||
* will wait for the promise to resolve before iterating on to the next one.
|
||||
* Returns a promise that resolves when done.
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @param {Function} [callback] executed when all docs have been processed
|
||||
* @return {Promise}
|
||||
* @api public
|
||||
* @method eachAsync
|
||||
*/
|
||||
|
||||
QueryCursor.prototype.eachAsync = function(fn, callback) {
|
||||
var Promise = PromiseProvider.get();
|
||||
var _this = this;
|
||||
|
||||
var handleNextResult = function(doc, callback) {
|
||||
var promise = fn(doc);
|
||||
if (promise && typeof promise.then === 'function') {
|
||||
promise.then(
|
||||
function() { callback(null); },
|
||||
function(error) { callback(error); });
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
};
|
||||
|
||||
var iterate = function(callback) {
|
||||
return _next(_this, function(error, doc) {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
if (!doc) {
|
||||
return callback(null);
|
||||
}
|
||||
handleNextResult(doc, function(error) {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
iterate(callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return new Promise.ES6(function(resolve, reject) {
|
||||
iterate(function(error) {
|
||||
if (error) {
|
||||
callback && callback(error);
|
||||
return reject(error);
|
||||
}
|
||||
callback && callback(null);
|
||||
return resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Get the next doc from the underlying cursor and mongooseify it
|
||||
* (populate, etc.)
|
||||
*/
|
||||
|
||||
function _next(ctx, callback) {
|
||||
if (ctx._error) {
|
||||
return process.nextTick(function() {
|
||||
callback(ctx._error);
|
||||
});
|
||||
}
|
||||
|
||||
if (ctx.cursor) {
|
||||
ctx.cursor.next(function(error, doc) {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
if (!doc) {
|
||||
return callback(null, null);
|
||||
}
|
||||
|
||||
var opts = ctx.query._mongooseOptions;
|
||||
if (!opts.populate) {
|
||||
return opts.lean === true ?
|
||||
callback(null, doc) :
|
||||
_create(ctx, doc, null, callback);
|
||||
}
|
||||
|
||||
var pop = helpers.preparePopulationOptionsMQ(ctx.query,
|
||||
ctx.query._mongooseOptions);
|
||||
pop.forEach(function(option) {
|
||||
delete option.model;
|
||||
});
|
||||
pop.__noPromise = true;
|
||||
ctx.query.model.populate(doc, pop, function(err, doc) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
return opts.lean === true ?
|
||||
callback(null, doc) :
|
||||
_create(ctx, doc, pop, callback);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
ctx.once('cursor', function() {
|
||||
_next(ctx, callback);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Convert a raw doc into a full mongoose doc.
|
||||
*/
|
||||
|
||||
function _create(ctx, doc, populatedIds, cb) {
|
||||
var instance = helpers.createModel(ctx.query.model, doc, ctx.query._fields);
|
||||
var opts = populatedIds ?
|
||||
{ populated: populatedIds } :
|
||||
undefined;
|
||||
|
||||
instance.init(doc, opts, function(err) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
cb(null, instance);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = QueryCursor;
|
||||
53
node_modules/mongoose/lib/queryhelpers.js
generated
vendored
53
node_modules/mongoose/lib/queryhelpers.js
generated
vendored
@@ -3,7 +3,7 @@
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var utils = require('./utils')
|
||||
var utils = require('./utils');
|
||||
|
||||
/*!
|
||||
* Prepare a set of path options for query population.
|
||||
@@ -13,14 +13,58 @@ var utils = require('./utils')
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
exports.preparePopulationOptions = function preparePopulationOptions (query, options) {
|
||||
exports.preparePopulationOptions = function preparePopulationOptions(query, options) {
|
||||
var pop = utils.object.vals(query.options.populate);
|
||||
|
||||
// lean options should trickle through all queries
|
||||
if (options.lean) pop.forEach(makeLean);
|
||||
|
||||
return pop;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Prepare a set of path options for query population. This is the MongooseQuery
|
||||
* version
|
||||
*
|
||||
* @param {Query} query
|
||||
* @param {Object} options
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query, options) {
|
||||
var pop = utils.object.vals(query._mongooseOptions.populate);
|
||||
|
||||
// lean options should trickle through all queries
|
||||
if (options.lean) pop.forEach(makeLean);
|
||||
|
||||
return pop;
|
||||
};
|
||||
|
||||
/*!
|
||||
* If the document is a mapped discriminator type, it returns a model instance for that type, otherwise,
|
||||
* it returns an instance of the given model.
|
||||
*
|
||||
* @param {Model} model
|
||||
* @param {Object} doc
|
||||
* @param {Object} fields
|
||||
*
|
||||
* @return {Model}
|
||||
*/
|
||||
exports.createModel = function createModel(model, doc, fields) {
|
||||
var discriminatorMapping = model.schema
|
||||
? model.schema.discriminatorMapping
|
||||
: null;
|
||||
|
||||
var key = discriminatorMapping && discriminatorMapping.isRoot
|
||||
? discriminatorMapping.key
|
||||
: null;
|
||||
|
||||
if (key && doc[key] && model.discriminators && model.discriminators[doc[key]]) {
|
||||
return new model.discriminators[doc[key]](undefined, fields, true);
|
||||
}
|
||||
|
||||
return new model(undefined, fields, true);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Set each path query option to lean
|
||||
@@ -28,8 +72,7 @@ exports.preparePopulationOptions = function preparePopulationOptions (query, opt
|
||||
* @param {Object} option
|
||||
*/
|
||||
|
||||
function makeLean (option) {
|
||||
function makeLean(option) {
|
||||
option.options || (option.options = {});
|
||||
option.options.lean = true;
|
||||
}
|
||||
|
||||
|
||||
177
node_modules/mongoose/lib/querystream.js
generated
vendored
177
node_modules/mongoose/lib/querystream.js
generated
vendored
@@ -1,12 +1,15 @@
|
||||
/* eslint no-empty: 1 */
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Stream = require('stream').Stream
|
||||
var utils = require('./utils')
|
||||
var helpers = require('./queryhelpers')
|
||||
var K = function(k){ return k }
|
||||
var Stream = require('stream').Stream;
|
||||
var utils = require('./utils');
|
||||
var helpers = require('./queryhelpers');
|
||||
var K = function(k) {
|
||||
return k;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides a Node.js 0.8 style [ReadStream](http://nodejs.org/docs/v0.8.21/api/stream.html#stream_readable_stream) interface for Queries.
|
||||
@@ -49,7 +52,7 @@ var K = function(k){ return k }
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function QueryStream (query, options) {
|
||||
function QueryStream(query, options) {
|
||||
Stream.call(this);
|
||||
|
||||
this.query = query;
|
||||
@@ -61,14 +64,14 @@ function QueryStream (query, options) {
|
||||
this._buffer = null;
|
||||
this._inline = T_INIT;
|
||||
this._running = false;
|
||||
this._transform = options && 'function' == typeof options.transform
|
||||
? options.transform
|
||||
: K;
|
||||
this._transform = options && typeof options.transform === 'function'
|
||||
? options.transform
|
||||
: K;
|
||||
|
||||
// give time to hook up events
|
||||
var self = this;
|
||||
process.nextTick(function () {
|
||||
self._init();
|
||||
var _this = this;
|
||||
process.nextTick(function() {
|
||||
_this._init();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,29 +110,33 @@ var T_CONT = 2;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._init = function () {
|
||||
if (this._destroyed) return;
|
||||
QueryStream.prototype._init = function() {
|
||||
if (this._destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var query = this.query
|
||||
, model = query.model
|
||||
, options = query._optionsForExec(model)
|
||||
, self = this
|
||||
var query = this.query,
|
||||
model = query.model,
|
||||
options = query._optionsForExec(model),
|
||||
_this = this;
|
||||
|
||||
try {
|
||||
query.cast(model);
|
||||
} catch (err) {
|
||||
return self.destroy(err);
|
||||
return _this.destroy(err);
|
||||
}
|
||||
|
||||
self._fields = utils.clone(query._fields);
|
||||
options.fields = query._castFields(self._fields);
|
||||
_this._fields = utils.clone(query._fields);
|
||||
options.fields = query._castFields(_this._fields);
|
||||
|
||||
model.collection.find(query._conditions, options, function (err, cursor) {
|
||||
if (err) return self.destroy(err);
|
||||
self._cursor = cursor;
|
||||
self._next();
|
||||
model.collection.find(query._conditions, options, function(err, cursor) {
|
||||
if (err) {
|
||||
return _this.destroy(err);
|
||||
}
|
||||
_this._cursor = cursor;
|
||||
_this._next();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Trampoline for pulling the next doc from cursor.
|
||||
@@ -138,24 +145,26 @@ QueryStream.prototype._init = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._next = function _next () {
|
||||
QueryStream.prototype._next = function _next() {
|
||||
if (this.paused || this._destroyed) {
|
||||
return this._running = false;
|
||||
this._running = false;
|
||||
return this._running;
|
||||
}
|
||||
|
||||
this._running = true;
|
||||
|
||||
if (this._buffer && this._buffer.length) {
|
||||
var arg;
|
||||
while (!this.paused && !this._destroyed && (arg = this._buffer.shift())) {
|
||||
while (!this.paused && !this._destroyed && (arg = this._buffer.shift())) { // eslint-disable-line no-cond-assign
|
||||
this._onNextObject.apply(this, arg);
|
||||
}
|
||||
}
|
||||
|
||||
// avoid stack overflows with large result sets.
|
||||
// trampoline instead of recursion.
|
||||
while (this.__next()) {}
|
||||
}
|
||||
while (this.__next()) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pulls the next doc from the cursor.
|
||||
@@ -164,28 +173,29 @@ QueryStream.prototype._next = function _next () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype.__next = function () {
|
||||
if (this.paused || this._destroyed)
|
||||
return this._running = false;
|
||||
QueryStream.prototype.__next = function() {
|
||||
if (this.paused || this._destroyed) {
|
||||
this._running = false;
|
||||
return this._running;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
self._inline = T_INIT;
|
||||
var _this = this;
|
||||
_this._inline = T_INIT;
|
||||
|
||||
self._cursor.nextObject(function cursorcb (err, doc) {
|
||||
self._onNextObject(err, doc);
|
||||
_this._cursor.nextObject(function cursorcb(err, doc) {
|
||||
_this._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;
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
@@ -195,16 +205,21 @@ QueryStream.prototype.__next = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
|
||||
if (this._destroyed) return;
|
||||
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;
|
||||
this._running = false;
|
||||
return this._running;
|
||||
}
|
||||
|
||||
if (err) return this.destroy(err);
|
||||
if (err) {
|
||||
return this.destroy(err);
|
||||
}
|
||||
|
||||
// when doc is null we hit the end of the cursor
|
||||
if (!doc) {
|
||||
@@ -212,29 +227,43 @@ QueryStream.prototype._onNextObject = function _onNextObject (err, doc) {
|
||||
return this.destroy();
|
||||
}
|
||||
|
||||
var opts = this.query.options;
|
||||
var opts = this.query._mongooseOptions;
|
||||
|
||||
if (!opts.populate) {
|
||||
return true === opts.lean
|
||||
? emit(this, doc)
|
||||
: createAndEmit(this, doc);
|
||||
return opts.lean === true ?
|
||||
emit(this, doc) :
|
||||
createAndEmit(this, null, doc);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var pop = helpers.preparePopulationOptions(self.query, self.query.options);
|
||||
var _this = this;
|
||||
var pop = helpers.preparePopulationOptionsMQ(_this.query, _this.query._mongooseOptions);
|
||||
|
||||
self.query.model.populate(doc, pop, function (err, doc) {
|
||||
if (err) return self.destroy(err);
|
||||
return true === opts.lean
|
||||
? emit(self, doc)
|
||||
: createAndEmit(self, doc);
|
||||
})
|
||||
}
|
||||
// Hack to work around gh-3108
|
||||
pop.forEach(function(option) {
|
||||
delete option.model;
|
||||
});
|
||||
|
||||
function createAndEmit (self, doc) {
|
||||
var instance = new self.query.model(undefined, self._fields, true);
|
||||
instance.init(doc, function (err) {
|
||||
if (err) return self.destroy(err);
|
||||
pop.__noPromise = true;
|
||||
_this.query.model.populate(doc, pop, function(err, doc) {
|
||||
if (err) {
|
||||
return _this.destroy(err);
|
||||
}
|
||||
return opts.lean === true ?
|
||||
emit(_this, doc) :
|
||||
createAndEmit(_this, pop, doc);
|
||||
});
|
||||
};
|
||||
|
||||
function createAndEmit(self, populatedIds, doc) {
|
||||
var instance = helpers.createModel(self.query.model, doc, self._fields);
|
||||
var opts = populatedIds ?
|
||||
{populated: populatedIds} :
|
||||
undefined;
|
||||
|
||||
instance.init(doc, opts, function(err) {
|
||||
if (err) {
|
||||
return self.destroy(err);
|
||||
}
|
||||
emit(self, instance);
|
||||
});
|
||||
}
|
||||
@@ -243,7 +272,7 @@ function createAndEmit (self, doc) {
|
||||
* Emit a data event and manage the trampoline state
|
||||
*/
|
||||
|
||||
function emit (self, doc) {
|
||||
function emit(self, doc) {
|
||||
self.emit('data', self._transform(doc));
|
||||
|
||||
// trampoline management
|
||||
@@ -263,9 +292,9 @@ function emit (self, doc) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.pause = function () {
|
||||
QueryStream.prototype.pause = function() {
|
||||
this.paused = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resumes this stream.
|
||||
@@ -273,7 +302,7 @@ QueryStream.prototype.pause = function () {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.resume = function () {
|
||||
QueryStream.prototype.resume = function() {
|
||||
this.paused = false;
|
||||
|
||||
if (!this._cursor) {
|
||||
@@ -290,17 +319,19 @@ QueryStream.prototype.resume = function () {
|
||||
// outside QueryStream control, need manual restart
|
||||
return this._next();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the stream, closing the underlying cursor. No more events will be emitted.
|
||||
* Destroys the stream, closing the underlying cursor, which emits the close event. No more events will be emitted after the close event.
|
||||
*
|
||||
* @param {Error} [err]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
QueryStream.prototype.destroy = function (err) {
|
||||
if (this._destroyed) return;
|
||||
QueryStream.prototype.destroy = function(err) {
|
||||
if (this._destroyed) {
|
||||
return;
|
||||
}
|
||||
this._destroyed = true;
|
||||
this._running = false;
|
||||
this.readable = false;
|
||||
@@ -314,7 +345,7 @@ QueryStream.prototype.destroy = function (err) {
|
||||
}
|
||||
|
||||
this.emit('close');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pipes this query stream into another stream. This method is inherited from NodeJS Streams.
|
||||
|
||||
1157
node_modules/mongoose/lib/schema.js
generated
vendored
1157
node_modules/mongoose/lib/schema.js
generated
vendored
File diff suppressed because it is too large
Load Diff
351
node_modules/mongoose/lib/schema/array.js
generated
vendored
351
node_modules/mongoose/lib/schema/array.js
generated
vendored
@@ -2,23 +2,25 @@
|
||||
* 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')
|
||||
, utils = require('../utils')
|
||||
, isMongooseObject = utils.isMongooseObject
|
||||
var SchemaType = require('../schematype');
|
||||
var CastError = SchemaType.CastError;
|
||||
var Types = {
|
||||
Boolean: require('./boolean'),
|
||||
Date: require('./date'),
|
||||
Number: require('./number'),
|
||||
String: require('./string'),
|
||||
ObjectId: require('./objectid'),
|
||||
Buffer: require('./buffer')
|
||||
};
|
||||
var MongooseArray = require('../types').Array;
|
||||
var EmbeddedDoc = require('../types').Embedded;
|
||||
var Mixed = require('./mixed');
|
||||
var cast = require('../cast');
|
||||
var util = require('util');
|
||||
var utils = require('../utils');
|
||||
var isMongooseObject = utils.isMongooseObject;
|
||||
var castToNumber = require('./operators/helpers').castToNumber;
|
||||
var geospatial = require('./operators/geospatial');
|
||||
|
||||
/**
|
||||
* Array SchemaType constructor
|
||||
@@ -27,14 +29,14 @@ var SchemaType = require('../schematype')
|
||||
* @param {SchemaType} cast
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaArray (key, cast, options) {
|
||||
function SchemaArray(key, cast, options) {
|
||||
if (cast) {
|
||||
var castOptions = {};
|
||||
|
||||
if ('Object' === cast.constructor.name) {
|
||||
if (utils.getFunctionName(cast.constructor) === 'Object') {
|
||||
if (cast.type) {
|
||||
// support { type: Woot }
|
||||
castOptions = utils.clone(cast); // do not alter user arguments
|
||||
@@ -46,52 +48,69 @@ function SchemaArray (key, cast, options) {
|
||||
}
|
||||
|
||||
// support { type: 'String' }
|
||||
var name = 'string' == typeof cast
|
||||
? cast
|
||||
: cast.name;
|
||||
var name = typeof cast === 'string'
|
||||
? cast
|
||||
: utils.getFunctionName(cast);
|
||||
|
||||
var caster = name in Types
|
||||
? Types[name]
|
||||
: cast;
|
||||
? Types[name]
|
||||
: cast;
|
||||
|
||||
this.casterConstructor = caster;
|
||||
this.caster = new caster(null, castOptions);
|
||||
if (typeof caster === 'function') {
|
||||
this.caster = new caster(null, castOptions);
|
||||
} else {
|
||||
this.caster = caster;
|
||||
}
|
||||
|
||||
if (!(this.caster instanceof EmbeddedDoc)) {
|
||||
this.caster.path = key;
|
||||
}
|
||||
}
|
||||
|
||||
SchemaType.call(this, key, options);
|
||||
SchemaType.call(this, key, options, 'Array');
|
||||
|
||||
var self = this
|
||||
, defaultArr
|
||||
, fn;
|
||||
var _this = this;
|
||||
var defaultArr;
|
||||
var fn;
|
||||
|
||||
if (this.defaultValue) {
|
||||
defaultArr = this.defaultValue;
|
||||
fn = 'function' == typeof defaultArr;
|
||||
fn = typeof defaultArr === 'function';
|
||||
}
|
||||
|
||||
this.default(function(){
|
||||
var arr = fn ? defaultArr() : defaultArr || [];
|
||||
return new MongooseArray(arr, self.path, this);
|
||||
});
|
||||
};
|
||||
if (!('defaultValue' in this) || this.defaultValue !== void 0) {
|
||||
this.default(function() {
|
||||
var arr = fn ? defaultArr() : defaultArr || [];
|
||||
return new MongooseArray(arr, _this.path, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaArray.schemaName = 'Array';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaArray.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaArray.prototype.constructor = SchemaArray;
|
||||
|
||||
/**
|
||||
* Check required
|
||||
* Check if the given value satisfies a required validator. The given value
|
||||
* must be not null nor undefined, and have a non-zero length.
|
||||
*
|
||||
* @param {Array} value
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.checkRequired = function (value) {
|
||||
SchemaArray.prototype.checkRequired = function(value) {
|
||||
return !!(value && value.length);
|
||||
};
|
||||
|
||||
@@ -103,7 +122,7 @@ SchemaArray.prototype.checkRequired = function (value) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.applyGetters = function (value, scope) {
|
||||
SchemaArray.prototype.applyGetters = function(value, scope) {
|
||||
if (this.caster.options && this.caster.options.ref) {
|
||||
// means the object id was populated
|
||||
return value;
|
||||
@@ -113,7 +132,7 @@ SchemaArray.prototype.applyGetters = function (value, scope) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
* Casts values for set().
|
||||
*
|
||||
* @param {Object} value
|
||||
* @param {Document} doc document that triggers the casting
|
||||
@@ -121,194 +140,164 @@ SchemaArray.prototype.applyGetters = function (value, scope) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.cast = function (value, doc, init) {
|
||||
SchemaArray.prototype.cast = function(value, doc, init) {
|
||||
if (Array.isArray(value)) {
|
||||
if (!(value instanceof MongooseArray)) {
|
||||
if (!value.length && doc) {
|
||||
var indexes = doc.schema.indexedPaths();
|
||||
|
||||
for (var i = 0, l = indexes.length; i < l; ++i) {
|
||||
var pathIndex = indexes[i][0][this.path];
|
||||
if (pathIndex === '2dsphere' || pathIndex === '2d') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(value && value.isMongooseArray)) {
|
||||
value = new MongooseArray(value, this.path, doc);
|
||||
}
|
||||
|
||||
if (this.caster) {
|
||||
try {
|
||||
for (var i = 0, l = value.length; i < l; i++) {
|
||||
for (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);
|
||||
throw new CastError('[' + e.kind + ']', util.inspect(value), this.path, e);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
} else {
|
||||
return this.cast([value], doc, init);
|
||||
}
|
||||
// gh-2442: if we're loading this from the db and its not an array, mark
|
||||
// the whole array as modified.
|
||||
if (!!doc && !!init) {
|
||||
doc.markModified(this.path);
|
||||
}
|
||||
return this.cast([value], doc, init);
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
* Casts values for queries.
|
||||
*
|
||||
* @param {String} $conditional
|
||||
* @param {any} [value]
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaArray.prototype.castForQuery = function ($conditional, value) {
|
||||
var handler
|
||||
, val;
|
||||
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.");
|
||||
|
||||
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;
|
||||
if (Array.isArray(val)) {
|
||||
val = val.map(function(v) {
|
||||
if (utils.isObject(v) && v.$elemMatch) {
|
||||
return v;
|
||||
}
|
||||
if (method) {
|
||||
v = method.call(caster, v);
|
||||
}
|
||||
return isMongooseObject(v) ?
|
||||
v.toObject({virtuals: false}) :
|
||||
v;
|
||||
});
|
||||
} else if (method) {
|
||||
val = method.call(caster, val);
|
||||
}
|
||||
}
|
||||
return val && isMongooseObject(val)
|
||||
? val.toObject()
|
||||
: val;
|
||||
|
||||
return val && isMongooseObject(val) ?
|
||||
val.toObject({virtuals: false}) :
|
||||
val;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ignore
|
||||
*/
|
||||
function cast$all(val) {
|
||||
if (!Array.isArray(val)) {
|
||||
val = [val];
|
||||
}
|
||||
|
||||
function castToNumber (val) {
|
||||
return Types.Number.prototype.cast.call(this, val);
|
||||
val = val.map(function(v) {
|
||||
if (utils.isObject(v)) {
|
||||
var o = {};
|
||||
o[this.path] = v;
|
||||
return cast(this.casterConstructor.schema, o)[this.path];
|
||||
}
|
||||
return v;
|
||||
}, this);
|
||||
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
|
||||
function castArray (arr, self) {
|
||||
self || (self = this);
|
||||
|
||||
arr.forEach(function (v, i) {
|
||||
if (Array.isArray(v)) {
|
||||
castArray(v, self);
|
||||
} else {
|
||||
arr[i] = castToNumber.call(self, v);
|
||||
function cast$elemMatch(val) {
|
||||
var keys = Object.keys(val);
|
||||
var numKeys = keys.length;
|
||||
var key;
|
||||
var value;
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
key = keys[i];
|
||||
value = val[key];
|
||||
if (key.indexOf('$') === 0 && value) {
|
||||
val[key] = this.castForQuery(key, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return cast(this.casterConstructor.schema, val);
|
||||
}
|
||||
|
||||
SchemaArray.prototype.$conditionalHandlers = {
|
||||
'$all': function handle$all (val) {
|
||||
if (!Array.isArray(val)) {
|
||||
val = [val];
|
||||
}
|
||||
var handle = SchemaArray.prototype.$conditionalHandlers = {};
|
||||
|
||||
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);
|
||||
handle.$all = cast$all;
|
||||
handle.$options = String;
|
||||
handle.$elemMatch = cast$elemMatch;
|
||||
handle.$geoIntersects = geospatial.cast$geoIntersects;
|
||||
handle.$or = handle.$and = function(val) {
|
||||
if (!Array.isArray(val)) {
|
||||
throw new TypeError('conditional $or/$and require array');
|
||||
}
|
||||
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
, '$elemMatch': function (val) {
|
||||
if (val.$in) {
|
||||
val.$in = this.castForQuery('$in', val.$in);
|
||||
return val;
|
||||
}
|
||||
var ret = [];
|
||||
for (var i = 0; i < val.length; ++i) {
|
||||
ret.push(cast(this.casterConstructor.schema, val[i]));
|
||||
}
|
||||
|
||||
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
|
||||
, '$options': String
|
||||
, '$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) {
|
||||
if (!Array.isArray(arr)) {
|
||||
var msg = 'Invalid $within $box argument. '
|
||||
+ 'Expected an array, received ' + arr;
|
||||
throw new TypeError(msg);
|
||||
}
|
||||
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);
|
||||
}
|
||||
})
|
||||
} else if (val.$geometry) {
|
||||
switch (val.$geometry.type) {
|
||||
case 'Polygon':
|
||||
case 'LineString':
|
||||
case 'Point':
|
||||
val.$geometry.coordinates.forEach(castArray);
|
||||
break;
|
||||
default:
|
||||
// ignore unknowns
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
, '$geoIntersects': function (val) {
|
||||
var geo = val.$geometry;
|
||||
if (!geo) return;
|
||||
|
||||
switch (val.$geometry.type) {
|
||||
case 'Polygon':
|
||||
case 'LineString':
|
||||
case 'Point':
|
||||
val.$geometry.coordinates.forEach(castArray);
|
||||
break;
|
||||
default:
|
||||
// ignore unknowns
|
||||
break;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
, '$maxDistance': castToNumber
|
||||
return ret;
|
||||
};
|
||||
|
||||
handle.$near =
|
||||
handle.$nearSphere = geospatial.cast$near;
|
||||
|
||||
handle.$within =
|
||||
handle.$geoWithin = geospatial.cast$within;
|
||||
|
||||
handle.$size =
|
||||
handle.$minDistance =
|
||||
handle.$maxDistance = castToNumber;
|
||||
|
||||
handle.$eq =
|
||||
handle.$gt =
|
||||
handle.$gte =
|
||||
handle.$in =
|
||||
handle.$lt =
|
||||
handle.$lte =
|
||||
handle.$ne =
|
||||
handle.$nin =
|
||||
handle.$regex = SchemaArray.prototype.castForQuery;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
73
node_modules/mongoose/lib/schema/boolean.js
generated
vendored
73
node_modules/mongoose/lib/schema/boolean.js
generated
vendored
@@ -2,6 +2,8 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var utils = require('../utils');
|
||||
|
||||
var SchemaType = require('../schematype');
|
||||
|
||||
/**
|
||||
@@ -10,25 +12,38 @@ var SchemaType = require('../schematype');
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaBoolean (path, options) {
|
||||
SchemaType.call(this, path, options);
|
||||
};
|
||||
function SchemaBoolean(path, options) {
|
||||
SchemaType.call(this, path, options, 'Boolean');
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaBoolean.schemaName = 'Boolean';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
SchemaBoolean.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaBoolean.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaBoolean.prototype.constructor = SchemaBoolean;
|
||||
|
||||
/**
|
||||
* Required validator
|
||||
* Check if the given value satisfies a required validator. For a boolean
|
||||
* to satisfy a required validator, it must be strictly equal to true or to
|
||||
* false.
|
||||
*
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.checkRequired = function (value) {
|
||||
SchemaBoolean.prototype.checkRequired = function(value) {
|
||||
return value === true || value === false;
|
||||
};
|
||||
|
||||
@@ -39,28 +54,24 @@ SchemaBoolean.prototype.checkRequired = function (value) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.cast = function (value) {
|
||||
if (null === value) return value;
|
||||
if ('0' === value) return false;
|
||||
if ('true' === value) return true;
|
||||
if ('false' === value) return false;
|
||||
return !! value;
|
||||
}
|
||||
SchemaBoolean.prototype.cast = function(value) {
|
||||
if (value === null) {
|
||||
return value;
|
||||
}
|
||||
if (value === '0') {
|
||||
return false;
|
||||
}
|
||||
if (value === 'true') {
|
||||
return true;
|
||||
}
|
||||
if (value === 'false') {
|
||||
return false;
|
||||
}
|
||||
return !!value;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaBoolean.$conditionalHandlers = {
|
||||
'$in': handleArray
|
||||
}
|
||||
SchemaBoolean.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {});
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
@@ -70,9 +81,9 @@ SchemaBoolean.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBoolean.prototype.castForQuery = function ($conditional, val) {
|
||||
SchemaBoolean.prototype.castForQuery = function($conditional, val) {
|
||||
var handler;
|
||||
if (2 === arguments.length) {
|
||||
if (arguments.length === 2) {
|
||||
handler = SchemaBoolean.$conditionalHandlers[$conditional];
|
||||
|
||||
if (handler) {
|
||||
|
||||
124
node_modules/mongoose/lib/schema/buffer.js
generated
vendored
124
node_modules/mongoose/lib/schema/buffer.js
generated
vendored
@@ -2,45 +2,59 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, MongooseBuffer = require('../types').Buffer
|
||||
, Binary = MongooseBuffer.Binary
|
||||
, Query = require('../query')
|
||||
, utils = require('../utils')
|
||||
, Document
|
||||
var handleBitwiseOperator = require('./operators/bitwise');
|
||||
var utils = require('../utils');
|
||||
|
||||
var MongooseBuffer = require('../types').Buffer;
|
||||
var SchemaType = require('../schematype');
|
||||
|
||||
var Binary = MongooseBuffer.Binary;
|
||||
var CastError = SchemaType.CastError;
|
||||
var Document;
|
||||
|
||||
/**
|
||||
* Buffer SchemaType constructor
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {SchemaType} cast
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaBuffer (key, options) {
|
||||
function SchemaBuffer(key, options) {
|
||||
SchemaType.call(this, key, options, 'Buffer');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaBuffer.schemaName = 'Buffer';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaBuffer.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaBuffer.prototype.constructor = SchemaBuffer;
|
||||
|
||||
/**
|
||||
* Check required
|
||||
* Check if the given value satisfies a required validator. To satisfy a
|
||||
* required validator, a buffer must not be null or undefined and have
|
||||
* non-zero length.
|
||||
*
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @param {Document} doc
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.checkRequired = function (value, doc) {
|
||||
SchemaBuffer.prototype.checkRequired = function(value, doc) {
|
||||
if (SchemaType._isRef(this, value, doc, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return !!(value && value.length);
|
||||
return !!value;
|
||||
}
|
||||
return !!(value && value.length);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -52,11 +66,12 @@ SchemaBuffer.prototype.checkRequired = function (value, doc) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.cast = function (value, doc, init) {
|
||||
SchemaBuffer.prototype.cast = function(value, doc, init) {
|
||||
var ret;
|
||||
if (SchemaType._isRef(this, value, doc, init)) {
|
||||
// wait! we may need to cast this to a document
|
||||
|
||||
if (null == value) {
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -81,7 +96,7 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
|
||||
var path = doc.$__fullPath(this.path);
|
||||
var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
|
||||
var pop = owner.populated(path, true);
|
||||
var ret = new pop.options.model(value);
|
||||
ret = new pop.options.model(value);
|
||||
ret.$__.wasPopulated = true;
|
||||
return ret;
|
||||
}
|
||||
@@ -91,25 +106,35 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
|
||||
value = value._id;
|
||||
}
|
||||
|
||||
if (value && value.isMongooseBuffer) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(value)) {
|
||||
if (!(value instanceof MongooseBuffer)) {
|
||||
if (!value || !value.isMongooseBuffer) {
|
||||
value = new MongooseBuffer(value, [this.path, doc]);
|
||||
}
|
||||
|
||||
return value;
|
||||
} else if (value instanceof Binary) {
|
||||
var ret = new MongooseBuffer(value.value(true), [this.path, doc]);
|
||||
ret = new MongooseBuffer(value.value(true), [this.path, doc]);
|
||||
if (typeof value.sub_type !== 'number') {
|
||||
throw new CastError('buffer', value, this.path);
|
||||
}
|
||||
ret._subtype = value.sub_type;
|
||||
// do not override Binary subtypes. users set this
|
||||
// to whatever they want.
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (null === value) return value;
|
||||
if (value === null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var type = typeof value;
|
||||
if ('string' == type || 'number' == type || Array.isArray(value)) {
|
||||
var ret = new MongooseBuffer(value, [this.path, doc]);
|
||||
if (type === 'string' || type === 'number' || Array.isArray(value)) {
|
||||
if (type === 'number') {
|
||||
value = [value];
|
||||
}
|
||||
ret = new MongooseBuffer(value, [this.path, doc]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -119,26 +144,21 @@ SchemaBuffer.prototype.cast = function (value, doc, init) {
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
function handleSingle (val) {
|
||||
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
|
||||
};
|
||||
SchemaBuffer.prototype.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {
|
||||
$bitsAllClear: handleBitwiseOperator,
|
||||
$bitsAnyClear: handleBitwiseOperator,
|
||||
$bitsAllSet: handleBitwiseOperator,
|
||||
$bitsAnySet: handleBitwiseOperator,
|
||||
$gt: handleSingle,
|
||||
$gte: handleSingle,
|
||||
$lt: handleSingle,
|
||||
$lte: handleSingle
|
||||
});
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
@@ -148,17 +168,17 @@ SchemaBuffer.prototype.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaBuffer.prototype.castForQuery = function ($conditional, val) {
|
||||
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.");
|
||||
if (!handler) {
|
||||
throw new Error('Can\'t use ' + $conditional + ' with Buffer.');
|
||||
}
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
val = $conditional;
|
||||
return this.cast(val).toObject();
|
||||
}
|
||||
val = $conditional;
|
||||
return this.cast(val).toObject();
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
217
node_modules/mongoose/lib/schema/date.js
generated
vendored
217
node_modules/mongoose/lib/schema/date.js
generated
vendored
@@ -2,33 +2,44 @@
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype');
|
||||
var CastError = SchemaType.CastError;
|
||||
var MongooseError = require('../error');
|
||||
var utils = require('../utils');
|
||||
|
||||
var SchemaType = require('../schematype');
|
||||
|
||||
var CastError = SchemaType.CastError;
|
||||
|
||||
/**
|
||||
* Date SchemaType constructor.
|
||||
*
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaDate (key, options) {
|
||||
SchemaType.call(this, key, options);
|
||||
};
|
||||
function SchemaDate(key, options) {
|
||||
SchemaType.call(this, key, options, 'Date');
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaDate.schemaName = 'Date';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaDate.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaDate.prototype.constructor = SchemaDate;
|
||||
|
||||
/**
|
||||
* 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 sets the `expireAfterSeconds` index option available in MongoDB >= 2.1.2.
|
||||
* This index type is only compatible with Date types.
|
||||
*
|
||||
* ####Example:
|
||||
@@ -56,8 +67,8 @@ SchemaDate.prototype.__proto__ = SchemaType.prototype;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.expires = function (when) {
|
||||
if (!this._index || 'Object' !== this._index.constructor.name) {
|
||||
SchemaDate.prototype.expires = function(when) {
|
||||
if (!this._index || this._index.constructor.name !== 'Object') {
|
||||
this._index = {};
|
||||
}
|
||||
|
||||
@@ -67,15 +78,131 @@ SchemaDate.prototype.expires = function (when) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Required validator for date
|
||||
* Check if the given value satisfies a required validator. To satisfy
|
||||
* a required validator, the given value must be an instance of `Date`.
|
||||
*
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @param {Document} doc
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.checkRequired = function (value) {
|
||||
SchemaDate.prototype.checkRequired = function(value) {
|
||||
return value instanceof Date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a minimum date validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ d: { type: Date, min: Date('1970-01-01') })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ d: Date('1969-12-31') })
|
||||
* m.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* m.d = Date('2014-12-08');
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MIN} token which will be replaced with the invalid value
|
||||
* var min = [Date('1970-01-01'), 'The value of path `{PATH}` ({VALUE}) is beneath the limit ({MIN}).'];
|
||||
* var schema = new Schema({ d: { type: Date, min: min })
|
||||
* var M = mongoose.model('M', schema);
|
||||
* var s= new M({ d: Date('1969-12-31') });
|
||||
* s.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `d` (1969-12-31) is before the limit (1970-01-01).
|
||||
* })
|
||||
*
|
||||
* @param {Date} value minimum date
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.min = function(value, message) {
|
||||
if (this.minValidator) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.minValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
var msg = message || MongooseError.messages.Date.min;
|
||||
msg = msg.replace(/{MIN}/, (value === Date.now ? 'Date.now()' : this.cast(value).toString()));
|
||||
var _this = this;
|
||||
this.validators.push({
|
||||
validator: this.minValidator = function(val) {
|
||||
var min = (value === Date.now ? value() : _this.cast(value));
|
||||
return val === null || val.valueOf() >= min.valueOf();
|
||||
},
|
||||
message: msg,
|
||||
type: 'min',
|
||||
min: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a maximum date validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ d: { type: Date, max: Date('2014-01-01') })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ d: Date('2014-12-08') })
|
||||
* m.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* m.d = Date('2013-12-31');
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MAX} token which will be replaced with the invalid value
|
||||
* var max = [Date('2014-01-01'), 'The value of path `{PATH}` ({VALUE}) exceeds the limit ({MAX}).'];
|
||||
* var schema = new Schema({ d: { type: Date, max: max })
|
||||
* var M = mongoose.model('M', schema);
|
||||
* var s= new M({ d: Date('2014-12-08') });
|
||||
* s.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `d` (2014-12-08) exceeds the limit (2014-01-01).
|
||||
* })
|
||||
*
|
||||
* @param {Date} maximum date
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.max = function(value, message) {
|
||||
if (this.maxValidator) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.maxValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
var msg = message || MongooseError.messages.Date.max;
|
||||
msg = msg.replace(/{MAX}/, (value === Date.now ? 'Date.now()' : this.cast(value).toString()));
|
||||
var _this = this;
|
||||
this.validators.push({
|
||||
validator: this.maxValidator = function(val) {
|
||||
var max = (value === Date.now ? value() : _this.cast(value));
|
||||
return val === null || val.valueOf() <= max.valueOf();
|
||||
},
|
||||
message: msg,
|
||||
type: 'max',
|
||||
max: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts to date
|
||||
*
|
||||
@@ -83,26 +210,34 @@ SchemaDate.prototype.checkRequired = function (value) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.cast = function (value) {
|
||||
if (value === null || value === '')
|
||||
SchemaDate.prototype.cast = function(value) {
|
||||
// If null or undefined
|
||||
if (value === null || value === void 0 || value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (value instanceof Date)
|
||||
if (value instanceof Date) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var date;
|
||||
|
||||
// support for timestamps
|
||||
if (value instanceof Number || 'number' == typeof value
|
||||
|| String(value) == Number(value))
|
||||
if (typeof value === 'boolean') {
|
||||
throw new CastError('date', value, this.path);
|
||||
}
|
||||
|
||||
if (value instanceof Number || typeof value === 'number'
|
||||
|| String(value) == Number(value)) {
|
||||
// support for timestamps
|
||||
date = new Date(Number(value));
|
||||
} else if (value.valueOf) {
|
||||
// support for moment.js
|
||||
date = new Date(value.valueOf());
|
||||
}
|
||||
|
||||
// support for date strings
|
||||
else if (value.toString)
|
||||
date = new Date(value.toString());
|
||||
|
||||
if (date.toString() != 'Invalid Date')
|
||||
if (!isNaN(date.valueOf())) {
|
||||
return date;
|
||||
}
|
||||
|
||||
throw new CastError('date', value, this.path);
|
||||
};
|
||||
@@ -113,27 +248,17 @@ SchemaDate.prototype.cast = function (value) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
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
|
||||
};
|
||||
SchemaDate.prototype.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {
|
||||
$gt: handleSingle,
|
||||
$gte: handleSingle,
|
||||
$lt: handleSingle,
|
||||
$lte: handleSingle
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
@@ -144,17 +269,17 @@ SchemaDate.prototype.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaDate.prototype.castForQuery = function ($conditional, val) {
|
||||
SchemaDate.prototype.castForQuery = function($conditional, val) {
|
||||
var handler;
|
||||
|
||||
if (2 !== arguments.length) {
|
||||
if (arguments.length !== 2) {
|
||||
return this.cast($conditional);
|
||||
}
|
||||
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
|
||||
if (!handler) {
|
||||
throw new Error("Can't use " + $conditional + " with Date.");
|
||||
throw new Error('Can\'t use ' + $conditional + ' with Date.');
|
||||
}
|
||||
|
||||
return handler.call(this, val);
|
||||
|
||||
237
node_modules/mongoose/lib/schema/documentarray.js
generated
vendored
237
node_modules/mongoose/lib/schema/documentarray.js
generated
vendored
@@ -1,13 +1,15 @@
|
||||
/* eslint no-empty: 1 */
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, ArrayType = require('./array')
|
||||
, MongooseDocumentArray = require('../types/documentarray')
|
||||
, Subdocument = require('../types/embedded')
|
||||
, Document = require('../document');
|
||||
var ArrayType = require('./array');
|
||||
var CastError = require('../error/cast');
|
||||
var MongooseDocumentArray = require('../types/documentarray');
|
||||
var SchemaType = require('../schematype');
|
||||
var Subdocument = require('../types/embedded');
|
||||
var util = require('util');
|
||||
|
||||
/**
|
||||
* SubdocsArray SchemaType constructor
|
||||
@@ -16,17 +18,16 @@ var SchemaType = require('../schematype')
|
||||
* @param {Schema} schema
|
||||
* @param {Object} options
|
||||
* @inherits SchemaArray
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function DocumentArray (key, schema, options) {
|
||||
|
||||
function DocumentArray(key, schema, options) {
|
||||
// compile an embedded document for this schema
|
||||
function EmbeddedDocument () {
|
||||
function EmbeddedDocument() {
|
||||
Subdocument.apply(this, arguments);
|
||||
}
|
||||
|
||||
EmbeddedDocument.prototype.__proto__ = Subdocument.prototype;
|
||||
EmbeddedDocument.prototype = Object.create(Subdocument.prototype);
|
||||
EmbeddedDocument.prototype.$__setSchema(schema);
|
||||
EmbeddedDocument.schema = schema;
|
||||
|
||||
@@ -36,30 +37,43 @@ function DocumentArray (key, schema, options) {
|
||||
}
|
||||
|
||||
// apply statics
|
||||
for (var i in schema.statics)
|
||||
for (i in schema.statics) {
|
||||
EmbeddedDocument[i] = schema.statics[i];
|
||||
}
|
||||
|
||||
EmbeddedDocument.options = options;
|
||||
this.schema = schema;
|
||||
|
||||
ArrayType.call(this, key, EmbeddedDocument, options);
|
||||
|
||||
this.schema = schema;
|
||||
this.$isMongooseDocumentArray = true;
|
||||
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);
|
||||
});
|
||||
};
|
||||
if (!('defaultValue' in this) || fn !== void 0) {
|
||||
this.default(function() {
|
||||
var arr = fn.call(this);
|
||||
if (!Array.isArray(arr)) {
|
||||
arr = [arr];
|
||||
}
|
||||
return new MongooseDocumentArray(arr, path, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
DocumentArray.schemaName = 'DocumentArray';
|
||||
|
||||
/*!
|
||||
* Inherits from ArrayType.
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.__proto__ = ArrayType.prototype;
|
||||
DocumentArray.prototype = Object.create(ArrayType.prototype);
|
||||
DocumentArray.prototype.constructor = DocumentArray;
|
||||
|
||||
/**
|
||||
* Performs local validations first, then validations on each embedded doc
|
||||
@@ -67,43 +81,109 @@ DocumentArray.prototype.__proto__ = ArrayType.prototype;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.doValidate = function (array, fn, scope) {
|
||||
var self = this;
|
||||
DocumentArray.prototype.doValidate = function(array, fn, scope, options) {
|
||||
var _this = this;
|
||||
SchemaType.prototype.doValidate.call(this, array, function(err) {
|
||||
if (err) {
|
||||
return fn(err);
|
||||
}
|
||||
|
||||
SchemaType.prototype.doValidate.call(this, array, function (err) {
|
||||
if (err) return fn(err);
|
||||
var count = array && array.length;
|
||||
var error;
|
||||
|
||||
var count = array && array.length
|
||||
, error;
|
||||
|
||||
if (!count) return fn();
|
||||
if (!count) {
|
||||
return fn();
|
||||
}
|
||||
if (options && options.updateValidator) {
|
||||
return fn();
|
||||
}
|
||||
|
||||
// handle sparse arrays, do not use array.forEach which does not
|
||||
// iterate over sparse elements yet reports array.length including
|
||||
// them :(
|
||||
|
||||
function callback(err) {
|
||||
if (err) {
|
||||
error = err;
|
||||
}
|
||||
--count || fn(error);
|
||||
}
|
||||
|
||||
for (var i = 0, len = count; i < len; ++i) {
|
||||
// sidestep sparse entries
|
||||
var doc = array[i];
|
||||
if (!doc) {
|
||||
--count || fn();
|
||||
--count || fn(error);
|
||||
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);
|
||||
// If you set the array index directly, the doc might not yet be
|
||||
// a full fledged mongoose subdoc, so make it into one.
|
||||
if (!(doc instanceof Subdocument)) {
|
||||
doc = array[i] = new _this.casterConstructor(doc, array, undefined,
|
||||
undefined, i);
|
||||
}
|
||||
|
||||
// HACK: use $__original_validate to avoid promises so bluebird doesn't
|
||||
// complain
|
||||
if (doc.$__original_validate) {
|
||||
doc.$__original_validate({__noPromise: true}, callback);
|
||||
} else {
|
||||
doc.validate({__noPromise: true}, callback);
|
||||
}
|
||||
}
|
||||
}, scope);
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs local validations first, then validations on each embedded doc.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* This method ignores the asynchronous validators.
|
||||
*
|
||||
* @return {MongooseError|undefined}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.doValidateSync = function(array, scope) {
|
||||
var schemaTypeError = SchemaType.prototype.doValidateSync.call(this, array, scope);
|
||||
if (schemaTypeError) {
|
||||
return schemaTypeError;
|
||||
}
|
||||
|
||||
var count = array && array.length,
|
||||
resultError = null;
|
||||
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// only first error
|
||||
if (resultError) {
|
||||
break;
|
||||
}
|
||||
// sidestep sparse entries
|
||||
var doc = array[i];
|
||||
if (!doc) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var subdocValidateError = doc.validateSync();
|
||||
|
||||
if (subdocValidateError) {
|
||||
resultError = subdocValidateError;
|
||||
}
|
||||
}
|
||||
|
||||
return resultError;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
*
|
||||
@@ -112,45 +192,78 @@ DocumentArray.prototype.doValidate = function (array, fn, scope) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
DocumentArray.prototype.cast = function (value, doc, init, prev) {
|
||||
var selected
|
||||
, subdoc
|
||||
, i
|
||||
DocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
||||
var selected,
|
||||
subdoc,
|
||||
i;
|
||||
|
||||
if (!Array.isArray(value)) {
|
||||
// gh-2442 mark whole array as modified if we're initializing a doc from
|
||||
// the db and the path isn't an array in the document
|
||||
if (!!doc && init) {
|
||||
doc.markModified(this.path);
|
||||
}
|
||||
return this.cast([value], doc, init, prev);
|
||||
}
|
||||
|
||||
if (!(value instanceof MongooseDocumentArray)) {
|
||||
if (!(value && value.isMongooseDocumentArray) &&
|
||||
(!options || !options.skipDocumentArrayCast)) {
|
||||
value = new MongooseDocumentArray(value, this.path, doc);
|
||||
if (prev && prev._handlers) {
|
||||
for (var key in prev._handlers) {
|
||||
doc.removeListener(key, prev._handlers[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i = value.length;
|
||||
|
||||
while (i--) {
|
||||
if (!value[i]) {
|
||||
continue;
|
||||
}
|
||||
// Check if the document has a different schema (re gh-3701)
|
||||
if ((value[i] instanceof Subdocument) &&
|
||||
value[i].schema !== this.casterConstructor.schema) {
|
||||
value[i] = value[i].toObject({virtuals: false});
|
||||
}
|
||||
if (!(value[i] instanceof Subdocument) && value[i]) {
|
||||
if (init) {
|
||||
selected || (selected = scopePaths(this, doc.$__.selected, init));
|
||||
subdoc = new this.casterConstructor(null, value, true, selected);
|
||||
subdoc = new this.casterConstructor(null, value, true, selected, i);
|
||||
value[i] = subdoc.init(value[i]);
|
||||
} else {
|
||||
if (prev && (subdoc = prev.id(value[i]._id))) {
|
||||
try {
|
||||
subdoc = prev.id(value[i]._id);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (prev && subdoc) {
|
||||
// handle resetting doc with existing id but differing data
|
||||
// doc.array = [{ doc: 'val' }]
|
||||
subdoc.set(value[i]);
|
||||
// if set() is hooked it will have no return value
|
||||
// see gh-746
|
||||
value[i] = subdoc;
|
||||
} else {
|
||||
subdoc = new this.casterConstructor(value[i], value);
|
||||
try {
|
||||
subdoc = new this.casterConstructor(value[i], value, undefined,
|
||||
undefined, i);
|
||||
// if set() is hooked it will have no return value
|
||||
// see gh-746
|
||||
value[i] = subdoc;
|
||||
} catch (error) {
|
||||
var valueInErrorMessage = util.inspect(value[i]);
|
||||
throw new CastError('embedded', valueInErrorMessage,
|
||||
value._path, error);
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -161,19 +274,21 @@ DocumentArray.prototype.cast = function (value, doc, init, prev) {
|
||||
* @param {Boolean|undefined} init - if we are being created part of a query result
|
||||
*/
|
||||
|
||||
function scopePaths (array, fields, init) {
|
||||
if (!(init && fields)) return undefined;
|
||||
function scopePaths(array, fields, init) {
|
||||
if (!(init && fields)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var path = array.path + '.'
|
||||
, keys = Object.keys(fields)
|
||||
, i = keys.length
|
||||
, selected = {}
|
||||
, hasKeys
|
||||
, key
|
||||
var path = array.path + '.',
|
||||
keys = Object.keys(fields),
|
||||
i = keys.length,
|
||||
selected = {},
|
||||
hasKeys,
|
||||
key;
|
||||
|
||||
while (i--) {
|
||||
key = keys[i];
|
||||
if (0 === key.indexOf(path)) {
|
||||
if (key.indexOf(path) === 0) {
|
||||
hasKeys || (hasKeys = true);
|
||||
selected[key.substring(path.length)] = fields[key];
|
||||
}
|
||||
|
||||
165
node_modules/mongoose/lib/schema/embedded.js
generated
vendored
165
node_modules/mongoose/lib/schema/embedded.js
generated
vendored
@@ -1,41 +1,170 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, errorMessages = require('../error').messages
|
||||
, utils = require('../utils')
|
||||
, Document
|
||||
var SchemaType = require('../schematype');
|
||||
var Subdocument = require('../types/subdocument');
|
||||
var castToNumber = require('./operators/helpers').castToNumber;
|
||||
var geospatial = require('./operators/geospatial');
|
||||
|
||||
module.exports = Embedded;
|
||||
|
||||
/**
|
||||
* EmbeddedDocument SchemaType constructor.
|
||||
* Sub-schema schematype constructor
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Embedded(schema, path, options) {
|
||||
var _embedded = function(value, path, parent) {
|
||||
var _this = this;
|
||||
Subdocument.apply(this, arguments);
|
||||
this.$parent = parent;
|
||||
if (parent) {
|
||||
parent.on('save', function() {
|
||||
_this.emit('save', _this);
|
||||
});
|
||||
|
||||
parent.on('isNew', function(val) {
|
||||
_this.isNew = val;
|
||||
_this.emit('isNew', val);
|
||||
});
|
||||
}
|
||||
};
|
||||
_embedded.prototype = Object.create(Subdocument.prototype);
|
||||
_embedded.prototype.$__setSchema(schema);
|
||||
_embedded.schema = schema;
|
||||
_embedded.$isSingleNested = true;
|
||||
_embedded.prototype.$basePath = path;
|
||||
|
||||
// apply methods
|
||||
for (var i in schema.methods) {
|
||||
_embedded.prototype[i] = schema.methods[i];
|
||||
}
|
||||
|
||||
// apply statics
|
||||
for (i in schema.statics) {
|
||||
_embedded[i] = schema.statics[i];
|
||||
}
|
||||
|
||||
this.caster = _embedded;
|
||||
this.schema = schema;
|
||||
this.$isSingleNested = true;
|
||||
SchemaType.call(this, path, options, 'Embedded');
|
||||
}
|
||||
|
||||
Embedded.prototype = Object.create(SchemaType.prototype);
|
||||
|
||||
/**
|
||||
* Special case for when users use a common location schema to represent
|
||||
* locations for use with $geoWithin.
|
||||
* https://docs.mongodb.org/manual/reference/operator/query/geoWithin/
|
||||
*
|
||||
* @param {Object} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function SchemaEmbedded (key, options, EmbeddedDoc, parentArray) {
|
||||
SchemaType.call(this, key, options, 'EmbeddedDocument');
|
||||
this.EmbeddedDoc = EmbeddedDoc;
|
||||
this.parentArray = parentArray;
|
||||
Embedded.prototype.$conditionalHandlers.$geoWithin = function(val) {
|
||||
return { $geometry: this.castForQuery(val.$geometry) };
|
||||
};
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
* ignore
|
||||
*/
|
||||
|
||||
SchemaEmbedded.prototype.__proto__ = SchemaType.prototype;
|
||||
Embedded.prototype.$conditionalHandlers.$near =
|
||||
Embedded.prototype.$conditionalHandlers.$nearSphere = geospatial.cast$near;
|
||||
|
||||
SchemaEmbedded.prototype.cast = function (value, doc, init) {
|
||||
return new this.EmbeddedDoc(value, this.parentArray);
|
||||
}
|
||||
Embedded.prototype.$conditionalHandlers.$within =
|
||||
Embedded.prototype.$conditionalHandlers.$geoWithin = geospatial.cast$within;
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
Embedded.prototype.$conditionalHandlers.$geoIntersects =
|
||||
geospatial.cast$geoIntersects;
|
||||
|
||||
Embedded.prototype.$conditionalHandlers.$minDistance = castToNumber;
|
||||
Embedded.prototype.$conditionalHandlers.$maxDistance = castToNumber;
|
||||
|
||||
/**
|
||||
* Casts contents
|
||||
*
|
||||
* @param {Object} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = SchemaEmbedded;
|
||||
Embedded.prototype.cast = function(val, doc, init) {
|
||||
if (val && val.$isSingleNested) {
|
||||
return val;
|
||||
}
|
||||
var subdoc = new this.caster(void 0, doc ? doc.$__.selected : void 0, doc);
|
||||
if (init) {
|
||||
subdoc.init(val);
|
||||
} else {
|
||||
subdoc.set(val, undefined, true);
|
||||
}
|
||||
return subdoc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Casts contents for query
|
||||
*
|
||||
* @param {string} [$conditional] optional query operator (like `$eq` or `$in`)
|
||||
* @param {any} value
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Embedded.prototype.castForQuery = function($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler) {
|
||||
throw new Error('Can\'t use ' + $conditional);
|
||||
}
|
||||
return handler.call(this, val);
|
||||
}
|
||||
val = $conditional;
|
||||
if (val == null) {
|
||||
return val;
|
||||
}
|
||||
return new this.caster(val).toObject({virtuals: false});
|
||||
};
|
||||
|
||||
/**
|
||||
* Async validation on this single nested doc.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Embedded.prototype.doValidate = function(value, fn) {
|
||||
SchemaType.prototype.doValidate.call(this, value, function(error) {
|
||||
if (error) {
|
||||
return fn(error);
|
||||
}
|
||||
if (!value) {
|
||||
return fn(null);
|
||||
}
|
||||
value.validate(fn, {__noPromise: true});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Synchronously validate this single nested doc
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Embedded.prototype.doValidateSync = function(value) {
|
||||
var schemaTypeError = SchemaType.prototype.doValidateSync.call(this, value);
|
||||
if (schemaTypeError) {
|
||||
return schemaTypeError;
|
||||
}
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
return value.validateSync();
|
||||
};
|
||||
|
||||
2
node_modules/mongoose/lib/schema/index.js
generated
vendored
2
node_modules/mongoose/lib/schema/index.js
generated
vendored
@@ -11,6 +11,8 @@ exports.Boolean = require('./boolean');
|
||||
|
||||
exports.DocumentArray = require('./documentarray');
|
||||
|
||||
exports.Embedded = require('./embedded');
|
||||
|
||||
exports.Array = require('./array');
|
||||
|
||||
exports.Buffer = require('./buffer');
|
||||
|
||||
51
node_modules/mongoose/lib/schema/mixed.js
generated
vendored
51
node_modules/mongoose/lib/schema/mixed.js
generated
vendored
@@ -1,4 +1,3 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
@@ -12,43 +11,39 @@ var utils = require('../utils');
|
||||
* @param {String} path
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Mixed (path, options) {
|
||||
function Mixed(path, options) {
|
||||
if (options && options.default) {
|
||||
var def = options.default;
|
||||
if (Array.isArray(def) && 0 === def.length) {
|
||||
if (Array.isArray(def) && def.length === 0) {
|
||||
// make sure empty array defaults are handled
|
||||
options.default = Array;
|
||||
} else if (!options.shared &&
|
||||
utils.isObject(def) &&
|
||||
0 === Object.keys(def).length) {
|
||||
} else if (!options.shared && utils.isObject(def) && Object.keys(def).length === 0) {
|
||||
// prevent odd "shared" objects between documents
|
||||
options.default = function () {
|
||||
return {}
|
||||
}
|
||||
options.default = function() {
|
||||
return {};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
SchemaType.call(this, path, options);
|
||||
};
|
||||
SchemaType.call(this, path, options, 'Mixed');
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
Mixed.schemaName = 'Mixed';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
Mixed.prototype.__proto__ = SchemaType.prototype;
|
||||
|
||||
/**
|
||||
* Required validator
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.checkRequired = function (val) {
|
||||
return true;
|
||||
};
|
||||
Mixed.prototype = Object.create(SchemaType.prototype);
|
||||
Mixed.prototype.constructor = Mixed;
|
||||
|
||||
/**
|
||||
* Casts `val` for Mixed.
|
||||
@@ -59,7 +54,7 @@ Mixed.prototype.checkRequired = function (val) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.cast = function (val) {
|
||||
Mixed.prototype.cast = function(val) {
|
||||
return val;
|
||||
};
|
||||
|
||||
@@ -71,8 +66,10 @@ Mixed.prototype.cast = function (val) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Mixed.prototype.castForQuery = function ($cond, val) {
|
||||
if (arguments.length === 2) return val;
|
||||
Mixed.prototype.castForQuery = function($cond, val) {
|
||||
if (arguments.length === 2) {
|
||||
return val;
|
||||
}
|
||||
return $cond;
|
||||
};
|
||||
|
||||
|
||||
199
node_modules/mongoose/lib/schema/number.js
generated
vendored
199
node_modules/mongoose/lib/schema/number.js
generated
vendored
@@ -2,10 +2,12 @@
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, utils = require('../utils')
|
||||
, Document
|
||||
var SchemaType = require('../schematype');
|
||||
var CastError = SchemaType.CastError;
|
||||
var handleBitwiseOperator = require('./operators/bitwise');
|
||||
var MongooseError = require('../error');
|
||||
var utils = require('../utils');
|
||||
var Document;
|
||||
|
||||
/**
|
||||
* Number SchemaType constructor.
|
||||
@@ -13,31 +15,41 @@ var SchemaType = require('../schematype')
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaNumber (key, options) {
|
||||
function SchemaNumber(key, options) {
|
||||
SchemaType.call(this, key, options, 'Number');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaNumber.schemaName = 'Number';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaNumber.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaNumber.prototype.constructor = SchemaNumber;
|
||||
|
||||
/**
|
||||
* Required validator for number
|
||||
* Check if the given value satisfies a required validator.
|
||||
*
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @param {Document} doc
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
SchemaNumber.prototype.checkRequired = function checkRequired(value, doc) {
|
||||
if (SchemaType._isRef(this, value, doc, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return typeof value == 'number' || value instanceof Number;
|
||||
return !!value;
|
||||
}
|
||||
return typeof value === 'number' || value instanceof Number;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,22 +66,41 @@ SchemaNumber.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MIN} token which will be replaced with the invalid value
|
||||
* var min = [10, 'The value of path `{PATH}` ({VALUE}) is beneath the limit ({MIN}).'];
|
||||
* var schema = new Schema({ n: { type: Number, min: min })
|
||||
* var M = mongoose.model('Measurement', schema);
|
||||
* var s= new M({ n: 4 });
|
||||
* s.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `n` (4) is beneath the limit (10).
|
||||
* })
|
||||
*
|
||||
* @param {Number} value minimum number
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.min = function (value) {
|
||||
SchemaNumber.prototype.min = function(value, message) {
|
||||
if (this.minValidator) {
|
||||
this.validators = this.validators.filter(function (v) {
|
||||
return 'min' != v[1];
|
||||
});
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.minValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
this.validators.push([this.minValidator = function (v) {
|
||||
return v === null || v >= value;
|
||||
}, 'min']);
|
||||
if (value !== null && value !== undefined) {
|
||||
var msg = message || MongooseError.messages.Number.min;
|
||||
msg = msg.replace(/{MIN}/, value);
|
||||
this.validators.push({
|
||||
validator: this.minValidator = function(v) {
|
||||
return v == null || v >= value;
|
||||
},
|
||||
message: msg,
|
||||
type: 'min',
|
||||
min: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -89,22 +120,41 @@ SchemaNumber.prototype.min = function (value) {
|
||||
* m.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MAX} token which will be replaced with the invalid value
|
||||
* var max = [10, 'The value of path `{PATH}` ({VALUE}) exceeds the limit ({MAX}).'];
|
||||
* var schema = new Schema({ n: { type: Number, max: max })
|
||||
* var M = mongoose.model('Measurement', schema);
|
||||
* var s= new M({ n: 4 });
|
||||
* s.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `n` (4) exceeds the limit (10).
|
||||
* })
|
||||
*
|
||||
* @param {Number} maximum number
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.max = function (value) {
|
||||
SchemaNumber.prototype.max = function(value, message) {
|
||||
if (this.maxValidator) {
|
||||
this.validators = this.validators.filter(function(v){
|
||||
return 'max' != v[1];
|
||||
});
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.maxValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
this.validators.push([this.maxValidator = function(v){
|
||||
return v === null || v <= value;
|
||||
}, 'max']);
|
||||
if (value !== null && value !== undefined) {
|
||||
var msg = message || MongooseError.messages.Number.max;
|
||||
msg = msg.replace(/{MAX}/, value);
|
||||
this.validators.push({
|
||||
validator: this.maxValidator = function(v) {
|
||||
return v == null || v <= value;
|
||||
},
|
||||
message: msg,
|
||||
type: 'max',
|
||||
max: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -119,11 +169,11 @@ SchemaNumber.prototype.max = function (value) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.cast = function (value, doc, init) {
|
||||
SchemaNumber.prototype.cast = function(value, doc, init) {
|
||||
if (SchemaType._isRef(this, value, doc, init)) {
|
||||
// wait! we may need to cast this to a document
|
||||
|
||||
if (null == value) {
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -136,7 +186,7 @@ SchemaNumber.prototype.cast = function (value, doc, init) {
|
||||
}
|
||||
|
||||
// setting a populated path
|
||||
if ('number' == typeof value) {
|
||||
if (typeof value === 'number') {
|
||||
return value;
|
||||
} else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
|
||||
throw new CastError('number', value, this.path);
|
||||
@@ -154,18 +204,27 @@ SchemaNumber.prototype.cast = function (value, doc, init) {
|
||||
}
|
||||
|
||||
var val = value && value._id
|
||||
? value._id // documents
|
||||
: value;
|
||||
? value._id // documents
|
||||
: value;
|
||||
|
||||
if (!isNaN(val)){
|
||||
if (null === val) return val;
|
||||
if ('' === val) return null;
|
||||
if ('string' == typeof val) val = Number(val);
|
||||
if (val instanceof Number) return val
|
||||
if ('number' == typeof val) return val;
|
||||
if (val.toString && !Array.isArray(val) &&
|
||||
val.toString() == Number(val)) {
|
||||
return new Number(val)
|
||||
if (!isNaN(val)) {
|
||||
if (val === null) {
|
||||
return val;
|
||||
}
|
||||
if (val === '') {
|
||||
return null;
|
||||
}
|
||||
if (typeof val === 'string' || typeof val === 'boolean') {
|
||||
val = Number(val);
|
||||
}
|
||||
if (val instanceof Number) {
|
||||
return val;
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
return val;
|
||||
}
|
||||
if (val.toString && !Array.isArray(val) && val.toString() == Number(val)) {
|
||||
return new Number(val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,28 +235,32 @@ SchemaNumber.prototype.cast = function (value, doc, init) {
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
return this.cast(val)
|
||||
function handleSingle(val) {
|
||||
return this.cast(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.cast(m)
|
||||
function handleArray(val) {
|
||||
var _this = this;
|
||||
if (!Array.isArray(val)) {
|
||||
return [this.cast(val)];
|
||||
}
|
||||
return val.map(function(m) {
|
||||
return _this.cast(m);
|
||||
});
|
||||
}
|
||||
|
||||
SchemaNumber.prototype.$conditionalHandlers = {
|
||||
'$lt' : handleSingle
|
||||
, '$lte': handleSingle
|
||||
, '$gt' : handleSingle
|
||||
, '$gte': handleSingle
|
||||
, '$ne' : handleSingle
|
||||
, '$in' : handleArray
|
||||
, '$nin': handleArray
|
||||
, '$mod': handleArray
|
||||
, '$all': handleArray
|
||||
};
|
||||
SchemaNumber.prototype.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {
|
||||
$bitsAllClear: handleBitwiseOperator,
|
||||
$bitsAnyClear: handleBitwiseOperator,
|
||||
$bitsAllSet: handleBitwiseOperator,
|
||||
$bitsAnySet: handleBitwiseOperator,
|
||||
$gt: handleSingle,
|
||||
$gte: handleSingle,
|
||||
$lt: handleSingle,
|
||||
$lte: handleSingle,
|
||||
$mod: handleArray
|
||||
});
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
@@ -207,17 +270,17 @@ SchemaNumber.prototype.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaNumber.prototype.castForQuery = function ($conditional, val) {
|
||||
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.");
|
||||
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
|
||||
}
|
||||
val = this.cast($conditional);
|
||||
return val;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
133
node_modules/mongoose/lib/schema/objectid.js
generated
vendored
133
node_modules/mongoose/lib/schema/objectid.js
generated
vendored
@@ -1,13 +1,14 @@
|
||||
/* eslint no-empty: 1 */
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, driver = global.MONGOOSE_DRIVER_PATH || './../drivers/node-mongodb-native'
|
||||
, oid = require('../types/objectid')
|
||||
, utils = require('../utils')
|
||||
, Document
|
||||
var SchemaType = require('../schematype'),
|
||||
CastError = SchemaType.CastError,
|
||||
oid = require('../types/objectid'),
|
||||
utils = require('../utils'),
|
||||
Document;
|
||||
|
||||
/**
|
||||
* ObjectId SchemaType constructor.
|
||||
@@ -15,18 +16,26 @@ var SchemaType = require('../schematype')
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function ObjectId (key, options) {
|
||||
function ObjectId(key, options) {
|
||||
SchemaType.call(this, key, options, 'ObjectID');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
ObjectId.schemaName = 'ObjectId';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
ObjectId.prototype.__proto__ = SchemaType.prototype;
|
||||
ObjectId.prototype = Object.create(SchemaType.prototype);
|
||||
ObjectId.prototype.constructor = ObjectId;
|
||||
|
||||
/**
|
||||
* Adds an auto-generated ObjectId default if turnOn is true.
|
||||
@@ -35,27 +44,29 @@ ObjectId.prototype.__proto__ = SchemaType.prototype;
|
||||
* @return {SchemaType} this
|
||||
*/
|
||||
|
||||
ObjectId.prototype.auto = function (turnOn) {
|
||||
ObjectId.prototype.auto = function(turnOn) {
|
||||
if (turnOn) {
|
||||
this.default(defaultId);
|
||||
this.set(resetId)
|
||||
this.set(resetId);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check required
|
||||
* Check if the given value satisfies a required validator.
|
||||
*
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @param {Document} doc
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
ObjectId.prototype.checkRequired = function checkRequired(value, doc) {
|
||||
if (SchemaType._isRef(this, value, doc, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return value instanceof oid;
|
||||
return !!value;
|
||||
}
|
||||
return value instanceof oid;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -67,11 +78,11 @@ ObjectId.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.cast = function (value, doc, init) {
|
||||
ObjectId.prototype.cast = function(value, doc, init) {
|
||||
if (SchemaType._isRef(this, value, doc, init)) {
|
||||
// wait! we may need to cast this to a document
|
||||
|
||||
if (null == value) {
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -96,22 +107,42 @@ ObjectId.prototype.cast = function (value, doc, init) {
|
||||
var path = doc.$__fullPath(this.path);
|
||||
var owner = doc.ownerDocument ? doc.ownerDocument() : doc;
|
||||
var pop = owner.populated(path, true);
|
||||
var ret = new pop.options.model(value);
|
||||
ret.$__.wasPopulated = true;
|
||||
var ret = value;
|
||||
if (!doc.$__.populated ||
|
||||
!doc.$__.populated[path] ||
|
||||
!doc.$__.populated[path].options ||
|
||||
!doc.$__.populated[path].options.options ||
|
||||
!doc.$__.populated[path].options.options.lean) {
|
||||
ret = new pop.options.model(value);
|
||||
ret.$__.wasPopulated = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value === null) return value;
|
||||
|
||||
if (value instanceof oid)
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value._id && value._id instanceof oid)
|
||||
return value._id;
|
||||
if (value instanceof oid) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value.toString) {
|
||||
if (value._id) {
|
||||
if (value._id instanceof oid) {
|
||||
return value._id;
|
||||
}
|
||||
if (value._id.toString instanceof Function) {
|
||||
try {
|
||||
return new oid(value._id.toString());
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.toString instanceof Function) {
|
||||
try {
|
||||
return oid.fromString(value.toString());
|
||||
return new oid(value.toString());
|
||||
} catch (err) {
|
||||
throw new CastError('ObjectId', value, this.path);
|
||||
}
|
||||
@@ -124,27 +155,17 @@ ObjectId.prototype.cast = function (value, doc, init) {
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
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
|
||||
};
|
||||
ObjectId.prototype.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {
|
||||
$gt: handleSingle,
|
||||
$gte: handleSingle,
|
||||
$lt: handleSingle,
|
||||
$lte: handleSingle
|
||||
});
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
@@ -154,27 +175,27 @@ ObjectId.prototype.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
ObjectId.prototype.castForQuery = function ($conditional, val) {
|
||||
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.");
|
||||
if (!handler) {
|
||||
throw new Error('Can\'t use ' + $conditional + ' with ObjectId.');
|
||||
}
|
||||
return handler.call(this, val);
|
||||
} else {
|
||||
return this.cast($conditional);
|
||||
}
|
||||
return this.cast($conditional);
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function defaultId () {
|
||||
function defaultId() {
|
||||
return new oid();
|
||||
};
|
||||
}
|
||||
|
||||
function resetId (v) {
|
||||
function resetId(v) {
|
||||
this.$__._id = null;
|
||||
return v;
|
||||
}
|
||||
|
||||
36
node_modules/mongoose/lib/schema/operators/bitwise.js
generated
vendored
Normal file
36
node_modules/mongoose/lib/schema/operators/bitwise.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var CastError = require('../../error/cast');
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleBitwiseOperator(val) {
|
||||
var _this = this;
|
||||
if (Array.isArray(val)) {
|
||||
return val.map(function(v) {
|
||||
return _castNumber(_this.path, v);
|
||||
});
|
||||
} else if (Buffer.isBuffer(val)) {
|
||||
return val;
|
||||
}
|
||||
// Assume trying to cast to number
|
||||
return _castNumber(_this.path, val);
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function _castNumber(path, num) {
|
||||
var v = Number(num);
|
||||
if (isNaN(v)) {
|
||||
throw new CastError('number', num, path);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
module.exports = handleBitwiseOperator;
|
||||
100
node_modules/mongoose/lib/schema/operators/geospatial.js
generated
vendored
Normal file
100
node_modules/mongoose/lib/schema/operators/geospatial.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var castArraysOfNumbers = require('./helpers').castArraysOfNumbers;
|
||||
var castToNumber = require('./helpers').castToNumber;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
exports.cast$geoIntersects = cast$geoIntersects;
|
||||
exports.cast$near = cast$near;
|
||||
exports.cast$within = cast$within;
|
||||
|
||||
function cast$near(val) {
|
||||
var SchemaArray = require('../array');
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
castArraysOfNumbers(val, this);
|
||||
return val;
|
||||
}
|
||||
|
||||
_castMinMaxDistance(this, val);
|
||||
|
||||
if (val && val.$geometry) {
|
||||
return cast$geometry(val, this);
|
||||
}
|
||||
|
||||
return SchemaArray.prototype.castForQuery.call(this, val);
|
||||
}
|
||||
|
||||
function cast$geometry(val, self) {
|
||||
switch (val.$geometry.type) {
|
||||
case 'Polygon':
|
||||
case 'LineString':
|
||||
case 'Point':
|
||||
castArraysOfNumbers(val.$geometry.coordinates, self);
|
||||
break;
|
||||
default:
|
||||
// ignore unknowns
|
||||
break;
|
||||
}
|
||||
|
||||
_castMinMaxDistance(this, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function cast$within(val) {
|
||||
_castMinMaxDistance(this, val);
|
||||
|
||||
if (val.$box || val.$polygon) {
|
||||
var type = val.$box ? '$box' : '$polygon';
|
||||
val[type].forEach(function(arr) {
|
||||
if (!Array.isArray(arr)) {
|
||||
var msg = 'Invalid $within $box argument. '
|
||||
+ 'Expected an array, received ' + arr;
|
||||
throw new TypeError(msg);
|
||||
}
|
||||
arr.forEach(function(v, i) {
|
||||
arr[i] = castToNumber.call(this, v);
|
||||
});
|
||||
});
|
||||
} else if (val.$center || val.$centerSphere) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
} else if (val.$geometry) {
|
||||
cast$geometry(val, this);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
function cast$geoIntersects(val) {
|
||||
var geo = val.$geometry;
|
||||
if (!geo) {
|
||||
return;
|
||||
}
|
||||
|
||||
cast$geometry(val, this);
|
||||
return val;
|
||||
}
|
||||
|
||||
function _castMinMaxDistance(self, val) {
|
||||
if (val.$maxDistance) {
|
||||
val.$maxDistance = castToNumber.call(self, val.$maxDistance);
|
||||
}
|
||||
if (val.$minDistance) {
|
||||
val.$minDistance = castToNumber.call(self, val.$minDistance);
|
||||
}
|
||||
}
|
||||
34
node_modules/mongoose/lib/schema/operators/helpers.js
generated
vendored
Normal file
34
node_modules/mongoose/lib/schema/operators/helpers.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module requirements.
|
||||
*/
|
||||
|
||||
var Types = {
|
||||
Number: require('../number')
|
||||
};
|
||||
|
||||
/*!
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
exports.castToNumber = castToNumber;
|
||||
exports.castArraysOfNumbers = castArraysOfNumbers;
|
||||
|
||||
/*!
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
function castToNumber(val) {
|
||||
return Types.Number.prototype.cast.call(this, val);
|
||||
}
|
||||
|
||||
function castArraysOfNumbers(arr, self) {
|
||||
arr.forEach(function(v, i) {
|
||||
if (Array.isArray(v)) {
|
||||
castArraysOfNumbers(v, self);
|
||||
} else {
|
||||
arr[i] = castToNumber.call(self, v);
|
||||
}
|
||||
});
|
||||
}
|
||||
380
node_modules/mongoose/lib/schema/string.js
generated
vendored
380
node_modules/mongoose/lib/schema/string.js
generated
vendored
@@ -1,12 +1,12 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var SchemaType = require('../schematype')
|
||||
, CastError = SchemaType.CastError
|
||||
, utils = require('../utils')
|
||||
, Document
|
||||
var SchemaType = require('../schematype');
|
||||
var CastError = SchemaType.CastError;
|
||||
var MongooseError = require('../error');
|
||||
var utils = require('../utils');
|
||||
var Document;
|
||||
|
||||
/**
|
||||
* String SchemaType constructor.
|
||||
@@ -14,67 +14,103 @@ var SchemaType = require('../schematype')
|
||||
* @param {String} key
|
||||
* @param {Object} options
|
||||
* @inherits SchemaType
|
||||
* @api private
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaString (key, options) {
|
||||
function SchemaString(key, options) {
|
||||
this.enumValues = [];
|
||||
this.regExp = null;
|
||||
SchemaType.call(this, key, options, 'String');
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This schema type's name, to defend against minifiers that mangle
|
||||
* function names.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
SchemaString.schemaName = 'String';
|
||||
|
||||
/*!
|
||||
* Inherits from SchemaType.
|
||||
*/
|
||||
|
||||
SchemaString.prototype.__proto__ = SchemaType.prototype;
|
||||
SchemaString.prototype = Object.create(SchemaType.prototype);
|
||||
SchemaString.prototype.constructor = SchemaString;
|
||||
|
||||
/**
|
||||
* Adds enumeration values and a coinciding validator.
|
||||
* Adds an enum validator
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var states = 'opening open closing closed'.split(' ')
|
||||
* var s = new Schema({ state: { type: String, enum: states })
|
||||
* 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
|
||||
* console.error(String(err)) // ValidationError: `invalid` is not a valid enum value for path `state`.
|
||||
* m.state = 'open'
|
||||
* m.save() // success
|
||||
* m.save(callback) // success
|
||||
* })
|
||||
*
|
||||
* @param {String} [args...] enumeration values
|
||||
* // or with custom error messages
|
||||
* var enu = {
|
||||
* values: 'opening open closing closed'.split(' '),
|
||||
* message: 'enum validator failed for path `{PATH}` with value `{VALUE}`'
|
||||
* }
|
||||
* var s = new Schema({ state: { type: String, enum: enu })
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ state: 'invalid' })
|
||||
* m.save(function (err) {
|
||||
* console.error(String(err)) // ValidationError: enum validator failed for path `state` with value `invalid`
|
||||
* m.state = 'open'
|
||||
* m.save(callback) // success
|
||||
* })
|
||||
*
|
||||
* @param {String|Object} [args...] enumeration values
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.enum = function () {
|
||||
var len = arguments.length;
|
||||
SchemaString.prototype.enum = function() {
|
||||
if (this.enumValidator) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.enumValidator;
|
||||
}, this);
|
||||
this.enumValidator = false;
|
||||
}
|
||||
|
||||
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';
|
||||
});
|
||||
}
|
||||
if (arguments[0] === void 0 || arguments[0] === false) {
|
||||
return this;
|
||||
}
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (undefined !== arguments[i]) {
|
||||
this.enumValues.push(this.cast(arguments[i]));
|
||||
var values;
|
||||
var errorMessage;
|
||||
|
||||
if (utils.isObject(arguments[0])) {
|
||||
values = arguments[0].values;
|
||||
errorMessage = arguments[0].message;
|
||||
} else {
|
||||
values = arguments;
|
||||
errorMessage = MongooseError.messages.String.enum;
|
||||
}
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
if (undefined !== values[i]) {
|
||||
this.enumValues.push(this.cast(values[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.enumValidator) {
|
||||
var values = this.enumValues;
|
||||
this.enumValidator = function(v){
|
||||
return undefined === v || ~values.indexOf(v);
|
||||
};
|
||||
this.validators.push([this.enumValidator, 'enum']);
|
||||
}
|
||||
var vals = this.enumValues;
|
||||
this.enumValidator = function(v) {
|
||||
return undefined === v || ~vals.indexOf(v);
|
||||
};
|
||||
this.validators.push({
|
||||
validator: this.enumValidator,
|
||||
message: errorMessage,
|
||||
type: 'enum',
|
||||
enumValues: vals
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -93,10 +129,14 @@ SchemaString.prototype.enum = function () {
|
||||
* @return {SchemaType} this
|
||||
*/
|
||||
|
||||
SchemaString.prototype.lowercase = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.toLowerCase();
|
||||
SchemaString.prototype.lowercase = function() {
|
||||
return this.set(function(v, self) {
|
||||
if (typeof v !== 'string') {
|
||||
v = self.cast(v);
|
||||
}
|
||||
if (v) {
|
||||
return v.toLowerCase();
|
||||
}
|
||||
return v;
|
||||
});
|
||||
};
|
||||
@@ -115,10 +155,14 @@ SchemaString.prototype.lowercase = function () {
|
||||
* @return {SchemaType} this
|
||||
*/
|
||||
|
||||
SchemaString.prototype.uppercase = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.toUpperCase();
|
||||
SchemaString.prototype.uppercase = function() {
|
||||
return this.set(function(v, self) {
|
||||
if (typeof v !== 'string') {
|
||||
v = self.cast(v);
|
||||
}
|
||||
if (v) {
|
||||
return v.toUpperCase();
|
||||
}
|
||||
return v;
|
||||
});
|
||||
};
|
||||
@@ -141,14 +185,126 @@ SchemaString.prototype.uppercase = function () {
|
||||
* @return {SchemaType} this
|
||||
*/
|
||||
|
||||
SchemaString.prototype.trim = function () {
|
||||
return this.set(function (v, self) {
|
||||
if ('string' != typeof v) v = self.cast(v)
|
||||
if (v) return v.trim();
|
||||
SchemaString.prototype.trim = function() {
|
||||
return this.set(function(v, self) {
|
||||
if (typeof v !== 'string') {
|
||||
v = self.cast(v);
|
||||
}
|
||||
if (v && self.options.trim) {
|
||||
return v.trim();
|
||||
}
|
||||
return v;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a minimum length validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var schema = new Schema({ postalCode: { type: String, minlength: 5 })
|
||||
* var Address = db.model('Address', schema)
|
||||
* var address = new Address({ postalCode: '9512' })
|
||||
* address.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* address.postalCode = '95125';
|
||||
* address.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MINLENGTH} token which will be replaced with the minimum allowed length
|
||||
* var minlength = [5, 'The value of path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).'];
|
||||
* var schema = new Schema({ postalCode: { type: String, minlength: minlength })
|
||||
* var Address = mongoose.model('Address', schema);
|
||||
* var address = new Address({ postalCode: '9512' });
|
||||
* address.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512`) is shorter than the minimum length (5).
|
||||
* })
|
||||
*
|
||||
* @param {Number} value minimum string length
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.minlength = function(value, message) {
|
||||
if (this.minlengthValidator) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.minlengthValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value !== null && value !== undefined) {
|
||||
var msg = message || MongooseError.messages.String.minlength;
|
||||
msg = msg.replace(/{MINLENGTH}/, value);
|
||||
this.validators.push({
|
||||
validator: this.minlengthValidator = function(v) {
|
||||
return v === null || v.length >= value;
|
||||
},
|
||||
message: msg,
|
||||
type: 'minlength',
|
||||
minlength: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a maximum length validator.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var schema = new Schema({ postalCode: { type: String, maxlength: 9 })
|
||||
* var Address = db.model('Address', schema)
|
||||
* var address = new Address({ postalCode: '9512512345' })
|
||||
* address.save(function (err) {
|
||||
* console.error(err) // validator error
|
||||
* address.postalCode = '95125';
|
||||
* address.save() // success
|
||||
* })
|
||||
*
|
||||
* // custom error messages
|
||||
* // We can also use the special {MAXLENGTH} token which will be replaced with the maximum allowed length
|
||||
* var maxlength = [9, 'The value of path `{PATH}` (`{VALUE}`) exceeds the maximum allowed length ({MAXLENGTH}).'];
|
||||
* var schema = new Schema({ postalCode: { type: String, maxlength: maxlength })
|
||||
* var Address = mongoose.model('Address', schema);
|
||||
* var address = new Address({ postalCode: '9512512345' });
|
||||
* address.validate(function (err) {
|
||||
* console.log(String(err)) // ValidationError: The value of path `postalCode` (`9512512345`) exceeds the maximum allowed length (9).
|
||||
* })
|
||||
*
|
||||
* @param {Number} value maximum string length
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.maxlength = function(value, message) {
|
||||
if (this.maxlengthValidator) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.maxlengthValidator;
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (value !== null && value !== undefined) {
|
||||
var msg = message || MongooseError.messages.String.maxlength;
|
||||
msg = msg.replace(/{MAXLENGTH}/, value);
|
||||
this.validators.push({
|
||||
validator: this.maxlengthValidator = function(v) {
|
||||
return v === null || v.length <= value;
|
||||
},
|
||||
message: msg,
|
||||
type: 'maxlength',
|
||||
maxlength: value
|
||||
});
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a regexp validator.
|
||||
*
|
||||
@@ -158,43 +314,74 @@ SchemaString.prototype.trim = function () {
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, match: /^a/ }})
|
||||
* var M = db.model('M', s)
|
||||
* var m = new M({ name: 'invalid' })
|
||||
* var m = new M({ name: 'I am invalid' })
|
||||
* m.validate(function (err) {
|
||||
* console.error(err) // validation error
|
||||
* console.error(String(err)) // "ValidationError: Path `name` is invalid (I am invalid)."
|
||||
* m.name = 'apples'
|
||||
* m.validate(function (err) {
|
||||
* assert.ok(err) // success
|
||||
* })
|
||||
* })
|
||||
*
|
||||
* // using a custom error message
|
||||
* var match = [ /\.html$/, "That file doesn't end in .html ({VALUE})" ];
|
||||
* var s = new Schema({ file: { type: String, match: match }})
|
||||
* var M = db.model('M', s);
|
||||
* var m = new M({ file: 'invalid' });
|
||||
* m.validate(function (err) {
|
||||
* console.log(String(err)) // "ValidationError: That file doesn't end in .html (invalid)"
|
||||
* })
|
||||
*
|
||||
* Empty strings, `undefined`, and `null` values always pass the match validator. If you require these values, enable the `required` validator also.
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, match: /^a/, required: true }})
|
||||
*
|
||||
* @param {RegExp} regExp regular expression to test against
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.match = function match (regExp) {
|
||||
this.validators.push([function(v){
|
||||
return null != v && '' !== v
|
||||
? regExp.test(v)
|
||||
: true
|
||||
}, 'regexp']);
|
||||
SchemaString.prototype.match = function match(regExp, message) {
|
||||
// yes, we allow multiple match validators
|
||||
|
||||
var msg = message || MongooseError.messages.String.match;
|
||||
|
||||
var matchValidator = function(v) {
|
||||
if (!regExp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var ret = ((v != null && v !== '')
|
||||
? regExp.test(v)
|
||||
: true);
|
||||
return ret;
|
||||
};
|
||||
|
||||
this.validators.push({
|
||||
validator: matchValidator,
|
||||
message: msg,
|
||||
type: 'regexp',
|
||||
regexp: regExp
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check required
|
||||
* Check if the given value satisfies a required validator.
|
||||
*
|
||||
* @param {String|null|undefined} value
|
||||
* @api private
|
||||
* @param {Any} value
|
||||
* @param {Document} doc
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaString.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
SchemaString.prototype.checkRequired = function checkRequired(value, doc) {
|
||||
if (SchemaType._isRef(this, value, doc, true)) {
|
||||
return null != value;
|
||||
} else {
|
||||
return (value instanceof String || typeof value == 'string') && value.length;
|
||||
return !!value;
|
||||
}
|
||||
return (value instanceof String || typeof value === 'string') && value.length;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -203,11 +390,11 @@ SchemaString.prototype.checkRequired = function checkRequired (value, doc) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaString.prototype.cast = function (value, doc, init) {
|
||||
SchemaString.prototype.cast = function(value, doc, init) {
|
||||
if (SchemaType._isRef(this, value, doc, init)) {
|
||||
// wait! we may need to cast this to a document
|
||||
|
||||
if (null == value) {
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -220,7 +407,7 @@ SchemaString.prototype.cast = function (value, doc, init) {
|
||||
}
|
||||
|
||||
// setting a populated path
|
||||
if ('string' == typeof value) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
} else if (Buffer.isBuffer(value) || !utils.isObject(value)) {
|
||||
throw new CastError('string', value, this.path);
|
||||
@@ -237,21 +424,25 @@ SchemaString.prototype.cast = function (value, doc, init) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
// If null or undefined
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if ('undefined' !== typeof value) {
|
||||
if (typeof value !== 'undefined') {
|
||||
// handle documents being passed
|
||||
if (value._id && 'string' == typeof value._id) {
|
||||
if (value._id && typeof value._id === 'string') {
|
||||
return value._id;
|
||||
}
|
||||
if (value.toString) {
|
||||
|
||||
// Re: gh-647 and gh-3030, we're ok with casting using `toString()`
|
||||
// **unless** its the default Object.toString, because "[object Object]"
|
||||
// doesn't really qualify as useful data
|
||||
if (value.toString && value.toString !== Object.prototype.toString) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new CastError('string', value, this.path);
|
||||
};
|
||||
|
||||
@@ -259,29 +450,30 @@ SchemaString.prototype.cast = function (value, doc, init) {
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle (val) {
|
||||
function handleSingle(val) {
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
|
||||
function handleArray (val) {
|
||||
var self = this;
|
||||
return val.map(function (m) {
|
||||
return self.castForQuery(m);
|
||||
function handleArray(val) {
|
||||
var _this = this;
|
||||
if (!Array.isArray(val)) {
|
||||
return [this.castForQuery(val)];
|
||||
}
|
||||
return val.map(function(m) {
|
||||
return _this.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
|
||||
};
|
||||
SchemaString.prototype.$conditionalHandlers =
|
||||
utils.options(SchemaType.prototype.$conditionalHandlers, {
|
||||
$all: handleArray,
|
||||
$gt: handleSingle,
|
||||
$gte: handleSingle,
|
||||
$lt: handleSingle,
|
||||
$lte: handleSingle,
|
||||
$options: handleSingle,
|
||||
$regex: handleSingle
|
||||
});
|
||||
|
||||
/**
|
||||
* Casts contents for queries.
|
||||
@@ -291,18 +483,20 @@ SchemaString.prototype.$conditionalHandlers = {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaString.prototype.castForQuery = function ($conditional, val) {
|
||||
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.");
|
||||
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);
|
||||
}
|
||||
val = $conditional;
|
||||
if (Object.prototype.toString.call(val) === '[object RegExp]') {
|
||||
return val;
|
||||
}
|
||||
return this.cast(val);
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
34
node_modules/mongoose/lib/schemadefault.js
generated
vendored
34
node_modules/mongoose/lib/schemadefault.js
generated
vendored
@@ -1,34 +0,0 @@
|
||||
|
||||
/*!
|
||||
* 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 });
|
||||
546
node_modules/mongoose/lib/schematype.js
generated
vendored
546
node_modules/mongoose/lib/schematype.js
generated
vendored
@@ -3,8 +3,9 @@
|
||||
*/
|
||||
|
||||
var utils = require('./utils');
|
||||
var CastError = require('./error').CastError;
|
||||
var ValidatorError = require('./error').ValidatorError;
|
||||
var MongooseError = require('./error');
|
||||
var CastError = MongooseError.CastError;
|
||||
var ValidatorError = MongooseError.ValidatorError;
|
||||
|
||||
/**
|
||||
* SchemaType constructor
|
||||
@@ -15,7 +16,7 @@ var ValidatorError = require('./error').ValidatorError;
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function SchemaType (path, options, instance) {
|
||||
function SchemaType(path, options, instance) {
|
||||
this.path = path;
|
||||
this.instance = instance;
|
||||
this.validators = [];
|
||||
@@ -25,17 +26,21 @@ function SchemaType (path, options, instance) {
|
||||
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;
|
||||
for (var i in options) {
|
||||
if (this[i] && typeof this[i] === 'function') {
|
||||
// { unique: true, index: true }
|
||||
if (i === 'index' && this._index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var opts = Array.isArray(options[i])
|
||||
? options[i]
|
||||
: [options[i]];
|
||||
var opts = Array.isArray(options[i])
|
||||
? options[i]
|
||||
: [options[i]];
|
||||
|
||||
this[i].apply(this, opts);
|
||||
this[i].apply(this, opts);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default value for this SchemaType.
|
||||
@@ -52,22 +57,42 @@ function SchemaType (path, options, instance) {
|
||||
* ####Example:
|
||||
*
|
||||
* // values are cast:
|
||||
* var schema = new Schema({ aNumber: Number, default: "4.815162342" })
|
||||
* var schema = new Schema({ aNumber: { type: Number, default: 4.815162342 }})
|
||||
* var M = db.model('M', schema)
|
||||
* var m = new M;
|
||||
* console.log(m.aNumber, typeof m.aNumber) // 4.815162342 "number"
|
||||
* 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;
|
||||
SchemaType.prototype.default = function(val) {
|
||||
if (arguments.length === 1) {
|
||||
if (val === void 0) {
|
||||
this.defaultValue = void 0;
|
||||
return void 0;
|
||||
}
|
||||
this.defaultValue = val;
|
||||
return this.defaultValue;
|
||||
} else if (arguments.length > 1) {
|
||||
this.defaultValue = utils.args(arguments);
|
||||
}
|
||||
@@ -99,7 +124,7 @@ SchemaType.prototype.default = function (val) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.index = function (options) {
|
||||
SchemaType.prototype.index = function(options) {
|
||||
this._index = options;
|
||||
utils.expires(this._index);
|
||||
return this;
|
||||
@@ -110,7 +135,7 @@ SchemaType.prototype.index = function (options) {
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ name: { type: String, unique: true })
|
||||
* 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._
|
||||
@@ -120,17 +145,48 @@ SchemaType.prototype.index = function (options) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.unique = function (bool) {
|
||||
if (null == this._index || 'boolean' == typeof this._index) {
|
||||
SchemaType.prototype.unique = function(bool) {
|
||||
if (this._index === false) {
|
||||
if (!bool) {
|
||||
return;
|
||||
}
|
||||
throw new Error('Path "' + this.path + '" may not have `index` set to ' +
|
||||
'false and `unique` set to true');
|
||||
}
|
||||
if (this._index == null || this._index === true) {
|
||||
this._index = {};
|
||||
} else if ('string' == typeof this._index) {
|
||||
this._index = { type: this._index };
|
||||
} else if (typeof this._index === 'string') {
|
||||
this._index = {type: this._index};
|
||||
}
|
||||
|
||||
this._index.unique = bool;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares a full text index.
|
||||
*
|
||||
* ###Example:
|
||||
*
|
||||
* var s = new Schema({name : {type: String, text : true })
|
||||
* Schema.path('name').index({text : true});
|
||||
* @param {Boolean} bool
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.text = function(bool) {
|
||||
if (this._index === null || this._index === undefined ||
|
||||
typeof this._index === 'boolean') {
|
||||
this._index = {};
|
||||
} else if (typeof this._index === 'string') {
|
||||
this._index = {type: this._index};
|
||||
}
|
||||
|
||||
this._index.text = bool;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Declares a sparse index.
|
||||
*
|
||||
@@ -144,11 +200,12 @@ SchemaType.prototype.unique = function (bool) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.sparse = function (bool) {
|
||||
if (null == this._index || 'boolean' == typeof this._index) {
|
||||
SchemaType.prototype.sparse = function(bool) {
|
||||
if (this._index === null || this._index === undefined ||
|
||||
typeof this._index === 'boolean') {
|
||||
this._index = {};
|
||||
} else if ('string' == typeof this._index) {
|
||||
this._index = { type: this._index };
|
||||
} else if (typeof this._index === 'string') {
|
||||
this._index = {type: this._index};
|
||||
}
|
||||
|
||||
this._index.sparse = bool;
|
||||
@@ -161,7 +218,7 @@ SchemaType.prototype.sparse = function (bool) {
|
||||
* ####Example:
|
||||
*
|
||||
* function capitalize (val) {
|
||||
* if ('string' != typeof val) val = '';
|
||||
* if (typeof val !== 'string') val = '';
|
||||
* return val.charAt(0).toUpperCase() + val.substring(1);
|
||||
* }
|
||||
*
|
||||
@@ -228,9 +285,10 @@ SchemaType.prototype.sparse = function (bool) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.set = function (fn) {
|
||||
if ('function' != typeof fn)
|
||||
SchemaType.prototype.set = function(fn) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError('A setter must be a function.');
|
||||
}
|
||||
this.setters.push(fn);
|
||||
return this;
|
||||
};
|
||||
@@ -297,9 +355,10 @@ SchemaType.prototype.set = function (fn) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.get = function (fn) {
|
||||
if ('function' != typeof fn)
|
||||
SchemaType.prototype.get = function(fn) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError('A getter must be a function.');
|
||||
}
|
||||
this.getters.push(fn);
|
||||
return this;
|
||||
};
|
||||
@@ -307,43 +366,60 @@ SchemaType.prototype.get = function (fn) {
|
||||
/**
|
||||
* 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.
|
||||
* Validators always receive the value to validate as their first argument and must return `Boolean`. Returning `false` means validation failed.
|
||||
*
|
||||
* The error message argument is optional. If not passed, the [default generic error message template](#error_messages_MongooseError-messages) will be used.
|
||||
*
|
||||
* ####Examples:
|
||||
*
|
||||
* // make sure every value is equal to "something"
|
||||
* function validator (val) {
|
||||
* return val == 'something';
|
||||
* }
|
||||
*
|
||||
* new Schema({ name: { type: String, validate: validator }});
|
||||
*
|
||||
* // with a custom error message
|
||||
*
|
||||
* var custom = [validator, 'validation failed']
|
||||
* var custom = [validator, 'Uh oh, {PATH} does not equal "something".']
|
||||
* new Schema({ name: { type: String, validate: custom }});
|
||||
*
|
||||
* // adding many validators at a time
|
||||
*
|
||||
* var many = [
|
||||
* { validator: validator, msg: 'uh oh' }
|
||||
* , { validator: fn, msg: 'failed' }
|
||||
* , { validator: anotherValidator, 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');
|
||||
* schema.path('name').validate(validator, 'validation of `{PATH}` failed with value `{VALUE}`');
|
||||
*
|
||||
* ####Error message templates:
|
||||
*
|
||||
* From the examples above, you may have noticed that error messages support basic templating. There are a few other template keywords besides `{PATH}` and `{VALUE}` too. To find out more, details are available [here](#error_messages_MongooseError-messages)
|
||||
*
|
||||
* ####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.
|
||||
* Passing a validator function that receives two arguments tells mongoose that the validator is an asynchronous validator. The first argument passed to the validator function is the value being validated. The second argument is a callback function that must called when you finish validating the value and passed either `true` or `false` to communicate either success or failure respectively.
|
||||
*
|
||||
* schema.path('name').validate(function (value, respond) {
|
||||
* doStuff(value, function () {
|
||||
* ...
|
||||
* respond(false); // validation failed
|
||||
* })
|
||||
* }, 'my error type');
|
||||
*
|
||||
* }, '{PATH} failed validation.');
|
||||
*
|
||||
* // or with dynamic message
|
||||
*
|
||||
* schema.path('name').validate(function (value, respond) {
|
||||
* doStuff(value, function () {
|
||||
* ...
|
||||
* respond(false, 'this message gets to the validation error');
|
||||
* });
|
||||
* }, 'this message does not matter');
|
||||
*
|
||||
* 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).
|
||||
@@ -363,71 +439,133 @@ SchemaType.prototype.get = function (fn) {
|
||||
* Product.on('error', handleError);
|
||||
*
|
||||
* @param {RegExp|Function|Object} obj validator
|
||||
* @param {String} [error] optional error message
|
||||
* @param {String} [errorMsg] optional error message
|
||||
* @param {String} [type] optional validator type
|
||||
* @return {SchemaType} this
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.validate = function (obj, error) {
|
||||
if ('function' == typeof obj || obj && 'RegExp' === obj.constructor.name) {
|
||||
this.validators.push([obj, error]);
|
||||
SchemaType.prototype.validate = function(obj, message, type) {
|
||||
if (typeof obj === 'function' || obj && utils.getFunctionName(obj.constructor) === 'RegExp') {
|
||||
var properties;
|
||||
if (message instanceof Object && !type) {
|
||||
properties = utils.clone(message);
|
||||
if (!properties.message) {
|
||||
properties.message = properties.msg;
|
||||
}
|
||||
properties.validator = obj;
|
||||
properties.type = properties.type || 'user defined';
|
||||
} else {
|
||||
if (!message) {
|
||||
message = MongooseError.messages.general.default;
|
||||
}
|
||||
if (!type) {
|
||||
type = 'user defined';
|
||||
}
|
||||
properties = {message: message, type: type, validator: obj};
|
||||
}
|
||||
this.validators.push(properties);
|
||||
return this;
|
||||
}
|
||||
|
||||
var i = arguments.length
|
||||
, arg
|
||||
var i,
|
||||
length,
|
||||
arg;
|
||||
|
||||
while (i--) {
|
||||
for (i = 0, length = arguments.length; i < length; i++) {
|
||||
arg = arguments[i];
|
||||
if (!(arg && 'Object' == arg.constructor.name)) {
|
||||
if (!(arg && utils.getFunctionName(arg.constructor) === 'Object')) {
|
||||
var msg = 'Invalid validator. Received (' + typeof arg + ') '
|
||||
+ arg
|
||||
+ '. See http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate';
|
||||
+ arg
|
||||
+ '. See http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate';
|
||||
|
||||
throw new Error(msg);
|
||||
}
|
||||
this.validate(arg.validator, arg.msg);
|
||||
this.validate(arg.validator, arg);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a required validator to this schematype.
|
||||
* Adds a required validator to this SchemaType. The validator gets added
|
||||
* to the front of this SchemaType's validators array using `unshift()`.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var s = new Schema({ born: { type: Date, required: true })
|
||||
* // or
|
||||
*
|
||||
* // or with custom error message
|
||||
*
|
||||
* var s = new Schema({ born: { type: Date, required: '{PATH} is required!' })
|
||||
*
|
||||
* // or through the path API
|
||||
*
|
||||
* Schema.path('name').required(true);
|
||||
*
|
||||
* // with custom error messaging
|
||||
*
|
||||
* Schema.path('name').required(true, 'grrr :( ');
|
||||
*
|
||||
* // or make a path conditionally required based on a function
|
||||
* var isOver18 = function() { return this.age >= 18; };
|
||||
* Schema.path('voterRegistrationId').required(isOver18);
|
||||
*
|
||||
* The required validator uses the SchemaType's `checkRequired` function to
|
||||
* determine whether a given value satisfies the required validator. By default,
|
||||
* a value satisfies the required validator if `val != null` (that is, if
|
||||
* the value is not null nor undefined). However, most built-in mongoose schema
|
||||
* types override the default `checkRequired` function:
|
||||
*
|
||||
* @param {Boolean} required enable/disable the validator
|
||||
* @param {String} [message] optional custom error message
|
||||
* @return {SchemaType} this
|
||||
* @see Customized Error Messages #error_messages_MongooseError-messages
|
||||
* @see SchemaArray#checkRequired #schema_array_SchemaArray.checkRequired
|
||||
* @see SchemaBoolean#checkRequired #schema_boolean_SchemaBoolean-checkRequired
|
||||
* @see SchemaBuffer#checkRequired #schema_buffer_SchemaBuffer.schemaName
|
||||
* @see SchemaNumber#checkRequired #schema_number_SchemaNumber-min
|
||||
* @see SchemaObjectId#checkRequired #schema_objectid_ObjectId-auto
|
||||
* @see SchemaString#checkRequired #schema_string_SchemaString-checkRequired
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.required = function (required) {
|
||||
var self = this;
|
||||
SchemaType.prototype.required = function(required, message) {
|
||||
if (required === false) {
|
||||
this.validators = this.validators.filter(function(v) {
|
||||
return v.validator !== this.requiredValidator;
|
||||
}, this);
|
||||
|
||||
function __checkRequired (v) {
|
||||
this.isRequired = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
this.isRequired = true;
|
||||
|
||||
this.requiredValidator = function(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, this);
|
||||
if ('isSelected' in this && !this.isSelected(_this.path) && !this.isModified(_this.path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((typeof required === 'function') && !required.apply(this)) ||
|
||||
_this.checkRequired(v, this);
|
||||
};
|
||||
this.originalRequiredValue = required;
|
||||
|
||||
if (typeof required === 'string') {
|
||||
message = required;
|
||||
required = undefined;
|
||||
}
|
||||
|
||||
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']);
|
||||
}
|
||||
var msg = message || MongooseError.messages.general.required;
|
||||
this.validators.unshift({
|
||||
validator: this.requiredValidator,
|
||||
message: msg,
|
||||
type: 'required'
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -440,16 +578,19 @@ SchemaType.prototype.required = function (required) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.getDefault = function (scope, init) {
|
||||
var ret = 'function' === typeof this.defaultValue
|
||||
? this.defaultValue.call(scope)
|
||||
: this.defaultValue;
|
||||
SchemaType.prototype.getDefault = function(scope, init) {
|
||||
var ret = typeof this.defaultValue === 'function'
|
||||
? this.defaultValue.call(scope)
|
||||
: this.defaultValue;
|
||||
|
||||
if (null !== ret && undefined !== ret) {
|
||||
return this.cast(ret, scope, init);
|
||||
} else {
|
||||
return ret;
|
||||
if (ret !== null && ret !== undefined) {
|
||||
var casted = this.cast(ret, scope, init);
|
||||
if (casted && casted.$isSingleNested) {
|
||||
casted.$parent = scope;
|
||||
}
|
||||
return casted;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -461,30 +602,30 @@ SchemaType.prototype.getDefault = function (scope, init) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
|
||||
if (SchemaType._isRef(this, value, scope, init)) {
|
||||
return init
|
||||
? value
|
||||
: this.cast(value, scope, init, priorVal);
|
||||
}
|
||||
|
||||
var v = value
|
||||
, setters = this.setters
|
||||
, len = setters.length
|
||||
|
||||
if (!len) {
|
||||
if (null === v || undefined === v) return v;
|
||||
return this.cast(v, scope, init, priorVal)
|
||||
}
|
||||
SchemaType.prototype.applySetters = function(value, scope, init, priorVal, options) {
|
||||
var v = value,
|
||||
setters = this.setters,
|
||||
len = setters.length,
|
||||
caster = this.caster;
|
||||
|
||||
while (len--) {
|
||||
v = setters[len].call(scope, v, this);
|
||||
}
|
||||
|
||||
if (null === v || undefined === v) return v;
|
||||
if (Array.isArray(v) && caster && caster.setters) {
|
||||
var newVal = [];
|
||||
for (var i = 0; i < v.length; i++) {
|
||||
newVal.push(caster.applySetters(v[i], scope, init, priorVal));
|
||||
}
|
||||
v = newVal;
|
||||
}
|
||||
|
||||
if (v === null || v === undefined) {
|
||||
return v;
|
||||
}
|
||||
|
||||
// do not cast until all setters are applied #665
|
||||
v = this.cast(v, scope, init, priorVal);
|
||||
v = this.cast(v, scope, init, priorVal, options);
|
||||
|
||||
return v;
|
||||
};
|
||||
@@ -497,12 +638,10 @@ SchemaType.prototype.applySetters = function (value, scope, init, priorVal) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.applyGetters = function (value, scope) {
|
||||
if (SchemaType._isRef(this, value, scope, true)) return value;
|
||||
|
||||
var v = value
|
||||
, getters = this.getters
|
||||
, len = getters.length;
|
||||
SchemaType.prototype.applyGetters = function(value, scope) {
|
||||
var v = value,
|
||||
getters = this.getters,
|
||||
len = getters.length;
|
||||
|
||||
if (!len) {
|
||||
return v;
|
||||
@@ -532,10 +671,10 @@ SchemaType.prototype.applyGetters = function (value, scope) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
SchemaType.prototype.select = function select (val) {
|
||||
this.selected = !! val;
|
||||
SchemaType.prototype.select = function select(val) {
|
||||
this.selected = !!val;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a validation of `value` using the validators declared for this SchemaType.
|
||||
@@ -546,40 +685,125 @@ SchemaType.prototype.select = function select (val) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.doValidate = function (value, fn, scope) {
|
||||
var err = false
|
||||
, path = this.path
|
||||
, count = this.validators.length;
|
||||
SchemaType.prototype.doValidate = function(value, fn, scope) {
|
||||
var err = false,
|
||||
path = this.path,
|
||||
count = this.validators.length;
|
||||
|
||||
if (!count) return fn(null);
|
||||
if (!count) {
|
||||
return fn(null);
|
||||
}
|
||||
|
||||
function validate (ok, msg, val) {
|
||||
if (err) return;
|
||||
var validate = function(ok, validatorProperties) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
if (ok === undefined || ok) {
|
||||
--count || fn(null);
|
||||
} else {
|
||||
fn(err = new ValidatorError(path, msg, val));
|
||||
err = new ValidatorError(validatorProperties);
|
||||
fn(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.validators.forEach(function (v) {
|
||||
var validator = v[0]
|
||||
, message = v[1];
|
||||
var _this = this;
|
||||
this.validators.forEach(function(v) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
var validator = v.validator;
|
||||
|
||||
var validatorProperties = utils.clone(v);
|
||||
validatorProperties.path = path;
|
||||
validatorProperties.value = value;
|
||||
|
||||
if (validator instanceof RegExp) {
|
||||
validate(validator.test(value), message, value);
|
||||
} else if ('function' === typeof validator) {
|
||||
if (2 === validator.length) {
|
||||
validator.call(scope, value, function (ok) {
|
||||
validate(ok, message, value);
|
||||
validate(validator.test(value), validatorProperties);
|
||||
} else if (typeof validator === 'function') {
|
||||
if (value === undefined && !_this.isRequired) {
|
||||
validate(true, validatorProperties);
|
||||
return;
|
||||
}
|
||||
if (validator.length === 2) {
|
||||
var returnVal = validator.call(scope, value, function(ok, customMsg) {
|
||||
if (typeof returnVal === 'boolean') {
|
||||
return;
|
||||
}
|
||||
if (customMsg) {
|
||||
validatorProperties.message = customMsg;
|
||||
}
|
||||
validate(ok, validatorProperties);
|
||||
});
|
||||
if (typeof returnVal === 'boolean') {
|
||||
validate(returnVal, validatorProperties);
|
||||
}
|
||||
} else {
|
||||
validate(validator.call(scope, value), message, value);
|
||||
validate(validator.call(scope, value), validatorProperties);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs a validation of `value` using the validators declared for this SchemaType.
|
||||
*
|
||||
* ####Note:
|
||||
*
|
||||
* This method ignores the asynchronous validators.
|
||||
*
|
||||
* @param {any} value
|
||||
* @param {Object} scope
|
||||
* @return {MongooseError|undefined}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.doValidateSync = function(value, scope) {
|
||||
var err = null,
|
||||
path = this.path,
|
||||
count = this.validators.length;
|
||||
|
||||
if (!count) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var validate = function(ok, validatorProperties) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
if (ok !== undefined && !ok) {
|
||||
err = new ValidatorError(validatorProperties);
|
||||
}
|
||||
};
|
||||
|
||||
var _this = this;
|
||||
if (value === undefined && !_this.isRequired) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.validators.forEach(function(v) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
var validator = v.validator;
|
||||
var validatorProperties = utils.clone(v);
|
||||
validatorProperties.path = path;
|
||||
validatorProperties.value = value;
|
||||
|
||||
if (validator instanceof RegExp) {
|
||||
validate(validator.test(value), validatorProperties);
|
||||
} else if (typeof validator === 'function') {
|
||||
// if not async validators
|
||||
if (validator.length !== 2) {
|
||||
validate(validator.call(scope, value), validatorProperties);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return err;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if value is a valid Reference.
|
||||
*
|
||||
@@ -591,7 +815,7 @@ SchemaType.prototype.doValidate = function (value, fn, scope) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType._isRef = function (self, value, doc, init) {
|
||||
SchemaType._isRef = function(self, value, doc, init) {
|
||||
// fast path
|
||||
var ref = init && self.options && self.options.ref;
|
||||
|
||||
@@ -605,18 +829,86 @@ SchemaType._isRef = function (self, value, doc, init) {
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
if (null == value) return true;
|
||||
if (value == null) {
|
||||
return true;
|
||||
}
|
||||
if (!Buffer.isBuffer(value) && // buffers are objects too
|
||||
'Binary' != value._bsontype // raw binary value from the db
|
||||
value._bsontype !== 'Binary' // raw binary value from the db
|
||||
&& utils.isObject(value) // might have deselected _id in population query
|
||||
) {
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleSingle(val) {
|
||||
return this.castForQuery(val);
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function handleArray(val) {
|
||||
var _this = this;
|
||||
if (!Array.isArray(val)) {
|
||||
return [this.castForQuery(val)];
|
||||
}
|
||||
return val.map(function(m) {
|
||||
return _this.castForQuery(m);
|
||||
});
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
SchemaType.prototype.$conditionalHandlers = {
|
||||
$all: handleArray,
|
||||
$eq: handleSingle,
|
||||
$in: handleArray,
|
||||
$ne: handleSingle,
|
||||
$nin: handleArray
|
||||
};
|
||||
|
||||
/**
|
||||
* Cast the given value with the given optional query operator.
|
||||
*
|
||||
* @param {String} [$conditional] query operator, like `$eq` or `$in`
|
||||
* @param {any} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.castForQuery = function($conditional, val) {
|
||||
var handler;
|
||||
if (arguments.length === 2) {
|
||||
handler = this.$conditionalHandlers[$conditional];
|
||||
if (!handler) {
|
||||
throw new Error('Can\'t use ' + $conditional);
|
||||
}
|
||||
return handler.call(this, val);
|
||||
}
|
||||
val = $conditional;
|
||||
return this.cast(val);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default check for if this path satisfies the `required` validator.
|
||||
*
|
||||
* @param {any} val
|
||||
* @api private
|
||||
*/
|
||||
|
||||
SchemaType.prototype.checkRequired = function(val) {
|
||||
return val != null;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
*/
|
||||
|
||||
83
node_modules/mongoose/lib/services/common.js
generated
vendored
Normal file
83
node_modules/mongoose/lib/services/common.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
'use strict';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var ObjectId = require('../types/objectid');
|
||||
var utils = require('../utils');
|
||||
|
||||
exports.flatten = flatten;
|
||||
exports.modifiedPaths = modifiedPaths;
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function flatten(update, path, options) {
|
||||
var keys = Object.keys(update || {});
|
||||
var numKeys = keys.length;
|
||||
var result = {};
|
||||
path = path ? path + '.' : '';
|
||||
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
var key = keys[i];
|
||||
var val = update[key];
|
||||
if (utils.isMongooseObject(val) && !Buffer.isBuffer(val)) {
|
||||
val = val.toObject({ virtuals: false });
|
||||
}
|
||||
if (shouldFlatten(val)) {
|
||||
result[path + key] = val;
|
||||
if (options && options.skipArrays && Array.isArray(val)) {
|
||||
continue;
|
||||
}
|
||||
var flat = flatten(val, path + key);
|
||||
for (var k in flat) {
|
||||
result[k] = flat[k];
|
||||
}
|
||||
if (Array.isArray(val)) {
|
||||
result[path + key] = val;
|
||||
}
|
||||
} else {
|
||||
result[path + key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function modifiedPaths(update, path, result) {
|
||||
var keys = Object.keys(update || {});
|
||||
var numKeys = keys.length;
|
||||
result = result || {};
|
||||
path = path ? path + '.' : '';
|
||||
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
var key = keys[i];
|
||||
var val = update[key];
|
||||
|
||||
result[path + key] = true;
|
||||
if (shouldFlatten(val)) {
|
||||
modifiedPaths(val, path + key, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function shouldFlatten(val) {
|
||||
return val &&
|
||||
typeof val === 'object' &&
|
||||
!(val instanceof Date) &&
|
||||
!(val instanceof ObjectId) &&
|
||||
(!Array.isArray(val) || val.length > 0) &&
|
||||
!(val instanceof Buffer);
|
||||
}
|
||||
112
node_modules/mongoose/lib/services/setDefaultsOnInsert.js
generated
vendored
Normal file
112
node_modules/mongoose/lib/services/setDefaultsOnInsert.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict';
|
||||
|
||||
var flatten = require('./common').flatten;
|
||||
var modifiedPaths = require('./common').modifiedPaths;
|
||||
|
||||
/**
|
||||
* Applies defaults to update and findOneAndUpdate operations.
|
||||
*
|
||||
* @param {Query} query
|
||||
* @param {Schema} schema
|
||||
* @param {Object} castedDoc
|
||||
* @param {Object} options
|
||||
* @method setDefaultsOnInsert
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function(query, schema, castedDoc, options) {
|
||||
var keys = Object.keys(castedDoc || {});
|
||||
var updatedKeys = {};
|
||||
var updatedValues = {};
|
||||
var numKeys = keys.length;
|
||||
var hasDollarUpdate = false;
|
||||
var modified = {};
|
||||
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
if (keys[i].charAt(0) === '$') {
|
||||
modifiedPaths(castedDoc[keys[i]], '', modified);
|
||||
var flat = flatten(castedDoc[keys[i]]);
|
||||
var paths = Object.keys(flat);
|
||||
var numPaths = paths.length;
|
||||
for (var j = 0; j < numPaths; ++j) {
|
||||
var updatedPath = paths[j].replace('.$.', '.0.');
|
||||
updatedPath = updatedPath.replace(/\.\$$/, '.0');
|
||||
if (keys[i] === '$set' || keys[i] === '$setOnInsert') {
|
||||
updatedValues[updatedPath] = flat[paths[j]];
|
||||
} else if (keys[i] === '$unset') {
|
||||
updatedValues[updatedPath] = undefined;
|
||||
}
|
||||
updatedKeys[updatedPath] = true;
|
||||
}
|
||||
hasDollarUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDollarUpdate) {
|
||||
modifiedPaths(castedDoc, '', modified);
|
||||
updatedValues = flatten(castedDoc);
|
||||
updatedKeys = Object.keys(updatedValues);
|
||||
}
|
||||
|
||||
if (options && options.upsert) {
|
||||
paths = Object.keys(query._conditions);
|
||||
numPaths = keys.length;
|
||||
for (i = 0; i < numPaths; ++i) {
|
||||
var path = paths[i];
|
||||
var condition = query._conditions[path];
|
||||
if (condition && typeof condition === 'object') {
|
||||
var conditionKeys = Object.keys(condition);
|
||||
var numConditionKeys = conditionKeys.length;
|
||||
var hasDollarKey = false;
|
||||
for (j = 0; j < numConditionKeys; ++j) {
|
||||
if (conditionKeys[j].charAt(0) === '$') {
|
||||
hasDollarKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasDollarKey) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
updatedKeys[path] = true;
|
||||
modified[path] = true;
|
||||
}
|
||||
|
||||
if (options.setDefaultsOnInsert) {
|
||||
schema.eachPath(function(path, schemaType) {
|
||||
if (path === '_id') {
|
||||
// Ignore _id for now because it causes bugs in 2.4
|
||||
return;
|
||||
}
|
||||
if (schemaType.$isSingleNested) {
|
||||
// Only handle nested schemas 1-level deep to avoid infinite
|
||||
// recursion re: https://github.com/mongodb-js/mongoose-autopopulate/issues/11
|
||||
schemaType.schema.eachPath(function(_path, _schemaType) {
|
||||
if (path === '_id') {
|
||||
// Ignore _id for now because it causes bugs in 2.4
|
||||
return;
|
||||
}
|
||||
|
||||
var def = _schemaType.getDefault(null, true);
|
||||
if (!modified[path + '.' + _path] && typeof def !== 'undefined') {
|
||||
castedDoc = castedDoc || {};
|
||||
castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
|
||||
castedDoc.$setOnInsert[path + '.' + _path] = def;
|
||||
updatedValues[path + '.' + _path] = def;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var def = schemaType.getDefault(null, true);
|
||||
if (!modified[path] && typeof def !== 'undefined') {
|
||||
castedDoc = castedDoc || {};
|
||||
castedDoc.$setOnInsert = castedDoc.$setOnInsert || {};
|
||||
castedDoc.$setOnInsert[path] = def;
|
||||
updatedValues[path] = def;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return castedDoc;
|
||||
};
|
||||
101
node_modules/mongoose/lib/services/updateValidators.js
generated
vendored
Normal file
101
node_modules/mongoose/lib/services/updateValidators.js
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Mixed = require('../schema/mixed');
|
||||
var ValidationError = require('../error/validation');
|
||||
var async = require('async');
|
||||
var flatten = require('./common').flatten;
|
||||
var modifiedPaths = require('./common').modifiedPaths;
|
||||
|
||||
/**
|
||||
* Applies validators and defaults to update and findOneAndUpdate operations,
|
||||
* specifically passing a null doc as `this` to validators and defaults
|
||||
*
|
||||
* @param {Query} query
|
||||
* @param {Schema} schema
|
||||
* @param {Object} castedDoc
|
||||
* @param {Object} options
|
||||
* @method runValidatorsOnUpdate
|
||||
* @api private
|
||||
*/
|
||||
|
||||
module.exports = function(query, schema, castedDoc, options) {
|
||||
var keys = Object.keys(castedDoc || {});
|
||||
var updatedKeys = {};
|
||||
var updatedValues = {};
|
||||
var numKeys = keys.length;
|
||||
var hasDollarUpdate = false;
|
||||
var modified = {};
|
||||
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
if (keys[i].charAt(0) === '$') {
|
||||
modifiedPaths(castedDoc[keys[i]], '', modified);
|
||||
var flat = flatten(castedDoc[keys[i]]);
|
||||
var paths = Object.keys(flat);
|
||||
var numPaths = paths.length;
|
||||
for (var j = 0; j < numPaths; ++j) {
|
||||
var updatedPath = paths[j].replace('.$.', '.0.');
|
||||
updatedPath = updatedPath.replace(/\.\$$/, '.0');
|
||||
if (keys[i] === '$set' || keys[i] === '$setOnInsert') {
|
||||
updatedValues[updatedPath] = flat[paths[j]];
|
||||
} else if (keys[i] === '$unset') {
|
||||
updatedValues[updatedPath] = undefined;
|
||||
}
|
||||
updatedKeys[updatedPath] = true;
|
||||
}
|
||||
hasDollarUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDollarUpdate) {
|
||||
modifiedPaths(castedDoc, '', modified);
|
||||
updatedValues = flatten(castedDoc);
|
||||
updatedKeys = Object.keys(updatedValues);
|
||||
}
|
||||
|
||||
var updates = Object.keys(updatedValues);
|
||||
var numUpdates = updates.length;
|
||||
var validatorsToExecute = [];
|
||||
var validationErrors = [];
|
||||
function iter(i) {
|
||||
var schemaPath = schema._getSchema(updates[i]);
|
||||
if (schemaPath) {
|
||||
// gh-4305: `_getSchema()` will report all sub-fields of a 'Mixed' path
|
||||
// as 'Mixed', so avoid double validating them.
|
||||
if (schemaPath instanceof Mixed && schemaPath.path !== updates[i]) {
|
||||
return;
|
||||
}
|
||||
|
||||
validatorsToExecute.push(function(callback) {
|
||||
schemaPath.doValidate(
|
||||
updatedValues[updates[i]],
|
||||
function(err) {
|
||||
if (err) {
|
||||
err.path = updates[i];
|
||||
validationErrors.push(err);
|
||||
}
|
||||
callback(null);
|
||||
},
|
||||
options && options.context === 'query' ? query : null,
|
||||
{updateValidator: true});
|
||||
});
|
||||
}
|
||||
}
|
||||
for (i = 0; i < numUpdates; ++i) {
|
||||
iter(i);
|
||||
}
|
||||
|
||||
return function(callback) {
|
||||
async.parallel(validatorsToExecute, function() {
|
||||
if (validationErrors.length) {
|
||||
var err = new ValidationError(null);
|
||||
for (var i = 0; i < validationErrors.length; ++i) {
|
||||
err.errors[validationErrors[i].path] = validationErrors[i];
|
||||
}
|
||||
return callback(err);
|
||||
}
|
||||
callback(null);
|
||||
});
|
||||
};
|
||||
};
|
||||
77
node_modules/mongoose/lib/statemachine.js
generated
vendored
77
node_modules/mongoose/lib/statemachine.js
generated
vendored
@@ -12,10 +12,8 @@ var utils = require('./utils');
|
||||
* @api private
|
||||
*/
|
||||
|
||||
var StateMachine = module.exports = exports = function StateMachine () {
|
||||
this.paths = {};
|
||||
this.states = {};
|
||||
}
|
||||
var StateMachine = module.exports = exports = function StateMachine() {
|
||||
};
|
||||
|
||||
/*!
|
||||
* StateMachine.ctor('state1', 'state2', ...)
|
||||
@@ -31,15 +29,17 @@ var StateMachine = module.exports = exports = function StateMachine () {
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.ctor = function () {
|
||||
StateMachine.ctor = function() {
|
||||
var states = utils.args(arguments);
|
||||
|
||||
var ctor = function () {
|
||||
var ctor = function() {
|
||||
StateMachine.apply(this, arguments);
|
||||
this.paths = {};
|
||||
this.states = {};
|
||||
this.stateNames = states;
|
||||
|
||||
var i = states.length
|
||||
, state;
|
||||
var i = states.length,
|
||||
state;
|
||||
|
||||
while (i--) {
|
||||
state = states[i];
|
||||
@@ -47,13 +47,13 @@ StateMachine.ctor = function () {
|
||||
}
|
||||
};
|
||||
|
||||
ctor.prototype.__proto__ = StateMachine.prototype;
|
||||
ctor.prototype = new StateMachine();
|
||||
|
||||
states.forEach(function (state) {
|
||||
states.forEach(function(state) {
|
||||
// Changes the `path`'s state to `state`.
|
||||
ctor.prototype[state] = function (path) {
|
||||
ctor.prototype[state] = function(path) {
|
||||
this._changeState(path, state);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return ctor;
|
||||
@@ -69,29 +69,29 @@ StateMachine.ctor = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
StateMachine.prototype._changeState = function _changeState (path, nextState) {
|
||||
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
|
||||
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`
|
||||
@@ -101,13 +101,13 @@ StateMachine.prototype.clear = function clear (state) {
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.some = function some () {
|
||||
var self = this;
|
||||
StateMachine.prototype.some = function some() {
|
||||
var _this = this;
|
||||
var what = arguments.length ? arguments : this.stateNames;
|
||||
return Array.prototype.some.call(what, function (state) {
|
||||
return Object.keys(self.states[state]).length;
|
||||
return Array.prototype.some.call(what, function(state) {
|
||||
return Object.keys(_this.states[state]).length;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* This function builds the functions that get assigned to `forEach` and `map`,
|
||||
@@ -118,25 +118,25 @@ StateMachine.prototype.some = function some () {
|
||||
* @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];
|
||||
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 _this = this;
|
||||
|
||||
var paths = states.reduce(function (paths, state) {
|
||||
return paths.concat(Object.keys(self.states[state]));
|
||||
var paths = states.reduce(function(paths, state) {
|
||||
return paths.concat(Object.keys(_this.states[state]));
|
||||
}, []);
|
||||
|
||||
return paths[iterMethod](function (path, i, paths) {
|
||||
return paths[iterMethod](function(path, i, paths) {
|
||||
return callback(path, i, paths);
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Iterates over the paths that belong to one of the parameter states.
|
||||
@@ -152,10 +152,10 @@ StateMachine.prototype._iter = function _iter (iterMethod) {
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.forEach = function forEach () {
|
||||
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.
|
||||
@@ -172,8 +172,7 @@ StateMachine.prototype.forEach = function forEach () {
|
||||
* @private
|
||||
*/
|
||||
|
||||
StateMachine.prototype.map = function map () {
|
||||
StateMachine.prototype.map = function map() {
|
||||
this.map = this._iter('map');
|
||||
return this.map.apply(this, arguments);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
1262
node_modules/mongoose/lib/types/array.js
generated
vendored
1262
node_modules/mongoose/lib/types/array.js
generated
vendored
File diff suppressed because it is too large
Load Diff
241
node_modules/mongoose/lib/types/buffer.js
generated
vendored
241
node_modules/mongoose/lib/types/buffer.js
generated
vendored
@@ -1,15 +1,9 @@
|
||||
|
||||
/*!
|
||||
* Access driver.
|
||||
*/
|
||||
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Binary = require(driver + '/binary');
|
||||
var Binary = require('../drivers').Binary,
|
||||
utils = require('../utils');
|
||||
|
||||
/**
|
||||
* Mongoose Buffer constructor.
|
||||
@@ -24,11 +18,11 @@ var Binary = require(driver + '/binary');
|
||||
* @see http://bit.ly/f6CnZU
|
||||
*/
|
||||
|
||||
function MongooseBuffer (value, encode, offset) {
|
||||
function MongooseBuffer(value, encode, offset) {
|
||||
var length = arguments.length;
|
||||
var val;
|
||||
|
||||
if (0 === length || null === arguments[0] || undefined === arguments[0]) {
|
||||
if (length === 0 || arguments[0] === null || arguments[0] === undefined) {
|
||||
val = 0;
|
||||
} else {
|
||||
val = value;
|
||||
@@ -47,111 +41,136 @@ function MongooseBuffer (value, encode, offset) {
|
||||
}
|
||||
|
||||
var buf = new Buffer(val, encoding, offset);
|
||||
buf.__proto__ = MongooseBuffer.prototype;
|
||||
utils.decorate(buf, MongooseBuffer.mixin);
|
||||
buf.isMongooseBuffer = true;
|
||||
|
||||
// make sure these internal props don't show up in Object.keys()
|
||||
Object.defineProperties(buf, {
|
||||
validators: { value: [] }
|
||||
, _path: { value: path }
|
||||
, _parent: { value: doc }
|
||||
validators: {value: []},
|
||||
_path: {value: path},
|
||||
_parent: {value: doc}
|
||||
});
|
||||
|
||||
if (doc && "string" === typeof path) {
|
||||
if (doc && typeof path === 'string') {
|
||||
Object.defineProperty(buf, '_schema', {
|
||||
value: doc.schema.path(path)
|
||||
value: doc.schema.path(path)
|
||||
});
|
||||
}
|
||||
|
||||
buf._subtype = 0;
|
||||
return buf;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from Buffer.
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype = new Buffer(0);
|
||||
// MongooseBuffer.prototype = new Buffer(0);
|
||||
|
||||
/**
|
||||
* Parent owner document
|
||||
*
|
||||
* @api private
|
||||
* @property _parent
|
||||
*/
|
||||
MongooseBuffer.mixin = {
|
||||
|
||||
MongooseBuffer.prototype._parent;
|
||||
/**
|
||||
* Parent owner document
|
||||
*
|
||||
* @api private
|
||||
* @property _parent
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marks this buffer as modified.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
_parent: undefined,
|
||||
|
||||
MongooseBuffer.prototype._markModified = function () {
|
||||
var parent = this._parent;
|
||||
/**
|
||||
* Default subtype for the Binary representing this Buffer
|
||||
*
|
||||
* @api private
|
||||
* @property _subtype
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
if (parent) {
|
||||
parent.markModified(this._path);
|
||||
_subtype: undefined,
|
||||
|
||||
/**
|
||||
* Marks this buffer as modified.
|
||||
*
|
||||
* @api private
|
||||
* @method _markModified
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
_markModified: function() {
|
||||
var parent = this._parent;
|
||||
|
||||
if (parent) {
|
||||
parent.markModified(this._path);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the buffer.
|
||||
*
|
||||
* @api public
|
||||
* @method write
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
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 {Number} The number of bytes copied.
|
||||
* @param {Buffer} target
|
||||
* @method copy
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
copy: function(target) {
|
||||
var ret = Buffer.prototype.copy.apply(this, arguments);
|
||||
|
||||
if (target && target.isMongooseBuffer) {
|
||||
target._markModified();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
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 ' +
|
||||
'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;'
|
||||
)
|
||||
'writeUInt16LE writeUInt16BE writeUInt32LE writeUInt32BE ' +
|
||||
'writeInt16LE writeInt16BE writeInt32LE writeInt32BE ' +
|
||||
'writeFloatLE writeFloatBE writeDoubleLE writeDoubleBE'
|
||||
).split(' ').forEach(function(method) {
|
||||
if (!Buffer.prototype[method]) {
|
||||
return;
|
||||
}
|
||||
MongooseBuffer.mixin[method] = function() {
|
||||
var ret = Buffer.prototype[method].apply(this, arguments);
|
||||
this._markModified();
|
||||
return ret;
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -173,12 +192,14 @@ MongooseBuffer.prototype.copy = function (target) {
|
||||
* @param {Hex} [subtype]
|
||||
* @return {Binary}
|
||||
* @api public
|
||||
* @method toObject
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype.toObject = function (options) {
|
||||
var subtype = 'number' == typeof options
|
||||
? options
|
||||
: (this._subtype || 0x00);
|
||||
MongooseBuffer.mixin.toObject = function(options) {
|
||||
var subtype = typeof options === 'number'
|
||||
? options
|
||||
: (this._subtype || 0);
|
||||
return new Binary(this, subtype);
|
||||
};
|
||||
|
||||
@@ -187,9 +208,11 @@ MongooseBuffer.prototype.toObject = function (options) {
|
||||
*
|
||||
* @param {Buffer} other
|
||||
* @return {Boolean}
|
||||
* @method equals
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
MongooseBuffer.prototype.equals = function (other) {
|
||||
MongooseBuffer.mixin.equals = function(other) {
|
||||
if (!Buffer.isBuffer(other)) {
|
||||
return false;
|
||||
}
|
||||
@@ -199,11 +222,47 @@ MongooseBuffer.prototype.equals = function (other) {
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.length; ++i) {
|
||||
if (this[i] !== other[i]) return false;
|
||||
if (this[i] !== other[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the subtype option and marks the buffer modified.
|
||||
*
|
||||
* ####SubTypes:
|
||||
*
|
||||
* var bson = require('bson')
|
||||
* bson.BSON_BINARY_SUBTYPE_DEFAULT
|
||||
* bson.BSON_BINARY_SUBTYPE_FUNCTION
|
||||
* bson.BSON_BINARY_SUBTYPE_BYTE_ARRAY
|
||||
* bson.BSON_BINARY_SUBTYPE_UUID
|
||||
* bson.BSON_BINARY_SUBTYPE_MD5
|
||||
* bson.BSON_BINARY_SUBTYPE_USER_DEFINED
|
||||
*
|
||||
* doc.buffer.subtype(bson.BSON_BINARY_SUBTYPE_UUID);
|
||||
*
|
||||
* @see http://bsonspec.org/#/specification
|
||||
* @param {Hex} subtype
|
||||
* @api public
|
||||
* @method subtype
|
||||
* @receiver MongooseBuffer
|
||||
*/
|
||||
|
||||
MongooseBuffer.mixin.subtype = function(subtype) {
|
||||
if (typeof subtype !== 'number') {
|
||||
throw new TypeError('Invalid subtype. Expected a number');
|
||||
}
|
||||
|
||||
if (this._subtype !== subtype) {
|
||||
this._markModified();
|
||||
}
|
||||
|
||||
this._subtype = subtype;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
|
||||
352
node_modules/mongoose/lib/types/documentarray.js
generated
vendored
352
node_modules/mongoose/lib/types/documentarray.js
generated
vendored
@@ -1,15 +1,12 @@
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var MongooseArray = require('./array')
|
||||
, driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native'
|
||||
, ObjectId = require(driver + '/objectid')
|
||||
, ObjectIdSchema = require('../schema/objectid')
|
||||
, utils = require('../utils')
|
||||
, util = require('util')
|
||||
, Document = require('../document')
|
||||
var MongooseArray = require('./array'),
|
||||
ObjectId = require('./objectid'),
|
||||
ObjectIdSchema = require('../schema/objectid'),
|
||||
utils = require('../utils'),
|
||||
Document = require('../document');
|
||||
|
||||
/**
|
||||
* DocumentArray constructor
|
||||
@@ -23,168 +20,229 @@ var MongooseArray = require('./array')
|
||||
* @see http://bit.ly/f6CnZU
|
||||
*/
|
||||
|
||||
function MongooseDocumentArray (values, path, doc) {
|
||||
var arr = [];
|
||||
function MongooseDocumentArray(values, path, doc) {
|
||||
var arr = [].concat(values);
|
||||
arr._path = path;
|
||||
|
||||
var props = {
|
||||
isMongooseArray: true,
|
||||
isMongooseDocumentArray: true,
|
||||
validators: [],
|
||||
_atomics: {},
|
||||
_schema: void 0,
|
||||
_handlers: void 0
|
||||
};
|
||||
|
||||
// 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;
|
||||
var keysMA = Object.keys(MongooseArray.mixin);
|
||||
var numKeys = keysMA.length;
|
||||
for (var j = 0; j < numKeys; ++j) {
|
||||
arr[keysMA[j]] = MongooseArray.mixin[keysMA[j]];
|
||||
}
|
||||
|
||||
arr._atomics = {};
|
||||
arr.validators = [];
|
||||
arr._path = path;
|
||||
var keysMDA = Object.keys(MongooseDocumentArray.mixin);
|
||||
numKeys = keysMDA.length;
|
||||
for (var i = 0; i < numKeys; ++i) {
|
||||
arr[keysMDA[i]] = MongooseDocumentArray.mixin[keysMDA[i]];
|
||||
}
|
||||
|
||||
if (doc) {
|
||||
var keysP = Object.keys(props);
|
||||
numKeys = keysP.length;
|
||||
for (var k = 0; k < numKeys; ++k) {
|
||||
arr[keysP[k]] = props[keysP[k]];
|
||||
}
|
||||
|
||||
// Because doc comes from the context of another function, doc === global
|
||||
// can happen if there was a null somewhere up the chain (see #3020 && #3034)
|
||||
// RB Jun 17, 2015 updated to check for presence of expected paths instead
|
||||
// to make more proof against unusual node environments
|
||||
if (doc && doc instanceof Document) {
|
||||
arr._parent = doc;
|
||||
arr._schema = doc.schema.path(path);
|
||||
doc.on('save', arr.notify('save'));
|
||||
doc.on('isNew', arr.notify('isNew'));
|
||||
arr._handlers = {
|
||||
isNew: arr.notify('isNew'),
|
||||
save: arr.notify('save')
|
||||
};
|
||||
|
||||
doc.on('save', arr._handlers.save);
|
||||
doc.on('isNew', arr._handlers.isNew);
|
||||
}
|
||||
|
||||
return arr;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherits from MongooseArray
|
||||
*/
|
||||
// MongooseDocumentArray.mixin = Object.create( MongooseArray.mixin );
|
||||
MongooseDocumentArray.mixin = {
|
||||
|
||||
MongooseDocumentArray.prototype.__proto__ = MongooseArray.prototype;
|
||||
/**
|
||||
* Overrides MongooseArray#cast
|
||||
*
|
||||
* @method _cast
|
||||
* @api private
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
/**
|
||||
* Overrides MongooseArray#cast
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype._cast = function (value) {
|
||||
if (value instanceof this._schema.casterConstructor) {
|
||||
if (!(value.__parent && value.__parentArray)) {
|
||||
// value may have been created using array.create()
|
||||
value.__parent = this._parent;
|
||||
value.__parentArray = this;
|
||||
_cast: function(value, index) {
|
||||
if (value instanceof this._schema.casterConstructor) {
|
||||
if (!(value.__parent && value.__parentArray)) {
|
||||
// value may have been created using array.create()
|
||||
value.__parent = this._parent;
|
||||
value.__parentArray = this;
|
||||
}
|
||||
value.__index = index;
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// handle cast('string') or cast(ObjectId) etc.
|
||||
// only objects are permitted so we can safely assume that
|
||||
// non-objects are to be interpreted as _id
|
||||
if (Buffer.isBuffer(value) ||
|
||||
value instanceof ObjectId || !utils.isObject(value)) {
|
||||
value = { _id: 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
|
||||
, sid
|
||||
, _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 Document) {
|
||||
sid || (sid = String(id));
|
||||
if (sid == _id._id) return this[i];
|
||||
} else if (!(_id instanceof ObjectId)) {
|
||||
sid || (sid = String(id));
|
||||
if (sid == _id) return this[i];
|
||||
} else if (casted == _id) {
|
||||
return this[i];
|
||||
if (value === undefined || value === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// handle cast('string') or cast(ObjectId) etc.
|
||||
// only objects are permitted so we can safely assume that
|
||||
// non-objects are to be interpreted as _id
|
||||
if (Buffer.isBuffer(value) ||
|
||||
value instanceof ObjectId || !utils.isObject(value)) {
|
||||
value = {_id: value};
|
||||
}
|
||||
return new this._schema.casterConstructor(value, this, undefined, undefined, index);
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches array items for the first document with a matching _id.
|
||||
*
|
||||
* ####Example:
|
||||
*
|
||||
* var embeddedDoc = m.array.id(some_id);
|
||||
*
|
||||
* @return {EmbeddedDocument|null} the subdocument or null if not found.
|
||||
* @param {ObjectId|String|Number|Buffer} id
|
||||
* @TODO cast to the _id based on schema for proper comparison
|
||||
* @method id
|
||||
* @api public
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
id: function(id) {
|
||||
var casted,
|
||||
sid,
|
||||
_id;
|
||||
|
||||
try {
|
||||
var casted_ = ObjectIdSchema.prototype.cast.call({}, id);
|
||||
if (casted_) {
|
||||
casted = String(casted_);
|
||||
}
|
||||
} catch (e) {
|
||||
casted = null;
|
||||
}
|
||||
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
_id = this[i].get('_id');
|
||||
|
||||
if (_id === null || typeof _id === 'undefined') {
|
||||
continue;
|
||||
} else if (_id instanceof Document) {
|
||||
sid || (sid = String(id));
|
||||
if (sid == _id._id) {
|
||||
return this[i];
|
||||
}
|
||||
} else if (!(id instanceof ObjectId) && !(_id instanceof ObjectId)) {
|
||||
if (utils.deepEqual(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._
|
||||
*
|
||||
* @param {Object} [options] optional options to pass to each documents `toObject` method call during conversion
|
||||
* @return {Array}
|
||||
* @method toObject
|
||||
* @api public
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
toObject: function(options) {
|
||||
return this.map(function(doc) {
|
||||
return doc && doc.toObject(options) || null;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper for console.log
|
||||
*
|
||||
* @method inspect
|
||||
* @api public
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
inspect: function() {
|
||||
return Array.prototype.slice.call(this);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @method create
|
||||
* @api public
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
create: function(obj) {
|
||||
return new this._schema.casterConstructor(obj);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a fn that notifies all child docs of `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Function}
|
||||
* @method notify
|
||||
* @api private
|
||||
* @receiver MongooseDocumentArray
|
||||
*/
|
||||
|
||||
notify: function notify(event) {
|
||||
var _this = this;
|
||||
return function notify(val) {
|
||||
var i = _this.length;
|
||||
while (i--) {
|
||||
if (!_this[i]) {
|
||||
continue;
|
||||
}
|
||||
switch (event) {
|
||||
// only swap for save event for now, we may change this to all event types later
|
||||
case 'save':
|
||||
val = _this[i];
|
||||
break;
|
||||
default:
|
||||
// NO-OP
|
||||
break;
|
||||
}
|
||||
_this[i].emit(event, val);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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._
|
||||
*
|
||||
* @param {Object} [options] optional options to pass to each documents `toObject` method call during conversion
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
MongooseDocumentArray.prototype.toObject = function (options) {
|
||||
return this.map(function (doc) {
|
||||
return doc && doc.toObject(options) || 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.
|
||||
*/
|
||||
|
||||
207
node_modules/mongoose/lib/types/embedded.js
generated
vendored
207
node_modules/mongoose/lib/types/embedded.js
generated
vendored
@@ -1,9 +1,11 @@
|
||||
/* eslint no-func-assign: 1 */
|
||||
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Document = require('../document')
|
||||
, inspect = require('util').inspect;
|
||||
var Document = require('../document_provider')();
|
||||
var PromiseProvider = require('../promise_provider');
|
||||
|
||||
/**
|
||||
* EmbeddedDocument constructor.
|
||||
@@ -15,7 +17,7 @@ var Document = require('../document')
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function EmbeddedDocument (obj, parentArr, skipId, fields) {
|
||||
function EmbeddedDocument(obj, parentArr, skipId, fields, index) {
|
||||
if (parentArr) {
|
||||
this.__parentArray = parentArr;
|
||||
this.__parent = parentArr._parent;
|
||||
@@ -23,20 +25,21 @@ function EmbeddedDocument (obj, parentArr, skipId, fields) {
|
||||
this.__parentArray = undefined;
|
||||
this.__parent = undefined;
|
||||
}
|
||||
this.__index = index;
|
||||
|
||||
Document.call(this, obj, fields, skipId);
|
||||
|
||||
var self = this;
|
||||
this.on('isNew', function (val) {
|
||||
self.isNew = val;
|
||||
var _this = this;
|
||||
this.on('isNew', function(val) {
|
||||
_this.isNew = val;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inherit from Document
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.__proto__ = Document.prototype;
|
||||
EmbeddedDocument.prototype = Object.create(Document.prototype);
|
||||
EmbeddedDocument.prototype.constructor = EmbeddedDocument;
|
||||
|
||||
/**
|
||||
* Marks the embedded doc modified.
|
||||
@@ -49,20 +52,23 @@ EmbeddedDocument.prototype.__proto__ = Document.prototype;
|
||||
*
|
||||
* @param {String} path the path which changed
|
||||
* @api public
|
||||
* @receiver EmbeddedDocument
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.markModified = function (path) {
|
||||
if (!this.__parentArray) return;
|
||||
|
||||
EmbeddedDocument.prototype.markModified = function(path) {
|
||||
this.$__.activePaths.modify(path);
|
||||
if (!this.__parentArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
this.__parentArray._markModified(this, path);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -73,39 +79,73 @@ EmbeddedDocument.prototype.markModified = function (path) {
|
||||
* _This is a no-op. Does not actually save the doc to the db._
|
||||
*
|
||||
* @param {Function} [fn]
|
||||
* @return {EmbeddedDocument} this
|
||||
* @return {Promise} resolved Promise
|
||||
* @api private
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.save = function(fn) {
|
||||
if (fn)
|
||||
fn(null);
|
||||
return this;
|
||||
var Promise = PromiseProvider.get();
|
||||
return new Promise.ES6(function(resolve) {
|
||||
fn && fn();
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
/*!
|
||||
* Registers remove event listeners for triggering
|
||||
* on subdocuments.
|
||||
*
|
||||
* @param {EmbeddedDocument} sub
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function registerRemoveListener(sub) {
|
||||
var owner = sub.ownerDocument();
|
||||
|
||||
function emitRemove() {
|
||||
owner.removeListener('save', emitRemove);
|
||||
owner.removeListener('remove', emitRemove);
|
||||
sub.emit('remove', sub);
|
||||
owner = sub = null;
|
||||
}
|
||||
|
||||
owner.on('save', emitRemove);
|
||||
owner.on('remove', emitRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the subdocument from its parent array.
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {Function} [fn]
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.remove = function (fn) {
|
||||
if (!this.__parentArray) return this;
|
||||
EmbeddedDocument.prototype.remove = function(options, fn) {
|
||||
if ( typeof options === 'function' && !fn ) {
|
||||
fn = options;
|
||||
options = undefined;
|
||||
}
|
||||
if (!this.__parentArray || (options && options.noop)) {
|
||||
fn && fn(null);
|
||||
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');
|
||||
'how to remove an EmbeddedDocument that has no _id');
|
||||
}
|
||||
this.__parentArray.pull({ _id: _id });
|
||||
this.__parentArray.pull({_id: _id});
|
||||
this.willRemove = true;
|
||||
registerRemoveListener(this);
|
||||
}
|
||||
|
||||
if (fn)
|
||||
if (fn) {
|
||||
fn(null);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
@@ -115,9 +155,9 @@ EmbeddedDocument.prototype.remove = function (fn) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.update = function () {
|
||||
EmbeddedDocument.prototype.update = function() {
|
||||
throw new Error('The #update method is not available on EmbeddedDocuments');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper for console.log
|
||||
@@ -125,8 +165,8 @@ EmbeddedDocument.prototype.update = function () {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.inspect = function () {
|
||||
return inspect(this.toObject());
|
||||
EmbeddedDocument.prototype.inspect = function() {
|
||||
return this.toObject();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -138,29 +178,65 @@ EmbeddedDocument.prototype.inspect = function () {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.invalidate = function (path, err, val, first) {
|
||||
EmbeddedDocument.prototype.invalidate = function(path, err, val, first) {
|
||||
if (!this.__parent) {
|
||||
var msg = 'Unable to invalidate a subdocument that has not been added to an array.'
|
||||
throw new Error(msg);
|
||||
throw err;
|
||||
}
|
||||
|
||||
var index = this.__parentArray.indexOf(this);
|
||||
var parentPath = this.__parentArray._path;
|
||||
var fullPath = [parentPath, index, path].join('.');
|
||||
|
||||
// sniffing arguments:
|
||||
// need to check if user passed a value to keep
|
||||
// our error message clean.
|
||||
if (2 < arguments.length) {
|
||||
var index = this.__index;
|
||||
if (typeof index !== 'undefined') {
|
||||
var parentPath = this.__parentArray._path;
|
||||
var fullPath = [parentPath, index, path].join('.');
|
||||
this.__parent.invalidate(fullPath, err, val);
|
||||
} else {
|
||||
this.__parent.invalidate(fullPath, err);
|
||||
}
|
||||
|
||||
if (first)
|
||||
if (first) {
|
||||
this.$__.validationError = this.ownerDocument().$__.validationError;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks a path as valid, removing existing validation errors.
|
||||
*
|
||||
* @param {String} path the field to mark as valid
|
||||
* @api private
|
||||
* @method $markValid
|
||||
* @receiver EmbeddedDocument
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.$markValid = function(path) {
|
||||
if (!this.__parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
var index = this.__index;
|
||||
if (typeof index !== 'undefined') {
|
||||
var parentPath = this.__parentArray._path;
|
||||
var fullPath = [parentPath, index, path].join('.');
|
||||
this.__parent.$markValid(fullPath);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a path is invalid
|
||||
*
|
||||
* @param {String} path the field to check
|
||||
* @api private
|
||||
* @method $isValid
|
||||
* @receiver EmbeddedDocument
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.$isValid = function(path) {
|
||||
var index = this.__index;
|
||||
if (typeof index !== 'undefined') {
|
||||
return !this.__parent.$__.validationError ||
|
||||
!this.__parent.$__.validationError.errors[this.$__fullPath(path)];
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the top level document of this sub-document.
|
||||
@@ -168,20 +244,23 @@ EmbeddedDocument.prototype.invalidate = function (path, err, val, first) {
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.ownerDocument = function () {
|
||||
EmbeddedDocument.prototype.ownerDocument = function() {
|
||||
if (this.$__.ownerDocument) {
|
||||
return this.$__.ownerDocument;
|
||||
}
|
||||
|
||||
var parent = this.__parent;
|
||||
if (!parent) return this;
|
||||
|
||||
while (parent.__parent) {
|
||||
parent = parent.__parent;
|
||||
if (!parent) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.$__.ownerDocument = parent;
|
||||
}
|
||||
while (parent.__parent || parent.$parent) {
|
||||
parent = parent.__parent || parent.$parent;
|
||||
}
|
||||
|
||||
this.$__.ownerDocument = parent;
|
||||
return this.$__.ownerDocument;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the full path to this document. If optional `path` is passed, it is appended to the full path.
|
||||
@@ -193,15 +272,21 @@ EmbeddedDocument.prototype.ownerDocument = function () {
|
||||
* @memberOf EmbeddedDocument
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.$__fullPath = function (path) {
|
||||
EmbeddedDocument.prototype.$__fullPath = function(path) {
|
||||
if (!this.$__.fullPath) {
|
||||
var parent = this;
|
||||
if (!parent.__parent) return path;
|
||||
var parent = this; // eslint-disable-line consistent-this
|
||||
if (!parent.__parent) {
|
||||
return path;
|
||||
}
|
||||
|
||||
var paths = [];
|
||||
while (parent.__parent) {
|
||||
paths.unshift(parent.__parentArray._path);
|
||||
parent = parent.__parent;
|
||||
while (parent.__parent || parent.$parent) {
|
||||
if (parent.__parent) {
|
||||
paths.unshift(parent.__parentArray._path);
|
||||
} else {
|
||||
paths.unshift(parent.$basePath);
|
||||
}
|
||||
parent = parent.__parent || parent.$parent;
|
||||
}
|
||||
|
||||
this.$__.fullPath = paths.join('.');
|
||||
@@ -213,9 +298,9 @@ EmbeddedDocument.prototype.$__fullPath = function (path) {
|
||||
}
|
||||
|
||||
return path
|
||||
? this.$__.fullPath + '.' + path
|
||||
: this.$__.fullPath;
|
||||
}
|
||||
? this.$__.fullPath + '.' + path
|
||||
: this.$__.fullPath;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns this sub-documents parent document.
|
||||
@@ -223,9 +308,9 @@ EmbeddedDocument.prototype.$__fullPath = function (path) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.parent = function () {
|
||||
EmbeddedDocument.prototype.parent = function() {
|
||||
return this.__parent;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns this sub-documents parent array.
|
||||
@@ -233,9 +318,9 @@ EmbeddedDocument.prototype.parent = function () {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
EmbeddedDocument.prototype.parentArray = function () {
|
||||
EmbeddedDocument.prototype.parentArray = function() {
|
||||
return this.__parentArray;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Module exports.
|
||||
|
||||
2
node_modules/mongoose/lib/types/index.js
generated
vendored
2
node_modules/mongoose/lib/types/index.js
generated
vendored
@@ -11,3 +11,5 @@ exports.Embedded = require('./embedded');
|
||||
|
||||
exports.DocumentArray = require('./documentarray');
|
||||
exports.ObjectId = require('./objectid');
|
||||
|
||||
exports.Subdocument = require('./subdocument');
|
||||
|
||||
34
node_modules/mongoose/lib/types/objectid.js
generated
vendored
34
node_modules/mongoose/lib/types/objectid.js
generated
vendored
@@ -1,10 +1,3 @@
|
||||
|
||||
/*!
|
||||
* Access driver.
|
||||
*/
|
||||
|
||||
var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
|
||||
|
||||
/**
|
||||
* ObjectId type constructor
|
||||
*
|
||||
@@ -15,29 +8,6 @@ var driver = global.MONGOOSE_DRIVER_PATH || '../drivers/node-mongodb-native';
|
||||
* @constructor ObjectId
|
||||
*/
|
||||
|
||||
var ObjectId = require(driver + '/objectid');
|
||||
var ObjectId = require('../drivers').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;
|
||||
|
||||
133
node_modules/mongoose/lib/types/subdocument.js
generated
vendored
Normal file
133
node_modules/mongoose/lib/types/subdocument.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
var Document = require('../document');
|
||||
var PromiseProvider = require('../promise_provider');
|
||||
|
||||
module.exports = Subdocument;
|
||||
|
||||
/**
|
||||
* Subdocument constructor.
|
||||
*
|
||||
* @inherits Document
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function Subdocument(value, fields) {
|
||||
this.$isSingleNested = true;
|
||||
Document.call(this, value, fields);
|
||||
}
|
||||
|
||||
Subdocument.prototype = Object.create(Document.prototype);
|
||||
|
||||
/**
|
||||
* 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 {Promise} resolved Promise
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Subdocument.prototype.save = function(fn) {
|
||||
var Promise = PromiseProvider.get();
|
||||
return new Promise.ES6(function(resolve) {
|
||||
fn && fn();
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Subdocument.prototype.$isValid = function(path) {
|
||||
if (this.$parent) {
|
||||
return this.$parent.$isValid([this.$basePath, path].join('.'));
|
||||
}
|
||||
};
|
||||
|
||||
Subdocument.prototype.markModified = function(path) {
|
||||
Document.prototype.markModified.call(this, path);
|
||||
if (this.$parent) {
|
||||
if (this.$parent.isModified(this.$basePath)) {
|
||||
return;
|
||||
}
|
||||
this.$parent.markModified([this.$basePath, path].join('.'));
|
||||
}
|
||||
};
|
||||
|
||||
Subdocument.prototype.$markValid = function(path) {
|
||||
if (this.$parent) {
|
||||
this.$parent.$markValid([this.$basePath, path].join('.'));
|
||||
}
|
||||
};
|
||||
|
||||
Subdocument.prototype.invalidate = function(path, err, val) {
|
||||
if (this.$parent) {
|
||||
this.$parent.invalidate([this.$basePath, path].join('.'), err, val);
|
||||
} else if (err.kind === 'cast' || err.name === 'CastError') {
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the top level document of this sub-document.
|
||||
*
|
||||
* @return {Document}
|
||||
*/
|
||||
|
||||
Subdocument.prototype.ownerDocument = function() {
|
||||
if (this.$__.ownerDocument) {
|
||||
return this.$__.ownerDocument;
|
||||
}
|
||||
|
||||
var parent = this.$parent;
|
||||
if (!parent) {
|
||||
return this;
|
||||
}
|
||||
|
||||
while (parent.$parent || parent.__parent) {
|
||||
parent = parent.$parent || parent.__parent;
|
||||
}
|
||||
this.$__.ownerDocument = parent;
|
||||
return this.$__.ownerDocument;
|
||||
};
|
||||
|
||||
/**
|
||||
* Null-out this subdoc
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @param {Function} [callback] optional callback for compatibility with Document.prototype.remove
|
||||
*/
|
||||
|
||||
Subdocument.prototype.remove = function(options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
this.$parent.set(this.$basePath, null);
|
||||
registerRemoveListener(this);
|
||||
if (typeof callback === 'function') {
|
||||
callback(null);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Registers remove event listeners for triggering
|
||||
* on subdocuments.
|
||||
*
|
||||
* @param {EmbeddedDocument} sub
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function registerRemoveListener(sub) {
|
||||
var owner = sub.ownerDocument();
|
||||
|
||||
function emitRemove() {
|
||||
owner.removeListener('save', emitRemove);
|
||||
owner.removeListener('remove', emitRemove);
|
||||
sub.emit('remove', sub);
|
||||
owner = sub = null;
|
||||
}
|
||||
|
||||
owner.on('save', emitRemove);
|
||||
owner.on('remove', emitRemove);
|
||||
}
|
||||
512
node_modules/mongoose/lib/utils.js
generated
vendored
512
node_modules/mongoose/lib/utils.js
generated
vendored
@@ -2,15 +2,14 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var ReadPref = require('mongodb').ReadPreference
|
||||
, ObjectId = require('./types/objectid')
|
||||
, cloneRegExp = require('regexp-clone')
|
||||
, sliced = require('sliced')
|
||||
, mpath = require('mpath')
|
||||
, ms = require('ms')
|
||||
, MongooseBuffer
|
||||
, MongooseArray
|
||||
, Document
|
||||
var ObjectId = require('./types/objectid');
|
||||
var cloneRegExp = require('regexp-clone');
|
||||
var sliced = require('sliced');
|
||||
var mpath = require('mpath');
|
||||
var ms = require('ms');
|
||||
var MongooseBuffer;
|
||||
var MongooseArray;
|
||||
var Document;
|
||||
|
||||
/*!
|
||||
* Produces a collection name from model `name`.
|
||||
@@ -20,9 +19,17 @@ var ReadPref = require('mongodb').ReadPreference
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.toCollectionName = function (name) {
|
||||
if ('system.profile' === name) return name;
|
||||
if ('system.indexes' === name) return name;
|
||||
exports.toCollectionName = function(name, options) {
|
||||
options = options || {};
|
||||
if (name === 'system.profile') {
|
||||
return name;
|
||||
}
|
||||
if (name === 'system.indexes') {
|
||||
return name;
|
||||
}
|
||||
if (options.pluralization === false) {
|
||||
return name;
|
||||
}
|
||||
return pluralize(name.toLowerCase());
|
||||
};
|
||||
|
||||
@@ -52,8 +59,10 @@ exports.pluralization = [
|
||||
[/(x|ch|ss|sh)$/gi, '$1es'],
|
||||
[/(matr|vert|ind)ix|ex$/gi, '$1ices'],
|
||||
[/([m|l])ouse$/gi, '$1ice'],
|
||||
[/(kn|w|l)ife$/gi, '$1ives'],
|
||||
[/(quiz)$/gi, '$1zes'],
|
||||
[/s$/gi, 's'],
|
||||
[/([^a-z])$/, '$1'],
|
||||
[/$/gi, 's']
|
||||
];
|
||||
var rules = exports.pluralization;
|
||||
@@ -104,16 +113,18 @@ var uncountables = exports.uncountables;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function pluralize (str) {
|
||||
var rule, found;
|
||||
if (!~uncountables.indexOf(str.toLowerCase())){
|
||||
found = rules.filter(function(rule){
|
||||
function pluralize(str) {
|
||||
var 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]);
|
||||
if (found[0]) {
|
||||
return str.replace(found[0][0], found[0][1]);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Determines if `a` and `b` are deep equal.
|
||||
@@ -126,30 +137,37 @@ function pluralize (str) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.deepEqual = function deepEqual (a, b) {
|
||||
if (a === b) return true;
|
||||
exports.deepEqual = function deepEqual(a, b) {
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a instanceof Date && b instanceof Date)
|
||||
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 (a instanceof RegExp && b instanceof RegExp) {
|
||||
return a.source == b.source &&
|
||||
a.ignoreCase == b.ignoreCase &&
|
||||
a.multiline == b.multiline &&
|
||||
a.global == b.global;
|
||||
return a.source === b.source &&
|
||||
a.ignoreCase === b.ignoreCase &&
|
||||
a.multiline === b.multiline &&
|
||||
a.global === b.global;
|
||||
}
|
||||
|
||||
if (typeof a !== 'object' && typeof b !== 'object')
|
||||
if (typeof a !== 'object' && typeof b !== 'object') {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
if (a === null || b === null || a === undefined || b === undefined)
|
||||
return false
|
||||
if (a === null || b === null || a === undefined || b === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.prototype !== b.prototype) return false;
|
||||
if (a.prototype !== b.prototype) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle MongooseNumbers
|
||||
if (a instanceof Number && b instanceof Number) {
|
||||
@@ -157,45 +175,49 @@ exports.deepEqual = function deepEqual (a, b) {
|
||||
}
|
||||
|
||||
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;
|
||||
return exports.buffer.areEqual(a, b);
|
||||
}
|
||||
|
||||
if (isMongooseObject(a)) a = a.toObject();
|
||||
if (isMongooseObject(b)) b = b.toObject();
|
||||
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
|
||||
} 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)
|
||||
if (ka.length !== kb.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//the same set of keys (although not necessarily the same order),
|
||||
// the same set of keys (although not necessarily the same order),
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
|
||||
//~~~cheap key test
|
||||
// ~~~cheap key test
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i])
|
||||
if (ka[i] !== kb[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//equivalent values for every corresponding key, and
|
||||
//~~~possibly expensive deep test
|
||||
// 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;
|
||||
if (!deepEqual(a[key], b[key])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -214,23 +236,24 @@ exports.deepEqual = function deepEqual (a, b) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.clone = function clone (obj, options) {
|
||||
if (obj === undefined || obj === null)
|
||||
exports.clone = function clone(obj, options) {
|
||||
if (obj === undefined || obj === null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj))
|
||||
if (Array.isArray(obj)) {
|
||||
return cloneArray(obj, options);
|
||||
}
|
||||
|
||||
if (isMongooseObject(obj)) {
|
||||
if (options && options.json && 'function' === typeof obj.toJSON) {
|
||||
if (options && options.json && typeof obj.toJSON === 'function') {
|
||||
return obj.toJSON(options);
|
||||
} else {
|
||||
return obj.toObject(options);
|
||||
}
|
||||
return obj.toObject(options);
|
||||
}
|
||||
|
||||
if (obj.constructor) {
|
||||
switch (obj.constructor.name) {
|
||||
switch (exports.getFunctionName(obj.constructor)) {
|
||||
case 'Object':
|
||||
return cloneObject(obj, options);
|
||||
case 'Date':
|
||||
@@ -243,16 +266,18 @@ exports.clone = function clone (obj, options) {
|
||||
}
|
||||
}
|
||||
|
||||
if (obj instanceof ObjectId)
|
||||
if (obj instanceof ObjectId) {
|
||||
return new ObjectId(obj.id);
|
||||
}
|
||||
|
||||
if (!obj.constructor && exports.isObject(obj)) {
|
||||
// object created with Object.create(null)
|
||||
return cloneObject(obj, options);
|
||||
}
|
||||
|
||||
if (obj.valueOf)
|
||||
if (obj.valueOf) {
|
||||
return obj.valueOf();
|
||||
}
|
||||
};
|
||||
var clone = exports.clone;
|
||||
|
||||
@@ -260,21 +285,21 @@ var clone = exports.clone;
|
||||
* ignore
|
||||
*/
|
||||
|
||||
function cloneObject (obj, options) {
|
||||
var retainKeyOrder = options && options.retainKeyOrder
|
||||
, minimize = options && options.minimize
|
||||
, ret = {}
|
||||
, hasKeys
|
||||
, keys
|
||||
, val
|
||||
, k
|
||||
, i
|
||||
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)) {
|
||||
if (!minimize || (typeof val !== 'undefined')) {
|
||||
hasKeys || (hasKeys = true);
|
||||
ret[k] = val;
|
||||
}
|
||||
@@ -289,24 +314,27 @@ function cloneObject (obj, options) {
|
||||
k = keys[i];
|
||||
val = clone(obj[k], options);
|
||||
|
||||
if (!minimize || ('undefined' !== typeof val)) {
|
||||
if (!hasKeys) hasKeys = true;
|
||||
if (!minimize || (typeof val !== 'undefined')) {
|
||||
if (!hasKeys) {
|
||||
hasKeys = true;
|
||||
}
|
||||
ret[k] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return minimize
|
||||
? hasKeys && ret
|
||||
: ret;
|
||||
};
|
||||
? hasKeys && ret
|
||||
: ret;
|
||||
}
|
||||
|
||||
function cloneArray (arr, options) {
|
||||
function cloneArray(arr, options) {
|
||||
var ret = [];
|
||||
for (var i = 0, l = arr.length; i < l; i++)
|
||||
for (var i = 0, l = arr.length; i < l; i++) {
|
||||
ret.push(clone(arr[i], options));
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* Shallow copies defaults into options.
|
||||
@@ -317,10 +345,10 @@ function cloneArray (arr, options) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.options = function (defaults, options) {
|
||||
var keys = Object.keys(defaults)
|
||||
, i = keys.length
|
||||
, k ;
|
||||
exports.options = function(defaults, options) {
|
||||
var keys = Object.keys(defaults),
|
||||
i = keys.length,
|
||||
k;
|
||||
|
||||
options = options || {};
|
||||
|
||||
@@ -340,7 +368,7 @@ exports.options = function (defaults, options) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.random = function () {
|
||||
exports.random = function() {
|
||||
return Math.random().toString().substr(3);
|
||||
};
|
||||
|
||||
@@ -352,21 +380,17 @@ exports.random = function () {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.merge = function merge (to, from) {
|
||||
var keys = Object.keys(from)
|
||||
, i = keys.length
|
||||
, key
|
||||
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]) {
|
||||
if (typeof to[key] === 'undefined') {
|
||||
to[key] = from[key];
|
||||
} else {
|
||||
if (exports.isObject(from[key])) {
|
||||
merge(to[key], from[key]);
|
||||
} else {
|
||||
to[key] = from[key];
|
||||
}
|
||||
} else if (exports.isObject(from[key])) {
|
||||
merge(to[key], from[key]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -377,6 +401,50 @@ exports.merge = function merge (to, from) {
|
||||
|
||||
var toString = Object.prototype.toString;
|
||||
|
||||
/*!
|
||||
* Applies toObject recursively.
|
||||
*
|
||||
* @param {Document|Array|Object} obj
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.toObject = function toObject(obj) {
|
||||
Document || (Document = require('./document'));
|
||||
var ret;
|
||||
|
||||
if (exports.isNullOrUndefined(obj)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (obj instanceof Document) {
|
||||
return obj.toObject();
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
ret = [];
|
||||
|
||||
for (var i = 0, len = obj.length; i < len; ++i) {
|
||||
ret.push(toObject(obj[i]));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((obj.constructor && exports.getFunctionName(obj.constructor) === 'Object') ||
|
||||
(!obj.constructor && exports.isObject(obj))) {
|
||||
ret = {};
|
||||
|
||||
for (var k in obj) {
|
||||
ret[k] = toObject(obj[k]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Determines if `arg` is an object.
|
||||
*
|
||||
@@ -385,9 +453,12 @@ var toString = Object.prototype.toString;
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
exports.isObject = function (arg) {
|
||||
return '[object Object]' == toString.call(arg);
|
||||
}
|
||||
exports.isObject = function(arg) {
|
||||
if (Buffer.isBuffer(arg)) {
|
||||
return true;
|
||||
}
|
||||
return toString.call(arg) === '[object Object]';
|
||||
};
|
||||
|
||||
/*!
|
||||
* A faster Array.prototype.slice.call(arguments) alternative
|
||||
@@ -407,20 +478,22 @@ exports.args = sliced;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.tick = function tick (callback) {
|
||||
if ('function' !== typeof callback) return;
|
||||
return function () {
|
||||
exports.tick = function tick(callback) {
|
||||
if (typeof callback !== 'function') {
|
||||
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 () {
|
||||
process.nextTick(function() {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
* Returns if `v` is a mongoose object that has a `toObject()` method we can use.
|
||||
@@ -431,15 +504,15 @@ exports.tick = function tick (callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.isMongooseObject = function (v) {
|
||||
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
|
||||
}
|
||||
(v && v.isMongooseArray) ||
|
||||
(v && v.isMongooseBuffer);
|
||||
};
|
||||
var isMongooseObject = exports.isMongooseObject;
|
||||
|
||||
/*!
|
||||
@@ -449,66 +522,37 @@ var isMongooseObject = exports.isMongooseObject;
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.expires = function expires (object) {
|
||||
if (!(object && 'Object' == object.constructor.name)) return;
|
||||
if (!('expires' in object)) return;
|
||||
exports.expires = function expires(object) {
|
||||
if (!(object && object.constructor.name === 'Object')) {
|
||||
return;
|
||||
}
|
||||
if (!('expires' in object)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var when;
|
||||
if ('string' != typeof object.expires) {
|
||||
if (typeof object.expires !== 'string') {
|
||||
when = object.expires;
|
||||
} else {
|
||||
when = Math.round(ms(object.expires) / 1000);
|
||||
}
|
||||
object.expireAfterSeconds = when;
|
||||
delete object.expires;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Converts arguments to ReadPrefs the driver
|
||||
* can understand.
|
||||
*
|
||||
* @TODO move this into the driver layer
|
||||
* @param {String|Array} pref
|
||||
* @param {Array} [tags]
|
||||
*/
|
||||
|
||||
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 = 'primaryPreferred';
|
||||
break;
|
||||
case 's':
|
||||
pref = 'secondary';
|
||||
break;
|
||||
case 'sp':
|
||||
pref = 'secondaryPreferred';
|
||||
break;
|
||||
case 'n':
|
||||
pref = 'nearest';
|
||||
break;
|
||||
}
|
||||
|
||||
return new ReadPref(pref, tags);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Populate options constructor
|
||||
*/
|
||||
|
||||
function PopulateOptions (path, select, match, options, model) {
|
||||
function PopulateOptions(path, select, match, options, model, subPopulate) {
|
||||
this.path = path;
|
||||
this.match = match;
|
||||
this.select = select;
|
||||
this.options = options;
|
||||
this.model = model;
|
||||
if (typeof subPopulate === 'object') {
|
||||
this.populate = subPopulate;
|
||||
}
|
||||
this._docs = {};
|
||||
}
|
||||
|
||||
@@ -522,19 +566,19 @@ exports.PopulateOptions = PopulateOptions;
|
||||
* populate helper
|
||||
*/
|
||||
|
||||
exports.populate = function populate (path, select, model, match, options) {
|
||||
exports.populate = function populate(path, select, model, match, options, subPopulate) {
|
||||
// The order of select/conditions args is opposite Model.find but
|
||||
// necessary to keep backward compatibility (select could be
|
||||
// an array, string, or object literal).
|
||||
|
||||
// might have passed an object specifying all arguments
|
||||
if (1 === arguments.length) {
|
||||
if (arguments.length === 1) {
|
||||
if (path instanceof PopulateOptions) {
|
||||
return [path];
|
||||
}
|
||||
|
||||
if (Array.isArray(path)) {
|
||||
return path.map(function(o){
|
||||
return path.map(function(o) {
|
||||
return exports.populate(o)[0];
|
||||
});
|
||||
}
|
||||
@@ -544,26 +588,32 @@ exports.populate = function populate (path, select, model, match, options) {
|
||||
options = path.options;
|
||||
select = path.select;
|
||||
model = path.model;
|
||||
subPopulate = path.populate;
|
||||
path = path.path;
|
||||
}
|
||||
} else if ('string' !== typeof model) {
|
||||
} else if (typeof model !== 'string' && typeof model !== 'function') {
|
||||
options = match;
|
||||
match = model;
|
||||
model = undefined;
|
||||
}
|
||||
|
||||
if ('string' != typeof path) {
|
||||
if (typeof path !== 'string') {
|
||||
throw new TypeError('utils.populate: invalid path. Expected string. Got typeof `' + typeof path + '`');
|
||||
}
|
||||
|
||||
if (typeof subPopulate === 'object') {
|
||||
subPopulate = exports.populate(subPopulate);
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
var paths = path.split(' ');
|
||||
options = exports.clone(options, { retainKeyOrder: true });
|
||||
for (var i = 0; i < paths.length; ++i) {
|
||||
ret.push(new PopulateOptions(paths[i], select, match, options, model));
|
||||
ret.push(new PopulateOptions(paths[i], select, match, options, model, subPopulate));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Return the value of `obj` at the given `path`.
|
||||
@@ -572,9 +622,9 @@ exports.populate = function populate (path, select, model, match, options) {
|
||||
* @param {Object} obj
|
||||
*/
|
||||
|
||||
exports.getValue = function (path, obj, map) {
|
||||
exports.getValue = function(path, obj, map) {
|
||||
return mpath.get(path, obj, '_doc', map);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Sets the value of `obj` at the given `path`.
|
||||
@@ -584,9 +634,9 @@ exports.getValue = function (path, obj, map) {
|
||||
* @param {Object} obj
|
||||
*/
|
||||
|
||||
exports.setValue = function (path, val, obj, map) {
|
||||
exports.setValue = function(path, val, obj, map) {
|
||||
mpath.set(path, val, obj, '_doc', map);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Returns an array of values from object `o`.
|
||||
@@ -597,17 +647,17 @@ exports.setValue = function (path, val, obj, map) {
|
||||
*/
|
||||
|
||||
exports.object = {};
|
||||
exports.object.vals = function vals (o) {
|
||||
var keys = Object.keys(o)
|
||||
, i = keys.length
|
||||
, ret = [];
|
||||
exports.object.vals = function vals(o) {
|
||||
var keys = Object.keys(o),
|
||||
i = keys.length,
|
||||
ret = [];
|
||||
|
||||
while (i--) {
|
||||
ret.push(o[keys[i]]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* @see exports.options
|
||||
@@ -622,9 +672,10 @@ exports.object.shallowCopy = exports.options;
|
||||
* @param {String} prop
|
||||
*/
|
||||
|
||||
exports.object.hasOwnProperty = function (obj, prop) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
var hop = Object.prototype.hasOwnProperty;
|
||||
exports.object.hasOwnProperty = function(obj, prop) {
|
||||
return hop.call(obj, prop);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Determine if `val` is null or undefined
|
||||
@@ -632,9 +683,9 @@ exports.object.hasOwnProperty = function (obj, prop) {
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
exports.isNullOrUndefined = function (val) {
|
||||
return null == val
|
||||
}
|
||||
exports.isNullOrUndefined = function(val) {
|
||||
return val === null || val === undefined;
|
||||
};
|
||||
|
||||
/*!
|
||||
* ignore
|
||||
@@ -653,10 +704,10 @@ exports.array = {};
|
||||
* @private
|
||||
*/
|
||||
|
||||
exports.array.flatten = function flatten (arr, filter, ret) {
|
||||
exports.array.flatten = function flatten(arr, filter, ret) {
|
||||
ret || (ret = []);
|
||||
|
||||
arr.forEach(function (item) {
|
||||
arr.forEach(function(item) {
|
||||
if (Array.isArray(item)) {
|
||||
flatten(item, filter, ret);
|
||||
} else {
|
||||
@@ -667,5 +718,130 @@ exports.array.flatten = function flatten (arr, filter, ret) {
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Removes duplicate values from an array
|
||||
*
|
||||
* [1, 2, 3, 3, 5] => [1, 2, 3, 5]
|
||||
* [ ObjectId("550988ba0c19d57f697dc45e"), ObjectId("550988ba0c19d57f697dc45e") ]
|
||||
* => [ObjectId("550988ba0c19d57f697dc45e")]
|
||||
*
|
||||
* @param {Array} arr
|
||||
* @return {Array}
|
||||
* @private
|
||||
*/
|
||||
|
||||
exports.array.unique = function(arr) {
|
||||
var primitives = {};
|
||||
var ids = {};
|
||||
var ret = [];
|
||||
var length = arr.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
if (typeof arr[i] === 'number' || typeof arr[i] === 'string') {
|
||||
if (primitives[arr[i]]) {
|
||||
continue;
|
||||
}
|
||||
ret.push(arr[i]);
|
||||
primitives[arr[i]] = true;
|
||||
} else if (arr[i] instanceof ObjectId) {
|
||||
if (ids[arr[i].toString()]) {
|
||||
continue;
|
||||
}
|
||||
ret.push(arr[i]);
|
||||
ids[arr[i].toString()] = true;
|
||||
} else {
|
||||
ret.push(arr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Determines if two buffers are equal.
|
||||
*
|
||||
* @param {Buffer} a
|
||||
* @param {Object} b
|
||||
*/
|
||||
|
||||
exports.buffer = {};
|
||||
exports.buffer.areEqual = function(a, b) {
|
||||
if (!Buffer.isBuffer(a)) {
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
exports.getFunctionName = function(fn) {
|
||||
if (fn.name) {
|
||||
return fn.name;
|
||||
}
|
||||
return (fn.toString().trim().match(/^function\s*([^\s(]+)/) || [])[1];
|
||||
};
|
||||
|
||||
exports.decorate = function(destination, source) {
|
||||
for (var key in source) {
|
||||
destination[key] = source[key];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* merges to with a copy of from
|
||||
*
|
||||
* @param {Object} to
|
||||
* @param {Object} fromObj
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.mergeClone = function(to, fromObj) {
|
||||
var keys = Object.keys(fromObj),
|
||||
i = keys.length,
|
||||
key;
|
||||
|
||||
while (i--) {
|
||||
key = keys[i];
|
||||
if (typeof to[key] === 'undefined') {
|
||||
// make sure to retain key order here because of a bug handling the $each
|
||||
// operator in mongodb 2.4.4
|
||||
to[key] = exports.clone(fromObj[key], {retainKeyOrder: 1});
|
||||
} else {
|
||||
if (exports.isObject(fromObj[key])) {
|
||||
var obj = fromObj[key];
|
||||
if (isMongooseObject(fromObj[key]) && !fromObj[key].isMongooseBuffer) {
|
||||
obj = obj.toObject({ virtuals: false });
|
||||
}
|
||||
exports.mergeClone(to[key], obj);
|
||||
} else {
|
||||
// make sure to retain key order here because of a bug handling the
|
||||
// $each operator in mongodb 2.4.4
|
||||
to[key] = exports.clone(fromObj[key], {retainKeyOrder: 1});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes a function on each element of an array (like _.each)
|
||||
*
|
||||
* @param {Array} arr
|
||||
* @param {Function} fn
|
||||
* @api private
|
||||
*/
|
||||
|
||||
exports.each = function(arr, fn) {
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
fn(arr[i]);
|
||||
}
|
||||
};
|
||||
|
||||
10
node_modules/mongoose/lib/virtualtype.js
generated
vendored
10
node_modules/mongoose/lib/virtualtype.js
generated
vendored
@@ -13,7 +13,7 @@
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function VirtualType (options, name) {
|
||||
function VirtualType(options, name) {
|
||||
this.path = name;
|
||||
this.getters = [];
|
||||
this.setters = [];
|
||||
@@ -35,7 +35,7 @@ function VirtualType (options, name) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.get = function (fn) {
|
||||
VirtualType.prototype.get = function(fn) {
|
||||
this.getters.push(fn);
|
||||
return this;
|
||||
};
|
||||
@@ -57,7 +57,7 @@ VirtualType.prototype.get = function (fn) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.set = function (fn) {
|
||||
VirtualType.prototype.set = function(fn) {
|
||||
this.setters.push(fn);
|
||||
return this;
|
||||
};
|
||||
@@ -71,7 +71,7 @@ VirtualType.prototype.set = function (fn) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.applyGetters = function (value, scope) {
|
||||
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);
|
||||
@@ -88,7 +88,7 @@ VirtualType.prototype.applyGetters = function (value, scope) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
VirtualType.prototype.applySetters = function (value, scope) {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user