index.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  6. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  7. var _util = require('./util');
  8. var _validator = require('./validator/');
  9. var _validator2 = _interopRequireDefault(_validator);
  10. var _messages2 = require('./messages');
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  12. /**
  13. * Encapsulates a validation schema.
  14. *
  15. * @param descriptor An object declaring validation rules
  16. * for this schema.
  17. */
  18. function Schema(descriptor) {
  19. this.rules = null;
  20. this._messages = _messages2.messages;
  21. this.define(descriptor);
  22. }
  23. Schema.prototype = {
  24. messages: function messages(_messages) {
  25. if (_messages) {
  26. this._messages = (0, _util.deepMerge)((0, _messages2.newMessages)(), _messages);
  27. }
  28. return this._messages;
  29. },
  30. define: function define(rules) {
  31. if (!rules) {
  32. throw new Error('Cannot configure a schema with no rules');
  33. }
  34. if ((typeof rules === 'undefined' ? 'undefined' : _typeof(rules)) !== 'object' || Array.isArray(rules)) {
  35. throw new Error('Rules must be an object');
  36. }
  37. this.rules = {};
  38. var z = void 0;
  39. var item = void 0;
  40. for (z in rules) {
  41. if (rules.hasOwnProperty(z)) {
  42. item = rules[z];
  43. this.rules[z] = Array.isArray(item) ? item : [item];
  44. }
  45. }
  46. },
  47. validate: function validate(source_) {
  48. var _this = this;
  49. var o = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  50. var oc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
  51. var source = source_;
  52. var options = o;
  53. var callback = oc;
  54. if (typeof options === 'function') {
  55. callback = options;
  56. options = {};
  57. }
  58. if (!this.rules || Object.keys(this.rules).length === 0) {
  59. if (callback) {
  60. callback();
  61. }
  62. return Promise.resolve();
  63. }
  64. function complete(results) {
  65. var i = void 0;
  66. var errors = [];
  67. var fields = {};
  68. function add(e) {
  69. if (Array.isArray(e)) {
  70. var _errors;
  71. errors = (_errors = errors).concat.apply(_errors, e);
  72. } else {
  73. errors.push(e);
  74. }
  75. }
  76. for (i = 0; i < results.length; i++) {
  77. add(results[i]);
  78. }
  79. if (!errors.length) {
  80. errors = null;
  81. fields = null;
  82. } else {
  83. fields = (0, _util.convertFieldsError)(errors);
  84. }
  85. callback(errors, fields);
  86. }
  87. if (options.messages) {
  88. var messages = this.messages();
  89. if (messages === _messages2.messages) {
  90. messages = (0, _messages2.newMessages)();
  91. }
  92. (0, _util.deepMerge)(messages, options.messages);
  93. options.messages = messages;
  94. } else {
  95. options.messages = this.messages();
  96. }
  97. var arr = void 0;
  98. var value = void 0;
  99. var series = {};
  100. var keys = options.keys || Object.keys(this.rules);
  101. keys.forEach(function (z) {
  102. arr = _this.rules[z];
  103. value = source[z];
  104. arr.forEach(function (r) {
  105. var rule = r;
  106. if (typeof rule.transform === 'function') {
  107. if (source === source_) {
  108. source = _extends({}, source);
  109. }
  110. value = source[z] = rule.transform(value);
  111. }
  112. if (typeof rule === 'function') {
  113. rule = {
  114. validator: rule
  115. };
  116. } else {
  117. rule = _extends({}, rule);
  118. }
  119. rule.validator = _this.getValidationMethod(rule);
  120. rule.field = z;
  121. rule.fullField = rule.fullField || z;
  122. rule.type = _this.getType(rule);
  123. if (!rule.validator) {
  124. return;
  125. }
  126. series[z] = series[z] || [];
  127. series[z].push({
  128. rule: rule,
  129. value: value,
  130. source: source,
  131. field: z
  132. });
  133. });
  134. });
  135. var errorFields = {};
  136. return (0, _util.asyncMap)(series, options, function (data, doIt) {
  137. var rule = data.rule;
  138. var deep = (rule.type === 'object' || rule.type === 'array') && (_typeof(rule.fields) === 'object' || _typeof(rule.defaultField) === 'object');
  139. deep = deep && (rule.required || !rule.required && data.value);
  140. rule.field = data.field;
  141. function addFullfield(key, schema) {
  142. return _extends({}, schema, {
  143. fullField: rule.fullField + '.' + key
  144. });
  145. }
  146. function cb() {
  147. var e = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  148. var errors = e;
  149. if (!Array.isArray(errors)) {
  150. errors = [errors];
  151. }
  152. if (!options.suppressWarning && errors.length) {
  153. Schema.warning('async-validator:', errors);
  154. }
  155. if (errors.length && rule.message) {
  156. errors = [].concat(rule.message);
  157. }
  158. errors = errors.map((0, _util.complementError)(rule));
  159. if (options.first && errors.length) {
  160. errorFields[rule.field] = 1;
  161. return doIt(errors);
  162. }
  163. if (!deep) {
  164. doIt(errors);
  165. } else {
  166. // if rule is required but the target object
  167. // does not exist fail at the rule level and don't
  168. // go deeper
  169. if (rule.required && !data.value) {
  170. if (rule.message) {
  171. errors = [].concat(rule.message).map((0, _util.complementError)(rule));
  172. } else if (options.error) {
  173. errors = [options.error(rule, (0, _util.format)(options.messages.required, rule.field))];
  174. } else {
  175. errors = [];
  176. }
  177. return doIt(errors);
  178. }
  179. var fieldsSchema = {};
  180. if (rule.defaultField) {
  181. for (var k in data.value) {
  182. if (data.value.hasOwnProperty(k)) {
  183. fieldsSchema[k] = rule.defaultField;
  184. }
  185. }
  186. }
  187. fieldsSchema = _extends({}, fieldsSchema, data.rule.fields);
  188. for (var f in fieldsSchema) {
  189. if (fieldsSchema.hasOwnProperty(f)) {
  190. var fieldSchema = Array.isArray(fieldsSchema[f]) ? fieldsSchema[f] : [fieldsSchema[f]];
  191. fieldsSchema[f] = fieldSchema.map(addFullfield.bind(null, f));
  192. }
  193. }
  194. var schema = new Schema(fieldsSchema);
  195. schema.messages(options.messages);
  196. if (data.rule.options) {
  197. data.rule.options.messages = options.messages;
  198. data.rule.options.error = options.error;
  199. }
  200. schema.validate(data.value, data.rule.options || options, function (errs) {
  201. var finalErrors = [];
  202. if (errors && errors.length) {
  203. finalErrors.push.apply(finalErrors, errors);
  204. }
  205. if (errs && errs.length) {
  206. finalErrors.push.apply(finalErrors, errs);
  207. }
  208. doIt(finalErrors.length ? finalErrors : null);
  209. });
  210. }
  211. }
  212. var res = void 0;
  213. if (rule.asyncValidator) {
  214. res = rule.asyncValidator(rule, data.value, cb, data.source, options);
  215. } else if (rule.validator) {
  216. res = rule.validator(rule, data.value, cb, data.source, options);
  217. if (res === true) {
  218. cb();
  219. } else if (res === false) {
  220. cb(rule.message || rule.field + ' fails');
  221. } else if (res instanceof Array) {
  222. cb(res);
  223. } else if (res instanceof Error) {
  224. cb(res.message);
  225. }
  226. }
  227. if (res && res.then) {
  228. res.then(function () {
  229. return cb();
  230. }, function (e) {
  231. return cb(e);
  232. });
  233. }
  234. }, function (results) {
  235. complete(results);
  236. });
  237. },
  238. getType: function getType(rule) {
  239. if (rule.type === undefined && rule.pattern instanceof RegExp) {
  240. rule.type = 'pattern';
  241. }
  242. if (typeof rule.validator !== 'function' && rule.type && !_validator2['default'].hasOwnProperty(rule.type)) {
  243. throw new Error((0, _util.format)('Unknown rule type %s', rule.type));
  244. }
  245. return rule.type || 'string';
  246. },
  247. getValidationMethod: function getValidationMethod(rule) {
  248. if (typeof rule.validator === 'function') {
  249. return rule.validator;
  250. }
  251. var keys = Object.keys(rule);
  252. var messageIndex = keys.indexOf('message');
  253. if (messageIndex !== -1) {
  254. keys.splice(messageIndex, 1);
  255. }
  256. if (keys.length === 1 && keys[0] === 'required') {
  257. return _validator2['default'].required;
  258. }
  259. return _validator2['default'][this.getType(rule)] || false;
  260. }
  261. };
  262. Schema.register = function register(type, validator) {
  263. if (typeof validator !== 'function') {
  264. throw new Error('Cannot register a validator by type, validator is not a function');
  265. }
  266. _validator2['default'][type] = validator;
  267. };
  268. Schema.warning = _util.warning;
  269. Schema.messages = _messages2.messages;
  270. exports['default'] = Schema;