index.js 9.2 KB

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