-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
03f1056
commit 73015be
Showing
13 changed files
with
978 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
'use strict'; | ||
|
||
module.exports = require('../package.json').version; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
'use strict'; | ||
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
|
||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
|
||
var QUERY_KEY = '_matman'; | ||
|
||
var QueryItem = function () { | ||
/** | ||
* 构造函数 | ||
* | ||
* @param {Object | String} mockerName mocker 的名字,或者是对象 | ||
* @param {String} [mockModuleName] mock module 的名字 | ||
* @param {Boolean} [shouldDisableMatman] 是否禁用 mocker 服务 | ||
*/ | ||
function QueryItem(mockerName, mockModuleName, shouldDisableMatman) { | ||
_classCallCheck(this, QueryItem); | ||
|
||
if (mockerName && (typeof mockerName === 'undefined' ? 'undefined' : _typeof(mockerName)) === 'object') { | ||
// 如果传入的时对象 | ||
this._m_name = mockerName._m_name; | ||
this._m_target = mockerName._m_target; | ||
this._m_disable = mockerName._m_disable; | ||
} else { | ||
// 依次设置 | ||
this._m_name = mockerName; | ||
this._m_target = mockModuleName; | ||
this._m_disable = shouldDisableMatman ? 1 : 0; | ||
} | ||
} | ||
|
||
_createClass(QueryItem, [{ | ||
key: 'isDisabled', | ||
value: function isDisabled() { | ||
return !!this._m_disable; | ||
} | ||
}]); | ||
|
||
return QueryItem; | ||
}(); | ||
|
||
var QueryHandler = function () { | ||
/** | ||
* 构造函数 | ||
*/ | ||
function QueryHandler() { | ||
_classCallCheck(this, QueryHandler); | ||
|
||
this.list = []; | ||
} | ||
|
||
/** | ||
* 增加一个元素 | ||
* | ||
* @param {Object | String} mockerName mocker 的名字 | ||
* @param {String} mockModuleName mock module 的名字 | ||
* @param {Boolean} shouldDisableMatman 是否禁用 mocker 服务 | ||
*/ | ||
|
||
|
||
_createClass(QueryHandler, [{ | ||
key: 'addOne', | ||
value: function addOne(mockerName, mockModuleName, shouldDisableMatman) { | ||
// TODO 也许这里应该要加一个去重判断 | ||
this.list.push(new QueryItem(name, target, shouldDisableMatman)); | ||
} | ||
}, { | ||
key: 'getQueryString', | ||
value: function getQueryString() { | ||
return QUERY_KEY + '=' + JSON.stringify(this.list); | ||
} | ||
}]); | ||
|
||
return QueryHandler; | ||
}(); | ||
|
||
module.exports = { | ||
QueryItem: QueryItem, | ||
QueryHandler: QueryHandler, | ||
QUERY_KEY: QUERY_KEY | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
'use strict'; | ||
|
||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
|
||
var fs = require('fs'); | ||
var path = require('path'); | ||
|
||
/** | ||
* 获取最终的配置数据 | ||
* @param {Object | String} opts 用户传递过来的参数 | ||
* @returns {Object} | ||
*/ | ||
function getConfigOpts(opts) { | ||
var configOpts = void 0; | ||
|
||
try { | ||
// opts 如果是字符串则认为是文件路径,可将配置项放在独立的配置文件中 | ||
if (typeof opts === 'string' && fs.existsSync(opts)) { | ||
configOpts = require(opts); | ||
} else if (opts && (typeof opts === 'undefined' ? 'undefined' : _typeof(opts)) === 'object') { | ||
configOpts = opts; | ||
} else { | ||
configOpts = null; | ||
} | ||
} catch (e) { | ||
console.error('getConfigOpts catch e:', e); | ||
} | ||
|
||
// 必须要存在配置 | ||
if (!configOpts) { | ||
console.error('Could not get configOpts!', opts); | ||
return null; | ||
} | ||
|
||
// 如果没有 ROOT_PATH,则将无法启动成功 | ||
if (!configOpts.ROOT_PATH) { | ||
console.error('Should define ROOT_PATH!', opts, configOpts); | ||
return null; | ||
} | ||
|
||
// 设置默认值 | ||
// 项目源文件的目录,默认值为 ${ROOT_PATH}/src | ||
configOpts.SRC_PATH = configOpts.SRC_PATH || path.join(configOpts.ROOT_PATH, './src'); | ||
|
||
// 运行目录,由 SRC_PATH 处理之后生成的,默认值为 ${ROOT_PATH}/app | ||
configOpts.APP_PATH = configOpts.APP_PATH || path.join(configOpts.ROOT_PATH, './app'); | ||
|
||
// 配置数据缓存路径,默认值为 APP_PATH | ||
configOpts.DATA_PATH = configOpts.DATA_PATH || configOpts.APP_PATH; | ||
|
||
// mocker 的根目录 | ||
configOpts.MOCKER_BASE_PATH = configOpts.MOCKER_BASE_PATH || './mocker'; | ||
|
||
// handler 文件相对 SRC_PATH 目录的路径,默认值为 './handlers' | ||
configOpts.HANDLERS_RELATIVE_PATH = configOpts.HANDLERS_RELATIVE_PATH || './handlers'; | ||
|
||
// 日志文件存储的路径,默认值为 ${ROOT_PATH}/logs | ||
configOpts.LOG_PATH = configOpts.LOG_PATH || path.join(configOpts.ROOT_PATH, 'logs'); | ||
|
||
// matman 启动之后的服务端口号,默认为 3000 | ||
configOpts.port = configOpts.port || 3000; | ||
|
||
// 外部 handler 列表,比如引入npm包或者其他目录下的 handler | ||
configOpts.definedHandlers = configOpts.definedHandlers || []; | ||
|
||
// 确认 HANDLERS_PATH 的值 | ||
configOpts.HANDLERS_PATH = path.join(configOpts.APP_PATH, configOpts.MOCKER_BASE_PATH, configOpts.HANDLERS_RELATIVE_PATH); | ||
|
||
// 是否 watch 文件变动 | ||
configOpts.shouldWatch = configOpts.shouldWatch || process.env.NODE_ENV === 'development' || false; | ||
|
||
return configOpts; | ||
} | ||
|
||
module.exports = { | ||
getConfigOpts: getConfigOpts | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
'use strict'; | ||
|
||
var version = require('./MatmanVersion'); | ||
var util = require('./util'); | ||
|
||
var Mocker = require('./mocker/Mocker'); | ||
var MockerParser = require('./mocker/MockerParser'); | ||
var mockerUtil = require('./mocker/util'); | ||
|
||
var matmanQuery = require('./business/matman-query'); | ||
|
||
module.exports = { | ||
version: version, | ||
util: util, | ||
Mocker: Mocker, | ||
MockerParser: MockerParser, | ||
matmanQuery: matmanQuery, | ||
mockerUtil: mockerUtil | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
'use strict'; | ||
|
||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
|
||
var MockModuleConfig = require('./MockModuleConfig'); | ||
|
||
var MockModule = function () { | ||
/** | ||
* 构造函数 | ||
* | ||
* @param {String} name 名字 | ||
* @param {Object | Function} module require('./index.js') | ||
* @param {Object} [config] require('./config.json'),有可能没有,此时则为null | ||
*/ | ||
function MockModule(name, module, config) { | ||
_classCallCheck(this, MockModule); | ||
|
||
this.name = name; | ||
this.module = module; | ||
this.config = new MockModuleConfig(name, config); | ||
} | ||
|
||
/** | ||
* 获得该模块的最终结果 | ||
* | ||
* @param {*} props | ||
* @returns {Promise} | ||
*/ | ||
|
||
|
||
_createClass(MockModule, [{ | ||
key: 'getResult', | ||
value: function getResult() { | ||
for (var _len = arguments.length, props = Array(_len), _key = 0; _key < _len; _key++) { | ||
props[_key] = arguments[_key]; | ||
} | ||
|
||
return getTargetResult.apply(undefined, [this.module].concat(props)); | ||
} | ||
}]); | ||
|
||
return MockModule; | ||
}(); | ||
|
||
/** | ||
* 获得模块内容之后,计算出最终返回值 | ||
* | ||
* @param {*} saveTarget 有可能是函数、对象或者普通字符串 | ||
* @param {*} props saveTarget 为函数时,会透传给它 | ||
* @return {Promise} | ||
*/ | ||
|
||
|
||
function getTargetResult(saveTarget) { | ||
try { | ||
for (var _len2 = arguments.length, props = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { | ||
props[_key2 - 1] = arguments[_key2]; | ||
} | ||
|
||
var result = typeof saveTarget === 'function' ? saveTarget.apply(undefined, props) : saveTarget; | ||
return Promise.resolve(result); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
|
||
module.exports = MockModule; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
'use strict'; | ||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
|
||
var _ = require('lodash'); | ||
|
||
var MockModuleConfig = | ||
/** | ||
* 构造函数 | ||
* | ||
* @param {String} mockModuleName 名字 | ||
* @param {Object} [config] config.json 中的值,注意 config.json 不一定存在 | ||
* @param {String} [config.name] 名字 | ||
* @param {String} [config.description] 简要描述 | ||
* @param {Number} [config.priority] 管理后台列表中排序的权重,值越大则越排在前面 | ||
* @param {Number} [config.delay] 延时返回的时间,单位 ms | ||
* @param {Object} [config.query] 标记 | ||
*/ | ||
function MockModuleConfig(mockModuleName) { | ||
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
|
||
_classCallCheck(this, MockModuleConfig); | ||
|
||
// 名字,注意名字不能够再被修改,即忽略 config.name | ||
this.name = mockModuleName; | ||
|
||
// 简要描述 | ||
this.description = config.description || this.name; | ||
|
||
// 管理后台列表中排序的权重,值越大则越排在前面 | ||
this.priority = config.priority || 0; | ||
|
||
// 延时多久返回,如果是 0,则不做延时返回,单位为 ms | ||
// 可以用来模拟 CGI 返回比较慢的场景 | ||
this.delay = config.delay || 0; | ||
|
||
// 请求中需要携带的额外数据,必须同时满足这个的条件,才算匹配了这个 mock module | ||
// 换言之,这里可以定义这个 mock module 的唯一标记(类似ID的概念), | ||
// 满足了这个标记则命中了这个 mock module | ||
this.query = _.merge({}, config.query, { | ||
_m_target: mockModuleName | ||
}); | ||
}; | ||
|
||
module.exports = MockModuleConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
'use strict'; | ||
|
||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
|
||
var fs = require('fs'); | ||
var path = require('path'); | ||
var _ = require('lodash'); | ||
var fsHandler = require('fs-handler'); | ||
|
||
var MockerConfig = require('./MockerConfig'); | ||
var MockModule = require('./MockModule'); | ||
|
||
var Mocker = function () { | ||
/** | ||
* 构造函数 | ||
* | ||
* @param {String} basePath mocker 的绝对路径 | ||
*/ | ||
function Mocker(basePath) { | ||
_classCallCheck(this, Mocker); | ||
|
||
this.basePath = basePath; | ||
|
||
// config.json 的内容 | ||
var config = require(path.join(this.basePath, './config')); | ||
|
||
// 优先使用 config.name,其次是模块的文件夹名 | ||
this.name = config.name || path.basename(this.basePath); | ||
|
||
// mock module 配置列表 | ||
this.mockModuleList = this._getMockModuleList(); | ||
|
||
// mocker config 配置参数 | ||
this.config = new MockerConfig(this.name, config, this.mockModuleList); | ||
} | ||
|
||
_createClass(Mocker, [{ | ||
key: 'updateConfig', | ||
value: function updateConfig(opts) { | ||
this.config = _.merge({}, this.config, opts); | ||
} | ||
}, { | ||
key: '_getMockModuleList', | ||
value: function _getMockModuleList() { | ||
var _this = this; | ||
|
||
var mockModuleList = []; | ||
|
||
// 1. 获取所有的 mocker,约定:this.basePath 的每个子目录都是一个独立的 mocker | ||
fsHandler.search.getAll(this.basePath, { globs: ['mock_modules/*'] }).forEach(function (item) { | ||
// 模块名字,默认取文件夹或文件名 | ||
var name = path.basename(item.relativePath, '.js'); | ||
|
||
// 注意也可能是 json 文件 | ||
name = path.basename(name, '.json'); | ||
|
||
// console.log('\n找到 mock module :', name, item); | ||
|
||
var requireModulePath = path.join(_this.basePath, 'mock_modules', name); | ||
|
||
var module = require(requireModulePath); | ||
|
||
// 是否存在配置文件 | ||
var config = void 0; | ||
if (item.isDirectory() && (fs.existsSync(path.join(requireModulePath, 'config.json')) || fs.existsSync(path.join(requireModulePath, 'config.js')))) { | ||
config = require(path.join(requireModulePath, 'config')); | ||
} | ||
|
||
mockModuleList.push(new MockModule(name, module, config)); | ||
}); | ||
|
||
return mockModuleList; | ||
} | ||
}]); | ||
|
||
return Mocker; | ||
}(); | ||
|
||
module.exports = Mocker; |
Oops, something went wrong.