mock-service-cli 2.0.3 → 2.1.1
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 +37 -0
- package/README.md +13 -10
- package/bin/mock-service-cli +7 -3
- package/lib/manageMockFiles.js +65 -17
- package/lib/mockServer.js +19 -10
- package/lib/utils.js +11 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,43 @@
|
|
|
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.1.1](https://github.com/chandq/mock-service-cli/compare/v2.1.0...v2.1.1) (2021-12-30)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* issue of friendly show error tip ([e9822c2](https://github.com/chandq/mock-service-cli/commit/e9822c2038ad411d91a170af33e7541e266ca8e6))
|
|
11
|
+
* issue of empty file content ([3949e00](https://github.com/chandq/mock-service-cli/commit/3949e00a46b4555bc08ec8564221cc230c780dcb))
|
|
12
|
+
|
|
13
|
+
## [2.1.0](https://github.com/chandq/mock-service-cli/compare/v2.0.5...v2.1.0) (2021-12-30)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* 根据命令行参数决定是否 打印api统计信息 ([0e838db](https://github.com/chandq/mock-service-cli/commit/0e838db7820fd096163d14eb87abbd9b852b6a0e))
|
|
19
|
+
* add arguments description ([097b373](https://github.com/chandq/mock-service-cli/commit/097b3733a1da0b43dae6b50080d270323b92f0d2))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* issue of comment typo ([85297a5](https://github.com/chandq/mock-service-cli/commit/85297a5895fd7c0446ee8b90a58ebed90a02e9e7))
|
|
25
|
+
* issue of maybe write content to file failed ([8ed910b](https://github.com/chandq/mock-service-cli/commit/8ed910b1e9687cae46ad6bdab641db0c305c83fb))
|
|
26
|
+
* socket connection show datetime ([c6db3b4](https://github.com/chandq/mock-service-cli/commit/c6db3b47a2370dc1c9aba5495dbb6606c20eb0c9))
|
|
27
|
+
|
|
28
|
+
### [2.0.5](https://github.com/chandq/mock-service-cli/compare/v2.0.4...v2.0.5) (2021-12-28)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* validate func parameter to avoid exception ([32e4d28](https://github.com/chandq/mock-service-cli/commit/32e4d28114a4907352491e16829d37345fbab9d9))
|
|
34
|
+
|
|
35
|
+
### [2.0.4](https://github.com/chandq/mock-service-cli/compare/v2.0.3...v2.0.4) (2021-12-27)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Bug Fixes
|
|
39
|
+
|
|
40
|
+
* get valid api url for route ([8770751](https://github.com/chandq/mock-service-cli/commit/877075107ea60244a52e345f37b7df855752d5f6))
|
|
41
|
+
|
|
5
42
|
### [2.0.3](https://github.com/chandq/mock-service-cli/compare/v2.0.2...v2.0.3) (2021-12-27)
|
|
6
43
|
|
|
7
44
|
|
package/README.md
CHANGED
|
@@ -45,15 +45,16 @@ This will install `mock-service-cli` globally so that it may be run from the com
|
|
|
45
45
|
|
|
46
46
|
`[path]` defaults to `./mock` .
|
|
47
47
|
|
|
48
|
-
| Command
|
|
49
|
-
|
|
|
50
|
-
| `-p` or `--port`
|
|
51
|
-
| `-d`
|
|
52
|
-
| `-f`
|
|
53
|
-
| `-s` or `--silent`
|
|
54
|
-
| `-h` or `--help`
|
|
55
|
-
| `-v` or `--version`
|
|
56
|
-
| `--
|
|
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 |
|
|
57
58
|
|
|
58
59
|
## Example
|
|
59
60
|
|
|
@@ -71,7 +72,7 @@ This will install `mock-service-cli` globally so that it may be run from the com
|
|
|
71
72
|
|
|
72
73
|
4. Start socket server for used to save api response data.
|
|
73
74
|
|
|
74
|
-
`mock-service-cli
|
|
75
|
+
`mock-service-cli -S`
|
|
75
76
|
|
|
76
77
|
### 编写 Mock 文件
|
|
77
78
|
|
|
@@ -124,6 +125,8 @@ module.exports = {
|
|
|
124
125
|
|
|
125
126
|
### 借助 socket.io 保留接口数据
|
|
126
127
|
|
|
128
|
+
> `save-data` 和 `mock-dir-stat` 事件会自动生成 `mock-list.json` 文件(维护接口`<url, [method]>`的关系映射),方便查阅接口统计信息
|
|
129
|
+
|
|
127
130
|
```js
|
|
128
131
|
// 连接SocketServer
|
|
129
132
|
import { io } from 'socket.io-client';
|
package/bin/mock-service-cli
CHANGED
|
@@ -20,7 +20,8 @@ if (argv.h || argv.help) {
|
|
|
20
20
|
' -f --file Specify the input data source, support javascript ',
|
|
21
21
|
' The priority is over the directory watches',
|
|
22
22
|
' -s --silent Suppress log messages from output',
|
|
23
|
-
' --
|
|
23
|
+
' -S --socket-server Whether start socket server or not, default false.',
|
|
24
|
+
' -a --api-stat Whether print api url and file path or not, default false.',
|
|
24
25
|
'',
|
|
25
26
|
' -h --help Print this list and exit.',
|
|
26
27
|
' -v --version Print the version and exit.'
|
|
@@ -29,11 +30,14 @@ if (argv.h || argv.help) {
|
|
|
29
30
|
process.exit();
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
// 保留命令行参数
|
|
34
|
+
process.env.ARGV = JSON.stringify(argv);
|
|
35
|
+
|
|
32
36
|
var port = argv.p || argv.port,
|
|
33
37
|
watchDir = argv.d,
|
|
34
38
|
specifiedFile = argv.f || argv.file,
|
|
35
39
|
version = argv.v || argv.version,
|
|
36
|
-
isStartSocketServer = argv.
|
|
40
|
+
isStartSocketServer = argv.S || false,
|
|
37
41
|
log = null;
|
|
38
42
|
|
|
39
43
|
if (!argv.s && !argv.silent) {
|
|
@@ -44,7 +48,7 @@ if (!argv.s && !argv.silent) {
|
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
if (isStartSocketServer) {
|
|
47
|
-
process.env.
|
|
51
|
+
process.env.SOCKET_SERVER = true;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
if (version) {
|
package/lib/manageMockFiles.js
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
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-30 16:43:04
|
|
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
|
-
|
|
13
|
-
const { getFileLatestContent, SupportMethods, filePath2ApiUrl } = require('./utils');
|
|
14
|
-
|
|
11
|
+
_ = require('lodash'),
|
|
12
|
+
colors = require('colors/safe');
|
|
13
|
+
const { getFileLatestContent, SupportMethods, filePath2ApiUrl, logger, getDataType } = require('./utils');
|
|
14
|
+
const log = logger(process.env.SILENT);
|
|
15
15
|
|
|
16
16
|
const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
|
|
17
17
|
/**
|
|
18
|
-
* @description: 生成mock
|
|
18
|
+
* @description: 生成mock文件(自动生成mock-list.json文件,并维护<url, [method]>的关系映射)
|
|
19
19
|
* @param {string} apiUrl 请求url
|
|
20
20
|
* @param {string} method 请求方法
|
|
21
21
|
* @param {object} resJsonData 响应数据
|
|
@@ -24,6 +24,25 @@ const methodRegExp = new RegExp(`(${SupportMethods.join('|')}) +(.*)`, 'i');
|
|
|
24
24
|
*
|
|
25
25
|
*/
|
|
26
26
|
const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mockDir }) {
|
|
27
|
+
const type = getDataType(resJsonData);
|
|
28
|
+
if (!apiUrl || !method || !resJsonData || !mockDir) {
|
|
29
|
+
log.info(
|
|
30
|
+
colors.red([`参数: apiUrl: ${apiUrl}, method: ${method}, mockDir: ${mockDir} `, `必须是有效值`].join(','))
|
|
31
|
+
);
|
|
32
|
+
return;
|
|
33
|
+
} else if (
|
|
34
|
+
!['object', 'array'].includes(type) ||
|
|
35
|
+
(type === 'object' && Object.keys(resJsonData).length === 0) ||
|
|
36
|
+
(type === 'array' && resJsonData.length === 0)
|
|
37
|
+
) {
|
|
38
|
+
log.info(
|
|
39
|
+
`参数: apiUrl: ${apiUrl}, method: ${method}, resJsonData:`,
|
|
40
|
+
resJsonData,
|
|
41
|
+
colors.red(', 参数字段resJsonData必须是非空的数组或对象!')
|
|
42
|
+
);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
apiUrl = apiUrl.trim().split('?')[0];
|
|
27
46
|
const normalizeApiUrl = filePath2ApiUrl(path.normalize(apiUrl));
|
|
28
47
|
const mockListFilePath = path.resolve(process.cwd(), `${mockDir}/mock-list.json`);
|
|
29
48
|
const mockFilePath = path.resolve(process.cwd(), `${mockDir}/${encodeURIComponent(path.normalize(apiUrl))}.json`);
|
|
@@ -43,7 +62,8 @@ const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mo
|
|
|
43
62
|
newMockListContent[normalizeApiUrl].push(method);
|
|
44
63
|
}
|
|
45
64
|
if (!oldMockListContent || !_.isEqual(oldMockListContent, newMockListContent)) {
|
|
46
|
-
|
|
65
|
+
Object.keys(newMockListContent).length > 0 &&
|
|
66
|
+
fs.writeFileSync(mockListFilePath, JSON.stringify(newMockListContent, null, 2));
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
// mock文件存在
|
|
@@ -57,17 +77,19 @@ const genMockFiles = function ({ url: apiUrl, method, data: resJsonData, dir: mo
|
|
|
57
77
|
// );
|
|
58
78
|
return;
|
|
59
79
|
}
|
|
60
|
-
mockFileContent[method] = resJsonData
|
|
61
|
-
|
|
80
|
+
mockFileContent[method] = resJsonData;
|
|
81
|
+
Object.keys(mockFileContent).length > 0 &&
|
|
82
|
+
fsa.writeFileSync(mockFilePath, JSON.stringify(mockFileContent, null, 2));
|
|
62
83
|
} else {
|
|
63
84
|
// fsa.ensureFileSync(mockFilePath);
|
|
64
|
-
|
|
85
|
+
Object.keys(mockFilePath).length > 0 &&
|
|
86
|
+
fsa.writeFileSync(mockFilePath, JSON.stringify({ [method]: resJsonData }, null, 2));
|
|
65
87
|
}
|
|
66
88
|
// console.debug('file::', `${mockDir}/${apiUrl}`, newMockListContent);
|
|
67
89
|
};
|
|
68
90
|
/**
|
|
69
91
|
* @description: 从js文件中收集mock数据
|
|
70
|
-
* @param {
|
|
92
|
+
* @param {object} mockDataMap
|
|
71
93
|
* @param {string} filePath
|
|
72
94
|
* @return {*} void
|
|
73
95
|
*/
|
|
@@ -93,7 +115,7 @@ const collectMockDataFromJsFile = function (mockDataMap, filePath) {
|
|
|
93
115
|
|
|
94
116
|
/**
|
|
95
117
|
* @description: 递归收集mock数据
|
|
96
|
-
* @param {
|
|
118
|
+
* @param {object} mockDataMap mock数据集
|
|
97
119
|
* @param {string} specialDir 目录
|
|
98
120
|
* @return {*} void
|
|
99
121
|
*/
|
|
@@ -126,22 +148,48 @@ const deepCollectMockData = function (mockDataMap, specialDir = '../mock') {
|
|
|
126
148
|
}
|
|
127
149
|
};
|
|
128
150
|
/**
|
|
129
|
-
* @description: 从文件目录中获取mock
|
|
151
|
+
* @description: 从文件目录中获取mock数据统计(若mock-list.json文件不存在则自动生成)
|
|
130
152
|
* @param {string} dirPath
|
|
131
|
-
* @return {
|
|
153
|
+
* @return {object} mock数据统计
|
|
132
154
|
*/
|
|
133
155
|
const getMockStatFromDir = dirPath => {
|
|
156
|
+
if (!fsa.pathExistsSync(dirPath)) {
|
|
157
|
+
throw new Error(`入参无效,${dirPath} 目录不存在`);
|
|
158
|
+
}
|
|
134
159
|
const mockDataMap = {};
|
|
135
160
|
deepCollectMockData(mockDataMap, dirPath);
|
|
161
|
+
|
|
162
|
+
const mockListFilePath = path.resolve(process.cwd(), `${dirPath}/mock-list.json`);
|
|
163
|
+
// 若不存在mock-list.json文件,则根据现有mock文件重新生成<api, [method]>映射关系
|
|
164
|
+
if (Object.keys(mockDataMap).length > 0 && !fsa.pathExistsSync(mockListFilePath)) {
|
|
165
|
+
fsa.ensureFileSync(mockListFilePath);
|
|
166
|
+
const reverseMockList = {};
|
|
167
|
+
Object.keys(mockDataMap).forEach(it => {
|
|
168
|
+
if (methodRegExp.exec(it)) {
|
|
169
|
+
const [, method, url] = methodRegExp.exec(it);
|
|
170
|
+
if (url.trim() && method.trim()) {
|
|
171
|
+
if (reverseMockList.hasOwnProperty(url)) {
|
|
172
|
+
reverseMockList[url].push(method);
|
|
173
|
+
} else {
|
|
174
|
+
reverseMockList[url] = [method];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
fs.writeFileSync(mockListFilePath, JSON.stringify(reverseMockList, null, 2));
|
|
180
|
+
}
|
|
136
181
|
return mockDataMap;
|
|
137
182
|
};
|
|
138
183
|
|
|
139
184
|
/**
|
|
140
185
|
* @description: 从js文件中获取mock数据统计
|
|
141
186
|
* @param {string} filePath
|
|
142
|
-
* @return {
|
|
187
|
+
* @return {object} mock数据统计
|
|
143
188
|
*/
|
|
144
189
|
const getMockStatFromFile = filePath => {
|
|
190
|
+
if (!fsa.pathExistsSync(filePath)) {
|
|
191
|
+
throw new Error(`入参无效,${filePath} 文件不存在`);
|
|
192
|
+
}
|
|
145
193
|
const mockDataMap = {};
|
|
146
194
|
collectMockDataFromJsFile(mockDataMap, filePath);
|
|
147
195
|
return mockDataMap;
|
|
@@ -154,8 +202,8 @@ const getMockStatFromFile = filePath => {
|
|
|
154
202
|
* @return {boolean}
|
|
155
203
|
*/
|
|
156
204
|
const hasMockApi = function (mockDataMap, apiUrl, method) {
|
|
157
|
-
if (!mockDataMap || !(mockDataMap instanceof Object)) {
|
|
158
|
-
throw new Error(
|
|
205
|
+
if (!apiUrl || !method || !mockDataMap || !(mockDataMap instanceof Object)) {
|
|
206
|
+
throw new Error(`入参无效,${mockDataMap} 必须是 mock数据的Object对象`);
|
|
159
207
|
}
|
|
160
208
|
return mockDataMap.hasOwnProperty(`${method.toLocaleLowerCase()} ${path.normalize(apiUrl)}`);
|
|
161
209
|
};
|
package/lib/mockServer.js
CHANGED
|
@@ -7,13 +7,14 @@ 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');
|
|
14
14
|
|
|
15
15
|
const app = express();
|
|
16
16
|
const log = logger(process.env.SILENT);
|
|
17
|
+
const argv = JSON.parse(process.env.ARGV);
|
|
17
18
|
let socketServer = null; // Socket server instance
|
|
18
19
|
|
|
19
20
|
let count = 0,
|
|
@@ -64,7 +65,7 @@ const composeRouteFromJsFile = function (file) {
|
|
|
64
65
|
// 先删除require之前导入的缓存文件,否则获取到的文件内容还是旧内容
|
|
65
66
|
const fileObject = getFileLatestContent(file);
|
|
66
67
|
|
|
67
|
-
log.info(colors.green(`Mockfile ${++fileCount}: `), file, colors.yellow('all API URL is follows: '));
|
|
68
|
+
argv.a && log.info(colors.green(`Mockfile ${++fileCount}: `), file, colors.yellow('all API URL is follows: '));
|
|
68
69
|
Object.keys(fileObject).forEach(item => {
|
|
69
70
|
let reqMethod = 'get',
|
|
70
71
|
reqUrl = item;
|
|
@@ -74,7 +75,7 @@ const composeRouteFromJsFile = function (file) {
|
|
|
74
75
|
reqMethod = method.toLowerCase();
|
|
75
76
|
reqUrl = url;
|
|
76
77
|
}
|
|
77
|
-
log.info(colors.yellow(`path ${++count}: `), item, colors.blue(typeof fileObject[item]));
|
|
78
|
+
argv.a && log.info(colors.yellow(`path ${++count}: `), item, colors.blue(typeof fileObject[item]));
|
|
78
79
|
log.assert(typeof app[reqMethod] === 'function', colors.red(`${file}, ${reqMethod}`));
|
|
79
80
|
if (typeof fileObject[item] === 'function') {
|
|
80
81
|
app[reqMethod](reqUrl, fileObject[item]);
|
|
@@ -103,12 +104,14 @@ const parseMockFiles = function (specialDir = '../mock') {
|
|
|
103
104
|
|
|
104
105
|
// 处理存放mock数据的json文件
|
|
105
106
|
if (el.name.endsWith('.json') && el.name !== 'mock-list.json') {
|
|
106
|
-
|
|
107
|
+
argv.a &&
|
|
108
|
+
log.info(colors.green(`Mockfile ${++fileCount}: `), filePath, colors.yellow('all API URL is follows: '));
|
|
107
109
|
const fileObject = getFileLatestContent(filePath);
|
|
108
110
|
// eslint-disable-next-line no-loop-func
|
|
109
111
|
Object.keys(fileObject).forEach(method => {
|
|
110
|
-
const apiUrl = decodeURIComponent(el.name.split('.')[0]);
|
|
111
|
-
|
|
112
|
+
const apiUrl = filePath2ApiUrl(decodeURIComponent(el.name.split('.')[0]));
|
|
113
|
+
argv.a &&
|
|
114
|
+
log.info(colors.yellow(`path ${++count}: `), `${method} ${apiUrl}`, colors.blue(typeof fileObject[method]));
|
|
112
115
|
log.assert(typeof app[method] === 'function', colors.red(`${filePath}, ${method}`));
|
|
113
116
|
app[method](apiUrl, function (req, res) {
|
|
114
117
|
res.json(fileObject[method]);
|
|
@@ -130,15 +133,17 @@ if (process.env.SPECIFIED_FILE) {
|
|
|
130
133
|
} else {
|
|
131
134
|
parseMockFiles(process.env.SPECIFIED_DIR);
|
|
132
135
|
}
|
|
133
|
-
log.info(chalk.hex('#ce5b34bd')(`${fileCount} mock file are parsed in total.`));
|
|
136
|
+
argv.a && log.info(chalk.hex('#ce5b34bd')(`${fileCount} mock file are parsed in total.`));
|
|
134
137
|
const http = require('http').createServer(app);
|
|
135
|
-
if (process.env.
|
|
138
|
+
if (process.env.SOCKET_SERVER) {
|
|
136
139
|
socketServer = new Server(http, { path: '/ws/mock-service' });
|
|
137
140
|
log.info(colors.bgBlue(`Socket server has started. path: /ws/mock-service, `));
|
|
138
141
|
socketServer.of('/mock-data').on('connection', function (socket) {
|
|
139
142
|
const { headers, address } = socket.handshake;
|
|
140
143
|
const clientIp = headers.hasOwnProperty('x-forwarded-for') ? headers['x-forwarded-for'] : address;
|
|
141
|
-
log.info(
|
|
144
|
+
log.info(
|
|
145
|
+
colors.green(`Socket client ${clientIp} has connected. --- ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`)
|
|
146
|
+
);
|
|
142
147
|
socket.on('mock-dir-stat', function (dir) {
|
|
143
148
|
socket.emit('mock-dir-stat', getMockStatFromDir(dir));
|
|
144
149
|
});
|
|
@@ -151,7 +156,11 @@ if (process.env.SOCKETSERVER) {
|
|
|
151
156
|
});
|
|
152
157
|
|
|
153
158
|
socket.on('disconnect', function () {
|
|
154
|
-
log.info(
|
|
159
|
+
log.info(
|
|
160
|
+
colors.gray(
|
|
161
|
+
`Socket client ${clientIp} has disconnected. --- ${dateFormat('YYYY-mm-dd HH:MM:SS', new Date())}`
|
|
162
|
+
)
|
|
163
|
+
);
|
|
155
164
|
});
|
|
156
165
|
});
|
|
157
166
|
}
|
package/lib/utils.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @description:
|
|
3
3
|
* @Date: 2021-12-25 17:52:48
|
|
4
4
|
* @LastEditors: chendq
|
|
5
|
-
* @LastEditTime: 2021-12-
|
|
5
|
+
* @LastEditTime: 2021-12-30 13:17:12
|
|
6
6
|
* @Author: chendq
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
@@ -93,6 +93,14 @@ const getFileLatestContent = function (filePath) {
|
|
|
93
93
|
const filePath2ApiUrl = function (filePath) {
|
|
94
94
|
return filePath.split(path.sep).join('/');
|
|
95
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* @description: 获取数据类型
|
|
98
|
+
* @param {any} data 数据值
|
|
99
|
+
* @return {string} 数据类型
|
|
100
|
+
*/
|
|
101
|
+
const getDataType = function (data) {
|
|
102
|
+
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase();
|
|
103
|
+
};
|
|
96
104
|
|
|
97
105
|
module.exports = {
|
|
98
106
|
getLogger,
|
|
@@ -101,5 +109,6 @@ module.exports = {
|
|
|
101
109
|
SupportMethods,
|
|
102
110
|
isValidMethod,
|
|
103
111
|
getFileLatestContent,
|
|
104
|
-
filePath2ApiUrl
|
|
112
|
+
filePath2ApiUrl,
|
|
113
|
+
getDataType
|
|
105
114
|
};
|