Skip to content

model-structure is a module that helps you to create Models based on a Schema's Object.

Notifications You must be signed in to change notification settings

itheodoro/model-structure

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status

#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

  1. Installation
  2. Usage
  1. Browser Support
  2. Running Tests

Installation

$ npm install model-structure

Model.init(constructor, schema);

Used to bind prototype properties in object constructor

  • constructor - Object constructor
  • schema - object schema with properties details

Model.instantiate(instance, data, options);

Used inside object constructor

  • instance - this reference
  • data - object data attributes
  • options - Model options

Usage

Sample object

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
});

Schema Declaration

var schema = {};

schema.messages = {}

Schema error messages based on Data Type.

schema.messages = {
  "integer": "Integer error message",
  "float": "Float error message",
}

schema.notInstantiate = false

If true, gets exactly the return data from Repository.

schema.properties = {}

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
  }
}

Using Repositories

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;
  });
});

Validating Models

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) {

});

Custom Validations

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

Swagger

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')
  }
}

Node DB Migrate

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

Messages

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');
    });
  });

Data/Object Definition

Data Types

Currently Supported Datatypes:

  • String
  • Char
  • Decimal
  • Float
  • Integer
  • Boolean
  • Date
  • Datetime
  • Enum
  • Array
  • Email
  • Nested Objects

ENUM Object

Property Type Description
ref Array/Object Reference Values
type String - Data Type

Model Ref Object

Property Type Description
ref Object - Model Structure A Model Structure instance

Browser Support

You can use on client-side too!

IE Chrome Firefox Opera Safari
IE 9+ ✔ Latest ✔ Latest ✔ Latest ✔ Latest ✔

Running Tests

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

About

model-structure is a module that helps you to create Models based on a Schema's Object.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%