mock-service-cli 2.1.1 → 2.4.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,41 @@
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
+ ## [2.4.0](https://github.com/chandq/mock-service-cli/compare/v2.3.2...v2.4.0) (2022-01-05)
6
+
7
+
8
+ ### Features
9
+
10
+ * 增加异步任务队列,移出不必要模块 ([c7f3608](https://github.com/chandq/mock-service-cli/commit/c7f3608e4d0185434154d6f8d84889f281147022))
11
+
12
+ ### [2.3.2](https://github.com/chandq/mock-service-cli/compare/v2.3.1...v2.3.2) (2022-01-02)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * be sure to write file successfully ([55415e3](https://github.com/chandq/mock-service-cli/commit/55415e387af4d8232db2bede0a51dad1dca474b3))
18
+
19
+ ### [2.3.1](https://github.com/chandq/mock-service-cli/compare/v2.2.0...v2.3.1) (2022-01-01)
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * issue of execute unit test case failed ([69f4609](https://github.com/chandq/mock-service-cli/commit/69f46099ed5b26de5d4cca523c56afcbf4db5f2c))
25
+
26
+ ## [2.2.0](https://github.com/chandq/mock-service-cli/compare/v2.1.1...v2.2.0) (2021-12-31)
27
+
28
+
29
+ ### Features
30
+
31
+ * 丰富日志工具函数 ([4dcd69c](https://github.com/chandq/mock-service-cli/commit/4dcd69c6400f65aaf77ea4a2923c9900d5954d09))
32
+ * 监听文件变化和写文件互斥执行 ([cfeab8e](https://github.com/chandq/mock-service-cli/commit/cfeab8ede05573974125a9fa91f1db6afa8a898d))
33
+ * record operation log ([42b74d8](https://github.com/chandq/mock-service-cli/commit/42b74d8be0e694600c999490d3fe93bfb3620051))
34
+
35
+
36
+ ### Bug Fixes
37
+
38
+ * issue of write large file failed ([d1c470d](https://github.com/chandq/mock-service-cli/commit/d1c470daf9829916016b73993b114fc5ffe3c985))
39
+
5
40
  ### [2.1.1](https://github.com/chandq/mock-service-cli/compare/v2.1.0...v2.1.1) (2021-12-30)
6
41
 
7
42
 
package/README.md CHANGED
@@ -55,6 +55,7 @@ This will install `mock-service-cli` globally so that it may be run from the com
55
55
  | `-v` or `--version` | Print the version and exit. | |
56
56
  | `-S` or `--socket-server` | Start socket server which used to save api response data for future mock. | false |
57
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 |
58
59
 
59
60
  ## Example
60
61
 
@@ -161,7 +162,7 @@ const socket = io.connect('http://192.168.31.54:8090/mock-data', {
161
162
  }
162
163
  });
163
164
 
164
- socket.emit('mock-dir-stat', '/home/chen/projects/isc-twin-model-ui/mock');
165
+ socket.emit('mock-dir-stat', '/home/chen/projects/model-ui/mock');
165
166
  socket.on('mock-dir-stat', function (data) {
166
167
  console.debug('mock-dir-stat:', data);
167
168
  });
@@ -6,6 +6,8 @@ const colors = require('colors/safe'),
6
6
  nodemon = require('nodemon');
7
7
  const argv = require('minimist')(process.argv.slice(2));
8
8
  const { logger } = require('../lib/utils');
9
+ const spawn = require('child_process').spawn;
10
+ const node = process.execPath;
9
11
  process.title = 'mock-service-cli';
10
12
 
11
13
  if (argv.h || argv.help) {
@@ -22,6 +24,7 @@ if (argv.h || argv.help) {
22
24
  ' -s --silent Suppress log messages from output',
23
25
  ' -S --socket-server Whether start socket server or not, default false.',
24
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.',
25
28
  '',
26
29
  ' -h --help Print this list and exit.',
27
30
  ' -v --version Print the version and exit.'
@@ -94,16 +97,34 @@ const watchMockFiles = function (watchDir) {
94
97
  );
95
98
  });
96
99
  };
100
+ // Node子进程启动MockServer
101
+ const startMockServer = function () {
102
+ spawn(node, [path.resolve(__dirname, '../lib/mockServer.js')], {
103
+ stdio: 'inherit'
104
+ });
105
+ };
97
106
 
98
107
  if (specifiedFile) {
99
108
  process.env.SPECIFIED_FILE = path.resolve(process.cwd(), specifiedFile);
100
- watchMockFiles(process.env.SPECIFIED_FILE);
109
+ if (isStartSocketServer) {
110
+ startMockServer();
111
+ } else {
112
+ watchMockFiles(process.env.SPECIFIED_FILE);
113
+ }
101
114
  } else if (watchDir) {
102
115
  process.env.SPECIFIED_DIR = path.resolve(process.cwd(), watchDir);
103
116
  // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
104
- watchMockFiles(process.env.SPECIFIED_DIR);
117
+ if (isStartSocketServer) {
118
+ startMockServer();
119
+ } else {
120
+ watchMockFiles(process.env.SPECIFIED_DIR);
121
+ }
105
122
  } else {
106
123
  watchDir = process.env.SPECIFIED_DIR = path.resolve(process.cwd(), './mock');
107
124
  // log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
108
- watchMockFiles(watchDir);
125
+ if (isStartSocketServer) {
126
+ startMockServer();
127
+ } else {
128
+ watchMockFiles(watchDir);
129
+ }
109
130
  }
@@ -0,0 +1,70 @@
1
+ /*
2
+ * @description: 异步任务队列
3
+ * @Date: 2022-01-04 10:46:20
4
+ * @LastEditors: chendq
5
+ * @LastEditTime: 2022-01-05 18:45:36
6
+ * @Author: chendq
7
+ */
8
+ // const { getDataType } = require('./utils');
9
+ class AsyncTaskQueue {
10
+ constructor() {
11
+ this.list = [];
12
+ this.index = 0;
13
+ this.isStop = false;
14
+ this.isParallel = false;
15
+ }
16
+
17
+ next() {
18
+ // 加限制
19
+ if (this.index >= this.list.length - 1 || this.isStop) return;
20
+ const cur = this.list[++this.index];
21
+ cur(this.next.bind(this));
22
+ }
23
+ /**
24
+ * @description: 增加异步任务
25
+ * @param {array} fn
26
+ */
27
+ add(...fn) {
28
+ this.list.push(...fn);
29
+ }
30
+ /**
31
+ * @description: 按序执行异步任务
32
+ */
33
+ run() {
34
+ const cur = this.list[this.index];
35
+ typeof cur === 'function' && cur(this.next.bind(this));
36
+ }
37
+
38
+ /**
39
+ * @description: 并发执行异步任务
40
+ */
41
+ parallelRun() {
42
+ this.isParallel = true;
43
+ for (const fn of this.list) {
44
+ fn(this.next.bind(this));
45
+ }
46
+ }
47
+
48
+ /**
49
+ * @description: 暂停执行异步任务
50
+ */
51
+ stop() {
52
+ this.isStop = true;
53
+ }
54
+
55
+ /**
56
+ * @description: 重试执行异步任务
57
+ */
58
+ retry() {
59
+ this.isStop = false;
60
+ run();
61
+ }
62
+ /**
63
+ * @description: 继续执行下一个异步任务
64
+ */
65
+ goOn() {
66
+ this.isStop = false;
67
+ this.next();
68
+ }
69
+ }
70
+ module.exports = AsyncTaskQueue;
@@ -2,18 +2,41 @@
2
2
  * @description: 生成Mock文件、获取mock数据统计
3
3
  * @Date: 2021-12-22 16:57:08
4
4
  * @LastEditors: chendq
5
- * @LastEditTime: 2021-12-30 16:43:04
5
+ * @LastEditTime: 2022-01-05 20:39:08
6
6
  * @Author: chendq
7
7
  */
8
8
  const fsa = require('fs-extra'),
9
9
  fs = require('fs'),
10
10
  path = require('path'),
11
- _ = require('lodash'),
12
11
  colors = require('colors/safe');
13
- const { getFileLatestContent, SupportMethods, filePath2ApiUrl, logger, getDataType } = require('./utils');
12
+ const {
13
+ getFileLatestContent,
14
+ SupportMethods,
15
+ filePath2ApiUrl,
16
+ logger,
17
+ getDataType,
18
+ getLogger,
19
+ writeStream
20
+ } = require('./utils');
14
21
  const log = logger(process.env.SILENT);
22
+ const processArgv = process.env.ARGV ? JSON.parse(process.env.ARGV) : {};
15
23
 
16
24
  const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
25
+ /**
26
+ * @description: 记录日志文件函数
27
+ * @param {boolean} isWriteLogFile 是否写入日志文件
28
+ * @param {string} mockDir 存放日志文件的目录
29
+ * @return {object}
30
+ */
31
+ const logFile = (isWriteLogFile = false, mockDir) => {
32
+ if (isWriteLogFile) {
33
+ return getLogger(mockDir);
34
+ }
35
+ return {
36
+ log: function () {},
37
+ error: function () {}
38
+ };
39
+ };
17
40
  /**
18
41
  * @description: 生成mock文件(自动生成mock-list.json文件,并维护<url, [method]>的关系映射)
19
42
  * @param {string} apiUrl 请求url
@@ -23,7 +46,7 @@ const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
23
46
  * @return {*} void
24
47
  *
25
48
  */
26
- const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mockDir }) {
49
+ const genMockFiles = async function ({ url: apiUrl, method, data: resJsonData, dir: mockDir }) {
27
50
  const type = getDataType(resJsonData);
28
51
  if (!apiUrl || !method || !resJsonData || !mockDir) {
29
52
  log.info(
@@ -43,47 +66,48 @@ const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mo
43
66
  return;
44
67
  }
45
68
  apiUrl = apiUrl.trim().split('?')[0];
69
+ const LOGGER = logFile(processArgv.l || processArgv.log, mockDir);
46
70
  const normalizeApiUrl = filePath2ApiUrl(path.normalize(apiUrl));
47
71
  const mockListFilePath = path.resolve(process.cwd(), `${mockDir}/mock-list.json`);
48
72
  const mockFilePath = path.resolve(process.cwd(), `${mockDir}/${encodeURIComponent(path.normalize(apiUrl))}.json`);
49
- let newMockListContent = {},
50
- oldMockListContent = null;
73
+ let newMockListContent = {};
51
74
  if (fsa.pathExistsSync(mockListFilePath)) {
52
- oldMockListContent = getFileLatestContent(mockListFilePath);
53
- newMockListContent = _.cloneDeep(oldMockListContent);
75
+ newMockListContent = getFileLatestContent(mockListFilePath);
54
76
  } else {
55
77
  fsa.ensureFileSync(mockListFilePath);
56
78
  }
57
79
 
80
+ let isChange = false;
58
81
  // update mock-list.json file
59
82
  if (!newMockListContent.hasOwnProperty(normalizeApiUrl)) {
60
83
  newMockListContent[normalizeApiUrl] = [method];
84
+ isChange = true;
61
85
  } else if (!newMockListContent[normalizeApiUrl].includes(method)) {
62
86
  newMockListContent[normalizeApiUrl].push(method);
87
+ isChange = true;
63
88
  }
64
- if (!oldMockListContent || !_.isEqual(oldMockListContent, newMockListContent)) {
89
+ if (isChange) {
65
90
  Object.keys(newMockListContent).length > 0 &&
66
91
  fs.writeFileSync(mockListFilePath, JSON.stringify(newMockListContent, null, 2));
67
92
  }
68
93
 
69
94
  // mock文件存在
70
95
  if (fsa.pathExistsSync(mockFilePath)) {
71
- const mockFileContent = getFileLatestContent(mockFilePath);
72
- // 内容一样不作修改
73
- if (mockFileContent.hasOwnProperty(method) && _.isEqual(mockFileContent[method], resJsonData)) {
74
- // log.assert(
75
- // !_.isEqual(mockFileContent[method], resJsonData),
76
- // colors.bgYellow(`${method} ${apiUrl}, Mock data is same`)
77
- // );
78
- return;
79
- }
96
+ const mockFileContent = {};
80
97
  mockFileContent[method] = resJsonData;
81
- Object.keys(mockFileContent).length > 0 &&
82
- fsa.writeFileSync(mockFilePath, JSON.stringify(mockFileContent, null, 2));
98
+ try {
99
+ await writeStream(mockFilePath, JSON.stringify(mockFileContent, null, 2));
100
+ } catch (error) {
101
+ LOGGER.error(`Update file: ${method} ${apiUrl} ${mockFilePath}`);
102
+ }
103
+ LOGGER.log(`Update file: ${method} ${apiUrl} ${mockFilePath}`);
83
104
  } else {
84
- // fsa.ensureFileSync(mockFilePath);
85
- Object.keys(mockFilePath).length > 0 &&
86
- fsa.writeFileSync(mockFilePath, JSON.stringify({ [method]: resJsonData }, null, 2));
105
+ try {
106
+ await writeStream(mockFilePath, JSON.stringify({ [method]: resJsonData }, null, 2));
107
+ } catch (error) {
108
+ LOGGER.error(`New file: ${method} ${apiUrl} ${mockFilePath}`);
109
+ }
110
+ LOGGER.log(`New file: ${method} ${apiUrl} ${mockFilePath}`);
87
111
  }
88
112
  // console.debug('file::', `${mockDir}/${apiUrl}`, newMockListContent);
89
113
  };
@@ -176,7 +200,7 @@ const getMockStatFromDir = dirPath => {
176
200
  }
177
201
  }
178
202
  });
179
- fs.writeFileSync(mockListFilePath, JSON.stringify(reverseMockList, null, 2));
203
+ writeStream(mockListFilePath, JSON.stringify(reverseMockList, null, 2));
180
204
  }
181
205
  return mockDataMap;
182
206
  };
package/lib/mockServer.js CHANGED
@@ -16,6 +16,8 @@ const app = express();
16
16
  const log = logger(process.env.SILENT);
17
17
  const argv = JSON.parse(process.env.ARGV);
18
18
  let socketServer = null; // Socket server instance
19
+ const AsyncTaskQueue = require('./asyncTaskQueue');
20
+ const saveDataAsyncTask = new AsyncTaskQueue();
19
21
 
20
22
  let count = 0,
21
23
  fileCount = 0; // 记录mock api个数,mock file个数
@@ -150,9 +152,22 @@ if (process.env.SOCKET_SERVER) {
150
152
  socket.on('mock-file-stat', function (filePath) {
151
153
  socket.emit('mock-file-stat', getMockStatFromFile(filePath));
152
154
  });
155
+ const async = args => {
156
+ return async next => {
157
+ await genMockFiles(args);
158
+ next();
159
+ };
160
+ };
153
161
  socket.on('save-data', function (data) {
154
162
  // console.log('lis save-data:', data);
155
- genMockFiles(data);
163
+ saveDataAsyncTask.add(async(data));
164
+
165
+ if (saveDataAsyncTask.list.length === 1) {
166
+ saveDataAsyncTask.run();
167
+ } else {
168
+ saveDataAsyncTask.next();
169
+ }
170
+ // await genMockFiles(data);
156
171
  });
157
172
 
158
173
  socket.on('disconnect', function () {
package/lib/utils.js CHANGED
@@ -1,35 +1,49 @@
1
1
  /*
2
- * @description:
2
+ * @description: 工具函数库
3
3
  * @Date: 2021-12-25 17:52:48
4
4
  * @LastEditors: chendq
5
- * @LastEditTime: 2021-12-30 13:17:12
5
+ * @LastEditTime: 2022-01-05 20:21:07
6
6
  * @Author: chendq
7
7
  */
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ // const JSONStream = require('JSONStream');
8
11
  /**
9
12
  * @description: 输出和错误输出写入不同文件
10
- * @param {*}
11
- * @return {*}
13
+ * @param {string} logFileDirPath
14
+ * @return {object}
12
15
  */
13
- const path = require('path');
14
- const getLogger = function () {
15
- const fs = require('fs');
16
- const output = fs.createWriteStream('./stdout.log');
17
- const errorOutput = fs.createWriteStream('./stderr.log');
16
+ const getLogger = function (logFileDirPath) {
17
+ const options = {
18
+ flags: 'a', // append模式
19
+ encoding: 'utf8' // utf8编码
20
+ };
21
+ const output = fs.createWriteStream(
22
+ path.resolve(logFileDirPath ? logFileDirPath : path.resolve(process.cwd()), './stdout.log'),
23
+ options
24
+ );
25
+ const errorOutput = fs.createWriteStream(
26
+ path.resolve(logFileDirPath ? logFileDirPath : path.resolve(process.cwd()), './stderr.log'),
27
+ options
28
+ );
18
29
  // 自定义日志打印
19
30
  const logger = new console.Console(output, errorOutput);
20
31
 
21
- logger.log('向 stdout 中写入数据');
22
- logger.error('向 stderr 中写入数据');
32
+ // logger.log('向 stdout 中写入数据');
33
+ // logger.error('向 stderr 中写入数据');
23
34
 
24
- return logger;
35
+ return {
36
+ log: (...args) => logger.log.call(null, `[${dateFormat('YYYY-mm-dd HH:MM:SS:fff')}] - `, ...args),
37
+ error: (...args) => logger.error.call(null, `[${dateFormat('YYYY-mm-dd HH:MM:SS:fff')}] - `, ...args)
38
+ };
25
39
  };
26
40
  /**
27
41
  * @description: 格式化时间日期
28
- * @param {*} fmt
29
- * @param {*} date
30
- * @returns {*}
42
+ * @param {string} fmt 时间日期字符串格式化模板
43
+ * @param {date} date 时间日期Date
44
+ * @returns {string}
31
45
  */
32
- function dateFormat(fmt, date) {
46
+ function dateFormat(fmt, date = new Date()) {
33
47
  let ret;
34
48
  const opt = {
35
49
  'Y+': date.getFullYear().toString(), // 年
@@ -37,7 +51,8 @@ function dateFormat(fmt, date) {
37
51
  'd+': date.getDate().toString(), // 日
38
52
  'H+': date.getHours().toString(), // 时
39
53
  'M+': date.getMinutes().toString(), // 分
40
- 'S+': date.getSeconds().toString() // 秒
54
+ 'S+': date.getSeconds().toString(), // 秒
55
+ 'f+': date.getMilliseconds().toString() // 毫秒
41
56
  // 有其他格式化字符需求可以继续添加,必须转化成字符串
42
57
  };
43
58
  // eslint-disable-next-line guard-for-in
@@ -51,8 +66,8 @@ function dateFormat(fmt, date) {
51
66
  }
52
67
  /**
53
68
  * @description: 控制是否写日志
54
- * @param {*} isSilent
55
- * @return {*}
69
+ * @param {boolean} isSilent 是否静默
70
+ * @return {object}
56
71
  */
57
72
  function logger(isSilent = false) {
58
73
  let logObj = null;
@@ -82,8 +97,12 @@ const isValidMethod = function (m) {
82
97
  * @return {object} 文件内容
83
98
  */
84
99
  const getFileLatestContent = function (filePath) {
85
- delete require.cache[require.resolve(filePath)];
86
- return require(path.resolve(process.cwd(), filePath));
100
+ try {
101
+ delete require.cache[require.resolve(filePath)];
102
+ return require(path.resolve(process.cwd(), filePath));
103
+ } catch (error) {
104
+ getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], error);
105
+ }
87
106
  };
88
107
  /**
89
108
  * @description: 文件路径转成API的url
@@ -101,6 +120,149 @@ const filePath2ApiUrl = function (filePath) {
101
120
  const getDataType = function (data) {
102
121
  return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
103
122
  };
123
+ /**
124
+ * @description: 流方式写文件(适合写超大文件)
125
+ * @param {string} filePath
126
+ * @param {object} data
127
+ * @return {promise}
128
+ */
129
+ const writeStream = function (filePath, data) {
130
+ // 创建一个可写流 也会创建一个test1.txt文件
131
+ return new Promise((resolve, reject) => {
132
+ const writerStream = fs.createWriteStream(filePath);
133
+ // 将数据写入流
134
+ writerStream.write(data, 'utf-8');
135
+ // 标记文件的结束
136
+ writerStream.end();
137
+ writerStream.on('finish', () => {});
138
+ writerStream.on('close', () => {
139
+ resolve(data);
140
+ });
141
+
142
+ writerStream.on('error', err => {
143
+ getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], err);
144
+ reject(err);
145
+ });
146
+ });
147
+ };
148
+ /**
149
+ * @description: 流方式读文件(适合写超大文件)
150
+ * @param {string} filePath
151
+ * @return {*}
152
+ */
153
+ const readStream = function (filePath) {
154
+ let data = '';
155
+ // 创建可读流
156
+ return new Promise((resovle, reject) => {
157
+ const readerStream = fs.createReadStream(filePath);
158
+ // 设置编码为 utf8。
159
+ readerStream.setEncoding('UTF8');
160
+ // 处理流事件 --> data, end, and error
161
+ readerStream.on('data', function (chunk) {
162
+ data += chunk;
163
+ });
164
+ readerStream.on('end', function () {
165
+ resovle(data);
166
+ });
167
+ readerStream.on('error', function (err) {
168
+ reject(err);
169
+ console.log(err.stack);
170
+ });
171
+ });
172
+ };
173
+
174
+ /**
175
+ * 防抖函数
176
+ * 当函数被连续调用时,该函数并不执行,只有当其全部停止调用超过一定时间后才执行1次。
177
+ * 例如:上电梯的时候,大家陆陆续续进来,电梯的门不会关上,只有当一段时间都没有人上来,电梯才会关门。
178
+ * @param {F} func
179
+ * @param {number} wait
180
+ * @returns {DebounceFunc<F>}
181
+ */
182
+ const debounce = (func, wait) => {
183
+ let timeout;
184
+ let canceled = false;
185
+ const f = function (...args) {
186
+ if (canceled) return;
187
+ clearTimeout(timeout);
188
+ timeout = setTimeout(() => {
189
+ func.call(this, ...args);
190
+ }, wait);
191
+ };
192
+ f.cancel = () => {
193
+ clearTimeout(timeout);
194
+ canceled = true;
195
+ };
196
+ return f;
197
+ };
198
+ /**
199
+ * 节流函数
200
+ * 节流就是节约流量,将连续触发的事件稀释成预设评率。 比如每间隔1秒执行一次函数,无论这期间触发多少次事件。
201
+ * 这有点像公交车,无论在站点等车的人多不多,公交车只会按时来一班,不会来一个人就来一辆公交车。
202
+ * @param {F} func
203
+ * @param {number} wait
204
+ * @param {boolean} immediate
205
+ * @returns {ThrottleFunc<F>}
206
+ */
207
+ const throttle = (func, wait, immediate) => {
208
+ let timeout;
209
+ let canceled = false;
210
+ let lastCalledTime = 0;
211
+ const f = function (...args) {
212
+ if (canceled) return;
213
+ const now = Date.now();
214
+ const call = () => {
215
+ lastCalledTime = now;
216
+ func.call(this, ...args);
217
+ };
218
+ // 第一次执行
219
+ if (lastCalledTime === 0) {
220
+ if (immediate) {
221
+ return call();
222
+ }
223
+
224
+ lastCalledTime = now;
225
+ return;
226
+ }
227
+ const remain = lastCalledTime + wait - now;
228
+ if (remain > 0) {
229
+ clearTimeout(timeout);
230
+ timeout = setTimeout(() => call(), wait);
231
+ } else {
232
+ call();
233
+ }
234
+ };
235
+ f.cancel = () => {
236
+ clearTimeout(timeout);
237
+ canceled = true;
238
+ };
239
+ return f;
240
+ };
241
+ // /**
242
+ // * @description: 带模糊搜索的分块读取大JSON文件
243
+ // * @param {string} filePath
244
+ // * @return {*}
245
+ // */
246
+ // const readBigJson = function (filePath) {
247
+ // return new Promise((resolve, reject) => {
248
+ // let res = '';
249
+ // const readable = fs.createReadStream(filePath, {
250
+ // encoding: 'utf8',
251
+ // highWaterMark: 10
252
+ // });
253
+ // const parser = JSONStream.parse('*');
254
+ // readable.pipe(parser);
255
+ // parser.on('end', function () {
256
+ // // I know it ends here,
257
+ // console.log('end::', res);
258
+ // resolve(res);
259
+ // });
260
+ // parser.on('data', function (data) {
261
+ // res += data;
262
+ // console.log('yy::', data);
263
+ // });
264
+ // });
265
+ // };
104
266
 
105
267
  module.exports = {
106
268
  getLogger,
@@ -110,5 +272,9 @@ module.exports = {
110
272
  isValidMethod,
111
273
  getFileLatestContent,
112
274
  filePath2ApiUrl,
113
- getDataType
275
+ getDataType,
276
+ writeStream,
277
+ readStream,
278
+ debounce,
279
+ throttle
114
280
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mock-service-cli",
3
- "version": "2.1.1",
3
+ "version": "2.4.0",
4
4
  "description": "🦅 Local mock server",
5
5
  "main": "./lib/mockServer.js",
6
6
  "bin": {
@@ -49,7 +49,6 @@
49
49
  "deasync": "^0.1.23",
50
50
  "express": "^4.17.1",
51
51
  "fs-extra": "^10.0.0",
52
- "lodash": "^4.17.21",
53
52
  "minimist": "^1.2.5",
54
53
  "nodemon": "^2.0.14",
55
54
  "portfinder": "^1.0.28",