index.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. function _extends() {
  4. _extends = Object.assign || function (target) {
  5. for (var i = 1; i < arguments.length; i++) {
  6. var source = arguments[i];
  7. for (var key in source) {
  8. if (Object.prototype.hasOwnProperty.call(source, key)) {
  9. target[key] = source[key];
  10. }
  11. }
  12. }
  13. return target;
  14. };
  15. return _extends.apply(this, arguments);
  16. }
  17. function _inheritsLoose(subClass, superClass) {
  18. subClass.prototype = Object.create(superClass.prototype);
  19. subClass.prototype.constructor = subClass;
  20. _setPrototypeOf(subClass, superClass);
  21. }
  22. function _getPrototypeOf(o) {
  23. _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
  24. return o.__proto__ || Object.getPrototypeOf(o);
  25. };
  26. return _getPrototypeOf(o);
  27. }
  28. function _setPrototypeOf(o, p) {
  29. _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
  30. o.__proto__ = p;
  31. return o;
  32. };
  33. return _setPrototypeOf(o, p);
  34. }
  35. function _isNativeReflectConstruct() {
  36. if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  37. if (Reflect.construct.sham) return false;
  38. if (typeof Proxy === "function") return true;
  39. try {
  40. Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
  41. return true;
  42. } catch (e) {
  43. return false;
  44. }
  45. }
  46. function _construct(Parent, args, Class) {
  47. if (_isNativeReflectConstruct()) {
  48. _construct = Reflect.construct;
  49. } else {
  50. _construct = function _construct(Parent, args, Class) {
  51. var a = [null];
  52. a.push.apply(a, args);
  53. var Constructor = Function.bind.apply(Parent, a);
  54. var instance = new Constructor();
  55. if (Class) _setPrototypeOf(instance, Class.prototype);
  56. return instance;
  57. };
  58. }
  59. return _construct.apply(null, arguments);
  60. }
  61. function _isNativeFunction(fn) {
  62. return Function.toString.call(fn).indexOf("[native code]") !== -1;
  63. }
  64. function _wrapNativeSuper(Class) {
  65. var _cache = typeof Map === "function" ? new Map() : undefined;
  66. _wrapNativeSuper = function _wrapNativeSuper(Class) {
  67. if (Class === null || !_isNativeFunction(Class)) return Class;
  68. if (typeof Class !== "function") {
  69. throw new TypeError("Super expression must either be null or a function");
  70. }
  71. if (typeof _cache !== "undefined") {
  72. if (_cache.has(Class)) return _cache.get(Class);
  73. _cache.set(Class, Wrapper);
  74. }
  75. function Wrapper() {
  76. return _construct(Class, arguments, _getPrototypeOf(this).constructor);
  77. }
  78. Wrapper.prototype = Object.create(Class.prototype, {
  79. constructor: {
  80. value: Wrapper,
  81. enumerable: false,
  82. writable: true,
  83. configurable: true
  84. }
  85. });
  86. return _setPrototypeOf(Wrapper, Class);
  87. };
  88. return _wrapNativeSuper(Class);
  89. }
  90. /* eslint no-console:0 */
  91. var formatRegExp = /%[sdj%]/g;
  92. var warning = function warning() {}; // don't print warning message when in production env or node runtime
  93. if (typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && typeof document !== 'undefined') {
  94. warning = function warning(type, errors) {
  95. if (typeof console !== 'undefined' && console.warn) {
  96. if (errors.every(function (e) {
  97. return typeof e === 'string';
  98. })) {
  99. console.warn(type, errors);
  100. }
  101. }
  102. };
  103. }
  104. function convertFieldsError(errors) {
  105. if (!errors || !errors.length) return null;
  106. var fields = {};
  107. errors.forEach(function (error) {
  108. var field = error.field;
  109. fields[field] = fields[field] || [];
  110. fields[field].push(error);
  111. });
  112. return fields;
  113. }
  114. function format() {
  115. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  116. args[_key] = arguments[_key];
  117. }
  118. var i = 1;
  119. var f = args[0];
  120. var len = args.length;
  121. if (typeof f === 'function') {
  122. return f.apply(null, args.slice(1));
  123. }
  124. if (typeof f === 'string') {
  125. var str = String(f).replace(formatRegExp, function (x) {
  126. if (x === '%%') {
  127. return '%';
  128. }
  129. if (i >= len) {
  130. return x;
  131. }
  132. switch (x) {
  133. case '%s':
  134. return String(args[i++]);
  135. case '%d':
  136. return Number(args[i++]);
  137. case '%j':
  138. try {
  139. return JSON.stringify(args[i++]);
  140. } catch (_) {
  141. return '[Circular]';
  142. }
  143. break;
  144. default:
  145. return x;
  146. }
  147. });
  148. return str;
  149. }
  150. return f;
  151. }
  152. function isNativeStringType(type) {
  153. return type === 'string' || type === 'url' || type === 'hex' || type === 'email' || type === 'date' || type === 'pattern';
  154. }
  155. function isEmptyValue(value, type) {
  156. if (value === undefined || value === null) {
  157. return true;
  158. }
  159. if (type === 'array' && Array.isArray(value) && !value.length) {
  160. return true;
  161. }
  162. if (isNativeStringType(type) && typeof value === 'string' && !value) {
  163. return true;
  164. }
  165. return false;
  166. }
  167. function asyncParallelArray(arr, func, callback) {
  168. var results = [];
  169. var total = 0;
  170. var arrLength = arr.length;
  171. function count(errors) {
  172. results.push.apply(results, errors);
  173. total++;
  174. if (total === arrLength) {
  175. callback(results);
  176. }
  177. }
  178. arr.forEach(function (a) {
  179. func(a, count);
  180. });
  181. }
  182. function asyncSerialArray(arr, func, callback) {
  183. var index = 0;
  184. var arrLength = arr.length;
  185. function next(errors) {
  186. if (errors && errors.length) {
  187. callback(errors);
  188. return;
  189. }
  190. var original = index;
  191. index = index + 1;
  192. if (original < arrLength) {
  193. func(arr[original], next);
  194. } else {
  195. callback([]);
  196. }
  197. }
  198. next([]);
  199. }
  200. function flattenObjArr(objArr) {
  201. var ret = [];
  202. Object.keys(objArr).forEach(function (k) {
  203. ret.push.apply(ret, objArr[k]);
  204. });
  205. return ret;
  206. }
  207. var AsyncValidationError = /*#__PURE__*/function (_Error) {
  208. _inheritsLoose(AsyncValidationError, _Error);
  209. function AsyncValidationError(errors, fields) {
  210. var _this;
  211. _this = _Error.call(this, 'Async Validation Error') || this;
  212. _this.errors = errors;
  213. _this.fields = fields;
  214. return _this;
  215. }
  216. return AsyncValidationError;
  217. }( /*#__PURE__*/_wrapNativeSuper(Error));
  218. function asyncMap(objArr, option, func, callback) {
  219. if (option.first) {
  220. var _pending = new Promise(function (resolve, reject) {
  221. var next = function next(errors) {
  222. callback(errors);
  223. return errors.length ? reject(new AsyncValidationError(errors, convertFieldsError(errors))) : resolve();
  224. };
  225. var flattenArr = flattenObjArr(objArr);
  226. asyncSerialArray(flattenArr, func, next);
  227. });
  228. _pending["catch"](function (e) {
  229. return e;
  230. });
  231. return _pending;
  232. }
  233. var firstFields = option.firstFields || [];
  234. if (firstFields === true) {
  235. firstFields = Object.keys(objArr);
  236. }
  237. var objArrKeys = Object.keys(objArr);
  238. var objArrLength = objArrKeys.length;
  239. var total = 0;
  240. var results = [];
  241. var pending = new Promise(function (resolve, reject) {
  242. var next = function next(errors) {
  243. results.push.apply(results, errors);
  244. total++;
  245. if (total === objArrLength) {
  246. callback(results);
  247. return results.length ? reject(new AsyncValidationError(results, convertFieldsError(results))) : resolve();
  248. }
  249. };
  250. if (!objArrKeys.length) {
  251. callback(results);
  252. resolve();
  253. }
  254. objArrKeys.forEach(function (key) {
  255. var arr = objArr[key];
  256. if (firstFields.indexOf(key) !== -1) {
  257. asyncSerialArray(arr, func, next);
  258. } else {
  259. asyncParallelArray(arr, func, next);
  260. }
  261. });
  262. });
  263. pending["catch"](function (e) {
  264. return e;
  265. });
  266. return pending;
  267. }
  268. function complementError(rule) {
  269. return function (oe) {
  270. if (oe && oe.message) {
  271. oe.field = oe.field || rule.fullField;
  272. return oe;
  273. }
  274. return {
  275. message: typeof oe === 'function' ? oe() : oe,
  276. field: oe.field || rule.fullField
  277. };
  278. };
  279. }
  280. function deepMerge(target, source) {
  281. if (source) {
  282. for (var s in source) {
  283. if (source.hasOwnProperty(s)) {
  284. var value = source[s];
  285. if (typeof value === 'object' && typeof target[s] === 'object') {
  286. target[s] = _extends({}, target[s], value);
  287. } else {
  288. target[s] = value;
  289. }
  290. }
  291. }
  292. }
  293. return target;
  294. }
  295. /**
  296. * Rule for validating required fields.
  297. *
  298. * @param rule The validation rule.
  299. * @param value The value of the field on the source object.
  300. * @param source The source object being validated.
  301. * @param errors An array of errors that this rule may add
  302. * validation errors to.
  303. * @param options The validation options.
  304. * @param options.messages The validation messages.
  305. */
  306. function required(rule, value, source, errors, options, type) {
  307. if (rule.required && (!source.hasOwnProperty(rule.field) || isEmptyValue(value, type || rule.type))) {
  308. errors.push(format(options.messages.required, rule.fullField));
  309. }
  310. }
  311. /**
  312. * Rule for validating whitespace.
  313. *
  314. * @param rule The validation rule.
  315. * @param value The value of the field on the source object.
  316. * @param source The source object being validated.
  317. * @param errors An array of errors that this rule may add
  318. * validation errors to.
  319. * @param options The validation options.
  320. * @param options.messages The validation messages.
  321. */
  322. function whitespace(rule, value, source, errors, options) {
  323. if (/^\s+$/.test(value) || value === '') {
  324. errors.push(format(options.messages.whitespace, rule.fullField));
  325. }
  326. }
  327. /* eslint max-len:0 */
  328. var pattern = {
  329. // http://emailregex.com/
  330. email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
  331. url: new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$", 'i'),
  332. hex: /^#?([a-f0-9]{6}|[a-f0-9]{3})$/i
  333. };
  334. var types = {
  335. integer: function integer(value) {
  336. return types.number(value) && parseInt(value, 10) === value;
  337. },
  338. "float": function float(value) {
  339. return types.number(value) && !types.integer(value);
  340. },
  341. array: function array(value) {
  342. return Array.isArray(value);
  343. },
  344. regexp: function regexp(value) {
  345. if (value instanceof RegExp) {
  346. return true;
  347. }
  348. try {
  349. return !!new RegExp(value);
  350. } catch (e) {
  351. return false;
  352. }
  353. },
  354. date: function date(value) {
  355. return typeof value.getTime === 'function' && typeof value.getMonth === 'function' && typeof value.getYear === 'function' && !isNaN(value.getTime());
  356. },
  357. number: function number(value) {
  358. if (isNaN(value)) {
  359. return false;
  360. }
  361. return typeof value === 'number';
  362. },
  363. object: function object(value) {
  364. return typeof value === 'object' && !types.array(value);
  365. },
  366. method: function method(value) {
  367. return typeof value === 'function';
  368. },
  369. email: function email(value) {
  370. return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
  371. },
  372. url: function url(value) {
  373. return typeof value === 'string' && !!value.match(pattern.url);
  374. },
  375. hex: function hex(value) {
  376. return typeof value === 'string' && !!value.match(pattern.hex);
  377. }
  378. };
  379. /**
  380. * Rule for validating the type of a value.
  381. *
  382. * @param rule The validation rule.
  383. * @param value The value of the field on the source object.
  384. * @param source The source object being validated.
  385. * @param errors An array of errors that this rule may add
  386. * validation errors to.
  387. * @param options The validation options.
  388. * @param options.messages The validation messages.
  389. */
  390. function type(rule, value, source, errors, options) {
  391. if (rule.required && value === undefined) {
  392. required(rule, value, source, errors, options);
  393. return;
  394. }
  395. var custom = ['integer', 'float', 'array', 'regexp', 'object', 'method', 'email', 'number', 'date', 'url', 'hex'];
  396. var ruleType = rule.type;
  397. if (custom.indexOf(ruleType) > -1) {
  398. if (!types[ruleType](value)) {
  399. errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type));
  400. } // straight typeof check
  401. } else if (ruleType && typeof value !== rule.type) {
  402. errors.push(format(options.messages.types[ruleType], rule.fullField, rule.type));
  403. }
  404. }
  405. /**
  406. * Rule for validating minimum and maximum allowed values.
  407. *
  408. * @param rule The validation rule.
  409. * @param value The value of the field on the source object.
  410. * @param source The source object being validated.
  411. * @param errors An array of errors that this rule may add
  412. * validation errors to.
  413. * @param options The validation options.
  414. * @param options.messages The validation messages.
  415. */
  416. function range(rule, value, source, errors, options) {
  417. var len = typeof rule.len === 'number';
  418. var min = typeof rule.min === 'number';
  419. var max = typeof rule.max === 'number'; // 正则匹配码点范围从U+010000一直到U+10FFFF的文字(补充平面Supplementary Plane)
  420. var spRegexp = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
  421. var val = value;
  422. var key = null;
  423. var num = typeof value === 'number';
  424. var str = typeof value === 'string';
  425. var arr = Array.isArray(value);
  426. if (num) {
  427. key = 'number';
  428. } else if (str) {
  429. key = 'string';
  430. } else if (arr) {
  431. key = 'array';
  432. } // if the value is not of a supported type for range validation
  433. // the validation rule rule should use the
  434. // type property to also test for a particular type
  435. if (!key) {
  436. return false;
  437. }
  438. if (arr) {
  439. val = value.length;
  440. }
  441. if (str) {
  442. // 处理码点大于U+010000的文字length属性不准确的bug,如"𠮷𠮷𠮷".lenght !== 3
  443. val = value.replace(spRegexp, '_').length;
  444. }
  445. if (len) {
  446. if (val !== rule.len) {
  447. errors.push(format(options.messages[key].len, rule.fullField, rule.len));
  448. }
  449. } else if (min && !max && val < rule.min) {
  450. errors.push(format(options.messages[key].min, rule.fullField, rule.min));
  451. } else if (max && !min && val > rule.max) {
  452. errors.push(format(options.messages[key].max, rule.fullField, rule.max));
  453. } else if (min && max && (val < rule.min || val > rule.max)) {
  454. errors.push(format(options.messages[key].range, rule.fullField, rule.min, rule.max));
  455. }
  456. }
  457. var ENUM = 'enum';
  458. /**
  459. * Rule for validating a value exists in an enumerable list.
  460. *
  461. * @param rule The validation rule.
  462. * @param value The value of the field on the source object.
  463. * @param source The source object being validated.
  464. * @param errors An array of errors that this rule may add
  465. * validation errors to.
  466. * @param options The validation options.
  467. * @param options.messages The validation messages.
  468. */
  469. function enumerable(rule, value, source, errors, options) {
  470. rule[ENUM] = Array.isArray(rule[ENUM]) ? rule[ENUM] : [];
  471. if (rule[ENUM].indexOf(value) === -1) {
  472. errors.push(format(options.messages[ENUM], rule.fullField, rule[ENUM].join(', ')));
  473. }
  474. }
  475. /**
  476. * Rule for validating a regular expression pattern.
  477. *
  478. * @param rule The validation rule.
  479. * @param value The value of the field on the source object.
  480. * @param source The source object being validated.
  481. * @param errors An array of errors that this rule may add
  482. * validation errors to.
  483. * @param options The validation options.
  484. * @param options.messages The validation messages.
  485. */
  486. function pattern$1(rule, value, source, errors, options) {
  487. if (rule.pattern) {
  488. if (rule.pattern instanceof RegExp) {
  489. // if a RegExp instance is passed, reset `lastIndex` in case its `global`
  490. // flag is accidentally set to `true`, which in a validation scenario
  491. // is not necessary and the result might be misleading
  492. rule.pattern.lastIndex = 0;
  493. if (!rule.pattern.test(value)) {
  494. errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern));
  495. }
  496. } else if (typeof rule.pattern === 'string') {
  497. var _pattern = new RegExp(rule.pattern);
  498. if (!_pattern.test(value)) {
  499. errors.push(format(options.messages.pattern.mismatch, rule.fullField, value, rule.pattern));
  500. }
  501. }
  502. }
  503. }
  504. var rules = {
  505. required: required,
  506. whitespace: whitespace,
  507. type: type,
  508. range: range,
  509. "enum": enumerable,
  510. pattern: pattern$1
  511. };
  512. /**
  513. * Performs validation for string types.
  514. *
  515. * @param rule The validation rule.
  516. * @param value The value of the field on the source object.
  517. * @param callback The callback function.
  518. * @param source The source object being validated.
  519. * @param options The validation options.
  520. * @param options.messages The validation messages.
  521. */
  522. function string(rule, value, callback, source, options) {
  523. var errors = [];
  524. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  525. if (validate) {
  526. if (isEmptyValue(value, 'string') && !rule.required) {
  527. return callback();
  528. }
  529. rules.required(rule, value, source, errors, options, 'string');
  530. if (!isEmptyValue(value, 'string')) {
  531. rules.type(rule, value, source, errors, options);
  532. rules.range(rule, value, source, errors, options);
  533. rules.pattern(rule, value, source, errors, options);
  534. if (rule.whitespace === true) {
  535. rules.whitespace(rule, value, source, errors, options);
  536. }
  537. }
  538. }
  539. callback(errors);
  540. }
  541. /**
  542. * Validates a function.
  543. *
  544. * @param rule The validation rule.
  545. * @param value The value of the field on the source object.
  546. * @param callback The callback function.
  547. * @param source The source object being validated.
  548. * @param options The validation options.
  549. * @param options.messages The validation messages.
  550. */
  551. function method(rule, value, callback, source, options) {
  552. var errors = [];
  553. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  554. if (validate) {
  555. if (isEmptyValue(value) && !rule.required) {
  556. return callback();
  557. }
  558. rules.required(rule, value, source, errors, options);
  559. if (value !== undefined) {
  560. rules.type(rule, value, source, errors, options);
  561. }
  562. }
  563. callback(errors);
  564. }
  565. /**
  566. * Validates a number.
  567. *
  568. * @param rule The validation rule.
  569. * @param value The value of the field on the source object.
  570. * @param callback The callback function.
  571. * @param source The source object being validated.
  572. * @param options The validation options.
  573. * @param options.messages The validation messages.
  574. */
  575. function number(rule, value, callback, source, options) {
  576. var errors = [];
  577. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  578. if (validate) {
  579. if (value === '') {
  580. value = undefined;
  581. }
  582. if (isEmptyValue(value) && !rule.required) {
  583. return callback();
  584. }
  585. rules.required(rule, value, source, errors, options);
  586. if (value !== undefined) {
  587. rules.type(rule, value, source, errors, options);
  588. rules.range(rule, value, source, errors, options);
  589. }
  590. }
  591. callback(errors);
  592. }
  593. /**
  594. * Validates a boolean.
  595. *
  596. * @param rule The validation rule.
  597. * @param value The value of the field on the source object.
  598. * @param callback The callback function.
  599. * @param source The source object being validated.
  600. * @param options The validation options.
  601. * @param options.messages The validation messages.
  602. */
  603. function _boolean(rule, value, callback, source, options) {
  604. var errors = [];
  605. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  606. if (validate) {
  607. if (isEmptyValue(value) && !rule.required) {
  608. return callback();
  609. }
  610. rules.required(rule, value, source, errors, options);
  611. if (value !== undefined) {
  612. rules.type(rule, value, source, errors, options);
  613. }
  614. }
  615. callback(errors);
  616. }
  617. /**
  618. * Validates the regular expression type.
  619. *
  620. * @param rule The validation rule.
  621. * @param value The value of the field on the source object.
  622. * @param callback The callback function.
  623. * @param source The source object being validated.
  624. * @param options The validation options.
  625. * @param options.messages The validation messages.
  626. */
  627. function regexp(rule, value, callback, source, options) {
  628. var errors = [];
  629. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  630. if (validate) {
  631. if (isEmptyValue(value) && !rule.required) {
  632. return callback();
  633. }
  634. rules.required(rule, value, source, errors, options);
  635. if (!isEmptyValue(value)) {
  636. rules.type(rule, value, source, errors, options);
  637. }
  638. }
  639. callback(errors);
  640. }
  641. /**
  642. * Validates a number is an integer.
  643. *
  644. * @param rule The validation rule.
  645. * @param value The value of the field on the source object.
  646. * @param callback The callback function.
  647. * @param source The source object being validated.
  648. * @param options The validation options.
  649. * @param options.messages The validation messages.
  650. */
  651. function integer(rule, value, callback, source, options) {
  652. var errors = [];
  653. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  654. if (validate) {
  655. if (isEmptyValue(value) && !rule.required) {
  656. return callback();
  657. }
  658. rules.required(rule, value, source, errors, options);
  659. if (value !== undefined) {
  660. rules.type(rule, value, source, errors, options);
  661. rules.range(rule, value, source, errors, options);
  662. }
  663. }
  664. callback(errors);
  665. }
  666. /**
  667. * Validates a number is a floating point number.
  668. *
  669. * @param rule The validation rule.
  670. * @param value The value of the field on the source object.
  671. * @param callback The callback function.
  672. * @param source The source object being validated.
  673. * @param options The validation options.
  674. * @param options.messages The validation messages.
  675. */
  676. function floatFn(rule, value, callback, source, options) {
  677. var errors = [];
  678. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  679. if (validate) {
  680. if (isEmptyValue(value) && !rule.required) {
  681. return callback();
  682. }
  683. rules.required(rule, value, source, errors, options);
  684. if (value !== undefined) {
  685. rules.type(rule, value, source, errors, options);
  686. rules.range(rule, value, source, errors, options);
  687. }
  688. }
  689. callback(errors);
  690. }
  691. /**
  692. * Validates an array.
  693. *
  694. * @param rule The validation rule.
  695. * @param value The value of the field on the source object.
  696. * @param callback The callback function.
  697. * @param source The source object being validated.
  698. * @param options The validation options.
  699. * @param options.messages The validation messages.
  700. */
  701. function array(rule, value, callback, source, options) {
  702. var errors = [];
  703. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  704. if (validate) {
  705. if ((value === undefined || value === null) && !rule.required) {
  706. return callback();
  707. }
  708. rules.required(rule, value, source, errors, options, 'array');
  709. if (value !== undefined && value !== null) {
  710. rules.type(rule, value, source, errors, options);
  711. rules.range(rule, value, source, errors, options);
  712. }
  713. }
  714. callback(errors);
  715. }
  716. /**
  717. * Validates an object.
  718. *
  719. * @param rule The validation rule.
  720. * @param value The value of the field on the source object.
  721. * @param callback The callback function.
  722. * @param source The source object being validated.
  723. * @param options The validation options.
  724. * @param options.messages The validation messages.
  725. */
  726. function object(rule, value, callback, source, options) {
  727. var errors = [];
  728. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  729. if (validate) {
  730. if (isEmptyValue(value) && !rule.required) {
  731. return callback();
  732. }
  733. rules.required(rule, value, source, errors, options);
  734. if (value !== undefined) {
  735. rules.type(rule, value, source, errors, options);
  736. }
  737. }
  738. callback(errors);
  739. }
  740. var ENUM$1 = 'enum';
  741. /**
  742. * Validates an enumerable list.
  743. *
  744. * @param rule The validation rule.
  745. * @param value The value of the field on the source object.
  746. * @param callback The callback function.
  747. * @param source The source object being validated.
  748. * @param options The validation options.
  749. * @param options.messages The validation messages.
  750. */
  751. function enumerable$1(rule, value, callback, source, options) {
  752. var errors = [];
  753. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  754. if (validate) {
  755. if (isEmptyValue(value) && !rule.required) {
  756. return callback();
  757. }
  758. rules.required(rule, value, source, errors, options);
  759. if (value !== undefined) {
  760. rules[ENUM$1](rule, value, source, errors, options);
  761. }
  762. }
  763. callback(errors);
  764. }
  765. /**
  766. * Validates a regular expression pattern.
  767. *
  768. * Performs validation when a rule only contains
  769. * a pattern property but is not declared as a string type.
  770. *
  771. * @param rule The validation rule.
  772. * @param value The value of the field on the source object.
  773. * @param callback The callback function.
  774. * @param source The source object being validated.
  775. * @param options The validation options.
  776. * @param options.messages The validation messages.
  777. */
  778. function pattern$2(rule, value, callback, source, options) {
  779. var errors = [];
  780. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  781. if (validate) {
  782. if (isEmptyValue(value, 'string') && !rule.required) {
  783. return callback();
  784. }
  785. rules.required(rule, value, source, errors, options);
  786. if (!isEmptyValue(value, 'string')) {
  787. rules.pattern(rule, value, source, errors, options);
  788. }
  789. }
  790. callback(errors);
  791. }
  792. function date(rule, value, callback, source, options) {
  793. // console.log('integer rule called %j', rule);
  794. var errors = [];
  795. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field); // console.log('validate on %s value', value);
  796. if (validate) {
  797. if (isEmptyValue(value, 'date') && !rule.required) {
  798. return callback();
  799. }
  800. rules.required(rule, value, source, errors, options);
  801. if (!isEmptyValue(value, 'date')) {
  802. var dateObject;
  803. if (value instanceof Date) {
  804. dateObject = value;
  805. } else {
  806. dateObject = new Date(value);
  807. }
  808. rules.type(rule, dateObject, source, errors, options);
  809. if (dateObject) {
  810. rules.range(rule, dateObject.getTime(), source, errors, options);
  811. }
  812. }
  813. }
  814. callback(errors);
  815. }
  816. function required$1(rule, value, callback, source, options) {
  817. var errors = [];
  818. var type = Array.isArray(value) ? 'array' : typeof value;
  819. rules.required(rule, value, source, errors, options, type);
  820. callback(errors);
  821. }
  822. function type$1(rule, value, callback, source, options) {
  823. var ruleType = rule.type;
  824. var errors = [];
  825. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  826. if (validate) {
  827. if (isEmptyValue(value, ruleType) && !rule.required) {
  828. return callback();
  829. }
  830. rules.required(rule, value, source, errors, options, ruleType);
  831. if (!isEmptyValue(value, ruleType)) {
  832. rules.type(rule, value, source, errors, options);
  833. }
  834. }
  835. callback(errors);
  836. }
  837. /**
  838. * Performs validation for any type.
  839. *
  840. * @param rule The validation rule.
  841. * @param value The value of the field on the source object.
  842. * @param callback The callback function.
  843. * @param source The source object being validated.
  844. * @param options The validation options.
  845. * @param options.messages The validation messages.
  846. */
  847. function any(rule, value, callback, source, options) {
  848. var errors = [];
  849. var validate = rule.required || !rule.required && source.hasOwnProperty(rule.field);
  850. if (validate) {
  851. if (isEmptyValue(value) && !rule.required) {
  852. return callback();
  853. }
  854. rules.required(rule, value, source, errors, options);
  855. }
  856. callback(errors);
  857. }
  858. var validators = {
  859. string: string,
  860. method: method,
  861. number: number,
  862. "boolean": _boolean,
  863. regexp: regexp,
  864. integer: integer,
  865. "float": floatFn,
  866. array: array,
  867. object: object,
  868. "enum": enumerable$1,
  869. pattern: pattern$2,
  870. date: date,
  871. url: type$1,
  872. hex: type$1,
  873. email: type$1,
  874. required: required$1,
  875. any: any
  876. };
  877. function newMessages() {
  878. return {
  879. "default": 'Validation error on field %s',
  880. required: '%s is required',
  881. "enum": '%s must be one of %s',
  882. whitespace: '%s cannot be empty',
  883. date: {
  884. format: '%s date %s is invalid for format %s',
  885. parse: '%s date could not be parsed, %s is invalid ',
  886. invalid: '%s date %s is invalid'
  887. },
  888. types: {
  889. string: '%s is not a %s',
  890. method: '%s is not a %s (function)',
  891. array: '%s is not an %s',
  892. object: '%s is not an %s',
  893. number: '%s is not a %s',
  894. date: '%s is not a %s',
  895. "boolean": '%s is not a %s',
  896. integer: '%s is not an %s',
  897. "float": '%s is not a %s',
  898. regexp: '%s is not a valid %s',
  899. email: '%s is not a valid %s',
  900. url: '%s is not a valid %s',
  901. hex: '%s is not a valid %s'
  902. },
  903. string: {
  904. len: '%s must be exactly %s characters',
  905. min: '%s must be at least %s characters',
  906. max: '%s cannot be longer than %s characters',
  907. range: '%s must be between %s and %s characters'
  908. },
  909. number: {
  910. len: '%s must equal %s',
  911. min: '%s cannot be less than %s',
  912. max: '%s cannot be greater than %s',
  913. range: '%s must be between %s and %s'
  914. },
  915. array: {
  916. len: '%s must be exactly %s in length',
  917. min: '%s cannot be less than %s in length',
  918. max: '%s cannot be greater than %s in length',
  919. range: '%s must be between %s and %s in length'
  920. },
  921. pattern: {
  922. mismatch: '%s value %s does not match pattern %s'
  923. },
  924. clone: function clone() {
  925. var cloned = JSON.parse(JSON.stringify(this));
  926. cloned.clone = this.clone;
  927. return cloned;
  928. }
  929. };
  930. }
  931. var messages = newMessages();
  932. /**
  933. * Encapsulates a validation schema.
  934. *
  935. * @param descriptor An object declaring validation rules
  936. * for this schema.
  937. */
  938. function Schema(descriptor) {
  939. this.rules = null;
  940. this._messages = messages;
  941. this.define(descriptor);
  942. }
  943. Schema.prototype = {
  944. messages: function messages(_messages) {
  945. if (_messages) {
  946. this._messages = deepMerge(newMessages(), _messages);
  947. }
  948. return this._messages;
  949. },
  950. define: function define(rules) {
  951. if (!rules) {
  952. throw new Error('Cannot configure a schema with no rules');
  953. }
  954. if (typeof rules !== 'object' || Array.isArray(rules)) {
  955. throw new Error('Rules must be an object');
  956. }
  957. this.rules = {};
  958. var z;
  959. var item;
  960. for (z in rules) {
  961. if (rules.hasOwnProperty(z)) {
  962. item = rules[z];
  963. this.rules[z] = Array.isArray(item) ? item : [item];
  964. }
  965. }
  966. },
  967. validate: function validate(source_, o, oc) {
  968. var _this = this;
  969. if (o === void 0) {
  970. o = {};
  971. }
  972. if (oc === void 0) {
  973. oc = function oc() {};
  974. }
  975. var source = source_;
  976. var options = o;
  977. var callback = oc;
  978. if (typeof options === 'function') {
  979. callback = options;
  980. options = {};
  981. }
  982. if (!this.rules || Object.keys(this.rules).length === 0) {
  983. if (callback) {
  984. callback();
  985. }
  986. return Promise.resolve();
  987. }
  988. function complete(results) {
  989. var i;
  990. var errors = [];
  991. var fields = {};
  992. function add(e) {
  993. if (Array.isArray(e)) {
  994. var _errors;
  995. errors = (_errors = errors).concat.apply(_errors, e);
  996. } else {
  997. errors.push(e);
  998. }
  999. }
  1000. for (i = 0; i < results.length; i++) {
  1001. add(results[i]);
  1002. }
  1003. if (!errors.length) {
  1004. errors = null;
  1005. fields = null;
  1006. } else {
  1007. fields = convertFieldsError(errors);
  1008. }
  1009. callback(errors, fields);
  1010. }
  1011. if (options.messages) {
  1012. var messages$1 = this.messages();
  1013. if (messages$1 === messages) {
  1014. messages$1 = newMessages();
  1015. }
  1016. deepMerge(messages$1, options.messages);
  1017. options.messages = messages$1;
  1018. } else {
  1019. options.messages = this.messages();
  1020. }
  1021. var arr;
  1022. var value;
  1023. var series = {};
  1024. var keys = options.keys || Object.keys(this.rules);
  1025. keys.forEach(function (z) {
  1026. arr = _this.rules[z];
  1027. value = source[z];
  1028. arr.forEach(function (r) {
  1029. var rule = r;
  1030. if (typeof rule.transform === 'function') {
  1031. if (source === source_) {
  1032. source = _extends({}, source);
  1033. }
  1034. value = source[z] = rule.transform(value);
  1035. }
  1036. if (typeof rule === 'function') {
  1037. rule = {
  1038. validator: rule
  1039. };
  1040. } else {
  1041. rule = _extends({}, rule);
  1042. }
  1043. rule.validator = _this.getValidationMethod(rule);
  1044. rule.field = z;
  1045. rule.fullField = rule.fullField || z;
  1046. rule.type = _this.getType(rule);
  1047. if (!rule.validator) {
  1048. return;
  1049. }
  1050. series[z] = series[z] || [];
  1051. series[z].push({
  1052. rule: rule,
  1053. value: value,
  1054. source: source,
  1055. field: z
  1056. });
  1057. });
  1058. });
  1059. var errorFields = {};
  1060. return asyncMap(series, options, function (data, doIt) {
  1061. var rule = data.rule;
  1062. var deep = (rule.type === 'object' || rule.type === 'array') && (typeof rule.fields === 'object' || typeof rule.defaultField === 'object');
  1063. deep = deep && (rule.required || !rule.required && data.value);
  1064. rule.field = data.field;
  1065. function addFullfield(key, schema) {
  1066. return _extends({}, schema, {
  1067. fullField: rule.fullField + "." + key
  1068. });
  1069. }
  1070. function cb(e) {
  1071. if (e === void 0) {
  1072. e = [];
  1073. }
  1074. var errors = e;
  1075. if (!Array.isArray(errors)) {
  1076. errors = [errors];
  1077. }
  1078. if (!options.suppressWarning && errors.length) {
  1079. Schema.warning('async-validator:', errors);
  1080. }
  1081. if (errors.length && rule.message !== undefined) {
  1082. errors = [].concat(rule.message);
  1083. }
  1084. errors = errors.map(complementError(rule));
  1085. if (options.first && errors.length) {
  1086. errorFields[rule.field] = 1;
  1087. return doIt(errors);
  1088. }
  1089. if (!deep) {
  1090. doIt(errors);
  1091. } else {
  1092. // if rule is required but the target object
  1093. // does not exist fail at the rule level and don't
  1094. // go deeper
  1095. if (rule.required && !data.value) {
  1096. if (rule.message !== undefined) {
  1097. errors = [].concat(rule.message).map(complementError(rule));
  1098. } else if (options.error) {
  1099. errors = [options.error(rule, format(options.messages.required, rule.field))];
  1100. }
  1101. return doIt(errors);
  1102. }
  1103. var fieldsSchema = {};
  1104. if (rule.defaultField) {
  1105. for (var k in data.value) {
  1106. if (data.value.hasOwnProperty(k)) {
  1107. fieldsSchema[k] = rule.defaultField;
  1108. }
  1109. }
  1110. }
  1111. fieldsSchema = _extends({}, fieldsSchema, data.rule.fields);
  1112. for (var f in fieldsSchema) {
  1113. if (fieldsSchema.hasOwnProperty(f)) {
  1114. var fieldSchema = Array.isArray(fieldsSchema[f]) ? fieldsSchema[f] : [fieldsSchema[f]];
  1115. fieldsSchema[f] = fieldSchema.map(addFullfield.bind(null, f));
  1116. }
  1117. }
  1118. var schema = new Schema(fieldsSchema);
  1119. schema.messages(options.messages);
  1120. if (data.rule.options) {
  1121. data.rule.options.messages = options.messages;
  1122. data.rule.options.error = options.error;
  1123. }
  1124. schema.validate(data.value, data.rule.options || options, function (errs) {
  1125. var finalErrors = [];
  1126. if (errors && errors.length) {
  1127. finalErrors.push.apply(finalErrors, errors);
  1128. }
  1129. if (errs && errs.length) {
  1130. finalErrors.push.apply(finalErrors, errs);
  1131. }
  1132. doIt(finalErrors.length ? finalErrors : null);
  1133. });
  1134. }
  1135. }
  1136. var res;
  1137. if (rule.asyncValidator) {
  1138. res = rule.asyncValidator(rule, data.value, cb, data.source, options);
  1139. } else if (rule.validator) {
  1140. res = rule.validator(rule, data.value, cb, data.source, options);
  1141. if (res === true) {
  1142. cb();
  1143. } else if (res === false) {
  1144. cb(rule.message || rule.field + " fails");
  1145. } else if (res instanceof Array) {
  1146. cb(res);
  1147. } else if (res instanceof Error) {
  1148. cb(res.message);
  1149. }
  1150. }
  1151. if (res && res.then) {
  1152. res.then(function () {
  1153. return cb();
  1154. }, function (e) {
  1155. return cb(e);
  1156. });
  1157. }
  1158. }, function (results) {
  1159. complete(results);
  1160. });
  1161. },
  1162. getType: function getType(rule) {
  1163. if (rule.type === undefined && rule.pattern instanceof RegExp) {
  1164. rule.type = 'pattern';
  1165. }
  1166. if (typeof rule.validator !== 'function' && rule.type && !validators.hasOwnProperty(rule.type)) {
  1167. throw new Error(format('Unknown rule type %s', rule.type));
  1168. }
  1169. return rule.type || 'string';
  1170. },
  1171. getValidationMethod: function getValidationMethod(rule) {
  1172. if (typeof rule.validator === 'function') {
  1173. return rule.validator;
  1174. }
  1175. var keys = Object.keys(rule);
  1176. var messageIndex = keys.indexOf('message');
  1177. if (messageIndex !== -1) {
  1178. keys.splice(messageIndex, 1);
  1179. }
  1180. if (keys.length === 1 && keys[0] === 'required') {
  1181. return validators.required;
  1182. }
  1183. return validators[this.getType(rule)] || false;
  1184. }
  1185. };
  1186. Schema.register = function register(type, validator) {
  1187. if (typeof validator !== 'function') {
  1188. throw new Error('Cannot register a validator by type, validator is not a function');
  1189. }
  1190. validators[type] = validator;
  1191. };
  1192. Schema.warning = warning;
  1193. Schema.messages = messages;
  1194. Schema.validators = validators;
  1195. exports.default = Schema;
  1196. //# sourceMappingURL=index.js.map