mock-service-cli 2.4.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [3.1.0](https://github.com/chandq/mock-service-cli/compare/v3.0.0...v3.1.0) (2022-04-27)
6
+
7
+
8
+ ### Features
9
+
10
+ * **web-proxy:** proxy配置项支持文件和命令行参数字符串两种 ([ee1ce1f](https://github.com/chandq/mock-service-cli/commit/ee1ce1fbefa5ce9b3c074192d2d9893a4414d346))
11
+
12
+ ## [3.0.0](https://github.com/chandq/mock-service-cli/compare/v2.5.1...v3.0.0) (2022-04-27)
13
+
14
+
15
+ ### Features
16
+
17
+ * add web server and request proxy ([e5be340](https://github.com/chandq/mock-service-cli/commit/e5be340940042eb05e2e5cb9d2fcc6f8316052d5))
18
+
19
+ ### [2.5.1](https://github.com/chandq/mock-service-cli/compare/v2.5.0...v2.5.1) (2022-04-25)
20
+
21
+ ## [2.5.0](https://github.com/chandq/mock-service-cli/compare/v2.4.0...v2.5.0) (2022-04-25)
22
+
23
+
24
+ ### Features
25
+
26
+ * **cors:** 支持cors-origin,cors-headers跨域配置 ([c2d2872](https://github.com/chandq/mock-service-cli/commit/c2d28723d047139a5165190b4ba197f46470f72f))
27
+ * 缓存mock统计信息 ([1ee87cd](https://github.com/chandq/mock-service-cli/commit/1ee87cd041e68b9f17b64e9e3cb906681cb855fc))
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * 修复无法同时保留相同url不同请求类型的响应数据 ([90326dc](https://github.com/chandq/mock-service-cli/commit/90326dc556760eb81efadd76b031366452c95d2b))
33
+
34
+ ### [2.4.3](https://github.com/chandq/mock-service-cli/compare/v2.4.2...v2.4.3) (2022-01-20)
35
+
5
36
  ### [2.4.2](https://github.com/chandq/mock-service-cli/compare/v2.4.1...v2.4.2) (2022-01-07)
6
37
 
7
38
 
package/README.md CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  ### 简介
12
12
 
13
+ 内置 Mock Server、Web Server、Http request proxy 等功能集。
14
+
13
15
  **简易轻量**、**B/S 架构**、**0 秒启动**的本地命令行 Mock 服务套件, 支持热更新,对于开发调试 mock 数据很实用,能提高前端开发者的开发效率。支持 `GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`OPTIONS`,`COPY`,`LINK`,`UNLINK`,`PURGE` 等常用请求类型,无需布署后端,可能是本地最好用的 Mock 工具。支持以下常见业务场景:
14
16
 
15
17
  - [x] 无服务端演示项目的数据 Mock
@@ -45,36 +47,66 @@ This will install `mock-service-cli` globally so that it may be run from the com
45
47
 
46
48
  `[path]` defaults to `./mock` .
47
49
 
48
- | Command | Description | Defaults |
49
- | ------------------------- | -------------------------------------------------------------------------------------------------------------- | -------- |
50
- | `-p` or `--port` | Port to use. Use `-p 0` to look for an open port, starting at 8090. It will also read from `process.env.PORT`. | 8090 |
51
- | `-d` | Specify mock directory | ./mock |
52
- | `-f` | Specify mock file | |
53
- | `-s` or `--silent` | Suppress log messages from output | |
54
- | `-h` or `--help` | Print this list and exit. | |
55
- | `-v` or `--version` | Print the version and exit. | |
56
- | `-S` or `--socket-server` | Start socket server which used to save api response data for future mock. | false |
57
- | `-a` or `--api-stat` | Whether print api url and file path info or not, default false. | false |
58
- | `-l` or `--log` | Whether record operation info by write file, default false. | false |
50
+ | Command | Description | Defaults |
51
+ | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
52
+ | `-h` or `--help` | Print this list and exit. | |
53
+ | `-p` or `--port` | Mock server port to use. Use `-p 8090` to look for an open port, starting at 8090. | 8090 |
54
+ | `-d` | Specify mock directory | ./mock |
55
+ | `-f` | Specify mock file | |
56
+ | `-s` or `--silent` | Suppress log messages from output | |
57
+ | `-v` or `--version` | Print the version and exit. | |
58
+ | `-S` or `--socket-server` | Start socket server which used to save api response data for future mock. | false |
59
+ | `-a` or `--api-stat` | Whether print api url and file path info or not, default false. | false |
60
+ | `-l` or `--log` | Whether record operation info by write file, default false. | false |
61
+ | `-o` or `--cors-origin` | Allow origin by cors, list separated by commas, must not be \* when withCredential is true .If specified, cors-headers will be `Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token,Token` | \* |
62
+ | `-O` or `--proxy-options` | Optionally provide http request proxy options list, support accept js file、json file、cli arguments string. Examples: `-O '/api/apaas\|http://192.168.0.105:60700,/api/permission\| http://192.168.0.105:60700'`. Must start web server to use proxy for http request test under browser console or api test tools. | - |
63
+ | `-P` or `--web-port` | Web server port to use. Use `-P 9090` to look for an open port, starting at 9090 | 9090 |
64
+ | `-b` or `--web-baseurl` | Specify public path of the static web server, can be base address of SPA route. | - |
59
65
 
60
66
  ## Example
61
67
 
62
- 1. Specify server port.
68
+ 1. Specify mock server port.
63
69
 
64
70
  `mock-service-cli -p 8085`
65
71
 
66
- 2. Specify mock directory.
72
+ 2. Enable cors of mock server, specify the origin and headers of http request.
73
+
74
+ `mock-service-cli -o "http://192.168.0.8:38200,http://10.30.30.3" -H "custom-header"`
75
+
76
+ 3. Specify mock directory.
67
77
 
68
78
  `mock-service-cli -d ./mock`
69
79
 
70
- 3. Specify mock file.
80
+ 4. Specify mock file.
71
81
 
72
82
  `mock-service-cli -f ./mock/test.js`
73
83
 
74
- 4. Start socket server for used to save api response data.
84
+ 5. Start socket server for used to save api response data.
75
85
 
76
86
  `mock-service-cli -S`
77
87
 
88
+ 6. Start static web server for SPA, and optionally specify public path and port.
89
+ `mock-service-cli -D ../react-best-practice/dist [-b '/redbridge/'] [-P 9090]`
90
+
91
+ 7. Enable Proxy base on above item 6. support accept js file、json file、cli arguments string
92
+
93
+ - cli arguments string
94
+
95
+ `mock-service-cli -D ./ -O '/api/apaas|http://192.168.0.105:60700,/api/permission|http://192.168.0.105:60700'`
96
+
97
+ - js file
98
+
99
+ `mock-service-cli -D ./ -O ./proxy.js`
100
+
101
+ proxy.js file content as follows:
102
+
103
+ ```js
104
+ module.exports = {
105
+ '/api/apaas': 'http://192.168.0.105:60700',
106
+ '/api/permission': 'http://192.168.0.105:60700'
107
+ };
108
+ ```
109
+
78
110
  ### 编写 Mock 文件
79
111
 
80
112
  > mock 请求的类型支持`GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`OPTIONS`,`COPY`,`LINK`,`UNLINK`,`PURGE`
@@ -107,6 +139,8 @@ module.exports = {
107
139
 
108
140
  然后访问 `本地代理地址` + `/mock/api/222/test` (例如`http://127.0.0.1:8090/mock/api/222/test`) 就能得到 { aa: 1, bb: '使用 id 占位符' } 的响应,其他以此类推。
109
141
 
142
+ ![Mock Server](/assets/mock-server.jpg)
143
+
110
144
  ### 引入 Mock.js
111
145
 
112
146
  [Mock.js](http://mockjs.com/) 是常用的辅助生成模拟数据的三方库,借助他可以提升我们的 mock 数据能力。
@@ -119,11 +153,30 @@ const mockjs = require('mockjs');
119
153
  module.exports = {
120
154
  // 使用 mockjs 等三方库
121
155
  'GET /api/tags': mockjs.mock({
122
- 'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }]
156
+ 'list|100': [
157
+ {
158
+ 'NO|+1': 1,
159
+ city: '@city',
160
+ maintainType: '@cname(3, 5)',
161
+ urgentType: '@cword(3, 5)',
162
+ 'isCrash|1': 'true',
163
+ createTime: '@date',
164
+ 'value|1-100': 50,
165
+ 'type|0-2': 1
166
+ }
167
+ ]
123
168
  })
124
169
  };
125
170
  ```
126
171
 
172
+ ### 启动 Web Server, 在本地像 nginx 一样运行 dist 文件对应的 SPA
173
+
174
+ ![Web Server](/assets/web-server.jpg)
175
+
176
+ ### 启动 Web Server, 启用 Proxy
177
+
178
+ ![Web Server Proxy](/assets/web-server-proxy.jpg)
179
+
127
180
  ### 借助 socket.io 保留接口数据
128
181
 
129
182
  > `save-data` 和 `mock-dir-stat` 事件会自动生成 `mock-list.json` 文件(维护接口`<url, [method]>`的关系映射),方便查阅接口统计信息
@@ -2,8 +2,9 @@
2
2
 
3
3
  const colors = require('colors/safe'),
4
4
  portfinder = require('portfinder'),
5
- path = require('path'),
5
+ { resolve } = require('path'),
6
6
  nodemon = require('nodemon');
7
+ const { existsSync } = require('fs-extra');
7
8
  const argv = require('minimist')(process.argv.slice(2));
8
9
  const { logger } = require('../lib/utils');
9
10
  const spawn = require('child_process').spawn;
@@ -16,15 +17,24 @@ if (argv.h || argv.help) {
16
17
  'usage: mock-service-cli [options]',
17
18
  '',
18
19
  'options:',
19
- ' -p --port Port to use. If 0, look for open port. [8090]',
20
+ ' -p --port Mock server port to use. If 0, look for open port. [8090]',
20
21
  ' -d Specify mock directory, default [./mock] directory,',
21
22
  ' Also watch js files changes and support hot reload',
22
23
  ' -f --file Specify the input data source, support javascript ',
23
24
  ' The priority is over the directory watches',
24
- ' -s --silent Suppress log messages from output',
25
+ ' -s --silent Suppress log messages from output',
25
26
  ' -S --socket-server Whether start socket server or not, default false.',
26
- ' -a --api-stat Whether print api url and file path or not, default false.',
27
- ' -l --log Whether record operation info by write file, default false.',
27
+ ' -a --api-stat Whether print api url and file path or not, default false.',
28
+ ' -l --log Whether record operation info by write file, default false.',
29
+ ' -o --cors-origin Allow origin by cors, list separated by commas, must not be * when withCredential is true',
30
+ ' .If specified, cors-headers will be "Authorization,Content-Type,Accept,Origin,User-Agent,DNT',
31
+ ' ,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token,Token", default *.',
32
+ ' -H --cors-headers Optionally provide CORS headers list separated by commas. default *',
33
+ '',
34
+ ' -O --proxy-options Optionally provide proxy options list separated by commas.',
35
+ ' -P --web-port Web server port to use. If 0, look for open port. [9090]',
36
+ ' -D --web-dir Enable web server, specify web directory, default [./dist] directory',
37
+ ' -b --web-baseurl Specify website public path when enabled web server.',
28
38
  '',
29
39
  ' -h --help Print this list and exit.',
30
40
  ' -v --version Print the version and exit.'
@@ -49,6 +59,12 @@ if (!argv.s && !argv.silent) {
49
59
  process.env.SILENT = true;
50
60
  log = logger(true);
51
61
  }
62
+ // 注入环境变量
63
+ const injectEnvVariable = (envName, envArgs) => {
64
+ if (envArgs) {
65
+ process.env[envName] = envArgs;
66
+ }
67
+ };
52
68
 
53
69
  if (isStartSocketServer) {
54
70
  process.env.SOCKET_SERVER = true;
@@ -59,25 +75,70 @@ if (version) {
59
75
  process.exit();
60
76
  }
61
77
 
62
- if (!port) {
63
- portfinder.basePort = 8090;
78
+ injectEnvVariable('CORS_ORIGIN', argv.o || argv['cors-origin']);
79
+ injectEnvVariable('CORS_HEADERS', argv.H || argv['cors-headers']);
80
+
81
+ injectEnvVariable('WEB_PUBLIC_PATH', argv.b || argv['web-baseurl']);
82
+ // injectEnvVariable('PROXY_OPTIONS', argv.O || argv['proxy-options']);
83
+ // 解析Web代理配置项(来源js|config文件或命令行参数字符串)
84
+ const proxyArg = argv.O || argv['proxy-options'];
85
+ if (proxyArg) {
86
+ const proxyTable = {};
87
+ if (proxyArg.endsWith('.js') || proxyArg.endsWith('.json')) {
88
+ const proxyOptFile = resolve(process.cwd(), proxyArg);
89
+ if (!existsSync(proxyOptFile)) {
90
+ console.error(`proxy-options: 文件 ${proxyOptFile} 不存在`);
91
+ process.exit();
92
+ }
93
+ const proxyObj = require(proxyOptFile);
94
+ Object.keys(proxyObj).forEach(function (h) {
95
+ proxyTable[h] = proxyObj[h];
96
+ }, this);
97
+ } else {
98
+ try {
99
+ proxyArg.split(/\s*,\s*/).forEach(function (h) {
100
+ const [origin, target] = h.split('|');
101
+ proxyTable[origin] = target;
102
+ }, this);
103
+ } catch (error) {
104
+ console.warn(colors.yellow('\nParse web proxy options Failed:', error));
105
+ throw error;
106
+ }
107
+ }
108
+ process.env.PROXY_OPTIONS = JSON.stringify(proxyTable);
109
+ }
110
+ if (argv.D || argv['web-dir']) {
111
+ process.env.WEB_ROOT = resolve(process.cwd(), argv.D || argv['web-dir']);
112
+ if (!existsSync(process.env.WEB_ROOT)) {
113
+ console.error(`web-dir: 目录 ${process.env.WEB_ROOT} 不存在`);
114
+ process.exit();
115
+ }
116
+ // Web Server port
117
+ portfinder.basePort = argv.P || argv['web-port'] || 9090;
64
118
  portfinder.getPort(function (err, port) {
65
119
  if (err) {
66
120
  throw err;
67
121
  }
68
- process.env.PORT = port;
122
+ process.env.WEB_PORT = port;
69
123
  });
70
- } else {
71
- process.env.PORT = port;
72
124
  }
73
125
 
126
+ // Mock Server port
127
+ portfinder.basePort = port || 8090;
128
+ portfinder.getPort(function (err, port) {
129
+ if (err) {
130
+ throw err;
131
+ }
132
+ process.env.PORT = port;
133
+ });
134
+
74
135
  const watchMockFiles = function (watchDir) {
75
136
  /**
76
137
  * script 重启的脚本
77
138
  * ext 检测的文件
78
139
  */
79
140
  nodemon({
80
- script: path.resolve(__dirname, '../lib/mockServer.js'),
141
+ script: resolve(__dirname, '../lib/mockServer.js'),
81
142
  watch: [watchDir],
82
143
  ext: 'js,json'
83
144
  });
@@ -99,20 +160,20 @@ const watchMockFiles = function (watchDir) {
99
160
  };
100
161
  // Node子进程启动MockServer
101
162
  const startMockServer = function () {
102
- spawn(node, [path.resolve(__dirname, '../lib/mockServer.js')], {
163
+ spawn(node, [resolve(__dirname, '../lib/mockServer.js')], {
103
164
  stdio: 'inherit'
104
165
  });
105
166
  };
106
167
 
107
168
  if (specifiedFile) {
108
- process.env.SPECIFIED_FILE = path.resolve(process.cwd(), specifiedFile);
169
+ process.env.SPECIFIED_FILE = resolve(process.cwd(), specifiedFile);
109
170
  if (isStartSocketServer) {
110
171
  startMockServer();
111
172
  } else {
112
173
  watchMockFiles(process.env.SPECIFIED_FILE);
113
174
  }
114
175
  } else if (watchDir) {
115
- process.env.SPECIFIED_DIR = path.resolve(process.cwd(), watchDir);
176
+ process.env.SPECIFIED_DIR = resolve(process.cwd(), watchDir);
116
177
  // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
117
178
  if (isStartSocketServer) {
118
179
  startMockServer();
@@ -120,7 +181,7 @@ if (specifiedFile) {
120
181
  watchMockFiles(process.env.SPECIFIED_DIR);
121
182
  }
122
183
  } else {
123
- watchDir = process.env.SPECIFIED_DIR = path.resolve(process.cwd(), './mock');
184
+ watchDir = process.env.SPECIFIED_DIR = resolve(process.cwd(), './mock');
124
185
  // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
125
186
  if (isStartSocketServer) {
126
187
  startMockServer();
package/lib/mockServer.js CHANGED
@@ -5,9 +5,18 @@ const express = require('express'), // 引入express
5
5
  colors = require('colors/safe'),
6
6
  portfinder = require('portfinder'),
7
7
  chalk = require('chalk');
8
+ const { createProxyMiddleware } = require('http-proxy-middleware');
8
9
  const ifaces = os.networkInterfaces();
9
10
  const { Server } = require('socket.io');
10
- const { dateFormat, logger, SupportMethods, getFileLatestContent, filePath2ApiUrl, isEmptyObj } = require('./utils');
11
+ const {
12
+ dateFormat,
13
+ logger,
14
+ SupportMethods,
15
+ DefaultHeaders,
16
+ getFileLatestContent,
17
+ filePath2ApiUrl,
18
+ isEmptyObj
19
+ } = require('./utils');
11
20
  const { genMockFiles, getMockStatFromDir, getMockStatFromFile } = require('./manageMockFiles');
12
21
 
13
22
  const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
@@ -40,6 +49,20 @@ if (!process.env.PORT) {
40
49
  require('deasync').loopWhile(function () {
41
50
  return !done;
42
51
  });
52
+ let corsOrigin = [],
53
+ corsHeaders = '';
54
+ if (process.env.CORS_ORIGIN) {
55
+ process.env.CORS_ORIGIN.split(/\s*,\s*/).forEach(function (h) {
56
+ corsOrigin.push(h);
57
+ }, this);
58
+
59
+ corsHeaders = DefaultHeaders;
60
+ }
61
+ if (process.env.CORS_HEADERS) {
62
+ process.env.CORS_HEADERS.split(/\s*,\s*/).forEach(function (h) {
63
+ corsHeaders += corsHeaders ? ', ' + h : h;
64
+ }, this);
65
+ }
43
66
  /**
44
67
  * @description: 跨域设置
45
68
  * @param {*}
@@ -48,14 +71,12 @@ require('deasync').loopWhile(function () {
48
71
  const crossDomain = () => (req, res, next) => {
49
72
  // 设置withCredentials: true时,需设置以下两项
50
73
  res.header('Access-Control-Allow-Credentials', true);
51
- // res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
52
- res.header('Access-Control-Allow-Origin', '*');
74
+ // withCredentials, must be specified value instead of *
75
+ res.header('Access-Control-Allow-Origin', corsOrigin.includes(req.headers.origin) ? req.headers.origin : '*');
76
+ // res.header('Access-Control-Allow-Origin', '*');
53
77
  res.header('Access-Control-Allow-Methods', SupportMethods.join(','));
54
- // res.header(
55
- // 'Access-Control-Allow-Headers',
56
- // 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
57
- // );
58
- res.header('Access-Control-Allow-Headers', '*');
78
+ res.header('Access-Control-Allow-Headers', corsHeaders ? corsHeaders : '*');
79
+ // res.header('Access-Control-Allow-Headers', '*');
59
80
  if (req.method === 'OPTIONS') res.status(200); // 让OPTIONS快速返回
60
81
  next();
61
82
  };
@@ -131,13 +152,62 @@ const parseMockFiles = function (specialDir = '../mock') {
131
152
  composeRouteFromJsFile(filePath);
132
153
  }
133
154
  };
155
+
156
+ // 允许跨域
134
157
  app.use(crossDomain());
158
+
135
159
  if (process.env.SPECIFIED_FILE) {
136
160
  composeRouteFromJsFile(process.env.SPECIFIED_FILE);
137
161
  } else {
138
162
  parseMockFiles(process.env.SPECIFIED_DIR);
139
163
  }
140
164
  argv.a && log.info(chalk.hex('#ce5b34bd')(`${fileCount} mock file are parsed in total.`));
165
+
166
+ let webApp = null,
167
+ webPublicPath = '/',
168
+ proxyTable = {};
169
+ // Enable Web Server
170
+ if (process.env.WEB_ROOT) {
171
+ webApp = express();
172
+ // Enable web proxy
173
+ if (process.env.PROXY_OPTIONS) {
174
+ try {
175
+ const options = JSON.parse(process.env.PROXY_OPTIONS);
176
+ Object.keys(options).forEach(function (origin) {
177
+ proxyTable[origin] = options[origin];
178
+ // 接口代理
179
+ webApp.use(origin, createProxyMiddleware({ target: options[origin], changeOrigin: true, ws: true }));
180
+ }, this);
181
+ } catch (error) {
182
+ console.warn(colors.yellow('\nEnable web proxy Failed:', error));
183
+ }
184
+ }
185
+ // console.log(process.env.WEB_PUBLIC_PATH, process.env.WEB_ROOT);
186
+ if (process.env.WEB_PUBLIC_PATH) {
187
+ webPublicPath = process.env.WEB_PUBLIC_PATH;
188
+ }
189
+ webApp.use(webPublicPath, express.static(process.env.WEB_ROOT)); // 将dist目录下所有文件作为静态文件来管理
190
+ const defaultStaticEntry = `${process.env.WEB_ROOT}/index.html`;
191
+ if (fs.existsSync(defaultStaticEntry)) {
192
+ webApp.get('*', (req, res) => {
193
+ res.sendFile(defaultStaticEntry);
194
+ });
195
+ } else {
196
+ webApp.use(webPublicPath, (req, res) => {
197
+ res.status(200)
198
+ .send(`Hi, welcome to web server entrance ui, you can test http proxy on browser console or api request tools. Examples as follows:<br />
199
+ fetch("http://localhost:${process.env.WEB_PORT}/api/permission/auth/login", {
200
+ method: 'post',
201
+ headers: {
202
+ "accept": "*/*",
203
+ "Content-type": "application/json; charset=UTF-8",
204
+ },
205
+ body:JSON.stringify({"loginName":"admin","password":"admin"})
206
+ })
207
+ `);
208
+ });
209
+ }
210
+ }
141
211
  const http = require('http').createServer(app);
142
212
  if (process.env.SOCKET_SERVER) {
143
213
  socketServer = new Server(http, { path: '/ws/mock-service' });
@@ -149,10 +219,13 @@ if (process.env.SOCKET_SERVER) {
149
219
  colors.green(`Socket client ${clientIp} has connected. --- ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`)
150
220
  );
151
221
  socket.on('mock-dir-stat', function (dir) {
152
- socket.emit('mock-dir-stat', isEmptyObj(mockDirStat) ? mockDirStat = getMockStatFromDir(dir) : mockDirStat);
222
+ socket.emit('mock-dir-stat', isEmptyObj(mockDirStat) ? (mockDirStat = getMockStatFromDir(dir)) : mockDirStat);
153
223
  });
154
224
  socket.on('mock-file-stat', function (filePath) {
155
- socket.emit('mock-file-stat', isEmptyObj(mockFileStat) ? mockFileStat = getMockStatFromFile(filePath) : mockFileStat);
225
+ socket.emit(
226
+ 'mock-file-stat',
227
+ isEmptyObj(mockFileStat) ? (mockFileStat = getMockStatFromFile(filePath)) : mockFileStat
228
+ );
156
229
  });
157
230
  const async = args => {
158
231
  return async next => {
@@ -194,7 +267,8 @@ http.listen(Number.parseInt(process.env.PORT, 10), () => {
194
267
  console.info(
195
268
  [colors.yellow('\n🌍 mock-server version: '), colors.cyan(require('../package.json').version), '\n'].join('')
196
269
  );
197
-
270
+ console.info(colors.yellow(`\n Mock server available on:\n`));
271
+ console.info(' http://localhost:' + colors.green(process.env.PORT));
198
272
  Object.keys(ifaces).forEach(function (dev) {
199
273
  ifaces[dev].forEach(function (details) {
200
274
  if (details.family === 'IPv4') {
@@ -205,6 +279,26 @@ http.listen(Number.parseInt(process.env.PORT, 10), () => {
205
279
  }
206
280
  });
207
281
 
282
+ if (webApp && !process.env.RESTARTED) {
283
+ webApp.listen(Number.parseInt(process.env.WEB_PORT, 10), () => {
284
+ console.info(colors.yellow(`\n Web server available on:\n`));
285
+ console.info(' http://localhost:' + colors.green(process.env.WEB_PORT) + webPublicPath);
286
+ Object.keys(ifaces).forEach(function (dev) {
287
+ ifaces[dev].forEach(function (details) {
288
+ if (details.family === 'IPv4') {
289
+ console.info(' http://' + details.address + ':' + colors.green(process.env.WEB_PORT) + webPublicPath);
290
+ }
291
+ });
292
+ });
293
+ if (!isEmptyObj(proxyTable)) {
294
+ console.info(colors.yellow(`\n Enable proxy at web server on:`));
295
+ Object.keys(proxyTable).forEach(origin => {
296
+ console.info(` ${origin} -> ${proxyTable[origin]}`);
297
+ });
298
+ }
299
+ });
300
+ }
301
+
208
302
  if (process.platform === 'win32') {
209
303
  require('readline')
210
304
  .createInterface({
package/lib/utils.js CHANGED
@@ -86,7 +86,8 @@ function logger(isSilent = false) {
86
86
  }
87
87
  // MockServer 支持的请求类型
88
88
  const SupportMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS', 'COPY', 'LINK', 'UNLINK', 'PURGE'];
89
-
89
+ const DefaultHeaders =
90
+ 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With,X-Data-Type,X-Auth-Token,Token';
90
91
  const isValidMethod = function (m) {
91
92
  return SupportMethods.includes(String(m).toLocaleUpperCase());
92
93
  };
@@ -279,6 +280,7 @@ module.exports = {
279
280
  dateFormat,
280
281
  logger,
281
282
  SupportMethods,
283
+ DefaultHeaders,
282
284
  isValidMethod,
283
285
  getFileLatestContent,
284
286
  filePath2ApiUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mock-service-cli",
3
- "version": "2.4.2",
3
+ "version": "3.1.0",
4
4
  "description": "🦅 Local mock server",
5
5
  "main": "./lib/mockServer.js",
6
6
  "bin": {
@@ -49,6 +49,7 @@
49
49
  "deasync": "^0.1.23",
50
50
  "express": "^4.17.1",
51
51
  "fs-extra": "^10.0.0",
52
+ "http-proxy-middleware": "^2.0.6",
52
53
  "lodash": "^4.17.21",
53
54
  "minimist": "^1.2.5",
54
55
  "nodemon": "^2.0.14",