mock平台

utils.js 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. const Mock = require('mockjs');
  2. const filter = require('./power-string.js').filter;
  3. const stringUtils = require('./power-string.js').utils;
  4. const json5 = require('json5');
  5. const Ajv = require('ajv');
  6. /**
  7. * 作用:解析规则串 key ,然后根据规则串的规则以及路径找到在 json 中对应的数据
  8. * 规则串:$.{key}.{body||params}.{dataPath} 其中 body 为返回数据,params 为请求数据,datapath 为数据的路径
  9. * 数组:$.key.body.data.arr[0]._id (获取 key 所指向请求的返回数据的 arr 数组的第 0 项元素的 _id 属性)
  10. * 对象:$.key.body.data.obj._id ((获取 key 所指向请求的返回数据的 obj 对象的 _id 属性))
  11. *
  12. * @param String key 规则串
  13. * @param Object json 数据
  14. * @returns
  15. */
  16. function simpleJsonPathParse(key, json) {
  17. if (!key || typeof key !== 'string' || key.indexOf('$.') !== 0 || key.length <= 2) {
  18. return null;
  19. }
  20. let keys = key.substr(2).split('.');
  21. keys = keys.filter(item => {
  22. return item;
  23. });
  24. for (let i = 0, l = keys.length; i < l; i++) {
  25. try {
  26. let m = keys[i].match(/(.*?)\[([0-9]+)\]/);
  27. if (m) {
  28. json = json[m[1]][m[2]];
  29. } else {
  30. json = json[keys[i]];
  31. }
  32. } catch (e) {
  33. json = '';
  34. break;
  35. }
  36. }
  37. return json;
  38. }
  39. // 全局变量 {{ global.value }}
  40. // value 是在环境变量中定义的字段
  41. function handleGlobalWord(word, json) {
  42. if (!word || typeof word !== 'string' || word.indexOf('global.') !== 0) return word;
  43. let keys = word.split('.');
  44. keys = keys.filter(item => {
  45. return item;
  46. });
  47. return json[keys[0]][keys[1]] || word;
  48. }
  49. function handleMockWord(word) {
  50. if (!word || typeof word !== 'string' || word[0] !== '@') return word;
  51. return Mock.mock(word);
  52. }
  53. /**
  54. *
  55. * @param {*} data
  56. * @param {*} handleValueFn 处理参数值函数
  57. */
  58. function handleJson(data, handleValueFn) {
  59. if (!data) {
  60. return data;
  61. }
  62. if (typeof data === 'string') {
  63. return handleValueFn(data);
  64. } else if (typeof data === 'object') {
  65. for (let i in data) {
  66. data[i] = handleJson(data[i], handleValueFn);
  67. }
  68. } else {
  69. return data;
  70. }
  71. return data;
  72. }
  73. function handleValueWithFilter(context) {
  74. return function(match) {
  75. if (match[0] === '@') {
  76. return handleMockWord(match);
  77. } else if (match.indexOf('$.') === 0) {
  78. return simpleJsonPathParse(match, context);
  79. } else if (match.indexOf('global.') === 0) {
  80. return handleGlobalWord(match, context);
  81. } else {
  82. return match;
  83. }
  84. };
  85. }
  86. function handleFilter(str, match, context) {
  87. match = match.trim();
  88. try {
  89. let a = filter(match, handleValueWithFilter(context));
  90. return a;
  91. } catch (err) {
  92. return str;
  93. }
  94. }
  95. function handleParamsValue(val, context = {}) {
  96. const variableRegexp = /\{\{\s*([^}]+?)\}\}/g;
  97. if (!val || typeof val !== 'string') {
  98. return val;
  99. }
  100. val = val.trim();
  101. let match = val.match(/^\{\{([^\}]+)\}\}$/);
  102. if (!match) {
  103. // val ==> @name 或者 $.body
  104. if (val[0] === '@' || val[0] === '$') {
  105. return handleFilter(val, val, context);
  106. }
  107. } else {
  108. return handleFilter(val, match[1], context);
  109. }
  110. return val.replace(variableRegexp, (str, match) => {
  111. return handleFilter(str, match, context);
  112. });
  113. }
  114. exports.handleJson = handleJson;
  115. exports.handleParamsValue = handleParamsValue;
  116. exports.simpleJsonPathParse = simpleJsonPathParse;
  117. exports.handleMockWord = handleMockWord;
  118. exports.joinPath = (domain, joinPath) => {
  119. let l = domain.length;
  120. if (domain[l - 1] === '/') {
  121. domain = domain.substr(0, l - 1);
  122. }
  123. if (joinPath[0] !== '/') {
  124. joinPath = joinPath.substr(1);
  125. }
  126. return domain + joinPath;
  127. };
  128. // exports.safeArray = arr => {
  129. // return Array.isArray(arr) ? arr : [];
  130. // };
  131. function safeArray(arr) {
  132. return Array.isArray(arr) ? arr : [];
  133. }
  134. exports.safeArray = safeArray;
  135. exports.isJson5 = function isJson5(json) {
  136. if (!json) return false;
  137. try {
  138. json = json5.parse(json);
  139. return json;
  140. } catch (e) {
  141. return false;
  142. }
  143. };
  144. function isJson(json) {
  145. if (!json) return false;
  146. try {
  147. json = JSON.parse(json);
  148. return json;
  149. } catch (e) {
  150. return false;
  151. }
  152. }
  153. exports.isJson = isJson;
  154. exports.unbase64 = function(base64Str) {
  155. try {
  156. return stringUtils.unbase64(base64Str);
  157. } catch (err) {
  158. return base64Str;
  159. }
  160. };
  161. exports.json_parse = function(json) {
  162. try {
  163. return JSON.parse(json);
  164. } catch (err) {
  165. return json;
  166. }
  167. };
  168. exports.json_format = function(json) {
  169. try {
  170. return JSON.stringify(JSON.parse(json), null, ' ');
  171. } catch (e) {
  172. return json;
  173. }
  174. };
  175. exports.ArrayToObject = function(arr) {
  176. let obj = {};
  177. safeArray(arr).forEach(item => {
  178. obj[item.name] = item.value;
  179. });
  180. return obj;
  181. };
  182. exports.timeago = function(timestamp) {
  183. let minutes, hours, days, seconds, mouth, year;
  184. const timeNow = parseInt(new Date().getTime() / 1000);
  185. seconds = timeNow - timestamp;
  186. if (seconds > 86400 * 30 * 12) {
  187. year = parseInt(seconds / (86400 * 30 * 12));
  188. } else {
  189. year = 0;
  190. }
  191. if (seconds > 86400 * 30) {
  192. mouth = parseInt(seconds / (86400 * 30));
  193. } else {
  194. mouth = 0;
  195. }
  196. if (seconds > 86400) {
  197. days = parseInt(seconds / 86400);
  198. } else {
  199. days = 0;
  200. }
  201. if (seconds > 3600) {
  202. hours = parseInt(seconds / 3600);
  203. } else {
  204. hours = 0;
  205. }
  206. minutes = parseInt(seconds / 60);
  207. if (year > 0) {
  208. return year + '年前';
  209. } else if (mouth > 0 && year <= 0) {
  210. return mouth + '月前';
  211. } else if (days > 0 && mouth <= 0) {
  212. return days + '天前';
  213. } else if (days <= 0 && hours > 0) {
  214. return hours + '小时前';
  215. } else if (hours <= 0 && minutes > 0) {
  216. return minutes + '分钟前';
  217. } else if (minutes <= 0 && seconds > 0) {
  218. if (seconds < 30) {
  219. return '刚刚';
  220. } else {
  221. return seconds + '秒前';
  222. }
  223. } else {
  224. return '刚刚';
  225. }
  226. };
  227. // json schema 验证器
  228. exports.schemaValidator = function(schema, params) {
  229. try {
  230. const ajv = new Ajv({
  231. format: false,
  232. meta: false
  233. });
  234. let metaSchema = require('ajv/lib/refs/json-schema-draft-04.json');
  235. ajv.addMetaSchema(metaSchema);
  236. ajv._opts.defaultMeta = metaSchema.id;
  237. ajv._refs['http://json-schema.org/schema'] = 'http://json-schema.org/draft-04/schema';
  238. var localize = require('ajv-i18n');
  239. schema = schema || {
  240. type: 'object',
  241. title: 'empty object',
  242. properties: {}
  243. };
  244. const validate = ajv.compile(schema);
  245. let valid = validate(params);
  246. let message = '';
  247. if (!valid) {
  248. localize.zh(validate.errors);
  249. message += ajv.errorsText(validate.errors, { separator: '\n' });
  250. }
  251. return {
  252. valid: valid,
  253. message: message
  254. };
  255. } catch (e) {
  256. return {
  257. valid: false,
  258. message: e.message
  259. };
  260. }
  261. };