diff --git a/lib/datatypes.js b/lib/datatypes.js index c26a0a2f..5768aaea 100644 --- a/lib/datatypes.js +++ b/lib/datatypes.js @@ -238,6 +238,26 @@ datatypes = { // FIXME: Does escaping a JSONized object make sense? return _serialize(val, opts); } + , unserialize: function(input, options) { + // unserialize strings only + if (typeof input == 'string') { + // catch exceptions from JSON.parse and return a null object instead + try { + return JSON.parse(input); + } + catch (err) { + return null; + } + } + // if it's already an object we do not need to unserialize + else if (typeof input == 'object') { + return input; + } + // as a fallback return a null object + else { + return null; + } + } } , 'date': { diff --git a/lib/index.js b/lib/index.js index 1bb55767..f040716e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -482,6 +482,7 @@ utils.mixin(model, new (function () { obj.all = function () { var args = Array.prototype.slice.call(arguments) + , Query = Query || require('./query/query').Query , callback = args.pop() || function () {} , query = args.shift() || {} , opts = args.shift() || {} @@ -580,6 +581,7 @@ utils.mixin(model, new (function () { obj.update = function () { var args = Array.prototype.slice.call(arguments) + , Query = Query || require('./query/query').Query , data , callback , query @@ -629,6 +631,7 @@ utils.mixin(model, new (function () { obj.remove = function () { var args = Array.prototype.slice.call(arguments) + , Query = Query || require('./query/query').Query , query , callback , opts @@ -755,13 +758,17 @@ utils.mixin(model, new (function () { , name = item.type , type = model.descriptionRegistry[name] , properties = type.properties + , property , validated = null , errs = null , camelizedKey , skip = opts.skip , skipKeys = {} + , datatype , val; + this.datatypes = this.datatypes || require('./datatypes'); + item.emit('beforeValidate') model[name].emit('beforeValidate', item, passedParams); @@ -774,7 +781,28 @@ utils.mixin(model, new (function () { for (var p in passedParams) { // Allow leading underscores in the keys for pseudo-privates camelizedKey = utils.string.camelize(p, {leadingUnderscore: true}); - params[camelizedKey] = passedParams[p]; + + // user defined properties might need unserialization + if (typeof properties[camelizedKey] != 'undefined') { + property = properties[camelizedKey]; + + if (typeof this.datatypes[property.datatype] != 'undefined') { + datatype = this.datatypes[property.datatype]; + + // unserialize the property if it's datatype has an unserialize method + if (typeof datatype['unserialize'] == 'function') { + val = datatype.unserialize(passedParams[p]); + } else { + val = passedParams[p]; + } + } else { + val = passedParams[p]; + } + } else { + val = passedParams[p]; + } + + params[camelizedKey] = val; } } else { @@ -835,6 +863,8 @@ utils.mixin(model, new (function () { this.validateProperty = function (prop, params, opts) { + this.datatypes = this.datatypes || require('./datatypes'); + var options = opts || {} , name = prop.name , val = params[name]