Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongoose 3.x and other fixes #25

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
**.swp
/node_modules/
/node_modules/*
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
EXPRESSO = support/expresso/bin/expresso -I lib
#EXPRESSO = support/expresso/bin/expresso -I lib
EXPRESSO = node_modules/.bin/expresso -I lib

TESTS = tests/*.test.js

Expand Down
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
mongoose-types - Useful types and type plugins for Mongoose
==============
mongoose-3x-types - Useful types and type plugins for Mongoose
=================

This library is a fork of [mongoose-types](http://github.com/bnoguchi/mongoose-types), updated to work both with [mongoose](http://mongoosejs.com) 2.x and 3.x.

It is meant to be used as an interim solution while waiting for the upstream version to be updated.


### Types include:

Expand All @@ -12,32 +17,38 @@ mongoose-types - Useful types and type plugins for Mongoose
Adds `createdAt` and `updatedAt` date attributes that get auto-assigned to the most recent create/update timestamp.

### Installation
npm install mongoose-types
npm install mongoose-3x-types

### Setup

To include all of the defined types:

var mongoose = require("mongoose");
var db = mongoose.createConnection("mongodb://localhost/sampledb");
var mongooseTypes = require("mongoose-types");
var mongooseTypes = require("mongoose-3x-types");
mongooseTypes.loadTypes(mongoose);

You can also specify that you only want to load and use a limited subset of the types provided:

var mongoose = require("mongoose");
var db = mongoose.createConnection("mongodb://localhost/sampledb");
var mongooseTypes = require("mongoose-types");
var mongooseTypes = require("mongoose-3x-types");
// Only load the email type
mongooseTypes.loadTypes(mongoose, "email");

### Using the types

Once you are setup, you can begin to use the new types.

#### Mongoose 2.x and 3.x

When on mongoose 3.x use `mongoose.Schema.Types`, otherwise if you're on mongoose 2.x use `mongoose.SchemaTypes`.

Keep this in mind when reading the following examples.

#### Email

var Email = mongoose.SchemaTypes.Email;
var Email = mongoose.Schema.Types.Email;
var UserSchema = new Schema({
email: {
work: Email
Expand All @@ -47,7 +58,7 @@ Once you are setup, you can begin to use the new types.

#### Url

var Url = mongoose.SchemaTypes.Url;
var Url = mongoose.Schema.Types.Url;
var VisitSchema = new Schema({
url: Url
, referer: Url
Expand All @@ -59,7 +70,7 @@ Once you are setup, you can begin to use the new types.

var mongoose = require("mongoose");
var db = mongoose.createConnection("mongodb://localhost/sampledb");
var mongooseTypes = require("mongoose-types")
var mongooseTypes = require("mongoose-3x-types")
, useTimestamps = mongooseTypes.useTimestamps;
var UserSchema = new Schema({
username: String
Expand Down Expand Up @@ -92,6 +103,7 @@ To run tests:
### Contributors

- [Brian Noguchi](https://github.com/bnoguchi)
- [Marco Pantaleoni](https://github.com/panta)

### License

Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/useTimestamps.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var mongoose = require('mongoose')
, ObjectID = mongoose.ObjectID
, BinaryParser = mongoose.mongo.BinaryParser;
, BinaryParser = mongoose.mongo.BinaryParser || require('mongoose/node_modules/mongodb/node_modules/bson').BinaryParser;

exports.useTimestamps = function (schema, options) {
if (schema.path('_id')) {
Expand Down
7 changes: 3 additions & 4 deletions lib/types/email.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
var mongoose = require('mongoose')
var mongoose = require('mongoose');

module.exports.loadType = function (mongoose) {
var SchemaTypes = mongoose.SchemaTypes;

var SchemaTypes = mongoose.SchemaTypes || mongoose.Schema.Types;
function Email (path, options) {
SchemaTypes.String.call(this, path, options);
function validateEmail (val) {
return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(val);
return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(val);
}
this.validate(validateEmail, 'email is invalid');
}
Expand Down
18 changes: 14 additions & 4 deletions lib/types/url.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
var Url = require("url");

module.exports.loadType = function (mongoose) {
var SchemaTypes = mongoose.SchemaTypes;
function isEmpty(obj) {
if (Object.keys !== undefined) {
return Object.keys(obj).length === 0;
}
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}

module.exports.loadType = function (mongoose) {
var SchemaTypes = mongoose.SchemaTypes || mongoose.Schema.Types;
function Url (path, options) {
SchemaTypes.String.call(this, path, options);
function validateUrl (val) {
var urlRegexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
var urlRegexp = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
return urlRegexp.test(val);
}
this.validate(validateUrl, 'url is invalid');
Expand Down Expand Up @@ -49,7 +59,7 @@ module.exports.normalizeUrl = (function () {
pathname.replace(/\/\.{1,2}\//g, "/").replace(/\/{2,}/, "/") : // Remove dot-segments; Remove duplicate slashes
"/" // Add trailing /
);
if (query) {
if (query && (! isEmpty(query))) {
urlstr += "?" + reorderQuery(query);
}
if (hash) {
Expand Down
18 changes: 15 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
{ "name": "mongoose-types"
{ "name": "mongoose-3x-types"
, "description": "More types for mongoose"
, "version": "1.0.3"
, "version": "1.0.5"
, "author": "Brian Noguchi"
, "dependencies": { "mongoose": ">= 1.0.16"}
, "contributors": [
{ "name": "Marco Pantaleoni"
, "email": "[email protected]"
} ]
, "dependencies": { "mongoose": ">= 2.6.0"}
, "devDependencies": {
"expresso": "0.9.2"
, "should": "1.1.0"
}
, "keywords": [ "mongoose", "mongo", "mongodb", "types" ]
, "scripts": { "test": "make test" }
, "engines": { "node": ">= 0.1.101" }
, "main": "./index"
, "repository": {
"type": "git"
, "url": "https://github.com/panta/mongoose-types.git"
}
, "licenses": [ { "type": "The MIT License", "url": "http://www.opensource.org/licenses/mit-license.php" } ]
}
10 changes: 6 additions & 4 deletions tests/email.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
require('should');
var should = require('should');
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, SchemaTypes = mongoose.SchemaTypes || mongoose.Schema.Types
, db = mongoose.createConnection('mongodb://localhost/mongoose_types_tests');

require("../").loadTypes(mongoose, 'email');

var UserSchema = new Schema({
email: mongoose.SchemaTypes.Email
email: SchemaTypes.Email
});

mongoose.model('User', UserSchema);
Expand All @@ -20,14 +21,15 @@ module.exports = {
'test invalid email validation': function () {
var user = new User({email: 'hello'});
user.save(function (err) {
err.message.should.equal('Validator "email is invalid" failed for path email');
var message = err.errors.email.message || err.message;
message.should.equal('Validator "email is invalid" failed for path email');
user.isNew.should.be.true;
});
},
'test valid email validation': function () {
var user = new User({ email: '[email protected]' });
user.save(function (err) {
err.should.eql(null);
should.not.exist(err);
user.isNew.should.be.false;
});
},
Expand Down
10 changes: 6 additions & 4 deletions tests/url.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
require('should');
var should = require('should');
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, SchemaTypes = mongoose.SchemaTypes || mongoose.Schema.Types
, db = mongoose.createConnection('mongodb://localhost/mongoose_types_tests');

require("../").loadTypes(mongoose, 'url');

var WebpageSchema = new Schema({
url: mongoose.SchemaTypes.Url
url: SchemaTypes.Url
});

mongoose.model('Webpage', WebpageSchema);
Expand All @@ -20,14 +21,15 @@ module.exports = {
'test invalid url validation': function () {
var webpage = new Webpage({url: 'file:///home/'});
webpage.save(function (err) {
err.message.should.equal('Validator "url is invalid" failed for path url');
var message = err.errors.url.message || err.message;
message.should.equal('Validator "url is invalid" failed for path url');
webpage.isNew.should.be.true;
});
},
'test valid url validation': function () {
var webpage = new Webpage({ url: 'http://www.google.com/' });
webpage.save(function (err) {
err.should.eql(null);
should.not.exist(err);
webpage.isNew.should.be.false;
});
},
Expand Down
18 changes: 9 additions & 9 deletions tests/useTimestamps.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require('should');
var should = require('should');
var mongoose = require('mongoose')
, Schema = mongoose.Schema
, db = mongoose.createConnection('mongodb://localhost/mongoose_types_tests')
Expand All @@ -17,25 +17,25 @@ module.exports = {
before: function(done){
TimeCop = db.model('TimeCop', TimeCopSchema);
TimeCop.remove({}, function () {
done();
//done();
});
},
'createdAt and updatedAt should be set to the same value on creation': function (done) {
'createdAt and updatedAt should be set to the same value on creation': function (done, assert) {
var cop = new TimeCop({ email: '[email protected]' });
cop.save( function (err) {
cop.createdAt.should.be.an.instanceof(Date);
cop.updatedAt.should.be.an.instanceof(Date);
done();
(cop.createdAt instanceof Date).should.be.true;
(cop.updatedAt instanceof Date).should.be.true;
//done();
});
},
'updatedAt should be later than createdAt upon updating': function (done) {
'updatedAt should be later than createdAt upon updating': function (done, assert) {
TimeCop.findOne({email: '[email protected]'}, function (err, found) {
found.email = '[email protected]';
setTimeout( function () {
found.save( function (err, updated) {
updated.updatedAt.should.be.greater.than(updated.createdAt);
updated.updatedAt.should.be.above(updated.createdAt);
assert.ok(updated.updatedAt > updated.createdAt);
done();
//done();
});
}, 1000);
});
Expand Down