index.js 37 KB

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