mock-service-cli 2.0.1 → 2.0.5
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 +28 -0
- package/bin/mock-service-cli +4 -4
- package/lib/manageMockFiles.js +29 -13
- package/lib/mockServer.js +6 -6
- package/lib/utils.js +24 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
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.0.5](https://github.com/chandq/mock-service-cli/compare/v2.0.4...v2.0.5) (2021-12-28)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* validate func parameter to avoid exception ([32e4d28](https://github.com/chandq/mock-service-cli/commit/32e4d28114a4907352491e16829d37345fbab9d9))
|
|
11
|
+
|
|
12
|
+
### [2.0.4](https://github.com/chandq/mock-service-cli/compare/v2.0.3...v2.0.4) (2021-12-27)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* get valid api url for route ([8770751](https://github.com/chandq/mock-service-cli/commit/877075107ea60244a52e345f37b7df855752d5f6))
|
|
18
|
+
|
|
19
|
+
### [2.0.3](https://github.com/chandq/mock-service-cli/compare/v2.0.2...v2.0.3) (2021-12-27)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* convert windows file path to api url ([1f15b33](https://github.com/chandq/mock-service-cli/commit/1f15b334ab5374bc102e5e11fbfaae994569bca5))
|
|
25
|
+
|
|
26
|
+
### [2.0.2](https://github.com/chandq/mock-service-cli/compare/v2.0.1...v2.0.2) (2021-12-27)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* issue of convert path ([5276488](https://github.com/chandq/mock-service-cli/commit/527648866f20fd25b5df0dc55b3898d7e7a1ad2c))
|
|
32
|
+
|
|
5
33
|
### [2.0.1](https://github.com/chandq/mock-service-cli/compare/v2.0.0...v2.0.1) (2021-12-27)
|
|
6
34
|
|
|
7
35
|
|
package/bin/mock-service-cli
CHANGED
|
@@ -70,7 +70,7 @@ const watchMockFiles = function (watchDir) {
|
|
|
70
70
|
* ext 检测的文件
|
|
71
71
|
*/
|
|
72
72
|
nodemon({
|
|
73
|
-
script: path.
|
|
73
|
+
script: path.resolve(__dirname, '../lib/mockServer.js'),
|
|
74
74
|
watch: [watchDir],
|
|
75
75
|
ext: 'js,json'
|
|
76
76
|
});
|
|
@@ -92,14 +92,14 @@ const watchMockFiles = function (watchDir) {
|
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
if (specifiedFile) {
|
|
95
|
-
process.env.SPECIFIED_FILE = path.
|
|
95
|
+
process.env.SPECIFIED_FILE = path.resolve(process.cwd(), specifiedFile);
|
|
96
96
|
watchMockFiles(process.env.SPECIFIED_FILE);
|
|
97
97
|
} else if (watchDir) {
|
|
98
|
-
process.env.SPECIFIED_DIR = path.
|
|
98
|
+
process.env.SPECIFIED_DIR = path.resolve(process.cwd(), watchDir);
|
|
99
99
|
// log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
|
|
100
100
|
watchMockFiles(process.env.SPECIFIED_DIR);
|
|
101
101
|
} else {
|
|
102
|
-
watchDir = process.env.SPECIFIED_DIR = path.
|
|
102
|
+
watchDir = process.env.SPECIFIED_DIR = path.resolve(process.cwd(), './mock');
|
|
103
103
|
// log.info('SPECIFIED_DIR::', process.env.SPECIFIED_DIR);
|
|
104
104
|
watchMockFiles(watchDir);
|
|
105
105
|
}
|
package/lib/manageMockFiles.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @description: 生成Mock文件、获取mock数据统计
|
|
3
3
|
* @Date: 2021-12-22 16:57:08
|
|
4
4
|
* @LastEditors: chendq
|
|
5
|
-
* @LastEditTime: 2021-12-
|
|
5
|
+
* @LastEditTime: 2021-12-28 16:23:43
|
|
6
6
|
* @Author: chendq
|
|
7
7
|
*/
|
|
8
8
|
const fsa = require('fs-extra'),
|
|
@@ -10,7 +10,7 @@ const fsa = require('fs-extra'),
|
|
|
10
10
|
path = require('path'),
|
|
11
11
|
_ = require('lodash'),
|
|
12
12
|
colors = require('colors/safe');
|
|
13
|
-
const { getFileLatestContent, SupportMethods, logger } = require('./utils');
|
|
13
|
+
const { getFileLatestContent, SupportMethods, filePath2ApiUrl, logger } = require('./utils');
|
|
14
14
|
const log = logger(process.env.SILENT);
|
|
15
15
|
|
|
16
16
|
const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
|
|
@@ -24,9 +24,16 @@ const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
|
|
|
24
24
|
*
|
|
25
25
|
*/
|
|
26
26
|
const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mockDir }) {
|
|
27
|
-
|
|
27
|
+
if (!apiUrl || !method || !resJsonData || !mockDir) {
|
|
28
|
+
log.info(
|
|
29
|
+
colors.red(`参数: apiUrl: ${apiUrl}, method: ${method}, resJsonData: ${resJsonData}, mockDir: ${mockDir}无效`)
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
apiUrl = apiUrl.trim().split('?')[0];
|
|
34
|
+
const normalizeApiUrl = filePath2ApiUrl(path.normalize(apiUrl));
|
|
28
35
|
const mockListFilePath = path.resolve(process.cwd(), `${mockDir}/mock-list.json`);
|
|
29
|
-
const mockFilePath = path.resolve(process.cwd(), `${mockDir}/${encodeURIComponent(
|
|
36
|
+
const mockFilePath = path.resolve(process.cwd(), `${mockDir}/${encodeURIComponent(path.normalize(apiUrl))}.json`);
|
|
30
37
|
let newMockListContent = {},
|
|
31
38
|
oldMockListContent = null;
|
|
32
39
|
if (fsa.pathExistsSync(mockListFilePath)) {
|
|
@@ -37,13 +44,14 @@ const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mo
|
|
|
37
44
|
}
|
|
38
45
|
|
|
39
46
|
// update mock-list.json file
|
|
40
|
-
if (!newMockListContent.hasOwnProperty(
|
|
41
|
-
newMockListContent[
|
|
42
|
-
} else if (!newMockListContent[
|
|
43
|
-
newMockListContent[
|
|
47
|
+
if (!newMockListContent.hasOwnProperty(normalizeApiUrl)) {
|
|
48
|
+
newMockListContent[normalizeApiUrl] = [method];
|
|
49
|
+
} else if (!newMockListContent[normalizeApiUrl].includes(method)) {
|
|
50
|
+
newMockListContent[normalizeApiUrl].push(method);
|
|
44
51
|
}
|
|
45
52
|
if (!oldMockListContent || !_.isEqual(oldMockListContent, newMockListContent)) {
|
|
46
|
-
|
|
53
|
+
Object.keys(newMockListContent).length > 0 &&
|
|
54
|
+
fsa.writeFileSync(mockListFilePath, JSON.stringify(newMockListContent, null, 2));
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
// mock文件存在
|
|
@@ -58,12 +66,14 @@ const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mo
|
|
|
58
66
|
return;
|
|
59
67
|
}
|
|
60
68
|
mockFileContent[method] = resJsonData ? resJsonData : {};
|
|
61
|
-
|
|
69
|
+
Object.keys(mockFileContent).length > 0 &&
|
|
70
|
+
fsa.writeFileSync(mockFilePath, JSON.stringify(mockFileContent, null, 2));
|
|
62
71
|
} else {
|
|
63
72
|
// fsa.ensureFileSync(mockFilePath);
|
|
64
|
-
|
|
73
|
+
Object.keys(mockFilePath).length > 0 &&
|
|
74
|
+
fsa.writeFileSync(mockFilePath, JSON.stringify({ [method]: resJsonData ? resJsonData : {} }, null, 2));
|
|
65
75
|
}
|
|
66
|
-
// console.debug('file::', `${mockDir}/${
|
|
76
|
+
// console.debug('file::', `${mockDir}/${apiUrl}`, newMockListContent);
|
|
67
77
|
};
|
|
68
78
|
/**
|
|
69
79
|
* @description: 从js文件中收集mock数据
|
|
@@ -131,6 +141,9 @@ const deepCollectMockData = function (mockDataMap, specialDir = '../mock') {
|
|
|
131
141
|
* @return {map} mock数据统计
|
|
132
142
|
*/
|
|
133
143
|
const getMockStatFromDir = dirPath => {
|
|
144
|
+
if (!fsa.pathExistsSync(dirPath)) {
|
|
145
|
+
throw new Error(`如参无效,${dirPath} 目录不存在`);
|
|
146
|
+
}
|
|
134
147
|
const mockDataMap = {};
|
|
135
148
|
deepCollectMockData(mockDataMap, dirPath);
|
|
136
149
|
return mockDataMap;
|
|
@@ -142,6 +155,9 @@ const getMockStatFromDir = dirPath => {
|
|
|
142
155
|
* @return {map} mock数据统计
|
|
143
156
|
*/
|
|
144
157
|
const getMockStatFromFile = filePath => {
|
|
158
|
+
if (!fsa.pathExistsSync(filePath)) {
|
|
159
|
+
throw new Error(`如参无效,${filePath} 文件不存在`);
|
|
160
|
+
}
|
|
145
161
|
const mockDataMap = {};
|
|
146
162
|
collectMockDataFromJsFile(mockDataMap, filePath);
|
|
147
163
|
return mockDataMap;
|
|
@@ -154,7 +170,7 @@ const getMockStatFromFile = filePath => {
|
|
|
154
170
|
* @return {boolean}
|
|
155
171
|
*/
|
|
156
172
|
const hasMockApi = function (mockDataMap, apiUrl, method) {
|
|
157
|
-
if (!mockDataMap || !(mockDataMap instanceof Object)) {
|
|
173
|
+
if (!apiUrl || !method || !mockDataMap || !(mockDataMap instanceof Object)) {
|
|
158
174
|
throw new Error(`如参无效,${mockDataMap} 必须是 mock数据的Object对象`);
|
|
159
175
|
}
|
|
160
176
|
return mockDataMap.hasOwnProperty(`${method.toLocaleLowerCase()} ${path.normalize(apiUrl)}`);
|
package/lib/mockServer.js
CHANGED
|
@@ -7,7 +7,7 @@ const express = require('express'), // 引入express
|
|
|
7
7
|
chalk = require('chalk');
|
|
8
8
|
const ifaces = os.networkInterfaces();
|
|
9
9
|
const { Server } = require('socket.io');
|
|
10
|
-
const { dateFormat, logger, SupportMethods, getFileLatestContent } = require('./utils');
|
|
10
|
+
const { dateFormat, logger, SupportMethods, getFileLatestContent, filePath2ApiUrl } = require('./utils');
|
|
11
11
|
const { genMockFiles, getMockStatFromDir, getMockStatFromFile } = require('./manageMockFiles');
|
|
12
12
|
|
|
13
13
|
const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
|
|
@@ -60,7 +60,7 @@ const crossDomain = () => (req, res, next) => {
|
|
|
60
60
|
* @param {*} file
|
|
61
61
|
* @returns {*}
|
|
62
62
|
*/
|
|
63
|
-
const
|
|
63
|
+
const composeRouteFromJsFile = function (file) {
|
|
64
64
|
// 先删除require之前导入的缓存文件,否则获取到的文件内容还是旧内容
|
|
65
65
|
const fileObject = getFileLatestContent(file);
|
|
66
66
|
|
|
@@ -107,7 +107,7 @@ const parseMockFiles = function (specialDir = '../mock') {
|
|
|
107
107
|
const fileObject = getFileLatestContent(filePath);
|
|
108
108
|
// eslint-disable-next-line no-loop-func
|
|
109
109
|
Object.keys(fileObject).forEach(method => {
|
|
110
|
-
const apiUrl = decodeURIComponent(el.name.split('.')[0]);
|
|
110
|
+
const apiUrl = filePath2ApiUrl(decodeURIComponent(el.name.split('.')[0]));
|
|
111
111
|
log.info(colors.yellow(`path ${++count}: `), `${method} ${apiUrl}`, colors.blue(typeof fileObject[method]));
|
|
112
112
|
log.assert(typeof app[method] === 'function', colors.red(`${filePath}, ${method}`));
|
|
113
113
|
app[method](apiUrl, function (req, res) {
|
|
@@ -121,12 +121,12 @@ const parseMockFiles = function (specialDir = '../mock') {
|
|
|
121
121
|
if (!el.name.endsWith('.js')) {
|
|
122
122
|
continue;
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
composeRouteFromJsFile(filePath);
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
app.use(crossDomain());
|
|
128
128
|
if (process.env.SPECIFIED_FILE) {
|
|
129
|
-
|
|
129
|
+
composeRouteFromJsFile(process.env.SPECIFIED_FILE);
|
|
130
130
|
} else {
|
|
131
131
|
parseMockFiles(process.env.SPECIFIED_DIR);
|
|
132
132
|
}
|
|
@@ -201,6 +201,6 @@ process.on('SIGTERM', function () {
|
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
module.exports = {
|
|
204
|
-
|
|
204
|
+
composeRouteFromJsFile,
|
|
205
205
|
parseMockFiles
|
|
206
206
|
};
|
package/lib/utils.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @description:
|
|
3
|
+
* @Date: 2021-12-25 17:52:48
|
|
4
|
+
* @LastEditors: chendq
|
|
5
|
+
* @LastEditTime: 2021-12-27 13:12:16
|
|
6
|
+
* @Author: chendq
|
|
7
|
+
*/
|
|
1
8
|
/**
|
|
2
9
|
* @description: 输出和错误输出写入不同文件
|
|
3
10
|
* @param {*}
|
|
@@ -78,5 +85,21 @@ const getFileLatestContent = function (filePath) {
|
|
|
78
85
|
delete require.cache[require.resolve(filePath)];
|
|
79
86
|
return require(path.resolve(process.cwd(), filePath));
|
|
80
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* @description: 文件路径转成API的url
|
|
90
|
+
* @param {string} filePath
|
|
91
|
+
* @return {string} apiUrl
|
|
92
|
+
*/
|
|
93
|
+
const filePath2ApiUrl = function (filePath) {
|
|
94
|
+
return filePath.split(path.sep).join('/');
|
|
95
|
+
};
|
|
81
96
|
|
|
82
|
-
module.exports = {
|
|
97
|
+
module.exports = {
|
|
98
|
+
getLogger,
|
|
99
|
+
dateFormat,
|
|
100
|
+
logger,
|
|
101
|
+
SupportMethods,
|
|
102
|
+
isValidMethod,
|
|
103
|
+
getFileLatestContent,
|
|
104
|
+
filePath2ApiUrl
|
|
105
|
+
};
|