mock-service-cli 3.7.0 → 4.0.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/bin/mock-service-cli +1 -266
- package/{lib → dist}/asyncTaskQueue.js +6 -18
- package/dist/cli.js +6608 -0
- package/dist/fileExplorerServer.js +28186 -0
- package/dist/manageMockFiles.js +5020 -0
- package/dist/mockServer.js +53214 -0
- package/dist/packageInfo.js +19 -0
- package/dist/staticServer.js +26688 -0
- package/dist/utils.js +857 -0
- package/package.json +21 -17
- package/lib/fileExplorerServer.js +0 -330
- package/lib/manageMockFiles.js +0 -252
- package/lib/mockServer.js +0 -497
- package/lib/staticServer.js +0 -104
- package/lib/utils.js +0 -297
- /package/{lib → dist}/api-overview.html +0 -0
- /package/{lib → dist}/file-explorer.html +0 -0
package/lib/utils.js
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @description: 工具函数库
|
|
3
|
-
* @Date: 2021-12-25 17:52:48
|
|
4
|
-
* @LastEditors: chendq
|
|
5
|
-
* @LastEditTime: 2024-01-16 22:28:37
|
|
6
|
-
* @Author: chendq
|
|
7
|
-
*/
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const colors = require('colors/safe');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
// const JSONStream = require('JSONStream');
|
|
12
|
-
/**
|
|
13
|
-
* @description: 输出和错误输出写入不同文件
|
|
14
|
-
* @param {string} logFileDirPath
|
|
15
|
-
* @return {object}
|
|
16
|
-
*/
|
|
17
|
-
const getLogger = function (logFileDirPath) {
|
|
18
|
-
const options = {
|
|
19
|
-
flags: 'a', // append模式
|
|
20
|
-
encoding: 'utf8' // utf8编码
|
|
21
|
-
};
|
|
22
|
-
const output = fs.createWriteStream(
|
|
23
|
-
path.resolve(logFileDirPath ? logFileDirPath : path.resolve(process.cwd()), './stdout.log'),
|
|
24
|
-
options
|
|
25
|
-
);
|
|
26
|
-
const errorOutput = fs.createWriteStream(
|
|
27
|
-
path.resolve(logFileDirPath ? logFileDirPath : path.resolve(process.cwd()), './stderr.log'),
|
|
28
|
-
options
|
|
29
|
-
);
|
|
30
|
-
// 自定义日志打印
|
|
31
|
-
const logger = new console.Console(output, errorOutput);
|
|
32
|
-
|
|
33
|
-
// logger.log('向 stdout 中写入数据');
|
|
34
|
-
// logger.error('向 stderr 中写入数据');
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
log: (...args) => logger.log.call(null, `[${dateFormat('YYYY-mm-dd HH:MM:SS:fff')}] - `, ...args),
|
|
38
|
-
error: (...args) => logger.error.call(null, `[${dateFormat('YYYY-mm-dd HH:MM:SS:fff')}] - `, ...args)
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* @description: 格式化时间日期
|
|
43
|
-
* @param {string} fmt 时间日期字符串格式化模板
|
|
44
|
-
* @param {date} date 时间日期Date
|
|
45
|
-
* @returns {string}
|
|
46
|
-
*/
|
|
47
|
-
function dateFormat(fmt, date = new Date()) {
|
|
48
|
-
let ret;
|
|
49
|
-
const opt = {
|
|
50
|
-
'Y+': date.getFullYear().toString(), // 年
|
|
51
|
-
'm+': (date.getMonth() + 1).toString(), // 月
|
|
52
|
-
'd+': date.getDate().toString(), // 日
|
|
53
|
-
'H+': date.getHours().toString(), // 时
|
|
54
|
-
'M+': date.getMinutes().toString(), // 分
|
|
55
|
-
'S+': date.getSeconds().toString(), // 秒
|
|
56
|
-
'f+': date.getMilliseconds().toString() // 毫秒
|
|
57
|
-
// 有其他格式化字符需求可以继续添加,必须转化成字符串
|
|
58
|
-
};
|
|
59
|
-
// eslint-disable-next-line guard-for-in
|
|
60
|
-
for (const k in opt) {
|
|
61
|
-
ret = new RegExp('(' + k + ')').exec(fmt);
|
|
62
|
-
if (ret) {
|
|
63
|
-
fmt = fmt.replace(ret[1], ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return fmt;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* @description: 控制是否写日志
|
|
70
|
-
* @param {boolean} isSilent 是否静默
|
|
71
|
-
* @return {object}
|
|
72
|
-
*/
|
|
73
|
-
function logger(isSilent = false) {
|
|
74
|
-
let logObj = null;
|
|
75
|
-
if (!isSilent) {
|
|
76
|
-
logObj = {
|
|
77
|
-
info: console.log,
|
|
78
|
-
assert: console.assert
|
|
79
|
-
};
|
|
80
|
-
} else {
|
|
81
|
-
logObj = {
|
|
82
|
-
info: function () {},
|
|
83
|
-
assert: function () {}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
return logObj;
|
|
87
|
-
}
|
|
88
|
-
// MockServer 支持的请求类型
|
|
89
|
-
const SupportMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS', 'COPY', 'LINK', 'UNLINK', 'PURGE'];
|
|
90
|
-
const DefaultHeaders =
|
|
91
|
-
'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';
|
|
92
|
-
const isValidMethod = function (m) {
|
|
93
|
-
return SupportMethods.includes(String(m).toLocaleUpperCase());
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @description: 获取文件最新内容
|
|
98
|
-
* @param {string} filePath 文件路径
|
|
99
|
-
* @return {object} 文件内容
|
|
100
|
-
*/
|
|
101
|
-
const getFileLatestContent = function (filePath) {
|
|
102
|
-
try {
|
|
103
|
-
delete require.cache[require.resolve(filePath)];
|
|
104
|
-
return require(path.resolve(process.cwd(), filePath));
|
|
105
|
-
} catch (error) {
|
|
106
|
-
// getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], error);
|
|
107
|
-
console.error(colors.red('[error]:'), error);
|
|
108
|
-
return 'getFileLatestContent_ERROR';
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* @description: 文件路径转成API的url
|
|
114
|
-
* @param {string} filePath
|
|
115
|
-
* @return {string} apiUrl
|
|
116
|
-
*/
|
|
117
|
-
const filePath2ApiUrl = function (filePath) {
|
|
118
|
-
return filePath.split(path.sep).join('/');
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* @description: 获取数据类型
|
|
122
|
-
* @param {any} data 数据值
|
|
123
|
-
* @return {string} 数据类型
|
|
124
|
-
*/
|
|
125
|
-
const getDataType = function (data) {
|
|
126
|
-
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
|
|
127
|
-
};
|
|
128
|
-
/**
|
|
129
|
-
* @description: 判断对象是否为空
|
|
130
|
-
* @param {object} obj
|
|
131
|
-
* @return {boolean}
|
|
132
|
-
*/
|
|
133
|
-
const isEmptyObj = function (obj) {
|
|
134
|
-
return getDataType(obj) === 'object' && Object.keys(obj).length === 0;
|
|
135
|
-
};
|
|
136
|
-
/**
|
|
137
|
-
* @description: 流方式写文件(适合写超大文件)
|
|
138
|
-
* @param {string} filePath
|
|
139
|
-
* @param {object} data
|
|
140
|
-
* @return {promise}
|
|
141
|
-
*/
|
|
142
|
-
const writeStream = function (filePath, data) {
|
|
143
|
-
// 创建一个可写流 也会创建一个test1.txt文件
|
|
144
|
-
return new Promise((resolve, reject) => {
|
|
145
|
-
const writerStream = fs.createWriteStream(filePath);
|
|
146
|
-
// 将数据写入流
|
|
147
|
-
writerStream.write(data, 'utf-8');
|
|
148
|
-
// 标记文件的结束
|
|
149
|
-
writerStream.end();
|
|
150
|
-
writerStream.on('finish', () => {});
|
|
151
|
-
writerStream.on('close', () => {
|
|
152
|
-
setTimeout(() => {
|
|
153
|
-
resolve(data);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
writerStream.on('error', err => {
|
|
158
|
-
getLogger(path.resolve(process.cwd())).error(filePath, require.cache[require.resolve(filePath)], err);
|
|
159
|
-
reject(err);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
|
-
/**
|
|
164
|
-
* @description: 流方式读文件(适合写超大文件)
|
|
165
|
-
* @param {string} filePath
|
|
166
|
-
* @return {*}
|
|
167
|
-
*/
|
|
168
|
-
const readStream = function (filePath) {
|
|
169
|
-
let data = '';
|
|
170
|
-
// 创建可读流
|
|
171
|
-
return new Promise((resovle, reject) => {
|
|
172
|
-
const readerStream = fs.createReadStream(filePath);
|
|
173
|
-
// 设置编码为 utf8。
|
|
174
|
-
readerStream.setEncoding('UTF8');
|
|
175
|
-
// 处理流事件 --> data, end, and error
|
|
176
|
-
readerStream.on('data', function (chunk) {
|
|
177
|
-
data += chunk;
|
|
178
|
-
});
|
|
179
|
-
readerStream.on('end', function () {
|
|
180
|
-
resovle(data);
|
|
181
|
-
});
|
|
182
|
-
readerStream.on('error', function (err) {
|
|
183
|
-
reject(err);
|
|
184
|
-
console.log(err.stack);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* 防抖函数
|
|
191
|
-
* 当函数被连续调用时,该函数并不执行,只有当其全部停止调用超过一定时间后才执行1次。
|
|
192
|
-
* 例如:上电梯的时候,大家陆陆续续进来,电梯的门不会关上,只有当一段时间都没有人上来,电梯才会关门。
|
|
193
|
-
* @param {F} func
|
|
194
|
-
* @param {number} wait
|
|
195
|
-
* @returns {DebounceFunc<F>}
|
|
196
|
-
*/
|
|
197
|
-
const debounce = (func, wait) => {
|
|
198
|
-
let timeout;
|
|
199
|
-
let canceled = false;
|
|
200
|
-
const f = function (...args) {
|
|
201
|
-
if (canceled) return;
|
|
202
|
-
clearTimeout(timeout);
|
|
203
|
-
timeout = setTimeout(() => {
|
|
204
|
-
func.call(this, ...args);
|
|
205
|
-
}, wait);
|
|
206
|
-
};
|
|
207
|
-
f.cancel = () => {
|
|
208
|
-
clearTimeout(timeout);
|
|
209
|
-
canceled = true;
|
|
210
|
-
};
|
|
211
|
-
return f;
|
|
212
|
-
};
|
|
213
|
-
/**
|
|
214
|
-
* 节流函数
|
|
215
|
-
* 节流就是节约流量,将连续触发的事件稀释成预设评率。 比如每间隔1秒执行一次函数,无论这期间触发多少次事件。
|
|
216
|
-
* 这有点像公交车,无论在站点等车的人多不多,公交车只会按时来一班,不会来一个人就来一辆公交车。
|
|
217
|
-
* @param {F} func
|
|
218
|
-
* @param {number} wait
|
|
219
|
-
* @param {boolean} immediate
|
|
220
|
-
* @returns {ThrottleFunc<F>}
|
|
221
|
-
*/
|
|
222
|
-
const throttle = (func, wait, immediate) => {
|
|
223
|
-
let timeout;
|
|
224
|
-
let canceled = false;
|
|
225
|
-
let lastCalledTime = 0;
|
|
226
|
-
const f = function (...args) {
|
|
227
|
-
if (canceled) return;
|
|
228
|
-
const now = Date.now();
|
|
229
|
-
const call = () => {
|
|
230
|
-
lastCalledTime = now;
|
|
231
|
-
func.call(this, ...args);
|
|
232
|
-
};
|
|
233
|
-
// 第一次执行
|
|
234
|
-
if (lastCalledTime === 0) {
|
|
235
|
-
if (immediate) {
|
|
236
|
-
return call();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
lastCalledTime = now;
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const remain = lastCalledTime + wait - now;
|
|
243
|
-
if (remain > 0) {
|
|
244
|
-
clearTimeout(timeout);
|
|
245
|
-
timeout = setTimeout(() => call(), wait);
|
|
246
|
-
} else {
|
|
247
|
-
call();
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
f.cancel = () => {
|
|
251
|
-
clearTimeout(timeout);
|
|
252
|
-
canceled = true;
|
|
253
|
-
};
|
|
254
|
-
return f;
|
|
255
|
-
};
|
|
256
|
-
// /**
|
|
257
|
-
// * @description: 带模糊搜索的分块读取大JSON文件
|
|
258
|
-
// * @param {string} filePath
|
|
259
|
-
// * @return {*}
|
|
260
|
-
// */
|
|
261
|
-
// const readBigJson = function (filePath) {
|
|
262
|
-
// return new Promise((resolve, reject) => {
|
|
263
|
-
// let res = '';
|
|
264
|
-
// const readable = fs.createReadStream(filePath, {
|
|
265
|
-
// encoding: 'utf8',
|
|
266
|
-
// highWaterMark: 10
|
|
267
|
-
// });
|
|
268
|
-
// const parser = JSONStream.parse('*');
|
|
269
|
-
// readable.pipe(parser);
|
|
270
|
-
// parser.on('end', function () {
|
|
271
|
-
// // I know it ends here,
|
|
272
|
-
// console.log('end::', res);
|
|
273
|
-
// resolve(res);
|
|
274
|
-
// });
|
|
275
|
-
// parser.on('data', function (data) {
|
|
276
|
-
// res += data;
|
|
277
|
-
// console.log('yy::', data);
|
|
278
|
-
// });
|
|
279
|
-
// });
|
|
280
|
-
// };
|
|
281
|
-
|
|
282
|
-
module.exports = {
|
|
283
|
-
getLogger,
|
|
284
|
-
dateFormat,
|
|
285
|
-
logger,
|
|
286
|
-
SupportMethods,
|
|
287
|
-
DefaultHeaders,
|
|
288
|
-
isValidMethod,
|
|
289
|
-
getFileLatestContent,
|
|
290
|
-
filePath2ApiUrl,
|
|
291
|
-
getDataType,
|
|
292
|
-
isEmptyObj,
|
|
293
|
-
writeStream,
|
|
294
|
-
readStream,
|
|
295
|
-
debounce,
|
|
296
|
-
throttle
|
|
297
|
-
};
|
|
File without changes
|
|
File without changes
|