yapi/common/utils.js

289 lines
6.7 KiB
JavaScript
Raw Permalink Normal View History

2018-07-18 10:16:55 +08:00
const Mock = require('mockjs');
2018-02-08 16:03:14 +08:00
const filter = require('./power-string.js').filter;
const stringUtils = require('./power-string.js').utils;
2018-07-18 10:16:55 +08:00
const json5 = require('json5');
2018-08-08 15:33:14 +08:00
const Ajv = require('ajv');
2018-02-08 16:03:14 +08:00
/**
* 作用解析规则串 key 然后根据规则串的规则以及路径找到在 json 中对应的数据
* 规则串$.{key}.{body||params}.{dataPath} 其中 body 为返回数据params 为请求数据datapath 为数据的路径
* 数组$.key.body.data.arr[0]._id (获取 key 所指向请求的返回数据的 arr 数组的第 0 项元素的 _id 属性)
* 对象$.key.body.data.obj._id ((获取 key 所指向请求的返回数据的 obj 对象的 _id 属性))
2018-07-18 10:16:55 +08:00
*
2018-02-08 16:03:14 +08:00
* @param String key 规则串
* @param Object json 数据
2018-07-18 10:16:55 +08:00
* @returns
2018-02-08 16:03:14 +08:00
*/
2018-07-18 10:16:55 +08:00
function simpleJsonPathParse(key, json) {
if (!key || typeof key !== 'string' || key.indexOf('$.') !== 0 || key.length <= 2) {
2018-02-08 16:03:14 +08:00
return null;
}
2018-07-18 10:16:55 +08:00
let keys = key.substr(2).split('.');
keys = keys.filter(item => {
2018-02-08 16:03:14 +08:00
return item;
2018-07-18 10:16:55 +08:00
});
for (let i = 0, l = keys.length; i < l; i++) {
try {
let m = keys[i].match(/(.*?)\[([0-9]+)\]/);
if (m) {
2018-02-08 16:03:14 +08:00
json = json[m[1]][m[2]];
2018-07-18 10:16:55 +08:00
} else {
2018-02-08 16:03:14 +08:00
json = json[keys[i]];
}
2018-07-18 10:16:55 +08:00
} catch (e) {
2018-02-08 16:03:14 +08:00
json = '';
break;
}
}
2018-07-18 10:16:55 +08:00
2018-02-08 16:03:14 +08:00
return json;
}
2018-07-18 10:16:55 +08:00
// 全局变量 {{ global.value }}
// value 是在环境变量中定义的字段
function handleGlobalWord(word, json) {
if (!word || typeof word !== 'string' || word.indexOf('global.') !== 0) return word;
2018-07-18 10:16:55 +08:00
let keys = word.split('.');
keys = keys.filter(item => {
return item;
});
return json[keys[0]][keys[1]] || word;
}
2018-02-08 16:03:14 +08:00
function handleMockWord(word) {
2018-07-18 10:16:55 +08:00
if (!word || typeof word !== 'string' || word[0] !== '@') return word;
2018-02-08 16:03:14 +08:00
return Mock.mock(word);
}
/**
2018-07-18 10:16:55 +08:00
*
* @param {*} data
2018-02-08 16:03:14 +08:00
* @param {*} handleValueFn 处理参数值函数
*/
function handleJson(data, handleValueFn) {
if (!data) {
return data;
}
if (typeof data === 'string') {
return handleValueFn(data);
} else if (typeof data === 'object') {
for (let i in data) {
data[i] = handleJson(data[i], handleValueFn);
}
} else {
return data;
}
return data;
}
2018-07-18 10:16:55 +08:00
function handleValueWithFilter(context) {
return function(match) {
2018-02-08 16:03:14 +08:00
if (match[0] === '@') {
return handleMockWord(match);
} else if (match.indexOf('$.') === 0) {
return simpleJsonPathParse(match, context);
2018-07-18 10:16:55 +08:00
} else if (match.indexOf('global.') === 0) {
return handleGlobalWord(match, context);
} else {
2018-02-08 16:03:14 +08:00
return match;
}
2018-07-18 10:16:55 +08:00
};
2018-02-08 16:03:14 +08:00
}
2018-07-18 10:16:55 +08:00
function handleFilter(str, match, context) {
2018-02-08 16:03:14 +08:00
match = match.trim();
2018-07-18 10:16:55 +08:00
try {
let a = filter(match, handleValueWithFilter(context));
2018-02-08 16:03:14 +08:00
return a;
2018-07-18 10:16:55 +08:00
} catch (err) {
2018-02-08 16:03:14 +08:00
return str;
}
}
2018-07-18 10:16:55 +08:00
function handleParamsValue(val, context = {}) {
2018-02-08 16:03:14 +08:00
const variableRegexp = /\{\{\s*([^}]+?)\}\}/g;
if (!val || typeof val !== 'string') {
return val;
}
2018-07-18 10:16:55 +08:00
val = val.trim();
let match = val.match(/^\{\{([^\}]+)\}\}$/);
if (!match) {
// val ==> @name 或者 $.body
if (val[0] === '@' || val[0] === '$') {
2018-02-08 16:03:14 +08:00
return handleFilter(val, val, context);
}
2018-07-18 10:16:55 +08:00
} else {
2018-02-08 16:03:14 +08:00
return handleFilter(val, match[1], context);
}
2018-07-18 10:16:55 +08:00
return val.replace(variableRegexp, (str, match) => {
return handleFilter(str, match, context);
});
2018-02-08 16:03:14 +08:00
}
exports.handleJson = handleJson;
exports.handleParamsValue = handleParamsValue;
exports.simpleJsonPathParse = simpleJsonPathParse;
exports.handleMockWord = handleMockWord;
2018-07-18 10:16:55 +08:00
exports.joinPath = (domain, joinPath) => {
2018-02-08 16:03:14 +08:00
let l = domain.length;
2018-07-18 10:16:55 +08:00
if (domain[l - 1] === '/') {
domain = domain.substr(0, l - 1);
2018-02-08 16:03:14 +08:00
}
2018-07-18 10:16:55 +08:00
if (joinPath[0] !== '/') {
2018-02-08 16:03:14 +08:00
joinPath = joinPath.substr(1);
}
return domain + joinPath;
2018-07-18 10:16:55 +08:00
};
2018-02-08 16:03:14 +08:00
2018-07-18 15:30:24 +08:00
// exports.safeArray = arr => {
// return Array.isArray(arr) ? arr : [];
// };
function safeArray(arr) {
2018-07-18 10:16:55 +08:00
return Array.isArray(arr) ? arr : [];
2018-07-18 15:30:24 +08:00
}
exports.safeArray = safeArray;
2018-07-18 10:16:55 +08:00
exports.isJson5 = function isJson5(json) {
if (!json) return false;
try {
2018-02-08 16:03:14 +08:00
json = json5.parse(json);
return json;
2018-07-18 10:16:55 +08:00
} catch (e) {
2018-02-08 16:03:14 +08:00
return false;
}
2018-07-18 10:16:55 +08:00
};
2018-02-08 16:03:14 +08:00
2018-07-18 10:16:55 +08:00
function isJson(json) {
if (!json) return false;
try {
2018-02-08 16:03:14 +08:00
json = JSON.parse(json);
return json;
2018-07-18 10:16:55 +08:00
} catch (e) {
2018-02-08 16:03:14 +08:00
return false;
}
}
2018-07-18 10:16:55 +08:00
exports.isJson = isJson;
2018-02-08 16:03:14 +08:00
exports.unbase64 = function(base64Str) {
try {
return stringUtils.unbase64(base64Str);
} catch (err) {
return base64Str;
}
};
2018-07-18 10:16:55 +08:00
exports.json_parse = function(json) {
try {
2018-02-08 16:03:14 +08:00
return JSON.parse(json);
2018-07-18 10:16:55 +08:00
} catch (err) {
2018-02-08 16:03:14 +08:00
return json;
}
2018-07-18 10:16:55 +08:00
};
2018-03-19 11:16:10 +08:00
2018-07-18 10:16:55 +08:00
exports.json_format = function(json) {
try {
2018-03-19 11:16:10 +08:00
return JSON.stringify(JSON.parse(json), null, ' ');
2018-07-18 10:16:55 +08:00
} catch (e) {
2018-03-19 11:16:10 +08:00
return json;
}
2018-07-18 10:16:55 +08:00
};
2018-07-18 15:30:24 +08:00
exports.ArrayToObject = function(arr) {
let obj = {};
2018-07-18 15:30:24 +08:00
safeArray(arr).forEach(item => {
obj[item.name] = item.value;
});
2018-07-18 15:30:24 +08:00
return obj;
};
2018-07-31 19:45:01 +08:00
exports.timeago = function(timestamp) {
let minutes, hours, days, seconds, mouth, year;
const timeNow = parseInt(new Date().getTime() / 1000);
seconds = timeNow - timestamp;
if (seconds > 86400 * 30 * 12) {
year = parseInt(seconds / (86400 * 30 * 12));
} else {
year = 0;
}
if (seconds > 86400 * 30) {
mouth = parseInt(seconds / (86400 * 30));
} else {
mouth = 0;
}
if (seconds > 86400) {
days = parseInt(seconds / 86400);
} else {
days = 0;
}
if (seconds > 3600) {
hours = parseInt(seconds / 3600);
} else {
hours = 0;
}
minutes = parseInt(seconds / 60);
if (year > 0) {
return year + '年前';
} else if (mouth > 0 && year <= 0) {
return mouth + '月前';
} else if (days > 0 && mouth <= 0) {
return days + '天前';
} else if (days <= 0 && hours > 0) {
return hours + '小时前';
} else if (hours <= 0 && minutes > 0) {
return minutes + '分钟前';
} else if (minutes <= 0 && seconds > 0) {
if (seconds < 30) {
return '刚刚';
} else {
return seconds + '秒前';
}
} else {
return '刚刚';
}
};
2018-08-08 15:33:14 +08:00
// json schema 验证器
exports.schemaValidator = function(schema, params) {
try {
const ajv = new Ajv({
format: false,
meta: false
2018-08-08 15:33:14 +08:00
});
let metaSchema = require('ajv/lib/refs/json-schema-draft-04.json');
ajv.addMetaSchema(metaSchema);
ajv._opts.defaultMeta = metaSchema.id;
ajv._refs['http://json-schema.org/schema'] = 'http://json-schema.org/draft-04/schema';
var localize = require('ajv-i18n');
schema = schema || {
type: 'object',
title: 'empty object',
properties: {}
};
2018-08-08 15:33:14 +08:00
const validate = ajv.compile(schema);
let valid = validate(params);
let message = '';
if (!valid) {
localize.zh(validate.errors);
message += ajv.errorsText(validate.errors, { separator: '\n' });
}
return {
valid: valid,
message: message
};
} catch (e) {
return {
valid: false,
message: e.message
};
}
};