UNPKG

micromodel

Version:

Model that can be used on both Client & Server

308 lines (275 loc) 8.05 kB
// Generated by CoffeeScript 1.8.0 (function() { var Model, defineClassInheritableAccessor, _, __hasProp = {}.hasOwnProperty, __slice = [].slice; if (typeof _ === "undefined" || _ === null) { _ = require('underscore'); } defineClassInheritableAccessor = function(obj, name, defaultValue) { var _name; _name = "_" + name; return obj[name] = function() { var _ref; if (this[_name] == null) { this[_name] = _(defaultValue).clone(); } if (this[_name] === ((_ref = this.__super__) != null ? _ref.constructor[_name] : void 0)) { this[_name] = _(this[_name]).clone(); } return this[_name]; }; }; Model = (function() { var attributeRe; attributeRe = /^_|^errors$/; Model.prototype.isModel = true; defineClassInheritableAccessor(Model, '_defaults', {}); Model.defaults = function(attrs) { var name, value, _results; if (attrs) { _results = []; for (name in attrs) { value = attrs[name]; _results.push(this._defaults()[name] = value); } return _results; } else { return this._defaults(); } }; function Model(attrs, options) { var defaults; this.errors = {}; if (!_.isEmpty(defaults = this.constructor.defaults())) { this.set(_(defaults).clone()); } if (attrs) { this.set(attrs, options); } this; } Model.prototype.isNew = function() { return this.id != null; }; Model.prototype.isEqual = function(other) { var name, otherSize, size, value; if (this === other) { return true; } if (!(other && this.id === other.id && other.isModel)) { return false; } size = 0; for (name in this) { if (!__hasProp.call(this, name)) continue; value = this[name]; if (!(!attributeRe.test(name))) { continue; } size += 1; if (!_.isEqual(value, other[name])) { return false; } } otherSize = 0; for (name in other) { if (!__hasProp.call(other, name)) continue; if (!attributeRe.test(name)) { otherSize += 1; } } return size === otherSize; }; Model.prototype.set = function(attrs, options) { var changes, name, newValue, oldValue; if (attrs == null) { return {}; } if (options && options.cast) { return this.castAndSet(attrs, options); } if (this.parse) { attrs = this.parse(attrs); } changes = {}; for (name in attrs) { if (!__hasProp.call(attrs, name)) continue; newValue = attrs[name]; if (!(!attributeRe.test(name))) { continue; } oldValue = this[name]; if (!_.isEqual(oldValue, newValue)) { changes[name] = oldValue; } this[name] = newValue; } return changes; }; Model.prototype.clone = function() { return new this.constructor(this.attributes()); }; Model.prototype.clear = function(options) { var changes, name; changes = attributes(); for (name in this) { if (!__hasProp.call(this, name)) continue; delete this[name]; } return changes; }; defineClassInheritableAccessor(Model, '_validations', {}); Model.validations = function(validations) { var name, validator, _results; if (validations) { _results = []; for (name in validations) { validator = validations[name]; _results.push(this._validations()[name] = validator); } return _results; } else { return this._validations(); } }; Model.prototype.validate = function() { var msg, name, validator, _base, _ref, _results; _ref = this.constructor.validations(); _results = []; for (name in _ref) { if (!__hasProp.call(_ref, name)) continue; validator = _ref[name]; if (msg = validator.call(this, this[name])) { _results.push(((_base = this.errors)[name] != null ? _base[name] : _base[name] = []).push(msg)); } else { _results.push(void 0); } } return _results; }; Model.prototype.isValid = function() { this.errors = {}; this.validate(); return _(this.errors).isEmpty(); }; Model.prototype.hasErrors = function() { return !_(this.errors).isEmpty(); }; Model.prototype.addError = function() { var args, _base, _base1, _name; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (args.length < 2) { return ((_base = this.errors).base != null ? _base.base : _base.base = []).push(args[0]); } else { return ((_base1 = this.errors)[_name = args[0]] != null ? _base1[_name] : _base1[_name] = []).push(args[1]); } }; Model.prototype.attributes = function() { var attrs, name, value; attrs = {}; for (name in this) { if (!__hasProp.call(this, name)) continue; value = this[name]; if (!attributeRe.test(name)) { attrs[name] = value; } } return attrs; }; Model.prototype.toJson = function() { return this.attributes(); }; Model.prototype.toJSON = function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.toJson.apply(this, args); }; Model.prototype.toString = function() { return JSON.stringify(this.toJson()); }; Model.generateId = function(length) { var count, id, rand, symbols, _ref; if (length == null) { length = 6; } symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; _ref = ["", length + 1], id = _ref[0], count = _ref[1]; while (count -= 1) { rand = Math.floor(Math.random() * symbols.length); id += symbols[rand]; } return id; }; Model.cast = function(value, type) { var tmp; if (_.isFunction(type)) { return type(value); } else if (type === String) { return v.toString(); } else if (type === Number) { if (_.isNumber(v)) { return v; } else if (_.isString(v)) { tmp = parseInt(v); if (_.isNumber(tmp)) { return tmp; } } } else if (type === Boolean) { if (_.isBoolean(v)) { return v; } else if (_.isString(v)) { return v === 'true'; } } else if (type === Date) { if (_.isDate(v)) { return v; } else if (_.isString(v)) { tmp = new Date(v); if (_.isDate(tmp)) { return tmp; } } } else { throw new Error("can't cast to unknown type '" + type + "'!"); } }; defineClassInheritableAccessor(Model, '_types', {}); Model.types = function(types) { var name, type, _results; if (types) { _results = []; for (name in types) { type = types[name]; _results.push(this._types()[name] = type); } return _results; } else { return this._types(); } }; Model.prototype.castAndSet = function(attrs, options) { var casted, name, type, _ref; casted = {}; _ref = this.constructor.types(); for (name in _ref) { type = _ref[name]; if (name in attrs) { casted[name] = Model.cast(attrs[name], type); } } if (options && options.cast) { options = _(options).clone(); delete options.cast; } return this.set(casted, options); }; return Model; })(); if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) { module.exports = Model; } else { window.Model = Model; } }).call(this);