Socket
Socket
Sign inDemoInstall

camo

Package Overview
Dependencies
125
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.1 to 0.2.1

16

CHANGELOG.md

@@ -0,1 +1,17 @@

## 0.2.1 (2015-06-17)
- README fix.
## 0.2.0 (2015-06-17)
Features:
- Added the following Document hooks:
- `preValidate()`
- `postValidate()`
- `preSave()`
- `postSave()`
- `preDelete()`
- `postDelete()`
## 0.1.1 (2015-06-17)

@@ -2,0 +18,0 @@

70

lib/document.js

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

var Reflect = require('harmony-reflect'); // Shim, remove ASAP
var EventEmitter = require('events').EventEmitter;
var DB = require('./clients').getClient;

@@ -129,2 +130,21 @@ var isSupportedType = require('./validate').isSupportedType;

/*
* Pre/post Hooks
*
* To add a hook, the extending class just needs
* to override the appropriate hook method below.
*/
preValidate() { }
postValidate() { }
preSave() { }
postSave() { }
preDelete() { }
postDelete() { }
save() {

@@ -134,2 +154,4 @@ var that = this;

return new Promise(function(resolve, reject) {
return resolve(that.preValidate());
}).then(function() {

@@ -165,3 +187,3 @@ // Ensure we at least have defaults set

' should be ' + typeName + ', got ' + valueName);
return reject(err);
return Promise.reject(err);
}

@@ -172,3 +194,3 @@

' should be in [' + that._schema[key].choices.join(', ') + '], got ' + value);
return reject(err);
return Promise.reject(err);
}

@@ -179,3 +201,3 @@

' is less than min, ' + that._schema[key].min + ', got ' + value);
return reject(err);
return Promise.reject(err);
}

@@ -186,3 +208,3 @@

' is less than max, ' + that._schema[key].max + ', got ' + value);
return reject(err);
return Promise.reject(err);
}

@@ -221,12 +243,21 @@ });

DB().save(that._meta.collection, that.id, toUpdate)
.then(function(data) {
if (that.id === null) {
that.id = data._id;
}
resolve(that);
})
.catch(function(error) {
reject(error);
});
return toUpdate;
}).then(function(data) {
that.postValidate();
return data;
}).then(function(data) {
that.preSave();
return data;
}).then(function(data) {
return DB().save(that._meta.collection, that.id, data);
}).then(function(data) {
that.postSave();
return data;
}).then(function(data) {
if (that.id === null) {
that.id = data._id;
}
return that;
}).catch(function(error) {
return Promise.reject(error);
});

@@ -236,3 +267,12 @@ }

delete() {
return DB().delete(this._meta.collection, this.id);
var that = this;
return new Promise(function(resolve, reject) {
return resolve(that.preDelete());
}).then(function() {
return DB().delete(that._meta.collection, that.id);
}).then(function(deleteReturn) {
that.postDelete();
return deleteReturn;
});
}

@@ -239,0 +279,0 @@

{
"name" : "camo",
"version" : "0.1.1",
"version" : "0.2.1",
"description" : "A lightweight ES6 ODM for Mongo-like databases.",

@@ -5,0 +5,0 @@ "author": {

# Camo
## Jump To
* <a href="#why-do-we-need-another-odm">Why do we need another ODM?</a>
* <a href="#advantages">Advantages</a>
* <a href="#install-and-run">Install and Run</a>
* <a href="#quick-start">Quick Start</a>
* <a href="#connect-to-the-database">Connect to the Database</a>
* <a href="#declaring-your-document">Declaring Your Document</a>
* <a href="#creating-and-saving">Creating and Saving</a>
* <a href="#loading">Loading</a>
* <a href="#deleting">Deleting</a>
* <a href="#counting">Counting</a>
* <a href="#hooks">Hooks</a>
* <a href="#copyright-license">Copyright & License</a>
## Why do we need another ODM?

@@ -11,6 +25,6 @@ Short answer, we probably don't. Camo was created for two reasons: to bring traditional-style classes to [MongoDB](https://www.mongodb.com/) JavaScript, and to support [NeDB](https://github.com/louischatriot/nedb) as a backend (which is much like the SQLite-alternative to Mongo).

- ES6: Although ES6 hasn't hit mainstream Node yet, it will soon (io.js is currently being merged with Node at the time of this writing). With all of these new features coming out soon, Camo is getting a head start in writing tested and proven ES6 code.
- Easy to use: While JavaScript is a great language overall, it isn't always the easiest for beginners to pick up. Camo aims to ease that transition by providing familiar-looking classes and a simple interface. Also, there is no need to install a full MongoDB instance to get started with the support of NeDB.
- Multiple backends: Camo was designed and built with multiple Mongo-like backends in mind, like NeDB, LokiJS\*, and TaffyDB\*. With NeDB support, for example, you don't need to install a full MongoDB instance for development or for smaller projects. This also allows you to use Camo in the browser, since it supports in-memory storage.
- Lightweight: Camo is just a very thin wrapper around the backend databases, which mean you won't be sacrificing performance.
- **ES6**: Although ES6 hasn't hit mainstream Node yet, it will soon (io.js is currently being merged with Node at the time of this writing). With all of these new features coming out soon, Camo is getting a head start in writing tested and proven ES6 code. This also means that native Promises are built-in to Camo, so no more `promisify`-ing your ODM or waiting for Promise support to be added.
- **Easy to use**: While JavaScript is a great language overall, it isn't always the easiest for beginners to pick up. Camo aims to ease that transition by providing familiar-looking classes and a simple interface. Also, there is no need to install a full MongoDB instance to get started with the support of NeDB.
- **Multiple backends**: Camo was designed and built with multiple Mongo-like backends in mind, like NeDB, LokiJS\*, and TaffyDB\*. With NeDB support, for example, you don't need to install a full MongoDB instance for development or for smaller projects. This also allows you to use Camo in the browser, since it supports in-memory storage.
- **Lightweight**: Camo is just a very thin wrapper around the backend databases, which mean you won't be sacrificing performance.

@@ -41,2 +55,4 @@ \* Support coming soon.

## Quick Start
Camo was built with ease-of-use and ES6 in mind, so you might notice it has more of an OOP feel to it than many existing libraries. Don't worry, focusing on object-oriented design doesn't mean we forgot about functional techniques or asynchronous programming. Promises are built-in to the API. Just about every call you make interacting with the database (load, save, delete, etc) will return a Promise. No more callback hell :)
### Connect to the Database

@@ -64,3 +80,3 @@ Before using any document methods, you must first connect to your underlying database. All supported databases have their own unique URL string used for connecting. The URL string usually describes the network location or file location of the database.

### Declare Your Document
### Declaring Your Document
All models must inherit from `Document`, which handles much of the interface to your backend NoSQL database.

@@ -204,3 +220,42 @@

### Hooks
Camo provides hooks for you to execute code before and after critical parts of your database interactions. For each hook you use, you may return a value (which, as of now, will be discarded) or a Promise for executing asynchronous code. Using Promises, we don't need to provide separate async and sync hooks, thus making your code simpler and easier to understand.
In order to create a hook, you must override a class method. The hooks currently provided, and their corresponding methods, are:
- pre-validate: `preValidate()`
- post-validate: `postValidate()`
- pre-save: `preSave()`
- post-save: `postSave()`
- pre-delete: `preDelete()`
- post-delete: `postDelete()`
Here is an example of using a hook (pre-delete, in this case):
```javascript
class Company extends Document {
constructor() {
super('company');
this.employees = [Person]
}
preDelete() {
var deletes = [];
this.employees.forEach(function(e) {
var p = new Promise(function(resolve, reject) {
resolve(e.delete());
});
deletes.push(p);
});
return Promise.all(deletes);
}
}
```
The code above shows a pre-delete hook that deletes all the employees of the company before it itself is deleted. As you can see, this is much more convenient than needing to always remember to delete referenced employees in the application code.
**Note**: The `.preDelete()` and `.postDelete()` hooks are _only_ called when calling `.delete()` on a Document instance. Calling `.deleteOne()` or `.deleteMany()` will **not** trigger the hook methods.
## Copyright & License

@@ -207,0 +262,0 @@ Copyright (c) 2015 Scott Robinson

@@ -491,2 +491,66 @@ "use strict";

});
describe('hooks', function() {
it('should call all pre and post functions', function(done) {
var preValidateCalled = false;
var preSaveCalled = false;
var preDeleteCalled = false;
var postValidateCalled = false;
var postSaveCalled = false;
var postDeleteCalled = false;
class Person extends Document {
constructor() {
super('person');
}
preValidate() {
preValidateCalled = true;
}
postValidate() {
postValidateCalled = true;
}
preSave() {
preSaveCalled = true;
}
postSave() {
postSaveCalled = true;
}
preDelete() {
preDeleteCalled = true;
}
postDelete() {
postDeleteCalled = true;
}
}
var person = Person.create();
person.save().then(function(p) {
validateId(p);
// Pre/post save and validate should be called
expect(preValidateCalled).to.be.equal(true);
expect(preSaveCalled).to.be.equal(true);
expect(postValidateCalled).to.be.equal(true);
expect(postSaveCalled).to.be.equal(true);
// Pre/post delete should not have been called yet
expect(preDeleteCalled).to.be.equal(false);
expect(postDeleteCalled).to.be.equal(false);
return person.delete();
}).then(function() {
expect(preDeleteCalled).to.be.equal(true);
expect(postDeleteCalled).to.be.equal(true);
}).then(done, done);
});
});
});
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc