diff --git a/controllers/mock.js b/controllers/mock.js index 6391a184..df1d65f3 100644 --- a/controllers/mock.js +++ b/controllers/mock.js @@ -16,6 +16,9 @@ const { MockProxy, ProjectProxy, UserGroupProxy } = require('../proxy') const redis = util.getRedis() const defPageSize = config.get('pageSize') +// /api/{user}/{id} => /api/:user/:id +const replacePathParams = (url) => url.replace(/{/g, ':').replace(/}/g, '') + async function checkByMockId (mockId, uid) { const api = await MockProxy.getById(mockId) @@ -224,15 +227,26 @@ module.exports = class MockController { mockURL = mockURL.replace(apis[0].project.url, '') || '/' } - api = apis.filter((item) => { - const url = item.url.replace(/{/g, ':').replace(/}/g, '') // /api/{user}/{id} => /api/:user/:id - return item.method === method && pathToRegexp(url).test(mockURL) - })[0] + api = apis + .filter(item => { + const url = replacePathParams(item.url) + return item.method === method && pathToRegexp(url).test(mockURL) + }) + // 按匹配度排序(包含路径参数越少匹配度越高) + .sort(function (a, b) { + const ap = pathToRegexp.parse( + replacePathParams(a.url) + ) + const bp = pathToRegexp.parse( + replacePathParams(b.url) + ) + return ap.length - bp.length + })[0] if (!api) ctx.throw(404) Mock.Handler.function = function (options) { - const mockUrl = api.url.replace(/{/g, ':').replace(/}/g, '') // /api/{user}/{id} => /api/:user/:id + const mockUrl = replacePathParams(api.url) options.Mock = Mock options._req = ctx.request options._req.params = util.params(mockUrl, mockURL) @@ -241,8 +255,8 @@ module.exports = class MockController { } if (/^http(s)?/.test(api.mode)) { // 代理模式 - const url = nodeURL.parse(api.mode.replace(/{/g, ':').replace(/}/g, ''), true) - const params = util.params(api.url.replace(/{/g, ':').replace(/}/g, ''), mockURL) + const url = nodeURL.parse(replacePathParams(api.mode), true) + const params = util.params(replacePathParams(api.url), mockURL) const pathname = pathToRegexp.compile(url.pathname)(params) try { apiData = await axios({ @@ -258,6 +272,31 @@ module.exports = class MockController { return } } else { + /** + * 支持直接返回数组 + */ + // eslint-disable-next-line no-empty-character-class + const arrayModeRegx = /^{\s*"?(\s*__arr__\s*)\|([0-9]+)\s*"?\s*:\s*(.*)}/s + + if (arrayModeRegx.test(api.mode)) { + const [, key, count] = arrayModeRegx.exec(api.mode) + api.mode = `[ + function({ + Mock + }) { + this.push(...Mock.mock({ + ${api.mode.slice(1, -1)} + })['${key}']) + this._res = { + headers: { + 'X-Total-Count': ${count} + } + }; + return this.pop() + } + ]` + } + const vm = new VM({ timeout: 1000, sandbox: { @@ -289,7 +328,8 @@ module.exports = class MockController { } } /* istanbul ignore next */ - if (_res.status && parseInt(_res.status, 10) !== 200 && _res.data) apiData = _res.data + if (_res.status && _res.data) apiData = _res.data + // if (_res.status && parseInt(_res.status, 10) !== 200 && _res.data) apiData = _res.data delete apiData['_res'] } } diff --git a/package-lock.json b/package-lock.json index 3ce82a96..79921b14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2060,7 +2060,8 @@ "version": "2.7.0", "resolved": "http://registry.npm.taobao.org/acorn/download/acorn-2.7.0.tgz", "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=", - "dev": true + "dev": true, + "optional": true }, "acorn-globals": { "version": "1.0.9", @@ -4527,7 +4528,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.1.1", @@ -4570,7 +4572,8 @@ }, "balanced-match": { "version": "0.4.2", - "bundled": true + "bundled": true, + "optional": true }, "bcrypt-pbkdf": { "version": "1.0.1", @@ -4583,6 +4586,7 @@ "block-stream": { "version": "0.0.9", "bundled": true, + "optional": true, "requires": { "inherits": "~2.0.0" } @@ -4590,6 +4594,7 @@ "boom": { "version": "2.10.1", "bundled": true, + "optional": true, "requires": { "hoek": "2.x.x" } @@ -4597,6 +4602,7 @@ "brace-expansion": { "version": "1.1.7", "bundled": true, + "optional": true, "requires": { "balanced-match": "^0.4.1", "concat-map": "0.0.1" @@ -4604,7 +4610,8 @@ }, "buffer-shims": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "caseless": { "version": "0.12.0", @@ -4618,30 +4625,36 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "combined-stream": { "version": "1.0.5", "bundled": true, + "optional": true, "requires": { "delayed-stream": "~1.0.0" } }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "cryptiles": { "version": "2.0.5", "bundled": true, + "optional": true, "requires": { "boom": "2.x.x" } @@ -4676,7 +4689,8 @@ }, "delayed-stream": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "delegates": { "version": "1.0.0", @@ -4703,7 +4717,8 @@ }, "extsprintf": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "forever-agent": { "version": "0.6.1", @@ -4722,11 +4737,13 @@ }, "fs.realpath": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "fstream": { "version": "1.0.11", "bundled": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -4777,6 +4794,7 @@ "glob": { "version": "7.1.2", "bundled": true, + "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4788,7 +4806,8 @@ }, "graceful-fs": { "version": "4.1.11", - "bundled": true + "bundled": true, + "optional": true }, "har-schema": { "version": "1.0.5", @@ -4812,6 +4831,7 @@ "hawk": { "version": "3.1.3", "bundled": true, + "optional": true, "requires": { "boom": "2.x.x", "cryptiles": "2.x.x", @@ -4821,7 +4841,8 @@ }, "hoek": { "version": "2.16.3", - "bundled": true + "bundled": true, + "optional": true }, "http-signature": { "version": "1.1.1", @@ -4836,6 +4857,7 @@ "inflight": { "version": "1.0.6", "bundled": true, + "optional": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4843,7 +4865,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.4", @@ -4853,6 +4876,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4864,7 +4888,8 @@ }, "isarray": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "isstream": { "version": "0.1.2", @@ -4927,11 +4952,13 @@ }, "mime-db": { "version": "1.27.0", - "bundled": true + "bundled": true, + "optional": true }, "mime-types": { "version": "2.1.15", "bundled": true, + "optional": true, "requires": { "mime-db": "~1.27.0" } @@ -4939,17 +4966,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -4999,7 +5029,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "oauth-sign": { "version": "0.8.2", @@ -5014,6 +5045,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5039,7 +5071,8 @@ }, "path-is-absolute": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "performance-now": { "version": "0.2.0", @@ -5048,7 +5081,8 @@ }, "process-nextick-args": { "version": "1.0.7", - "bundled": true + "bundled": true, + "optional": true }, "punycode": { "version": "1.4.1", @@ -5081,6 +5115,7 @@ "readable-stream": { "version": "2.2.9", "bundled": true, + "optional": true, "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", @@ -5123,13 +5158,15 @@ "rimraf": { "version": "2.6.1", "bundled": true, + "optional": true, "requires": { "glob": "^7.0.5" } }, "safe-buffer": { "version": "5.0.1", - "bundled": true + "bundled": true, + "optional": true }, "semver": { "version": "5.3.0", @@ -5149,6 +5186,7 @@ "sntp": { "version": "1.0.9", "bundled": true, + "optional": true, "requires": { "hoek": "2.x.x" } @@ -5179,6 +5217,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5188,6 +5227,7 @@ "string_decoder": { "version": "1.0.1", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.0.1" } @@ -5200,6 +5240,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5212,6 +5253,7 @@ "tar": { "version": "2.2.1", "bundled": true, + "optional": true, "requires": { "block-stream": "*", "fstream": "^1.0.2", @@ -5261,7 +5303,8 @@ }, "util-deprecate": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "uuid": { "version": "3.0.1", @@ -5286,7 +5329,8 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -13110,9 +13154,9 @@ "dev": true }, "restc": { - "version": "0.2.2", - "resolved": "http://registry.npm.taobao.org/restc/download/restc-0.2.2.tgz", - "integrity": "sha1-y9P2X6C/Q0exnoYxZQU6SamMNCk=" + "version": "0.5.0", + "resolved": "http://192.168.2.10:8081/repository/npm.gm/restc/-/restc-0.5.0.tgz", + "integrity": "sha512-H+01yehBng+bis9IhXXgAdZJ44Wm9md1b0D4tZzG5Ef41kClTa7ZQ2YB4eX4qucWT60+lUT796HPUEP+JYJKkg==" }, "restore-cursor": { "version": "2.0.0", diff --git a/package.json b/package.json index 727c39ff..05f654b3 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "mongoose": "^4.13.9", "path-to-regexp": "^2.1.0", "pino-multi-stream": "^3.1.2", - "restc": "^0.2.2", + "restc": "^0.5.0", "rimraf": "^2.6.2", "swagger-parser-mock": "^1.1.2", "universal-cookie": "^2.1.2", diff --git a/util/swagger.js b/util/swagger.js index ec71ab05..245d0dc2 100644 --- a/util/swagger.js +++ b/util/swagger.js @@ -95,9 +95,9 @@ async function createMock (projectId, swaggerDocs) { newKeys = newKeys.filter(key => !/\[[1-9]\d*\]/.test(key)) oldKeys = oldKeys.filter(key => !/\[[1-9]\d*\]/.test(key)) // [ 'data[0].item', 'data[1].item', 'data[2].item' ] => [ 'data[0]____item' ] .map(o => o.replace(/\|[^_\[]*(__)?/g, '$1')) // 'data|1-10.item' => 'data____item' 'data|1-10[0].item' => 'data[0]____item' - api.mode = _.xor(newKeys, oldKeys).length > 0 ? /* istanbul ignore next */ mode : api.mode + api.mode = _.xor(newKeys, oldKeys).length === 0 || oldKeys.filter(key => key.startsWith('__arr__')) ? /* istanbul ignore next */ api.mode : mode } catch (error) { - errorURLs.push(`${api.method.toUpperCase()}-${api.url}`) + // errorURLs.push(`${api.method.toUpperCase()}-${api.url}`) } api.method = method @@ -121,6 +121,8 @@ async function createMock (projectId, swaggerDocs) { module.exports = class SwaggerUtil { static async create (project) { + // 不验证 tls 证书 + process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0' const docs = await swaggerParserMock(project.swagger_url) return createMock(project.id, docs) } diff --git a/views/pages/editor/index.vue b/views/pages/editor/index.vue index 116b3cdb..130c9279 100644 --- a/views/pages/editor/index.vue +++ b/views/pages/editor/index.vue @@ -67,7 +67,7 @@ export default { data () { return { codeEditor: null, - autoClose: true, + autoClose: false, methods: [ { label: 'get', value: 'get' }, { label: 'post', value: 'post' }, @@ -126,7 +126,7 @@ export default { }) if (this.isEdit) { - this.autoClose = true + this.autoClose = false this.temp.url = this.mockData.url.slice(1) // remove / this.temp.mode = this.mockData.mode this.temp.method = this.mockData.method