| import _extends from 'babel-runtime/helpers/extends'; | 
| import _typeof from 'babel-runtime/helpers/typeof'; | 
| import { format, complementError, asyncMap, warning, deepMerge } from './util'; | 
| import validators from './validator/'; | 
| import { messages as defaultMessages, newMessages } from './messages'; | 
|   | 
| /** | 
|  *  Encapsulates a validation schema. | 
|  * | 
|  *  @param descriptor An object declaring validation rules | 
|  *  for this schema. | 
|  */ | 
| function Schema(descriptor) { | 
|   this.rules = null; | 
|   this._messages = defaultMessages; | 
|   this.define(descriptor); | 
| } | 
|   | 
| Schema.prototype = { | 
|   messages: function messages(_messages) { | 
|     if (_messages) { | 
|       this._messages = deepMerge(newMessages(), _messages); | 
|     } | 
|     return this._messages; | 
|   }, | 
|   define: function define(rules) { | 
|     if (!rules) { | 
|       throw new Error('Cannot configure a schema with no rules'); | 
|     } | 
|     if ((typeof rules === 'undefined' ? 'undefined' : _typeof(rules)) !== 'object' || Array.isArray(rules)) { | 
|       throw new Error('Rules must be an object'); | 
|     } | 
|     this.rules = {}; | 
|     var z = void 0; | 
|     var item = void 0; | 
|     for (z in rules) { | 
|       if (rules.hasOwnProperty(z)) { | 
|         item = rules[z]; | 
|         this.rules[z] = Array.isArray(item) ? item : [item]; | 
|       } | 
|     } | 
|   }, | 
|   validate: function validate(source_) { | 
|     var _this = this; | 
|   | 
|     var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | 
|     var oc = arguments[2]; | 
|   | 
|     var source = source_; | 
|     var options = o; | 
|     var callback = oc; | 
|     if (typeof options === 'function') { | 
|       callback = options; | 
|       options = {}; | 
|     } | 
|     if (!this.rules || Object.keys(this.rules).length === 0) { | 
|       if (callback) { | 
|         callback(); | 
|       } | 
|       return; | 
|     } | 
|     function complete(results) { | 
|       var i = void 0; | 
|       var field = void 0; | 
|       var errors = []; | 
|       var fields = {}; | 
|   | 
|       function add(e) { | 
|         if (Array.isArray(e)) { | 
|           errors = errors.concat.apply(errors, e); | 
|         } else { | 
|           errors.push(e); | 
|         } | 
|       } | 
|   | 
|       for (i = 0; i < results.length; i++) { | 
|         add(results[i]); | 
|       } | 
|       if (!errors.length) { | 
|         errors = null; | 
|         fields = null; | 
|       } else { | 
|         for (i = 0; i < errors.length; i++) { | 
|           field = errors[i].field; | 
|           fields[field] = fields[field] || []; | 
|           fields[field].push(errors[i]); | 
|         } | 
|       } | 
|       callback(errors, fields); | 
|     } | 
|   | 
|     if (options.messages) { | 
|       var messages = this.messages(); | 
|       if (messages === defaultMessages) { | 
|         messages = newMessages(); | 
|       } | 
|       deepMerge(messages, options.messages); | 
|       options.messages = messages; | 
|     } else { | 
|       options.messages = this.messages(); | 
|     } | 
|     var arr = void 0; | 
|     var value = void 0; | 
|     var series = {}; | 
|     var keys = options.keys || Object.keys(this.rules); | 
|     keys.forEach(function (z) { | 
|       arr = _this.rules[z]; | 
|       value = source[z]; | 
|       arr.forEach(function (r) { | 
|         var rule = r; | 
|         if (typeof rule.transform === 'function') { | 
|           if (source === source_) { | 
|             source = _extends({}, source); | 
|           } | 
|           value = source[z] = rule.transform(value); | 
|         } | 
|         if (typeof rule === 'function') { | 
|           rule = { | 
|             validator: rule | 
|           }; | 
|         } else { | 
|           rule = _extends({}, rule); | 
|         } | 
|         rule.validator = _this.getValidationMethod(rule); | 
|         rule.field = z; | 
|         rule.fullField = rule.fullField || z; | 
|         rule.type = _this.getType(rule); | 
|         if (!rule.validator) { | 
|           return; | 
|         } | 
|         series[z] = series[z] || []; | 
|         series[z].push({ | 
|           rule: rule, | 
|           value: value, | 
|           source: source, | 
|           field: z | 
|         }); | 
|       }); | 
|     }); | 
|     var errorFields = {}; | 
|     asyncMap(series, options, function (data, doIt) { | 
|       var rule = data.rule; | 
|       var deep = (rule.type === 'object' || rule.type === 'array') && (_typeof(rule.fields) === 'object' || _typeof(rule.defaultField) === 'object'); | 
|       deep = deep && (rule.required || !rule.required && data.value); | 
|       rule.field = data.field; | 
|       function addFullfield(key, schema) { | 
|         return _extends({}, schema, { | 
|           fullField: rule.fullField + '.' + key | 
|         }); | 
|       } | 
|   | 
|       function cb() { | 
|         var e = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | 
|   | 
|         var errors = e; | 
|         if (!Array.isArray(errors)) { | 
|           errors = [errors]; | 
|         } | 
|         if (errors.length) { | 
|           warning('async-validator:', errors); | 
|         } | 
|         if (errors.length && rule.message) { | 
|           errors = [].concat(rule.message); | 
|         } | 
|   | 
|         errors = errors.map(complementError(rule)); | 
|   | 
|         if (options.first && errors.length) { | 
|           errorFields[rule.field] = 1; | 
|           return doIt(errors); | 
|         } | 
|         if (!deep) { | 
|           doIt(errors); | 
|         } else { | 
|           // if rule is required but the target object | 
|           // does not exist fail at the rule level and don't | 
|           // go deeper | 
|           if (rule.required && !data.value) { | 
|             if (rule.message) { | 
|               errors = [].concat(rule.message).map(complementError(rule)); | 
|             } else if (options.error) { | 
|               errors = [options.error(rule, format(options.messages.required, rule.field))]; | 
|             } else { | 
|               errors = []; | 
|             } | 
|             return doIt(errors); | 
|           } | 
|   | 
|           var fieldsSchema = {}; | 
|           if (rule.defaultField) { | 
|             for (var k in data.value) { | 
|               if (data.value.hasOwnProperty(k)) { | 
|                 fieldsSchema[k] = rule.defaultField; | 
|               } | 
|             } | 
|           } | 
|           fieldsSchema = _extends({}, fieldsSchema, data.rule.fields); | 
|           for (var f in fieldsSchema) { | 
|             if (fieldsSchema.hasOwnProperty(f)) { | 
|               var fieldSchema = Array.isArray(fieldsSchema[f]) ? fieldsSchema[f] : [fieldsSchema[f]]; | 
|               fieldsSchema[f] = fieldSchema.map(addFullfield.bind(null, f)); | 
|             } | 
|           } | 
|           var schema = new Schema(fieldsSchema); | 
|           schema.messages(options.messages); | 
|           if (data.rule.options) { | 
|             data.rule.options.messages = options.messages; | 
|             data.rule.options.error = options.error; | 
|           } | 
|           schema.validate(data.value, data.rule.options || options, function (errs) { | 
|             doIt(errs && errs.length ? errors.concat(errs) : errs); | 
|           }); | 
|         } | 
|       } | 
|   | 
|       var res = rule.validator(rule, data.value, cb, data.source, options); | 
|       if (res && res.then) { | 
|         res.then(function () { | 
|           return cb(); | 
|         }, function (e) { | 
|           return cb(e); | 
|         }); | 
|       } | 
|     }, function (results) { | 
|       complete(results); | 
|     }); | 
|   }, | 
|   getType: function getType(rule) { | 
|     if (rule.type === undefined && rule.pattern instanceof RegExp) { | 
|       rule.type = 'pattern'; | 
|     } | 
|     if (typeof rule.validator !== 'function' && rule.type && !validators.hasOwnProperty(rule.type)) { | 
|       throw new Error(format('Unknown rule type %s', rule.type)); | 
|     } | 
|     return rule.type || 'string'; | 
|   }, | 
|   getValidationMethod: function getValidationMethod(rule) { | 
|     if (typeof rule.validator === 'function') { | 
|       return rule.validator; | 
|     } | 
|     var keys = Object.keys(rule); | 
|     var messageIndex = keys.indexOf('message'); | 
|     if (messageIndex !== -1) { | 
|       keys.splice(messageIndex, 1); | 
|     } | 
|     if (keys.length === 1 && keys[0] === 'required') { | 
|       return validators.required; | 
|     } | 
|     return validators[this.getType(rule)] || false; | 
|   } | 
| }; | 
|   | 
| Schema.register = function register(type, validator) { | 
|   if (typeof validator !== 'function') { | 
|     throw new Error('Cannot register a validator by type, validator is not a function'); | 
|   } | 
|   validators[type] = validator; | 
| }; | 
|   | 
| Schema.messages = defaultMessages; | 
|   | 
| export default Schema; |