Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

modelfactory

pgherveou440.2.2

Data models with schema definition, and event propagation inspired by Mongoose & Backbone.js

readme

modelfactory

Data models with schema definition, and event propagation inspired by Mongoose & Backbone.js

Installation

Install with component:

$ component install pgherveou/modelfactory

Install with npm:

$ npm install modelfactory

Example

var modelfactory = require('modelfactory'),
    regex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

// create a User Model

var User = modelfactory.model({
  email: {type: String, required: true, match: regex},
  age: {type: Number, min: 13},
  date: {type: Date, default: Date.now},
  name: {
    first: {type: String, required: true},
    last: {type: String, required: true}
  },
  trophies: [{name: String, date: Date}]
})

// define virtuals
User.schema.virtual('name.full').get(function () {
  return this.name.first + ' ' + this.name.last;
})

// define getters
User.schema.path('email').get(function(v) {
  var split = v.split('@')
  return split[0] + '[at]' + split[1];
});

// define setters
User.schema.path('name.last').set(function(v) {
  return v[0].toUpperCase() + v.slice(1);
});

// define static methods
User.schema.static('fetch', function() {
 // ...
});

// define instance methods
User.schema.method('greeting', function() {
 return 'hello ' + this.name.full;
});

// create an instance
var user = new User({
  email: "john@gmail.com",
  name: {first: 'john', last: 'mcenroe'},
  trophies: [
   {name: 'Roland Garros', date: 'june-1984'},
   {name: 'Wimbledon', date: 'aug-1984'}
  ]
});

// data are casted according to their type
user.age = "56"
user.age === 56 // true
user.date = 'oct-2013'
user.date instanceof Date // true

// events are emitted on ppty change
user.on('change:email', function() {/* do something when email change */});
user.email = 'johny@gmail.com'
user.set('email',  'johny2@gmail.com', {silent: true}) // or silent it

// work for nested properties as well
user.on('change:name.first', function() {/* do something when firstname change */});
user.on('change:name', function() {/* do something when name change */});
user.name.first = 'johny'

// or embedded arrays
user.trophies.on('add', function() {/* do something with added trophee */});
user.trophies.on('change:name', function() {/* do something when a trophee name change */});

// validation use schema rules
user.email = "johnyatgmail.com";
console.log(user.validate()); // KO

reuse mongoose schema definition

You can share your schema definition between node and the browser here is one way of doing it

/*!
 * user.shared.js
 */

module.exports = function (Schema) {

  var User = new Schema({
    email: {type: String, lowercase: true, match: emailRegex},
    firstname: {type: String, min: 2},
    lastname: {type: String, min: 2}
  });

  User.virtual('fullname').get(function () {
    return this.firstname + ' ' + this.lastname;
  });

  User.method('greating').get(function () {
    return 'Hello ' + this.fullname;
  });

  return User;
};
/*!
 * user.server.js
 */

var mongoose = require('mongoose'),
    User = require('./user.shared')(mongoose.Schema);

// create a user
var user = new User({
  email: 'pg@jogabo.com',
  firstname: 'PG',
  lastname: 'Herveou'
});

// ...

// play with user
user.fullname; // => PG Herveou
user.validate(); // =>  no errs
user.save();
/*!
 * user.client.js
 */

var factory = require('modelfactory'),
    User = require('./user.shared')(factory.Schema);

// add some client specific methods
User.prototype.save = function() { /* ... */ };

// create a user
var user = new User({
  email: 'pg@jogabo.com',
  firstname: 'PG',
  lastname: 'Herveou'
});

// ...

user.fullname; // => PG Herveou
user.validate(); // => no errs

// do something when firstname change
user.on('change:firstname', function() { /*...*/});

// => trigger change:firstname event
user.firstname = 'Pierre-Guillaume';
user.save();

Reuse models & ref / populate

Usually you set your client model with populated objects coming from the server Here is an example of a Post model that reference a User model.

/*!
 * post.shared.js
 */

module.exports = function(Schema) {
  return new Schema({
    date: { type: Date, required: true },
    msg: { type: String, trim: true, required: true },
  });
};

/*!
 * post.server.js
 */

var mongoose = require('mongoose'),
    schema = require('./post.shared')(mongoose.Schema);

schema.add({  _from: { type: ObjectId, ref: 'User' });
module.exports = schema;
/*!
 * post.client.js
 */

var factory = require('modelfactory'),
    User = require('./user').schema;
    schema = require('./post.shared')(factory);

schema.add({  _from:  User });
module.exports = schema;

API

coming soon..

supported browsers

should work on any browser supporting Object.defineProperty

Credits

License

MIT

changelog

0.2.2 / 2014-09-05

  • quick fix bug with different array definition

0.2.1 / 2014-09-03

  • make it work with array of objectId

0.2.0 / 2014-09-03

  • add objectId ref support

0.1.37 / 2014-08-15

  • add pickModifiedPaths

0.1.36 / 2014-08-15

  • add modifiedpaths

0.1.35 / 2014-08-15

  • add toJSON options

0.1.34 / 2014-06-21

  • create model without new keyword

0.1.32 / 2014-04-27

  • fixed pgherveou/modelfactory/issues/4 (make setter work with object and dot notation)
  • update read me

0.1.31 / 2014-04-27

  • fixed pgherveou/modelfactory/issues/6 add mixed types and support Array constructor as type

0.1.29 / 2014-03-05

  • use Object.create(null) instead of {} to initialize schema properties
  • hide private indexes from store

0.1.28 / 2014-01-16

  • update store indexing
  • keep indexes in sync

0.1.25 / 2014-01-06

  • fix type resolution after mangling for non standard types
  • fix test for latest component build

0.1.24 / 2013-12-28

  • add set null scenario

0.1.22 / 2013-11-29

  • add collection method

0.1.21 / 2013-11-26

  • automatically add id key to schema

0.1.20 / 2013-11-26

  • make property writable

0.1.9 / 2013-11-25

  • fix bug isNew

0.1.8 / 2013-11-09

  • add pick method
  • allow array option in validate

0.1.7 / 2013-11-02

  • add store options

0.1.6 / 2013-10-30

  • add plugins

0.1.5 / 2013-10-30

  • add embedded model, fix schema array defs

0.1.4 / 2013-10-26

  • add schema ppty to model

0.1.3 / 2013-10-17

  • fix proxy array event bug

0.1.2 / 2013-10-17

  • proxy event on array

0.1.1 / 2013-10-17

  • Update Readme.md
  • add parent and parentArray methods on model

0.1.0 / 2013-10-17

  • use modelArray for documentArray
  • refactor model / get / set and event propagation
  • remove backbone deps

0.0.18 / 2013-08-29

  • add test for deeply nested field

0.0.17 / 2013-07-20

  • fixed dummy objectid type

0.0.16 / 2013-07-19

  • add ObjectId alias to String in types

0.0.15 / 2013-07-18

  • use setter when use with key and value
  • add testing node package config

0.0.14 / 2013-07-14

  • add getValue to get raw data

0.0.13 / 2013-07-14

  • return this from set instead of null

0.0.12 / 2013-07-14

  • fix validators context

0.0.11 / 2013-07-14

  • expose Error object

0.0.10 / 2013-07-14

  • fix enum validator bug

0.0.9 / 2013-07-14

  • fix validation bug add string/array format for specific path validation

0.0.8 / 2013-07-14

  • expose Schema.Types

0.0.7 / 2013-07-14

  • use Backbone.Model instead of Backbone in model function

0.0.6 / 2013-07-13

  • support type: [...] and [...] array def in shchema

0.0.5 / 2013-07-13

  • add basic array support

0.0.4 / 2013-07-13

  • add virtual and path getter support
  • add statics and methods

0.0.3 / 2013-07-13

  • use reduce for getPath
  • add virtual support
  • add path get accessor support

0.0.2 / 2013-07-13

  • fix consturctor name creation function
  • update doc