Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

camo

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

camo - npm Package Compare versions

Comparing version 0.9.1 to 0.10.0

8

CHANGELOG.md

@@ -0,1 +1,9 @@

## 0.10.0 (2015-11-12)
Features:
- Added support for setting the 'unique' index on a field
- Added support for specifying which reference fields should be populated in `loadOne()` and `loadMany()`
Bugfixes:
- Fixed issue in `isNativeId` where we weren't returning a proper Boolean.
## 0.9.1 (2015-11-06)

@@ -2,0 +10,0 @@

12

lib/base-document.js

@@ -239,8 +239,13 @@ "use strict";

static create(data) {
this.createIndexes();
if (typeof(data) !== 'undefined') {
return this._fromData(data);
}
return this._instantiate();
}
static createIndexes() { }
static _instantiate() {

@@ -314,3 +319,3 @@ var instance = new this();

//
static populate(docs) {
static populate(docs, fields) {
if (!docs) return Promise.all([]);

@@ -337,2 +342,7 @@

_.keys(anInstance._schema).forEach(function(key) {
// Only populate specified fields
if (isArray(fields) && fields.indexOf(key) < 0) {
return;
}
// Handle array of references (ex: { type: [MyObject] })

@@ -339,0 +349,0 @@ if (isArray(anInstance._schema[key].type) &&

@@ -44,2 +44,6 @@ "use strict";

createIndex(collection, field, options) {
throw new TypeError('You must override createIndex.');
}
static connect(url, options) {

@@ -46,0 +50,0 @@ throw new TypeError('You must override connect (static).');

@@ -179,2 +179,14 @@ "use strict";

createIndex(collection, field, options) {
options = options || {};
options.unique = options.unique || false;
options.sparse = options.sparse || false;
var db = this._mongo.collection(collection);
var keys = {};
keys[field] = 1;
db.createIndex(keys, {unique: options.unique, sparse: options.sparse});
}
static connect(url, options) {

@@ -227,3 +239,3 @@ if (typeof(options) === 'undefined') {

isNativeId(value) {
return value instanceof ObjectId || String(value).match(/^[a-fA-F0-9]{24}$/);
return value instanceof ObjectId || String(value).match(/^[a-fA-F0-9]{24}$/) !== null;
}

@@ -230,0 +242,0 @@

@@ -222,2 +222,11 @@ "use strict";

createIndex(collection, field, options) {
options = options || {};
options.unique = options.unique || false;
options.sparse = options.sparse || false;
var db = getCollection(collection, this._collections, this._path);
db.ensureIndex({fieldName: field, unique: options.unique, sparse: options.sparse});
}
static connect(url, options) {

@@ -297,3 +306,3 @@ // Could be directory path or 'memory'

isNativeId(value) {
return String(value).match(/^[a-zA-Z0-9]{16}$/);
return String(value).match(/^[a-zA-Z0-9]{16}$/) !== null;
}

@@ -300,0 +309,0 @@

@@ -238,4 +238,4 @@ "use strict";

var doc = that._fromData(data);
if (populate) {
return that.populate(doc);
if (populate === true || (isArray(populate) && populate.length > 0)) {
return that.populate(doc, populate);
}

@@ -318,5 +318,8 @@

var docs = that._fromData(datas);
if (options.populate) {
return that.populate(docs);
if (options.populate === true ||
(isArray(options.populate) && options.populate.length > 0)) {
return that.populate(docs, options.populate);
}
return docs;

@@ -334,2 +337,19 @@ }).then(function(docs) {

static createIndexes() {
if (this._indexesCreated) {
return;
}
var that = this;
var instance = this._instantiate();
_.keys(instance._schema).forEach(function(k) {
if (instance._schema[k].unique) {
DB().createIndex(that.collectionName(), k, {unique: true});
}
});
this._indexesCreated = true;
}
static _fromData(datas) {

@@ -336,0 +356,0 @@ var instances = super._fromData(datas);

4

package.json
{
"name": "camo",
"version": "0.9.1",
"version": "0.10.0",
"description": "A class-based ES6 ODM for Mongo-like databases.",

@@ -42,3 +42,3 @@ "author": {

"optionalDependencies": {
"mongodb": "2.0.33",
"mongodb": "2.0.42",
"nedb": "1.1.2"

@@ -45,0 +45,0 @@ },

@@ -150,3 +150,4 @@ # Camo

max: 25,
choices: [2, 3, 5, 7, 11, 13, 17, 19, 23]
choices: [2, 3, 5, 7, 11, 13, 17, 19, 23],
unique: true
}

@@ -164,2 +165,3 @@ ```

- `validate`: A 1-argument function that returns `false` if the value is invalid *(optional)*
- `unique`: A boolean value indicating if a 'unique' index should be set *(optional)*

@@ -265,4 +267,13 @@ To reference another document, just use its class name as the type.

With the `.loadOne()` method you can now pass it options to modify the returned results:
`.loadOne()` currently accepts the following option:
- `populate`: Boolean value to load all or no references. Pass an array of field names to only populate the specified references
- `Person.loadOne({name: 'Billy'}, {populate: true})` populates all references in `Person` object
- `Person.loadOne({name: 'Billy'}, {populate: ['address', 'spouse']})` populates only 'address' and 'spouse' in `Person` object
`.loadMany()` currently accepts the following options:
- `populate`: Boolean value to load all or no references. Pass an array of field names to only populate the specified references
- `Person.loadMany({lastName: 'Smith'}, {populate: true})` populates all references in `Person` object
- `Person.loadMany({lastName: 'Smith'}, {populate: ['address', 'spouse']})` populates only 'address' and 'spouse' in `Person` object
- `sort`: Sort the documents by the given field

@@ -269,0 +280,0 @@ - `Person.loadMany({}, {sort: '-age'})` sorts by age in descending order

@@ -6,2 +6,3 @@ "use strict";

var connect = require('../index').connect;
var Document = require('../index').Document;
var Data = require('./data');

@@ -13,2 +14,3 @@ var getData1 = require('./util').data1;

var validateId = require('./util').validateId;
var isNativeId = require('../lib/validate').isNativeId;

@@ -54,2 +56,36 @@ describe('Client', function() {

class Address extends Document {
constructor() {
super('address');
this.street = String;
this.city = String;
this.zipCode = Number;
}
}
class Pet extends Document {
constructor() {
super('pet');
this.schema({
type: String,
name: String,
});
}
}
class User extends Document {
constructor() {
super('user');
this.schema({
firstName: String,
lastName: String,
pet: Pet,
address: Address
});
}
}
describe('#loadOne()', function() {

@@ -68,2 +104,98 @@ it('should load a single object from the collection', function(done) {

});
it('should populate all fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return user.save();
}).then(function() {
validateId(user);
return User.loadOne({_id: user.id}, {populate: true});
}).then(function(u) {
expect(u.pet).to.be.an.instanceof(Pet);
expect(u.address).to.be.an.instanceof(Address);
}).then(done, done);
});
it('should not populate any fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return user.save();
}).then(function() {
validateId(user);
return User.loadOne({_id: user.id}, {populate: false});
}).then(function(u) {
expect(isNativeId(u.pet)).to.be.true;
expect(isNativeId(u.address)).to.be.true;
}).then(done, done);
});
it('should populate specified fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return user.save();
}).then(function() {
validateId(user);
return User.loadOne({_id: user.id}, {populate: ['pet']});
}).then(function(u) {
expect(u.pet).to.be.an.instanceof(Pet);
expect(isNativeId(u.address)).to.be.true;
}).then(done, done);
});
});

@@ -228,2 +360,128 @@

});
it('should populate all fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user1 = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
var user2 = User.create({
firstName: 'Sally',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return Promise.all([user1.save(), user2.save()]);
}).then(function() {
validateId(user1);
validateId(user2);
return User.loadMany({}, {populate: true});
}).then(function(users) {
expect(users[0].pet).to.be.an.instanceof(Pet);
expect(users[0].address).to.be.an.instanceof(Address);
expect(users[1].pet).to.be.an.instanceof(Pet);
expect(users[1].address).to.be.an.instanceof(Address);
}).then(done, done);
});
it('should not populate any fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user1 = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
var user2 = User.create({
firstName: 'Sally',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return Promise.all([user1.save(), user2.save()]);
}).then(function() {
validateId(user1);
validateId(user2);
return User.loadMany({}, {populate: false});
}).then(function(users) {
expect(isNativeId(users[0].pet)).to.be.true;
expect(isNativeId(users[0].address)).to.be.true;
expect(isNativeId(users[1].pet)).to.be.true;
expect(isNativeId(users[1].address)).to.be.true;
}).then(done, done);
});
it('should populate specified fields', function(done) {
var address = Address.create({
street: '123 Fake St.',
city: 'Cityville',
zipCode: 12345
});
var dog = Pet.create({
type: 'dog',
name: 'Fido',
});
var user1 = User.create({
firstName: 'Billy',
lastName: 'Bob',
pet: dog,
address: address
});
var user2 = User.create({
firstName: 'Sally',
lastName: 'Bob',
pet: dog,
address: address
});
Promise.all([address.save(), dog.save()]).then(function() {
validateId(address);
validateId(dog);
return Promise.all([user1.save(), user2.save()]);
}).then(function() {
validateId(user1);
validateId(user2);
return User.loadMany({}, {populate: ['pet']});
}).then(function(users) {
expect(users[0].pet).to.be.an.instanceof(Pet);
expect(isNativeId(users[0].address)).to.be.true;
expect(users[1].pet).to.be.an.instanceof(Pet);
expect(isNativeId(users[1].address)).to.be.true;
}).then(done, done);
});
});

@@ -230,0 +488,0 @@

@@ -148,2 +148,65 @@ "use strict";

});
describe('indexes', function() {
it('should reject documents with duplicate values in unique-indexed fields', function(done) {
class User extends Document {
constructor() {
super('user');
this.schema({
name: String,
email: {
type: String,
unique: true
}
});
}
}
var user1 = User.create();
user1.name = 'Bill';
user1.email = 'billy@example.com';
var user2 = User.create();
user1.name = 'Billy';
user2.email = 'billy@example.com';
Promise.all([user1.save(), user2.save()]).then(function() {
expect.fail(null, Error, 'Expected error, but got none.');
}).catch(function(error) {
expect(error instanceof Error).to.be.true;
}).then(done, done);
});
it('should accept documents with duplicate values in non-unique-indexed fields', function(done) {
class User extends Document {
constructor() {
super('user');
this.schema({
name: String,
email: {
type: String,
unique: false
}
});
}
}
var user1 = User.create();
user1.name = 'Bill';
user1.email = 'billy@example.com';
var user2 = User.create();
user1.name = 'Billy';
user2.email = 'billy@example.com';
Promise.all([user1.save(), user2.save()]).then(function() {
validateId(user1);
validateId(user2);
expect(user1.email).to.be.equal('billy@example.com');
expect(user2.email).to.be.equal('billy@example.com');
}).then(done, done);
});
});
});

@@ -7,5 +7,3 @@ "use strict";

var connect = require('../index').connect;
var Data = require('./data');
var getData1 = require('./util').data1;
var getData2 = require('./util').data2;
var Document = require('../index').Document;
var validateId = require('./util').validateId;

@@ -22,3 +20,3 @@

// floating around due to document.test.js?
/*before(function(done) {
before(function(done) {
connect(url).then(function(db) {

@@ -44,3 +42,3 @@ database = db;

describe('#dropDatabase()', function() {
/*describe('#dropDatabase()', function() {
it('should drop the database and delete all its data', function(done) {

@@ -98,2 +96,65 @@

});*/
describe('indexes', function() {
it('should reject documents with duplicate values in unique-indexed fields', function(done) {
class User extends Document {
constructor() {
super('user');
this.schema({
name: String,
email: {
type: String,
unique: true
}
});
}
}
var user1 = User.create();
user1.name = 'Bill';
user1.email = 'billy@example.com';
var user2 = User.create();
user1.name = 'Billy';
user2.email = 'billy@example.com';
Promise.all([user1.save(), user2.save()]).then(function() {
expect.fail(null, Error, 'Expected error, but got none.');
}).catch(function(error) {
expect(error.errorType).to.be.equal('uniqueViolated');
}).then(done, done);
});
it('should accept documents with duplicate values in non-unique-indexed fields', function(done) {
class User extends Document {
constructor() {
super('user');
this.schema({
name: String,
email: {
type: String,
unique: false
}
});
}
}
var user1 = User.create();
user1.name = 'Bill';
user1.email = 'billy@example.com';
var user2 = User.create();
user1.name = 'Billy';
user2.email = 'billy@example.com';
Promise.all([user1.save(), user2.save()]).then(function() {
validateId(user1);
validateId(user2);
expect(user1.email).to.be.equal('billy@example.com');
expect(user2.email).to.be.equal('billy@example.com');
}).then(done, done);
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc