#Model Structure
model-structure
helps you to create Models based on a Schema's Object.
It can:
- Set a custom repository to create, update, get and delete
- Get Swagger models
- Get db-migrate JSON
- Nested objects support (validations too!)
- Call validations before create, update or standalone
- Custom async validations based on Schema
- Custom validation messages, by validation or attribute
- Schema Declaration
- Using Repositories
- Validating Models
- Swagger
- Node DB Migrate
- Messages
- Data/Object Definition
$ npm install model-structure
Used to bind prototype properties in object constructor
constructor
- Object constructorschema
- object schema with properties details
Used inside object constructor
instance
-this
referencedata
- object data attributesoptions
- Model options-
repository
- Repository Object - contains object with crud functionsvalidator
- Validators Array - an array with validators to be used against object data
-
var Model = require('model-structure');
function Lead(args, options) {
Model.instantiate(this, args, options);
}
var schema = {
properties: {
"id" : {
"type": "integer",
"primaryKey": true,
"autoIncrement": true
},
"name" : {
"type": "string",
"maximum": 30
},
"email" : {
"type": "email",
"message": "%s field is not a valid email!!",
},
}
}
Model.init(Lead, schema);
var data = {name: 'Kurosaki Ichigo', email: '[email protected]'};
var lead = new Lead(data);
lead.create(function(err, leadResponse) {
// return created lead
});
var schema = {};
Schema error messages based on Data Type.
schema.messages = {
"integer": "Integer error message",
"float": "Float error message",
}
If true
, gets exactly the return data from Repository.
Property | Type | Description |
---|---|---|
type |
String - Data Type |
Required. |
primaryKey |
Boolean |
|
autoIncrement |
Boolean |
|
minimum |
Number |
If type is a Number , minimum value. If it's a String , minimum length. |
maximum |
Number |
If type is a Number , maximum value. If it's a String , maximum length. |
values |
Object - ENUM |
. |
model |
Object - Model Ref |
schema.properties = {
"id": {
"type": "integer",
"primaryKey": true,
"autoIncrement": true
}
}
The Model calls repository's functions passing object with this
context.
var datas = {};
// Simple repository to use memory to save data
function Repository() {
Repository.prototype.create = function create(callback) {
this.id = new Date().getTime();
datas[this.id] = this;
if (typeof callback === 'function') callback(null, this);
};
Repository.prototype.get = function get(args, callback) {
var data = [];
for (var i in datas) data.push(JSON.parse(JSON.stringify(datas[i])));
callback(null, data);
};
Repository.prototype.load = function load(args, callback) {
args = args || {};
var data = args.data || {};
if (args.id) {
data = datas[args.id];
}
callback(null, data);
};
Repository.prototype.update = function update(callback) {
datas[this.id] = this;
if (typeof callback === 'function') callback(null, this);
};
Repository.prototype.destroy = function destroy(callback) {
delete datas[this.id];
if (typeof callback === 'function') callback(null, this);
};
}
var data = {name: 'Kurosaki Ichigo', email: '[email protected]'};
var options = {};
options.repository = new Repository();
var lead = new Lead(data, options);
lead.create(function(err, leadResponse) {
lead.load({id:lead.id}, function (err, secondResponse) {
// get saved lead;
});
});
The validations methods are fired before create
or update
methods. But you may trigger it directly:
var data = {name: 'Kurosaki Ichigo', email: '[email protected]'};
options.repository = new Repository();
var lead = new Lead(data, options);
lead.isValid(function(err, fields) {
});
var Validator = Model.Validator;
var validators = [];
var validator = new Validator({validate: firstLetterLowerCase});
var expect = require('expect.js');
var error = {message: "Name field must be first letter in lowercase", field: 'name'};;
function firstLetterLowerCase(done) {
if (this.name[0].toLowerCase() === this.name[0]) {
done();
} else {
done(error);
}
}
validators.push(validator);
lead.isValid(validators, function (err) {
expect(err[0].field).to.be(error.field);
expect(err[0].message).to.contain(error.message);
done();
});
// OR
Validator.validate(lead, validators, function (err) {
expect(err[0].field).to.be(error.field);
expect(err[0].message).to.contain(error.message);
done();
});
//TODO More examples
Get Swagger Model schema
var swaggerSchema = {
"apiVersion": "0.0.1",
"swaggerVersion": "1.2",
"basePath": "http://localhost:1214",
"resourcePath": "/lead",
"apis": [{
"path": "/lead/",
"operations": [{
"description": "Get all leads",
"notes": "Returns all leads.",
"summary": "Get leads",
"method": "GET",
"type": "Lead",
"nickname": "getAllLeads"
}]
}],
"models": Lead.access('swagger')
}
}
If you are using node-db-migrate to manager your migrations, you can get the migration schema directly from Model.getSchema('dbMigrate', [YOUR_SCHEMA])
.
var schema = {
"properties": {
"id" : {
"type": "integer",
"primaryKey": true,
"autoIncrement": true
},
"name" : {
"type": "string",
"minimum": 3,
"maximum": 30
},
"email" : {
"type": "email",
"required": true,
"unique": true,
"minimum": 7
}
}
}
Model.getSchema('dbMigrate', schema); // returns the node-db-migrate schema
Add custom error messages to field or validation
var expect = require('expect.js');
var lead = new Lead({id:"not a valid integer"});
Model.addMessages('pt-BR', {types: {integer: "%s não é um inteiro"}});
Model.setLocale('pt-BR');
lead.isValid(function (err) {
expect(err[0].field).to.be('id');
expect(err[0].message).to.contain('id não é um inteiro');
Model.setLocale('en');
lead.isValid(function (err2) {
expect(err2[0].field).to.be('active');
expect(err2[0].message).to.contain('id is not an integer');
});
});
Currently Supported Datatypes:
String
Char
Decimal
Float
Integer
Boolean
Date
Datetime
Enum
Array
Email
Nested Objects
Property | Type | Description |
---|---|---|
ref |
Array/Object |
Reference Values |
type |
String - Data Type |
Property | Type | Description |
---|---|---|
ref |
Object - Model Structure |
A Model Structure instance |
You can use on client-side too!
IE 9+ ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |
To run the test suite, first invoke the following command within the repo, installing the development dependencies:
$ npm install
Then run the tests:
$ npm test
To run the coverage report:
$ npm run cover