function defineModel(modelType, options) {
  var primaryAttributes;
  var attributes;
  var prototype;
  var staticProto;
  var ModelConstructor;
  var typeName;
  var namespace;

  if (types.isValidType(modelType).indexes) {
    throw ModelException('Model type cannot be an array `{{type}}`', null, null, { type: String(modelType) });
  } else if (models[modelType]) {
    throw ModelException('Model already defined `{{type}}`', null, null, { type: String(modelType) });
  }

  options = options || {};
  primaryAttributes = [];
  namespace = _getNamespace(modelType);
  typeName = _getTypeName(modelType);
  attributes = _prepareAttributes(options.attributes || {}, primaryAttributes);
  prototype = _preparePrototype(options.methods || {}, primaryAttributes, modelType, namespace, typeName);
  staticProto = _prepareStaticProto(options.staticMethods || {}, primaryAttributes, options.attributes, prototype._type);

  ModelConstructor = Function('Model, events, attributes',
    'return function ' + typeName + 'Model(data) { ' +
      'if (!(this instanceof ' + typeName + 'Model)){' +
        'return new ' + typeName + 'Model(data);' +
      '}' +
      (attributes ? 'Object.defineProperties(this, attributes);' : '') +
      'events.emit("create", data);' +
      'Model.call(this, data);' +
    ' }'
  )(Model, events, attributes);
  util.inherits(ModelConstructor, Model);

  Object.defineProperties(ModelConstructor.prototype, prototype);
  Object.defineProperties(ModelConstructor, staticProto);

  if (!types.isDefined(modelType)) {
    types.define(modelType, options.typeValidator || _modelTypeValidator(ModelConstructor));
  }

  // assign
  models[modelType] = ModelConstructor;

  events.emit('define', {
    modelType: modelType,
    namespace: namespace,
    typeName: typeName,
    attributes: attributes,
    constructor: ModelConstructor,
    options: options
  });

  // Freeze model API
  for (var attr in attributes) {
    Object.freeze(attributes[attr]);
  }

  if (options.attributes) {
    Object.freeze(options.attributes); // freeze declared attributes
  }

  if (attributes) {
    Object.freeze(attributes);         // freeze attributes list
  }

  Object.freeze(primaryAttributes);  // freeze primary attributes
  //Object.freeze(ModelConstructor.prototype);  // do not freeze to allow extensions

  return ModelConstructor;
}
function defineModel(modelType, options) {
  var primaryAttributes;
  var attributes;
  var prototype;
  var staticProto;
  var ModelConstructor;
  var typeName;
  var namespace;

  if (types.isValidType(modelType).indexes) {
    throw ModelException('Model type cannot be an array `{{type}}`', null, null, { type: String(modelType) });
  } else if (models[modelType]) {
    throw ModelException('Model already defined `{{type}}`', null, null, { type: String(modelType) });
  }

  options = options || {};
  primaryAttributes = [];
  namespace = _getNamespace(modelType);
  typeName = _getTypeName(modelType);
  attributes = _prepareAttributes(options.attributes || {}, primaryAttributes);
  prototype = _preparePrototype(options.methods || {}, primaryAttributes, modelType, namespace, typeName);
  staticProto = _prepareStaticProto(options.staticMethods || {}, primaryAttributes, options.attributes, prototype._type);

  ModelConstructor = Function('Model, events, attributes',
    'return function ' + typeName + 'Model(data) { ' +
      'if (!(this instanceof ' + typeName + 'Model)){' +
        'return new ' + typeName + 'Model(data);' +
      '}' +
      (attributes ? 'Object.defineProperties(this, attributes);' : '') +
      'events.emit("create", data);' +
      'Model.call(this, data);' +
    ' }'
  )(Model, events, attributes);
  util.inherits(ModelConstructor, Model);

  Object.defineProperties(ModelConstructor.prototype, prototype);
  Object.defineProperties(ModelConstructor, staticProto);

  if (!types.isDefined(modelType)) {
    types.define(modelType, options.typeValidator || _modelTypeValidator(ModelConstructor));
  }

  // assign
  models[modelType] = ModelConstructor;

  events.emit('define', {
    modelType: modelType,
    namespace: namespace,
    typeName: typeName,
    attributes: attributes,
    constructor: ModelConstructor,
    options: options
  });

  // Freeze model API
  for (var attr in attributes) {
    Object.freeze(attributes[attr]);
  }

  if (options.attributes) {
    Object.freeze(options.attributes); // freeze declared attributes
  }

  if (attributes) {
    Object.freeze(attributes);         // freeze attributes list
  }

  Object.freeze(primaryAttributes);  // freeze primary attributes
  //Object.freeze(ModelConstructor.prototype);  // do not freeze to allow extensions

  return ModelConstructor;
}
function defineModel ( modelType , options ) { var primaryAttributes ; var attributes ; var prototype ; var staticProto ; var ModelConstructor ; var typeName ; var namespace ; if ( types . isValidType ( modelType ) . indexes ) { throw ModelException ( 'Model type cannot be an array `{{type}}`' , null , null , { type : String ( modelType ) } ) ; } else if ( models [ modelType ] ) { throw ModelException ( 'Model already defined `{{type}}`' , null , null , { type : String ( modelType ) } ) ; } options = options || { } ; primaryAttributes = [ ] ; namespace = _getNamespace ( modelType ) ; typeName = _getTypeName ( modelType ) ; attributes = _prepareAttributes ( options . attributes || { } , primaryAttributes ) ; prototype = _preparePrototype ( options . methods || { } , primaryAttributes , modelType , namespace , typeName ) ; staticProto = _prepareStaticProto ( options . staticMethods || { } , primaryAttributes , options . attributes , prototype . _type ) ; ModelConstructor = Function ( 'Model, events, attributes' , 'return function ' + typeName + 'Model(data) { ' + 'if (!(this instanceof ' + typeName + 'Model)){' + 'return new ' + typeName + 'Model(data);' + '}' + ( attributes ? 'Object.defineProperties(this, attributes);' : '' ) + 'events.emit("create", data);' + 'Model.call(this, data);' + ' }' ) ( Model , events , attributes ) ; util . inherits ( ModelConstructor , Model ) ; Object . defineProperties ( ModelConstructor . prototype , prototype ) ; Object . defineProperties ( ModelConstructor , staticProto ) ; if ( ! types . isDefined ( modelType ) ) { types . define ( modelType , options . typeValidator || _modelTypeValidator ( ModelConstructor ) ) ; } // assign models [ modelType ] = ModelConstructor ; events . emit ( 'define' , { modelType : modelType , namespace : namespace , typeName : typeName , attributes : attributes , constructor : ModelConstructor , options : options } ) ; // Freeze model API for ( var attr in attributes ) { Object . freeze ( attributes [ attr ] ) ; } if ( options . attributes ) { Object . freeze ( options . attributes ) ; // freeze declared attributes } if ( attributes ) { Object . freeze ( attributes ) ; // freeze attributes list } Object . freeze ( primaryAttributes ) ; // freeze primary attributes //Object.freeze(ModelConstructor.prototype);  // do not freeze to allow extensions return ModelConstructor ; }
Define a new model prototype.

This will define a new model

@param {String} modelType         the model type name
@param {Object} options           the model options
@return {Function}                the model constructor
Define a new model prototype .