summaryrefslogtreecommitdiff
path: root/node_modules/mongoose/docs
diff options
context:
space:
mode:
authorJules Laplace <jules@okfoc.us>2012-09-24 16:22:07 -0400
committerJules Laplace <jules@okfoc.us>2012-09-24 16:22:07 -0400
commit686106d544ecc3b6ffd4db2b665d3bc879a58d8c (patch)
treea5b5e50237cef70e12f0745371896e96f5f6d578 /node_modules/mongoose/docs
ok
Diffstat (limited to 'node_modules/mongoose/docs')
-rw-r--r--node_modules/mongoose/docs/defaults.md29
-rw-r--r--node_modules/mongoose/docs/embedded-documents.md79
-rw-r--r--node_modules/mongoose/docs/errors.md54
-rw-r--r--node_modules/mongoose/docs/finding-documents.md124
-rw-r--r--node_modules/mongoose/docs/getters-setters.md52
-rw-r--r--node_modules/mongoose/docs/indexes.md43
-rw-r--r--node_modules/mongoose/docs/methods-statics.md55
-rw-r--r--node_modules/mongoose/docs/middleware.md61
-rw-r--r--node_modules/mongoose/docs/migration-guide.md148
-rw-r--r--node_modules/mongoose/docs/model-definition.md142
-rw-r--r--node_modules/mongoose/docs/plugins.md38
-rw-r--r--node_modules/mongoose/docs/populate.md166
-rw-r--r--node_modules/mongoose/docs/query.md362
-rw-r--r--node_modules/mongoose/docs/querystream.md6
-rw-r--r--node_modules/mongoose/docs/schematypes.md197
-rw-r--r--node_modules/mongoose/docs/validation.md92
-rw-r--r--node_modules/mongoose/docs/virtuals.md84
17 files changed, 1732 insertions, 0 deletions
diff --git a/node_modules/mongoose/docs/defaults.md b/node_modules/mongoose/docs/defaults.md
new file mode 100644
index 0000000..0497787
--- /dev/null
+++ b/node_modules/mongoose/docs/defaults.md
@@ -0,0 +1,29 @@
+
+Defaults
+========
+
+Each `SchemaType` that you define \(you can read more about them in the [model
+definition chapter](/docs/model-definition.html) \) can have a default value.
+
+Default values are applied when the document skeleton is constructed. This
+means that if you create a new document (`new MyModel`) or if you find an
+existing document (`MyModel.findById`), both will have defaults
+provided that a certain key is missing.
+
+## Definition
+
+You can define a default with a function:
+
+ new Schema({
+ date: { type: Date, default: Date.now }
+ })
+
+or a value:
+
+ new Schema({
+ date: { type: Date, default: '12/10/1990' }
+ })
+
+Notice that defaults are automatically casted. In both cases, the defaults will
+become actual `Date` objects, but we're passing a timestamp first, and a string
+date second.
diff --git a/node_modules/mongoose/docs/embedded-documents.md b/node_modules/mongoose/docs/embedded-documents.md
new file mode 100644
index 0000000..10b6aae
--- /dev/null
+++ b/node_modules/mongoose/docs/embedded-documents.md
@@ -0,0 +1,79 @@
+
+Embedded Documents
+==================
+
+Embedded documents are documents with schemas of their own that are part of
+other documents (as items within an array).
+
+Embedded documents enjoy all the same features as your models. Defaults,
+validators, middleware. Whenever an error occurs, it's bubbled to the `save()`
+error callback, so error handling is a snap!
+
+Mongoose interacts with your embedded documents in arrays _atomically_, out of
+the box.
+
+## Definition and initialization
+
+When you define a Schema like this:
+
+ var Comments = new Schema({
+ title : String
+ , body : String
+ , date : Date
+ });
+
+ var BlogPost = new Schema({
+ author : ObjectId
+ , title : String
+ , body : String
+ , date : Date
+ , comments : [Comments]
+ , meta : {
+ votes : Number
+ , favs : Number
+ }
+ });
+
+ mongoose.model('BlogPost', BlogPost);
+
+The `comments` key of your `BlogPost` documents will then be an instance of
+`DocumentArray`. This is a special subclassed `Array` that can deal with
+casting, and has special methods to work with embedded documents.
+
+## Adding an embedded document to an array
+
+ // retrieve my model
+ var BlogPost = mongoose.model('BlogPost');
+
+ // create a blog post
+ var post = new BlogPost();
+
+ // create a comment
+ post.comments.push({ title: 'My comment' });
+
+ post.save(function (err) {
+ if (!err) console.log('Success!');
+ });
+
+## Removing an embedded document
+
+ BlogPost.findById(myId, function (err, post) {
+ if (!err) {
+ post.comments[0].remove();
+ post.save(function (err) {
+ // do something
+ });
+ }
+ });
+
+## Finding an embedded document by id
+
+`DocumentArray`s have an special method `id` that filters your embedded
+documents by their `_id` property (each embedded document gets one):
+
+Consider the following snippet:
+
+ post.comments.id(my_id).remove();
+ post.save(function (err) {
+ // embedded comment with id `my_id` removed!
+ });
diff --git a/node_modules/mongoose/docs/errors.md b/node_modules/mongoose/docs/errors.md
new file mode 100644
index 0000000..a1852ef
--- /dev/null
+++ b/node_modules/mongoose/docs/errors.md
@@ -0,0 +1,54 @@
+
+Error handling
+==============
+
+Errors returned after failed validation contain an `errors` object
+holding the actual ValidatorErrors. Each ValidatorError has a `type` and `path` property
+providing us with a little more error handling flexibility.
+
+ var ToySchema = new Schema({
+ color: String
+ , name: String
+ });
+
+ var Toy = db.model('Toy', ToySchema);
+
+ Toy.schema.path('name').validate(function (value) {
+ return /blue|green|white|red|orange|periwinkel/i.test(value);
+ }, 'Invalid color');
+
+ var toy = new Toy({ color: 'grease'});
+
+ toy.save(function (err) {
+ // previous behavior (v1x):
+
+ console.log(err.errors.color)
+ // prints 'Validator "Invalid color" failed for path color'
+
+ // new v2x behavior - err.errors.color is a ValidatorError object
+
+ console.log(err.errors.color.message)
+ // prints 'Validator "Invalid color" failed for path color'
+
+ // you can get v1 behavior back by casting error.color toString
+
+ console.log(String(err.errors.color))
+ // prints 'Validator "Invalid color" failed for path color'
+
+ console.log(err.errors.color.type);
+ // prints "Invalid color"
+
+ console.log(err.errors.color.path)
+ // prints "color"
+
+ console.log(err.name)
+ // prints "ValidationError"
+
+ console.log(err.message)
+ // prints "Validation failed"
+ });
+
+BTW, the `err.errors` object is also available on the model instance.
+
+ toy.errors.color.message === err.errors.color.message
+
diff --git a/node_modules/mongoose/docs/finding-documents.md b/node_modules/mongoose/docs/finding-documents.md
new file mode 100644
index 0000000..db6e25d
--- /dev/null
+++ b/node_modules/mongoose/docs/finding-documents.md
@@ -0,0 +1,124 @@
+
+Querying
+=================
+
+Documents can be retrieved through `find`, `findOne` and `findById`. These
+methods are executed on your `Model`s.
+
+## Model.find
+
+ Model.find(query, fields, options, callback)
+
+ // fields and options can be omitted
+
+### Simple query:
+
+ Model.find({ 'some.value': 5 }, function (err, docs) {
+ // docs is an array
+ });
+
+### Retrieving only certain fields
+
+ Model.find({}, ['first', 'last'], function (err, docs) {
+ // docs is an array of partially-`init`d documents
+ // defaults are still applied and will be "populated"
+ })
+
+## Model.findOne
+
+Same as `Model#find`, but only receives a single document as second parameter:
+
+ Model.findOne({ age: 5}, function (err, doc){
+ // doc is a Document
+ });
+
+## Model.findById
+
+Same as `findOne`, but receives a value to search a document by their `_id`
+key. This value is subject to casting, so it can be a hex string or a proper
+ObjectId.
+
+ Model.findById(obj._id, function (err, doc){
+ // doc is a Document
+ });
+
+## Model.count
+
+Counts the number of documents matching `conditions`.
+
+ Model.count(conditions, callback);
+
+## Model.remove
+
+Removes documents matching `conditions`.
+
+ Model.remove(conditions, callback);
+
+## Model.distinct
+
+Finds distinct values of `field` for documents matching `conditions`.
+
+ Model.distinct(field, conditions, callback);
+
+## Model.where
+
+Creates a Query for this model.
+Handy when expressing complex directives.
+
+ Model
+ .where('age').gte(25)
+ .where('tags').in(['movie', 'music', 'art'])
+ .select('name', 'age', 'tags')
+ .skip(20)
+ .limit(10)
+ .asc('age')
+ .slaveOk()
+ .hint({ age: 1, name: 1 })
+ .run(callback);
+
+## Model.$where
+
+Sometimes you need to query for things in mongodb using a JavaScript
+expression. You can do so via find({$where: javascript}), or you can
+use the mongoose shortcut method $where via a Query chain or from
+your mongoose Model.
+
+ Model.$where('this.firstname === this.lastname').exec(callback)
+
+## Model.update
+
+Updates all documents matching `conditions` using the `update` clause. All
+`update` values are casted to their appropriate types before being sent.
+
+ var conditions = { name: 'borne' }
+ , update = { $inc: { visits: 1 }}
+ , options = { multi: true };
+
+ Model.update(conditions, update, options, callback)
+
+Note: for backwards compatibility, all top-level `update` keys that are
+not $atomic operation names are treated as `$set` operations. Example:
+
+ var query = { name: 'borne' };
+ Model.update(query, { name: 'jason borne' }, options, callback)
+
+ // is sent as
+
+ Model.update(query, { $set: { name: 'jason borne' }}, options, callback)
+
+## Query
+
+Each of these methods returns a [Query](https://github.com/LearnBoost/mongoose/blob/master/lib/query.js).
+If you don't pass a callback to these methods, the Query can be continued to be
+modified (such as adding options, fields, etc), before it's `exec`d.
+
+ var query = Model.find({});
+
+ query.where('field', 5);
+ query.limit(5);
+ query.skip(100);
+
+ query.exec(function (err, docs) {
+ // called when the `query.complete` or `query.error` are called
+ // internally
+ });
diff --git a/node_modules/mongoose/docs/getters-setters.md b/node_modules/mongoose/docs/getters-setters.md
new file mode 100644
index 0000000..7cf7b94
--- /dev/null
+++ b/node_modules/mongoose/docs/getters-setters.md
@@ -0,0 +1,52 @@
+Getters and Setters
+====================
+
+Getters and setters help you change how you get and set the attributes defined by the keys and values in the underlying raw document.
+
+## Setters
+
+Setters allow you to transform the mongoose document's data before it gets to the raw mongodb document and is set as a value on an actual key.
+
+Suppose you are implementing user registration for a website. User provide an email and password, which gets saved to mongodb. The email is a string that you will want to normalize to lower case, in order to avoid one email having more than one account -- e.g., otherwise, avenue@q.com can be registered for 2 accounts via avenue@q.com and AvEnUe@Q.CoM.
+
+You can set up email lower case normalization easily via a Mongoose setter. Note in the following snippet that setters (and also getters) are defined in the `Schema`:
+
+ function toLower (v) {
+ return v.toLowerCase();
+ }
+
+ var UserSchema = new Schema({
+ email: { type: String, set: toLower }
+ });
+
+ var User = mongoose.model('User', UserSchema);
+ var user = new User({email: 'AVENUE@Q.COM'});
+
+ console.log(user.email); // 'avenue@q.com'
+
+
+As you can see above, setters allow you to transform the data before it gets to the raw mongodb document and is set as a value on an actual key.
+
+## Getters
+
+Getters allow you to transform the representation of the data as it travels from the raw mongodb document to the value that you see.
+
+Suppose you are storing credit card numbers and you want to hide everything except the last 4 digits to the mongoose user. You can do so by defining a getter in the following way (again, notice that getters are defined in the `Schema`):
+
+ function obfuscate (cc) {
+ return '****-****-****-' + cc.slice(cc.length-4, cc.length);
+ }
+
+ var AccountSchema = new Schema({
+ creditCardNumber: { type: String, get: obfuscate }
+ });
+
+ var Account = mongoose.model('Account', AccountSchema);
+
+ Account.findById( someId, function (err, found) {
+ console.log(found.creditCardNumber); // '****-****-****-1234'
+ });
+
+## Summary
+
+Setters are intended to modify the underlying raw data. Getters are intended to transform (but not modify at the raw data level) the underlying raw data into something that the user expects to see. They are both defined in the `Schema` definition.
diff --git a/node_modules/mongoose/docs/indexes.md b/node_modules/mongoose/docs/indexes.md
new file mode 100644
index 0000000..f294318
--- /dev/null
+++ b/node_modules/mongoose/docs/indexes.md
@@ -0,0 +1,43 @@
+
+Indexes
+=======
+
+Indexes are defined through `ensureIndex` every time a model is compiled for a
+certain connection / database. This means that indexes will only be ensured
+once during the lifetime of your app.
+
+## Definition
+
+Regular indexes:
+
+ var User = new Schema({
+ name: { type: String, index: true }
+ })
+
+[Sparse](http://www.mongodb.org/display/DOCS/Indexes#Indexes-SparseIndexes) indexes:
+
+ var User = new Schema({
+ name: { type: String, sparse: true }
+ })
+
+Unique indexes:
+
+ var User = new Schema({
+ name: { type: String, unique: true }
+ })
+
+ // or
+
+ var User = new Schema({
+ name: { type: String, index: { unique: true } }
+ })
+
+Unique sparse indexes:
+
+ var User = new Schema({
+ name: { type: String, unique: true, sparse: true }
+ })
+
+Compound indexes are defined on the `Schema` itself.
+
+ User.index({ first: 1, last: -1 }, { unique: true })
diff --git a/node_modules/mongoose/docs/methods-statics.md b/node_modules/mongoose/docs/methods-statics.md
new file mode 100644
index 0000000..27b5902
--- /dev/null
+++ b/node_modules/mongoose/docs/methods-statics.md
@@ -0,0 +1,55 @@
+Methods and Statics
+====================
+
+Each `Schema` can define instance and static methods for its model.
+
+## Methods
+
+Methods are easy to define:
+
+ var AnimalSchema = new Schema({
+ name: String
+ , type: String
+ });
+
+ AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
+ return this.find({ type: this.type }, cb);
+ };
+
+Now when we have an instance of `Animal` we can call our `findSimilarType` method and
+find all animals with a matching `type`.
+
+ var Animal = mongoose.model('Animal', AnimalSchema);
+ var dog = new Animal({ name: 'Rover', type: 'dog' });
+
+ dog.findSimilarType(function (err, dogs) {
+ if (err) return ...
+ dogs.forEach(..);
+ })
+
+Note that we return what `.find()` returns in our method. The advantages are two-fold.
+First, by passing `cb` into `find` we are making it optional b/c `find` called
+without a callback will not run the query. Secondly, `this.find`, `this.where`,
+and other Model methods return instances of [Query](/docs/finding-documents.html)
+which allow us to further utilize its expressive capabilities.
+
+ dog
+ .findSimilarType()
+ .where('name': /rover/i)
+ .limit(20)
+ .run(function (err, rovers) {
+ if (err) ...
+ })
+
+## Statics
+
+Statics are pretty much the same as methods but allow for defining functions that
+exist directly on your Model.
+
+ AnimalSchema.statics.search = function search (name, cb) {
+ return this.where('name', new RegExp(name, 'i')).run(cb);
+ }
+
+ Animal.search('Rover', function (err) {
+ if (err) ...
+ })
diff --git a/node_modules/mongoose/docs/middleware.md b/node_modules/mongoose/docs/middleware.md
new file mode 100644
index 0000000..947006d
--- /dev/null
+++ b/node_modules/mongoose/docs/middleware.md
@@ -0,0 +1,61 @@
+
+Middleware
+==========
+
+Middleware are defined at the Schema level and are applied when the methods
+`init` (when a document is initialized with data from MongoDB), `save`, and
+`remove` are called on a document instance.
+
+There are two types of middleware, serial and parallel.
+
+Serial middleware are defined like:
+
+ schema.pre('save', function (next) {
+ // ...
+ })
+
+They're executed one after the other, when each middleware calls `next`.
+
+Parallel middleware offer more fine-grained flow control, and are defined
+like
+
+ schema.pre('remove', true, function (next, done) {
+ // ...
+ })
+
+Parallel middleware can `next()` immediately, but the final argument will be
+called when all the parallel middleware have called `done()`.
+
+## Use cases
+
+Middleware are useful for:
+
+- Complex validation
+- Removing dependent documents when a certain document is removed (eg:
+removing a user removes all his blogposts)
+- Asynchronous defaults
+- Asynchronous tasks that a certain action triggers. For example:
+ - Triggering custom events
+ - Creating notifications
+ - Emails
+
+and many other things. They're specially useful for atomizing model logic
+and avoiding nested blocks of async code.
+
+## Error handling
+
+If any middleware calls `next` or `done` with an `Error` instance, the flow is
+interrupted, and the error is passed to the callback.
+
+For example:
+
+ schema.pre('save', function (next) {
+ // something goes wrong
+ next(new Error('something went wrong'));
+ });
+
+ // later...
+
+ myModel.save(function (err) {
+ // err can come from a middleware
+ });
diff --git a/node_modules/mongoose/docs/migration-guide.md b/node_modules/mongoose/docs/migration-guide.md
new file mode 100644
index 0000000..214bd4e
--- /dev/null
+++ b/node_modules/mongoose/docs/migration-guide.md
@@ -0,0 +1,148 @@
+
+Migrating from v1.x to 2.x
+==========================
+
+Migrating from __v1.x__ to __2.x__ brings with it a few changes to be aware of.
+
+## Auto-reconnect
+
+Previously the `auto_reconnect` option of the node-mongodb-driver
+defaulted to false. It now defaults to true so if your connection drops
+while your app is running the driver will continue retrying until it
+can connect again.
+
+## Private props
+
+Several internal instance props have had name changes so its more obvious that
+they are not intended for public use. Namely `instance.doc` has changed
+to `instance._doc` since it contains the structure Mongoose relies on
+to operate properly and should only be manipulated with caution.
+
+Here are the relavent changes:
+
+ var thing = new Thing;
+
+ thing.doc -> thing._doc
+ thing.activePaths -> thing._activePaths
+ thing.saveError -> thing._saveError
+ thing.validationError -> thing._validationError
+
+## Circular refs in getters
+
+Previously Mongoose exibited very odd behavior with getters:
+
+ toy.color.color.color.color ... // actually worked!
+
+Obviously this was wrong and has now been fixed.
+
+ toy.color.color // undefined
+
+## Getter / Setter scope
+
+Nested getter/setter scopes were set incorrectly since version 1.7 or so.
+This has been fixed. In your getter/setter, `this` now properly refers
+to the instance.
+
+ var SongSchema = new Schema({
+ title: String
+ , detail: {
+ format: String
+ }
+ });
+
+ SongSchema.path('detail.format').get(function () {
+ console.log(this !== this.detail) // true, used to be false
+ });
+
+You may not have noticed this bug since the circular getters previously
+masked (_mostly_) this bad behavior.
+
+## Setters application
+
+Setters are no longer applied when the doc returns from the db (bug). It
+caused problems for folks trying to use setters for passwords / salts
+resulting in doubly hashed passwords after queries.
+
+ UserSchema.path('password').set(function (val) {
+ // now only runs when you change `user.password`
+ // not when the doc returns from the db
+ });
+
+## Query#bind
+
+If you were using the `Query` object directly and calling its `bind`
+method, the v1.x behavior cloned the query and returned the
+new one. This is no longer the case. The query is now simply
+bound and returns itself.
+
+## Multiple collection support removed
+
+In 1.x Mongoose had support for multiple collection names per model. This
+was an edge case and support for it has been removed.
+
+## Compat.js removed
+
+Backward compatibility with verions 0.x has been removed.
+
+ require('mongoose').compat = true // no longer does anything
+
+## Utils.erase removed
+
+We removed utils.erase since it was unused in the project. If you were
+using it you'll need to copy it from the 1.x branch into your own.
+
+## Error handling
+
+Previously, the error returned after failed validation contained an `errors`
+object which was a hash of path keys to error message values.
+Now the Error returned is more helpful. Instead of the `errors`
+object containing string values it holds the actual
+ValidatorError. Each ValidatorError has a `type` and `path` property
+providing us with a little more error handling flexibility.
+
+ var ToySchema = new Schema({
+ color: String
+ , name: String
+ });
+
+ var Toy = db.model('Toy', ToySchema);
+
+ Toy.schema.path('name').validate(function (value) {
+ return /blue|green|white|red|orange|periwinkel/i.test(value);
+ }, 'Invalid color');
+
+ var toy = new Toy({ color: 'grease'});
+
+ toy.save(function (err) {
+ // previous behavior (v1x):
+
+ console.log(err.errors.color)
+ // prints 'Validator "Invalid color" failed for path color'
+
+ // new v2x behavior - err.errors.color is a ValidatorError object
+
+ console.log(err.errors.color.message)
+ // prints 'Validator "Invalid color" failed for path color'
+
+ // you can get v1 behavior back by casting error.color toString
+
+ console.log(String(err.errors.color))
+ // prints 'Validator "Invalid color" failed for path color'
+
+ console.log(err.errors.color.type);
+ // prints "Invalid color"
+
+ console.log(err.errors.color.path)
+ // prints "color"
+
+ console.log(err.name)
+ // prints "ValidationError"
+
+ console.log(err.message)
+ // prints "Validation failed"
+ });
+
+BTW, the `err.errors` object is also available on the model instance.
+
+ toy.errors.color.message === err.errors.color.message
+
diff --git a/node_modules/mongoose/docs/model-definition.md b/node_modules/mongoose/docs/model-definition.md
new file mode 100644
index 0000000..69700ff
--- /dev/null
+++ b/node_modules/mongoose/docs/model-definition.md
@@ -0,0 +1,142 @@
+Defining a model
+================
+
+Models are defined by passing a `Schema` instance to `mongoose.model`.
+
+ mongoose.model('MyModel', mySchema);
+ // mySchema is <a Schema>
+
+You can easily access the `Schema` constructor from the `mongoose` singleton:
+
+ var mongoose = require('mongoose')
+ , Schema = mongoose.Schema;
+
+ var mySchema = new Schema({
+ // my props
+ });
+
+Models are then accessed from `mongoose` if you want to use a single
+connection:
+
+ // connect the `mongoose` instance
+ mongoose.connect('mongodb://host/db');
+
+ var BlogPost = mongoose.model('BlogPost');
+
+Or from a `Connection` instance if you want to use multiple
+databases/connections:
+
+ var db = mongoose.createConnection('mongodb://host/db')
+ , BlogPost = db.model('BlogPost');
+
+**Important**: the actual interaction with the data happens with the `Model`
+that you obtain through `mongoose.model` or `db.model`. That's the object that
+you can instantiate or that you can call `.find()`, `.findOne()`, etc upon.
+Don't confuse schemas and actual models!
+
+## Defining your keys
+
+The `Schema` constructor receives an object representation of your schemas as
+its first parameter. If you want to add more keys later, `Schema#add` provides
+the same functionality.
+
+Your schema is constructed by passing all the
+JavaScript natives that you know (String, Number, Date, Buffer) as well
+as others exclusive to MongoDb (for example `Schema.ObjectId`). For details on all
+SchemaTypes see the [Schema Type chapter](/docs/schematypes.html).
+
+ var ObjectId = Schema.ObjectId;
+
+ var PostSchema = new Schema({
+ owner : ObjectId
+ , title : String
+ , date : Date
+ });
+
+### Defining documents within documents
+
+To define an array of documents that follows a certain schema, make the value
+an array with the schema constructor inside.
+
+For example, let's assume we want to have a collection of comments within a
+blogpost, and we want them to be subject to casting, validation, and other
+functionality provided by models:
+
+ var Comment = new Schema({
+ body : String
+ , date : Date
+ });
+
+ var Post = new Schema({
+ title : String
+ , comments : [Comment]
+ });
+
+This will allow you to interact very easily with subdocuments later on. For
+more information, refer to the chapter on
+[embedded documents](/docs/embedded-documents.html).
+
+### Defining custom options for keys
+
+Each key that you define is internally mapped to a `SchemaType`. Bear in mind, a
+Schema is not something that you interact directly with, but it's a way to
+describe to Mongoose what your want your data to look like, and how you want
+it to behave.
+
+`SchemaType`s take care of validation, casting, defaults, and other general
+options. Some functionality is exclusive to certain types of `SchemaType`s, for
+example only numbers support `min` and `max` values.
+
+In order to customize some of these options directly from the definition of
+your model, set your key to an object with the format `{ type: Type, ... }`.
+
+ var Person = new Schema({
+ title : { type: String, required: true }
+ , age : { type: Number, min: 5, max: 20 }
+ , meta : {
+ likes : [String]
+ , birth : { type: Date, default: Date.now }
+ }
+ });
+
+Those options are functions that are called on each SchemaType.
+If you want to define options later on, you could access a certain key through
+the `path` function:
+
+ Person.path('age').max(400);
+
+ Person.path('meta.birth').set(function (v) {
+ // this is a setter
+ });
+
+ Person.path('title').validate(function (v) {
+ return v.length > 50;
+ });
+
+Some of the options are versatile. `default` takes a `Function` or a value.
+`validate` takes a `Function` or a `RegExp`. More information on these can be
+found in the [Schema Type chapter](/docs/schematypes.html).
+
+## Beyond keys: Middleware
+
+Middleware are special user-defined functions that are called transparently
+when certain native methods are called on `Document` instances (`init`, `save`
+and `remove`).
+
+Let's say that you want to email a certain user when his document changes.
+You'd then define a hook on the User schema like this:
+
+ User.pre('save', function (next) {
+ email(this.email, 'Your record has changed');
+ next();
+ });
+
+More information about the specifics of middleware can be found [here](/docs/middleware.html).
+
+## Instance Methods and Static methods
+
+For details about defining your own custom static and instance methods read [this](/docs/methods-statics.html).
+
+## Plugins
+
+Schemas also support plugins. Read more about it on the [Plugins](/docs/plugins.html) page.
diff --git a/node_modules/mongoose/docs/plugins.md b/node_modules/mongoose/docs/plugins.md
new file mode 100644
index 0000000..2d22a55
--- /dev/null
+++ b/node_modules/mongoose/docs/plugins.md
@@ -0,0 +1,38 @@
+Plugins
+====================
+
+`Schema`s are pluggable, that is, they allow for applying pre-packaged
+capabilities to extend their functionality.
+
+Suppose that we have several collections in our database and want
+to add last-modified functionality to each one. With plugins this
+is easy. Just create a plugin once and apply it to each `Schema`:
+
+ // lastMod.js
+ module.exports = exports = function lastModifiedPlugin (schema, options) {
+ schema.add({ lastMod: Date })
+
+ schema.pre('save', function (next) {
+ this.lastMod = new Date
+ next()
+ })
+
+ if (options && options.index) {
+ schema.path('lastMod').index(options.index)
+ }
+ }
+
+ // in your schema files
+ var lastMod = require('./lastMod');
+
+ var Game = new Schema({ ... });
+
+ Game.plugin(lastMod);
+
+ var Player = new Schema({ ... });
+
+ Player.plugin(lastMod, { index: true });
+
+In the example above we added last-modified functionality to both the Game
+and Player schemas. We also took advantage of options passing supported by
+the `plugin()` method to dynamically define an index on the Player.
diff --git a/node_modules/mongoose/docs/populate.md b/node_modules/mongoose/docs/populate.md
new file mode 100644
index 0000000..d2ad207
--- /dev/null
+++ b/node_modules/mongoose/docs/populate.md
@@ -0,0 +1,166 @@
+Populate - DBRef-like behavior (experimental)
+=============================================
+
+`ObjectIds` can now refer to another document in a
+collection within our database and be populated when
+querying. An example is helpful:
+
+ var mongoose = require('mongoose')
+ , Schema = mongoose.Schema
+
+ var PersonSchema = new Schema({
+ name : String
+ , age : Number
+ , stories : [{ type: Schema.ObjectId, ref: 'Story' }]
+ });
+
+ var StorySchema = new Schema({
+ _creator : { type: Schema.ObjectId, ref: 'Person' }
+ , title : String
+ , fans : [{ type: Schema.ObjectId, ref: 'Person' }]
+ });
+
+ var Story = mongoose.model('Story', StorySchema);
+ var Person = mongoose.model('Person', PersonSchema);
+
+So far we've created two models. Our `Person` model has it's `stories` field
+set to an array of `ObjectId`s. The `ref` option is what tells Mongoose in which
+model to look, in our case the `Story` model. All `_id`s we
+store here must be document `_id`s from the `Story` model. We also added
+a `_creator` `ObjectId` to our `Story` schema which refers to a single `Person`.
+
+## Saving a ref (to the parent)
+
+Below you can see how we "save" a ref in 'story1' back to the _creator. This
+is usually all you need to do.
+
+
+ var aaron = new Person({ name: 'Aaron', age: 100 });
+
+ aaron.save(function (err) {
+ if (err) ...
+
+ var story1 = new Story({
+ title: "A man who cooked Nintendo"
+ , _creator: aaron._id
+ });
+
+ story1.save(function (err) {
+ if (err) ...
+ });
+ })
+
+## Populating the refs (to the parent)
+
+So far we haven't done anything special. We've merely created a `Person` and
+a `Story`. Now let's take a look at populating our story's `_creator`:
+
+ Story
+ .findOne({ title: /Nintendo/i })
+ .populate('_creator') // <--
+ .run(function (err, story) {
+ if (err) ..
+ console.log('The creator is %s', story._creator.name);
+ // prints "The creator is Aaron"
+ })
+
+Yup that's it. We've just queried for a `Story` with the term Nintendo in it's
+title and also queried the `Person` collection for the story's creator. Nice!
+
+Arrays of `ObjectId` refs work the same way. Just call the `populate` method on the query and
+an array of documents will be returned in place of the `ObjectId`s.
+
+What if we only want a few specific fields returned for the query? This can
+be accomplished by passing an array of field names to the `populate` method:
+
+ Story
+ .findOne({ title: /Nintendo/i })
+ .populate('_creator', ['name']) // <-- only return the Persons name
+ .run(function (err, story) {
+ if (err) ..
+
+ console.log('The creator is %s', story._creator.name);
+ // prints "The creator is Aaron"
+
+ console.log('The creators age is %s', story._creator.age)
+ // prints "The creators age is null'
+ })
+
+Now this is much better. The only property of the creator we are using
+is the `name` so we only returned that field from the db. Efficiency FTW!
+
+
+## References to the children
+
+You may find however, if you use the `aaron` object, you are unable to get
+a list of the `stories`. This is because no `story` objects were ever 'pushed'
+on to `aaron.stories`.
+
+There are two perspectives to this story. First, it's nice to have aaron know
+which are his stories.
+
+ aaron.stories.push(story1);
+ aaron.save();
+
+This allows you do a find & populate like:
+
+ Person
+ .findOne({ name: 'Aaron' })
+ .populate('stories') // <-- only works if you pushed refs to children
+ .run(function (err, person) {
+ if (err) ..
+
+ console.log('JSON for person is: ', person);
+
+ })
+
+However, it is debatable that you really want two sets of pointers as they
+may get out of sync. So you could instead merely find() the documents you
+are interested in.
+
+ Story
+ .find({ _creator: aaron._id })
+ .populate('_creator') // <-- not really necessary
+ .run(function (err, stories) {
+ if (err) ..
+
+ console.log('The stories JSON is an array: ', stoires);
+ })
+
+
+
+
+## Updating
+
+Now that we have a story we realized that the `_creator` was incorrect. We can
+update `ObjectId` refs the same as any other property through the magic of Mongooses
+internal casting:
+
+ var guille = new Person({ name: 'Guillermo' });
+ guille.save(function (err) {
+ if (err) ..
+
+ story._creator = guille; // or guille._id
+
+ story.save(function (err) {
+ if (err) ..
+
+ Story
+ .findOne({ title: /Nintendo/i })
+ .populate('_creator', ['name'])
+ .run(function (err, story) {
+ if (err) ..
+
+ console.log('The creator is %s', story._creator.name)
+ // prints "The creator is Guillermo"
+ })
+
+ })
+ })
+
+### Note:
+
+The documents returned from calling `populate` become fully functional,
+`remove`able, `save`able documents. Do not confuse them with embedded
+docs. Take caution when calling its `remove` method because
+you'll be removing it from the database, not just the array.
diff --git a/node_modules/mongoose/docs/query.md b/node_modules/mongoose/docs/query.md
new file mode 100644
index 0000000..d12892e
--- /dev/null
+++ b/node_modules/mongoose/docs/query.md
@@ -0,0 +1,362 @@
+
+Queries
+=================
+
+A `Query` is what is returned when calling many `Model`
+[methods](/docs/finding-documents.html). These `Query`
+objects provide a chaining api to specify search terms,
+cursor options, hints, and other behavior.
+
+## Query#where
+
+Lets you specify query terms with sugar.
+
+ query.where(path [, val])
+
+`path` is a valid document path. `val` is optional. Its useful to omit
+`val` when used in conjunction with other query methods. For example:
+
+ query
+ .where('name', 'Space Ghost')
+ .where('age').gte(21).lte(65)
+ .run(callback)
+
+In this case, `gte()` and `lte()` operate on the previous path if not
+explicitly passed. The above query results in the following query expression:
+
+ { name: 'Space Ghost', age: { $gte: 21, $lte: 65 }}
+
+## Query#$where
+
+Specifies the javascript function to run on MongoDB on each document scanned.
+See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-JavascriptExpressionsand%7B%7B%24where%7D%7D) for details.
+
+ Model.find().$where(fn)
+
+`fn` can be either a function or a string.
+
+## Query#$or, Query#or
+
+Specifies the [$or](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24or) operator.
+
+ query.$or(array);
+
+`array` is an array of expressions.
+
+ query.or([{ color: 'blue' }, { color: 'red' }]);
+
+## Query#gt, Query#$gt
+
+Specifies a [greater than](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D) expression.
+
+ query.$gt(path, val);
+
+`$gt` is also one of the methods with extra chaining sugar: when only one
+argument is passed, it uses the path used the last call to `where()`. Example:
+
+ Model.where('age').$gt(21)
+
+Results in:
+
+ { age: { $gt: 21 }}
+
+## Query#gte, Query#$gte
+
+Specifies a [greater than or equal to](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D) expression.
+
+ query.$gte(path, val);
+
+`$gte` is also one of the methods with extra chaining sugar: when only one
+argument is passed, it uses the path used the last call to `where()`. Example:
+
+ Model.where('age').$gte(21)
+
+Results in:
+
+ { age: { $gte: 21 }}
+
+## Query#lt,Query#$lt
+
+Specifies a [less than](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D) expression.
+
+ query.$lt(path, val);
+
+`$lt` is also one of the methods with extra chaining sugar: when only one
+argument is passed, it uses the path used the last call to `where()`. Example:
+
+ Model.where('age').$lt(21)
+
+Results in:
+
+ { age: { $lt: 21 }}
+
+## Query#lte, Query#$lte
+
+Specifies a [less than or equal to](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%3C%2C%3C%3D%2C%3E%2C%3E%3D) expression.
+
+ query.$lte(path, val);
+
+`$lte` is also one of the methods with extra chaining sugar: when only one
+argument is passed, it uses the path used the last call to `where()`. Example:
+
+ Model.where('age').$lte(21)
+
+Results in:
+
+ { age: { $lte: 21 }}
+
+## Query#ne, Query#$ne, Query#notEqualTo
+
+Specifies the [$ne](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24ne) operator.
+
+ query.$ne(path, val);
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used. Example:
+
+ query.where('_id').ne('4ecf92f31993a52c58e07f6a')
+
+and
+
+ query.notEqualTo('_id', '4ecf92f31993a52c58e07f6a')
+
+both result in
+
+ { _id: { $ne: ObjectId('4ecf92f31993a52c58e07f6a') }}
+
+## Query#in, Query#$in
+
+Specifies the [$in](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24in) operator.
+
+ query.$in(path, array)
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used.
+
+ query.where('tags').in(['game', 'fun', 'holiday'])
+
+results in
+
+ { tags: { $in: ['game', 'fun', 'holiday'] }}
+
+## Query#nin, Query#$nin
+
+Specifies the [$nin](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24nin) operator.
+
+ query.$nin(path, array)
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used.
+
+ query.where('games').nin(['boring', 'lame'])
+
+results in
+
+ { games: { $nin: ['boring', 'lame'] }}
+
+## Query#all, Query#$all
+
+Specifies the [$all](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24all) operator.
+
+ query.$all(path, array)
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used.
+
+ query.where('games').all(['fun', 'exhausting'])
+
+results in
+
+ { games: { $all: ['fun', 'exhausting'] }}
+
+## Query#regex, Query#$regex
+
+Specifies the [$regex](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions) operator.
+
+ query.regex('name.first', /^a/i)
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used.
+
+ query.where('name.first').$regex(/^a/i)
+
+results in
+
+ { 'name.first': { $regex: /^a/i }}
+
+## Query#size, Query#$size
+
+Specifies the [$size](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size) operator.
+
+ query.$size(path, integer)
+
+These methods have extra sugar in that
+when only one argument is passed, the path in the last call
+to `where()` is used.
+
+ query.size('comments', 2)
+ query.where('comments').size(2)
+
+both result in
+
+ { comments: { $size: 2 }}
+
+## Query#mod, Query#$mod
+
+Specifies the [$mod](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24mod) operator.
+
+ var array = [10, 1]
+ query.mod(path, array)
+
+ query.mod(path, 10, 1)
+
+ query.where(path).$mod(10, 1)
+
+all result in
+
+ { path: { $mod: [10, 1] }}
+
+## Query#exists, Query#$exists
+
+Specifies the [$exists](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24exists) operator.
+
+ query.exists(path, Boolean)
+
+These methods have extra sugar in that
+when only one argument is passed, the path from the last call
+to `where()` is used.
+
+Given the following query,
+
+ var query = Model.find();
+
+the following queries
+
+ query.exists('occupation');
+ query.exists('occupation', true);
+ query.where('occupation').exists();
+
+all result in
+
+ { occupation: { $exists: true }}
+
+Another example:
+
+ query.exists('occupation', false)
+ query.where('occupation').exists(false);
+
+result in
+
+ { occupation: { $exists: false }}
+
+## Query#elemMatch, Query#$elemMatch
+
+Specifies the [$elemMatch](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24elemMatch) operator.
+
+ query.elemMatch(path, criteria)
+ query.where(path).elemMatch(criteria)
+
+Functions can also be passed so you can further use query sugar
+to declare the expression:
+
+ query.where(path).elemMatch(function)
+ query.elemMatch(path, function)
+
+In this case a `query` is passed as the only argument into the function.
+
+ query.where('comments').elemMatch(function (elem) {
+ elem.where('author', 'bnoguchi')
+ elem.where('votes').gte(5);
+ });
+
+Results in
+
+ { comments: { $elemMatch: { author: 'bnoguchi', votes: { $gte: 5 }}}}
+
+## Query#within, Query#$within
+
+## Query#box, Query#$box
+
+## Query#center, Query#$center
+
+## Query#centerSphere, Query#$centerSphere
+
+## Query#near, Query#$near
+
+Specifies the [$near](http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-Querying) operator.
+
+ var array = [10, 1]
+ query.near(path, array)
+
+ query.near(path, 10, 1)
+
+ query.where(path).$near(10, 1)
+
+all result in
+
+ { path: { $near: [10, 1] }}
+
+## Query#maxDistance, Query#$maxDistance
+
+Specifies the [$maxDistance](http://www.mongodb.org/display/DOCS/Geospatial+Indexing#GeospatialIndexing-Querying) operator.
+
+ query.where('checkin').near([40, -72]).maxDistance(1);
+
+results in
+
+ { checkin: { $near: [40, -72], $maxDistance: 1 }}
+
+## Query#select
+## Query#fields
+
+## Query#only
+## Query#exclude
+
+## Query#slice
+## Query#$slice
+
+## Query#populate
+
+// sorting
+## Query#sort
+## Query#asc
+## Query#desc
+
+// options
+## Query#limit
+## Query#skip
+## Query#maxscan
+## Query#snapshot
+## Query#batchSize
+## Query#slaveOk
+## Query#hint
+
+// executing
+## Query#find
+
+ query.find(criteria [, callback])
+
+## Query#findOne
+## Query#count
+## Query#distinct
+## Query#update
+## Query#remove
+
+## Query#run
+## Query#exec
+
+ query.run([callback])
+
+## Query#each
+
+## Query#stream
+
+Returns a [QueryStream](/docs/querystream.html) for the query.
+
+ Model.find({}).stream().pipe(writeStream)
+
diff --git a/node_modules/mongoose/docs/querystream.md b/node_modules/mongoose/docs/querystream.md
new file mode 100644
index 0000000..a2a7300
--- /dev/null
+++ b/node_modules/mongoose/docs/querystream.md
@@ -0,0 +1,6 @@
+
+Querystreams
+=================
+
+Docs coming soon
+
diff --git a/node_modules/mongoose/docs/schematypes.md b/node_modules/mongoose/docs/schematypes.md
new file mode 100644
index 0000000..f1e2787
--- /dev/null
+++ b/node_modules/mongoose/docs/schematypes.md
@@ -0,0 +1,197 @@
+
+Schema Types
+============
+
+`SchemaType`s take care of validation, casting, defaults, and other general
+options in our models. We can specify our types one of two ways:
+
+ // directly without options
+ var Person = new Schema({
+ title : String
+ });
+
+ // or with options
+ var Person = new Schema({
+ title : { type: String, lowercase: true }
+ });
+
+In the example above we specified the `lowercase` option for strings which
+will lowercase the string whenever it is set. Options are functions that are
+called on each SchemaType. Each `SchemaType` has its own set of custom options.
+
+## Available Schema Types
+
+### String
+
+ - `lowercase`: {Boolean}
+
+ Creates a setter which calls `.toLowerCase()` on the value
+
+ - `uppercase`: {Boolean}
+
+ Creates a setter which calls `.toUpperCase()` on the value
+
+ - `trim`: {Boolean}
+
+ Creates a setter which calls `.trim()` on the value
+
+ - `match`: {RegExp}
+
+ Creates a RegExp based [validator](/docs/validation.html). The value being set is `.test()`ed
+ against the RegExp. If it does not pass, validation will fail.
+
+ - `enum`: {Array}
+
+ Creates an enum validator. If the value being set is not in this
+ array, validation will fail.
+
+### Number
+
+ - `min`: {Number}
+
+ Creates a validator which checks that the value being set is not less
+ than the value specified.
+
+ - `max`: {Number}
+
+ Creates a validator which checks that the value being set is not greater
+ than the value specified.
+
+### Date
+
+ - no custom options
+
+### Boolean
+
+ - no custom options
+
+### Buffer (v2.x only)
+
+ - no custom options
+
+### ObjectId
+
+ To specify a type of `ObjectId`, use `Schema.ObjectId` in your declaration.
+
+ var mongoose = require('mongoose');
+ var Schema = mongoose.Schema;
+ var Car = new Schema({ driver: Schema.ObjectId })
+
+ - no custom options
+
+### Mixed
+
+ An "anything goes" `SchemaType`, its flexibility comes at a trade-off of it being
+ harder to maintain. `Mixed` is available either through `Schema.Types.Mixed` or
+ by passing an empty object literal. The following are equivalent:
+
+ var Any = new Schema({ any: {} });
+ var Any = new Schema({ any: Schema.Types.Mixed });
+
+ Since it is a schema-less type, you can change the value to anything else
+ you like, but Mongoose loses the ability to auto detect/save those changes.
+ To "tell" Mongoose that the value of a `Mixed` type has changed, call
+ the `.markModified(path)` method of the document passing the path to
+ the `Mixed` type you just changed.
+
+ person.anything = { x: [3, 4, { y: "changed" }] };
+ person.markModified('anything');
+ person.save(); // anything will now get saved
+
+ - no custom options
+
+### Array
+
+ Creates an array of `SchemaTypes` or [Embedded Documents](/docs/embedded-documents.html).
+
+ var ToySchema = new Schema({ name: String });
+ var ToyBox = new Schema({
+ toys: [ToySchema]
+ , buffers: [Buffer]
+ , string: [String]
+ , numbers: [Number]
+ ... etc
+ });
+
+ Note: specifying an empty array is equivalent to `[Mixed]`. The following all
+ create arrays of `Mixed`:
+
+ var Empty1 = new Schema({ any: [] });
+ var Empty2 = new Schema({ any: Array });
+ var Empty3 = new Schema({ any: [Schema.Types.Mixed] });
+ var Empty4 = new Schema({ any: [{}] });
+
+ - no custom options
+
+## Additional options
+
+Besides the options listed above, all SchemaTypes share the following additional
+options.
+
+ - `default`: {Function|value} - Determines the default value for the path. All values are casted. If using a function, the value it returns will be casted as the default value.
+
+ - `required`: {Boolean} - If true, creates a validation rule requiring this path be set before saving occurs.
+
+ - `get`: {Function} - Adds a getter for this path. See the [getters / setters](/docs/getters-setters.html) docs for more detail.
+
+ - `set`: {Function} - Adds a setter for this path. See the [getters / setters](/docs/getters-setters.html) docs for more detail.
+
+ - `index`: {Boolean|Object} - Tells Mongoose to ensure an index is created for this path. An object can be passed as well.
+
+ var Person = new Schema({ name: String, index: true })
+ var Person = new Schema({ name: String, index: { unique: true }})
+
+ Note: indexes cannot be created for `Buffer` `SchemaTypes`. <br>
+ Note: if the index already exists on the db, it will _not_ be replaced.
+
+ - `unique`: {Boolean} - Tells Mongoose to ensure a unique index is created for this path. The following are equivalent:
+
+ var Person = new Schema({ name: String, unique: true })
+ var Person = new Schema({ name: String, index: { unique: true }})
+
+ Note: indexes cannot be created for `Buffer` `SchemaTypes`. <br>
+ Note: if the index already exists on the db, it will _not_ be replaced.
+
+ - `sparse`: {Boolean} - Tells Mongoose to ensure a sparse index is created for this path. The following are equivalent:
+
+ var Person = new Schema({ name: String, sparse: true })
+ var Person = new Schema({ name: String, index: { sparse: true }})
+
+ Note: indexes cannot be created for `Buffer` `SchemaTypes`. <br>
+ Note: if the index already exists on the db, it will _not_ be replaced.
+
+ - `validate`: {Function|RegExp|Array} - Creates a [validator](/docs/validation.html) for this path.
+
+ // passing a function
+ function hasNumber (v) {
+ return v.length && /\d/.test(v);
+ }
+ var Person = new Schema({ street: String, validate: hasNumber });
+
+ // passing a RegExp
+ var Person = new Schema({ street: String, validate: /\d/ });
+
+ // passing an array
+ var Person = new Schema({ street: String, validate: [hasNumber, 'street number required'] });
+
+ // or
+ var Person = new Schema({ street: String, validate: [/\d/, 'street number required'] });
+
+ For more detail about validation including async validation, see the [validation](/docs/validation.html) page.
+
+## Alternate options definition
+
+Instead of defining options when instanciating your `Schema` we can also
+access keys through the `path` function and add options there:
+
+ Person.path('age').max(400);
+
+ Person.path('meta.birth').set(function (v) {
+ // this is a setter
+ });
+
+ Person.path('title').validate(function (v) {
+ return v.length > 50;
+ });
+
+
diff --git a/node_modules/mongoose/docs/validation.md b/node_modules/mongoose/docs/validation.md
new file mode 100644
index 0000000..7748e8b
--- /dev/null
+++ b/node_modules/mongoose/docs/validation.md
@@ -0,0 +1,92 @@
+
+Validation in models
+====================
+
+Before we get into the specifics of validation syntax, please keep the
+following rules in mind:
+
+- Validation is defined in the `Schema`
+
+- Validation occurs when a document attempts to be saved, after defaults have
+been applied.
+
+- Mongoose doesn't care about complex error message construction. Errors have
+type identifiers. For example, `"min"` is the identifier for the error
+triggered when a number doesn't meet the minimum value. The path and value
+that triggered the error can be accessed in the `ValidationError` object.
+
+- Validation is an internal piece of middleware
+
+- Validation is asynchronously recursive: when you call `Model#save`, embedded
+ documents validation is executed. If an error happens, your `Model#save`
+ callback receives it.
+
+## Simple validation
+
+Simple validation is declared by passing a function to `validate` and an error
+type to your `SchemaType` \(please read the chapter on [model definition](/docs/model-definition.html) to learn
+more about schemas).
+
+ function validator (v) {
+ return v.length > 5;
+ };
+
+ new Schema({
+ name: { type: String, validate: [validator, 'my error type'] }
+ })
+
+If you find this syntax too clumsy, you can also define the type
+
+ var schema = new Schema({
+ name: String
+ })
+
+and then your validator
+
+ schema.path('name').validate(function (v) {
+ return v.length > 5;
+ }, 'my error type');
+
+## Regular expressions
+
+If you want to test a certain value against a regular expression:
+
+ var schema = new Schema({
+ name: { type: String, validate: /[a-z]/ }
+ });
+
+## Asynchronous validation
+
+If you define a validator function with two parameters, like:
+
+ schema.path('name').validate(function (v, fn) {
+ // my logic
+ }, 'my error type');
+
+Then the function `fn` has to be called with `true` or `false`, depending on
+whether the validator passed. This allows for calling other models and querying
+data asynchronously from your validator.
+
+## Built in validators
+
+Strings:
+
+ - `enum`: takes a list of allowed values. Example:
+
+ var Post = new Schema({
+ type: { type: String, enum: ['page', 'post', 'link'] }
+ })
+
+Numbers:
+
+ - `min`: minimum value
+
+ var Person = new Schema({
+ age: { type: Number, min: 5 }
+ })
+
+ - `max`: maxmimum value
+
+ var Person = new Schema({
+ age: { type: Number, max: 100 }
+ })
diff --git a/node_modules/mongoose/docs/virtuals.md b/node_modules/mongoose/docs/virtuals.md
new file mode 100644
index 0000000..65bc2bf
--- /dev/null
+++ b/node_modules/mongoose/docs/virtuals.md
@@ -0,0 +1,84 @@
+Virtual attributes
+====================
+
+Mongoose supports virtual attributes. Virtual attributes are attributes
+that are convenient to have around but that do not get persisted to mongodb.
+
+An example is helpful.
+
+## Example
+Take the following schema:
+
+ var PersonSchema = new Schema({
+ name: {
+ first: String
+ , last: String
+ }
+ });
+
+ var Person = mongoose.model('Person', PersonSchema);
+
+ var theSituation = new Person({name: { first: 'Michael', last: 'Sorrentino' }});
+
+Suppose you want to write `theSituation`'s full name. You could do so via:
+
+ console.log(theSituation.name.first + ' ' + theSituation.name.last);
+
+It is more convenient to define a virtual attribute, `name.full`, so you can instead write:
+
+ console.log(theSituation.name.full);
+
+To do so, you can declare a virtual attribute on the Schema, `Person`:
+
+ PersonSchema
+ .virtual('name.full')
+ .get(function () {
+ return this.name.first + ' ' + this.name.last;
+ });
+
+So when you get `name.full`, via
+
+ theSituation.name.full;
+
+the implementation ends up invoking the getter function
+
+ function () {
+ return this.name.first + ' ' + this.name.last;
+ }
+
+and returning it.
+
+It would also be nice to be able to set `this.name.first` and `this.name.last` by setting `this.name.full`. For example, it would be nice if we wanted to change theSituation's `name.first` and `name.last` to 'The' and 'Situation' respectively just by invoking:
+
+ theSituation.set('name.full', 'The Situation');
+
+Mongoose allows you to do this, too, via virtual attribute setters. You can define a virtual attribute setter thusly:
+
+ PersonSchema
+ .virtual('name.full')
+ .get(function () {
+ return this.name.first + ' ' + this.name.last;
+ })
+ .set(function (setFullNameTo) {
+ var split = setFullNameTo.split(' ')
+ , firstName = split[0]
+ , lastName = split[1];
+
+ this.set('name.first', firstName);
+ this.set('name.last', lastName);
+ });
+
+Then, when you invoke:
+
+ theSituation.set('name.full', 'The Situation');
+
+and you save the document, then `name.first` and `name.last` will be changed in monbodb, but the mongodb document will not have persisted a `name.full` key or value to the database:
+
+ theSituation.save(function (err) {
+ Person.findById(theSituation._id, function (err, found) {
+ console.log(found.name.first); // 'The'
+ console.log(found.name.last); // 'Situation'
+ });
+ });
+
+If you want attributes that you can get and set but that are not themselves persisted to mongodb, virtual attributes is the Mongoose feature for you.