UNPKG

mockm

Version:

Analog interface server, painless parallel development of front and back ends.

431 lines (383 loc) 11.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise")); var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map")); var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter")); var _trim = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/trim")); var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes")); var _reduce = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reduce")); var _reverse = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/reverse")); var _some = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/some")); var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/keys")); var _find = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find")); const util = require(`./index.js`); const http = require(`./http.js`); const { tool } = util; /** * 批量处理文本为 mockm 的数据定义表 * @param {object} param0 * @param {string} param0.text 要翻译的多行文本 * @param {string} param0.appid 百度 appid * @param {string} param0.key 百度 key * @param {string} param0.type tree 或 list */ function batchTextEnglish({ text, appid, key, type = `tree` }) { return new _promise.default((resove, reject) => { if (text === undefined) { return reject(new Error(`请填写 text 参数`)); } translateTextToLine({ text, key, appid }).then(res => { // 小驼峰列表 const littleHumpResList = (0, _map.default)(res).call(res, (item, index) => { const littleHump = tool.string.toLittleHump(item.en.replace(/^-*\s*/, ``)).match(/[a-zA-Z0-9]+/ig).join(``); // 根据翻译结果返回 mock 模板 const { mock, type } = ruleHandle({ word: littleHump }); return { // ...item, name: littleHump, type: type[0], example: mock, description: item.zh }; }); if (type === `tree`) { // 转换为树形结构 const tree = tool.array.arrToTree(littleHumpResList, { key: `description`, tag: `-` }); resove(tree); } else { resove(littleHumpResList); } }).catch(err => { console.log(`err`, err); reject(err); }); }); } /** * 翻译多行文本并处理为数组 * @param {object} param0 * @param {string} param0.text 要翻译的多行文本 * @param {string} param0.appid 百度 appid * @param {string} param0.key 百度 key */ async function translateTextToLine({ text, appid, key }) { var _context, _context2, _context3; // 翻译行 const str = (0, _filter.default)(_context = (0, _map.default)(_context2 = text.split(/[\r\n]/)).call(_context2, item => (0, _trim.default)(item).call(item))).call(_context, item => Boolean(item)).join(`\n`); // 删除多余字符 const isChinese = (0, _includes.default)(_context3 = escape(str.match(/(.+?)\s?/)[1])).call(_context3, `%u`); // 查看第一个字符是不是中文 const translateFormat = isChinese ? { from: `zh`, to: `en` } : { from: `en`, to: `zh` }; async function translatePlatforms() { return new _promise.default(async (resolve, reject) => { await tool.generate.initPackge(`translate-platforms`, { getRequire: false }); const { google, microsoft, youdao, baidu } = require(`translate-platforms`); let errInfo = []; const handleYouDao = (...arg) => { // - [ ] fix: youdao 的翻译结果 text 和 word 顺序颠倒了: https://github.com/imlinhanchao/translate-platforms/issues/1 return new _promise.default((resolve, reject) => { youdao(...arg).then(res => { return resolve({ ...res, text: res.word, word: res.text }); }).catch(err => reject(err)); }); }; const apiList = [baidu, microsoft, google, handleYouDao // 有道不能直接翻译驼峰式文本, 并且词语会被翻译为句子的形式 ]; let result = undefined; for (let index = 0; index < apiList.length; index++) { if (result !== undefined) { break; } else { result = await apiList[index](str, translateFormat).catch(err => { errInfo.push(err); }); } } if (result === undefined) { reject(errInfo); } else { const enArr = (isChinese ? result.text : result.word).split(`\n`); const zhArr = (isChinese ? result.word : result.text).split(`\n`); const rawArr = isChinese ? zhArr : enArr; const handleRes = (0, _reduce.default)(enArr).call(enArr, (acc, cur, index) => { return [...acc, { raw: rawArr[index], en: cur, zh: zhArr[index] }]; }, []); resolve(handleRes); } }); } async function baiduTranslate({ key, appid }) { return new _promise.default(async (resolve, reject) => { var _context4; if (Boolean(key && appid) === false) { return reject(`请添加百度翻译 key appid`); } const querystring = require(`querystring`); const cfg = { appid, key, q: str, salt: `Date.now()` }; const isChinese = (0, _includes.default)(_context4 = escape(cfg.q.match(/(.+?)\s?/)[1])).call(_context4, `%u`); // 查看第一个字符是不是中文 const md5 = tool.string.getMd5(`${cfg.appid}${cfg.q}${cfg.salt}${cfg.key}`); const paramsObj = { ...translateFormat, q: cfg.q, salt: cfg.salt, appid: cfg.appid, sign: md5 }; const paramsUrl = querystring.stringify(paramsObj); const url = `http://api.fanyi.baidu.com/api/trans/vip/translate?${paramsUrl}`; http.get(url).then(res => { var _context5; // if (Boolean(res.data.trans_result) === false) { // reject(res.data) // } const handle = (0, _map.default)(_context5 = res.trans_result).call(_context5, item => { const zh = isChinese ? item.src : item.dst; const en = isChinese ? item.dst : item.src; const raw = isChinese ? zh : en; return { raw, zh, en }; }); resolve(handle); }).catch(err => reject(err)); }); } return new _promise.default(async (resolve, reject) => { let errInfo = []; let fnArr = [() => translatePlatforms().catch(err => { errInfo.push({ key: `translatePlatforms`, err }); }), () => baiduTranslate({ key, appid }).catch(err => { errInfo.push({ key: `baiduTranslate`, err }); })]; fnArr = appid && key ? (0, _reverse.default)(fnArr).call(fnArr) // 如果传了 key, 则优先使用需要 key 的方法 : fnArr; const res = (await fnArr[0]()) || (await fnArr[1]()); res ? resolve(res) : reject(errInfo); }); } /** * 根据类型和词语返回 mock 模版 * @param {object} param0 参数 * @param {string} param0.type 参数 * @param {string} param0.word 单词 */ function ruleHandle({ type, word }) { var _context6; const ruleList = [{ type: [`string`], re: `avatar|icon`, reOption: `i`, mock: `@image('100x100')`, des: `头像、icon` }, { type: [`string`], re: `image|img|photo|pic`, reOption: `i`, mock: `@image('400x400')`, des: `图片` }, { type: [`string`], re: `.*url`, reOption: `i`, mock: `@url('http')`, des: `URL` }, { type: [`string`], re: `nick|user_?name`, reOption: `i`, mock: `@cname`, des: `用户名、昵称` }, { type: [`string`], re: `title|name`, reOption: `i`, mock: `@ctitle`, des: `标题、名称` }, { type: [`number`, `integer`, `string`], re: `No$|Code$`, reOption: ``, mock: `@natural(1,100)`, des: `XX编号、XX码` }, { type: [`number`, `integer`, `string`], re: `id|age|total|num|code|amount|quantity|price|discount|balance|money`, reOption: `i`, mock: `@natural(1,100)`, des: `常见数字型` }, { type: [`number`, `integer`], re: `state|status`, reOption: `i`, mock: `@pick(1,2,3)`, des: `状态` }, { type: [`number`, `integer`, `string`], re: `phone|mobile|tel$`, reOption: `i`, mock: `@phone`, des: `手机号` }, { type: [`string`], re: `.*date`, reOption: `i`, mock: `@date('yyyy-MM-dd')`, des: `字符串日期` }, { type: [`number`, `integer`], re: `.*date`, reOption: `i`, mock: `@date('yyyyMMdd')`, des: `数字型日期` }, { type: [`string`], re: `created?_?at|updated?_?at|deleted?_?at|.*time`, reOption: `i`, mock: `@datetime('yyyy-MM-dd HH:mm:ss')`, des: `字符串时间` }, { type: [`number`, `integer`], re: `created?_?at|updated?_?at|deleted?_?at|.*time`, reOption: `i`, mock: `@datetime('T')`, des: `时间戳` }, { type: [`string`], re: `e?mail*`, reOption: `i`, mock: `@email('qq.com')`, des: `邮箱` }, { type: [`string`], re: `.*province*`, reOption: `i`, mock: `@province`, des: `省份` }, { type: [`string`], re: `.*city*`, reOption: `i`, mock: `@city`, des: `城市` }, { type: [`string`], re: `.*address`, reOption: `i`, mock: `@address`, des: `地址` }, { type: [`string`], re: `.*district|region`, reOption: `i`, mock: `@county`, des: `区` }, { type: [`string`], re: `.*ip`, reOption: `i`, mock: `@ip`, des: `IP 地址` }]; let res; // 结果 const Random = require(`@wll8/better-mock`).Random; const hasMockMethod = (0, _some.default)(_context6 = (0, _keys.default)(Random)).call(_context6, method => { return method.match(new RegExp(`^${word}$`, `i`)); }); // 如果完整匹配 mockjs 的方法则直接返回 if (hasMockMethod) { res = { type: [`string`], re: word, mock: Random[`c${word.toLowerCase()}`] ? `@c${word}` : `@${word}`, // 如果存在 c 开头的方法, 则优先使用 des: `mockjs.Mock.Random.${word}` }; } else { if (type) { // 如果传入 type 则先匹配 type res = (0, _find.default)(ruleList).call(ruleList, item => { var _context7; return (0, _includes.default)(_context7 = item.type).call(_context7, type) && word.match(new RegExp(item.re, item.reOption)); }); } if (res === undefined) { // 如果 type 没有匹配到, 则忽略 type 进行匹配 res = (0, _find.default)(ruleList).call(ruleList, item => word.match(new RegExp(item.re, item.reOption))); } } if (res === undefined) { // 如果啥也没匹配到, 就返回一个默认值 res = { type: [`string`], re: word, reOption: `i`, mock: `@ctitle`, des: `未知匹配` }; } return res; } module.exports = { batchTextEnglish, translateTextToLine };