util.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. const formatRegExp = /%[sdj%]/g;
  2. export let warning = () => {
  3. };
  4. export function format(...args) {
  5. let i = 1;
  6. const f = args[0];
  7. const len = args.length;
  8. if (typeof f === 'function') {
  9. return f.apply(null, args.slice(1));
  10. }
  11. if (typeof f === 'string') {
  12. let str = String(f).replace(formatRegExp, (x) => {
  13. if (x === '%%') {
  14. return '%';
  15. }
  16. if (i >= len) {
  17. return x;
  18. }
  19. switch (x) {
  20. case '%s':
  21. return String(args[i++]);
  22. case '%d':
  23. return Number(args[i++]);
  24. case '%j':
  25. try {
  26. return JSON.stringify(args[i++]);
  27. } catch (_) {
  28. return '[Circular]';
  29. }
  30. default:
  31. return x;
  32. }
  33. });
  34. for (let arg = args[i]; i < len; arg = args[++i]) {
  35. str += ` ${arg}`;
  36. }
  37. return str;
  38. }
  39. return f;
  40. }
  41. function isNativeStringType(type) {
  42. return type === 'string' ||
  43. type === 'url' ||
  44. type === 'hex' ||
  45. type === 'email' ||
  46. type === 'pattern';
  47. }
  48. export function isEmptyValue(value, type) {
  49. if (value === undefined || value === null) {
  50. return true;
  51. }
  52. if (type === 'array' && Array.isArray(value) && !value.length) {
  53. return true;
  54. }
  55. if (isNativeStringType(type) && typeof value === 'string' && !value) {
  56. return true;
  57. }
  58. return false;
  59. }
  60. export function isEmptyObject(obj) {
  61. return Object.keys(obj).length === 0;
  62. }
  63. function asyncParallelArray(arr, func, callback) {
  64. const results = [];
  65. let total = 0;
  66. const arrLength = arr.length;
  67. function count(errors) {
  68. results.push.apply(results, errors);
  69. total++;
  70. if (total === arrLength) {
  71. callback(results);
  72. }
  73. }
  74. arr.forEach((a) => {
  75. func(a, count);
  76. });
  77. }
  78. function asyncSerialArray(arr, func, callback) {
  79. let index = 0;
  80. const arrLength = arr.length;
  81. function next(errors) {
  82. if (errors && errors.length) {
  83. callback(errors);
  84. return;
  85. }
  86. const original = index;
  87. index = index + 1;
  88. if (original < arrLength) {
  89. func(arr[original], next);
  90. } else {
  91. callback([]);
  92. }
  93. }
  94. next([]);
  95. }
  96. function flattenObjArr(objArr) {
  97. const ret = [];
  98. Object.keys(objArr).forEach((k) => {
  99. ret.push.apply(ret, objArr[k]);
  100. });
  101. return ret;
  102. }
  103. export function asyncMap(objArr, option, func, callback) {
  104. if (option.first) {
  105. const flattenArr = flattenObjArr(objArr);
  106. return asyncSerialArray(flattenArr, func, callback);
  107. }
  108. let firstFields = option.firstFields || [];
  109. if (firstFields === true) {
  110. firstFields = Object.keys(objArr);
  111. }
  112. const objArrKeys = Object.keys(objArr);
  113. const objArrLength = objArrKeys.length;
  114. let total = 0;
  115. const results = [];
  116. const next = (errors) => {
  117. results.push.apply(results, errors);
  118. total++;
  119. if (total === objArrLength) {
  120. callback(results);
  121. }
  122. };
  123. objArrKeys.forEach((key) => {
  124. const arr = objArr[key];
  125. if (firstFields.indexOf(key) !== -1) {
  126. asyncSerialArray(arr, func, next);
  127. } else {
  128. asyncParallelArray(arr, func, next);
  129. }
  130. });
  131. }
  132. export function complementError(rule) {
  133. return (oe) => {
  134. if (oe && oe.message) {
  135. oe.field = oe.field || rule.fullField;
  136. return oe;
  137. }
  138. return {
  139. message: oe,
  140. field: oe.field || rule.fullField,
  141. };
  142. };
  143. }
  144. export function deepMerge(target, source) {
  145. if (source) {
  146. for (const s in source) {
  147. if (source.hasOwnProperty(s)) {
  148. const value = source[s];
  149. if (typeof value === 'object' && typeof target[s] === 'object') {
  150. target[s] = {
  151. ...target[s],
  152. ...value,
  153. };
  154. } else {
  155. target[s] = value;
  156. }
  157. }
  158. }
  159. }
  160. return target;
  161. }