mock-service-cli 1.0.1 → 1.2.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/LICENSE.md +1 -1
- package/README.md +21 -8
- package/bin/mock-service-cli +8 -6
- package/lib/mockServer.js +27 -9
- package/package.json +8 -6
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021-present, [chendq](https://github.com/chandq)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
[](https://github.com/chandq/mock-service-cli/actions)
|
|
2
2
|
[](https://coveralls.io/github/chandq/mock-service-cli?branch=master)
|
|
3
|
-
[](https://github.com/chandq/mock-service-cli)
|
|
4
|
+
[](https://nodejs.org/download/release/v14.0.0/)
|
|
5
|
+
[](https://nodejs.org/download/release/v14.0.0/)
|
|
6
|
+
[](https://github.com/chandq/mock-service-cli/blob/master/LICENSE.md)
|
|
5
7
|
[](https://npmcharts.com/compare/mock-service-cli?minimal=true)
|
|
6
8
|
|
|
7
9
|
# mock-service-cli: 🦅 一个基于 node 和 express 的 本地 Mock Server 命令行工具
|
|
8
10
|
|
|
9
11
|
### 简介
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
**使用简单**、**零配置**、**0 秒启动**的本地命令行 Mock 服务器, 支持热更新,对于开发调试 mock 数据很实用,能提高前端开发者的开发效率。支持 `GET`,`POST`,`PUT`,`DELETE`,`PATCH`,`OPTIONS`,`COPY`,`LINK`,`UNLINK`,`PURGE` 等常用请求类型,对工程代码无任何侵入性,可能是本地最好用的 Mock 工具。
|
|
12
14
|
|
|
13
15
|
## Installation:
|
|
14
16
|
|
|
@@ -41,8 +43,8 @@ This will install `mock-service-cli` globally so that it may be run from the com
|
|
|
41
43
|
| Command | Description | Defaults |
|
|
42
44
|
| ------------------- | -------------------------------------------------------------------------------------------------------------- | -------- |
|
|
43
45
|
| `-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 |
|
|
44
|
-
| `-d` |
|
|
45
|
-
| `-f` |
|
|
46
|
+
| `-d` | Specify mock directory | ./mock |
|
|
47
|
+
| `-f` | Specify mock file | |
|
|
46
48
|
| `-s` or `--silent` | Suppress log messages from output | |
|
|
47
49
|
| `-h` or `--help` | Print this list and exit. | |
|
|
48
50
|
| `-v` or `--version` | Print the version and exit. | |
|
|
@@ -64,14 +66,25 @@ This will install `mock-service-cli` globally so that it may be run from the com
|
|
|
64
66
|
### mock file template
|
|
65
67
|
|
|
66
68
|
> e.g. `./mock/test.js`
|
|
69
|
+
|
|
67
70
|
```javascript
|
|
68
71
|
module.exports = {
|
|
69
|
-
'/mock/:id/test': { aa: 1, bb: '
|
|
72
|
+
'/mock/:id/test': { aa: 1, bb: '默认GET请求' },
|
|
73
|
+
'GET /mock/:id/test': { aa: 1, bb: '指定GET 方法' },
|
|
74
|
+
'POST /mock/:id/test': { aa: 1, bb: 'POST 方法' },
|
|
75
|
+
'DELETE /mock/:id/test': { aa: 1, bb: 'DELETE 方法' },
|
|
76
|
+
'PUT /mock/:id/test': { aa: 1, bb: 'PUT 方法' },
|
|
77
|
+
'PATCH /mock/:id/test': { aa: 1, bb: 'PATCH 方法' },
|
|
78
|
+
'OPTIONS /mock/:id/test': { aa: 1, bb: 'OPTIONS 方法' },
|
|
79
|
+
'COPY /mock/:id/test': { aa: 1, bb: 'COPY 方法' },
|
|
80
|
+
'LINK /mock/:id/test': { aa: 1, bb: 'LINK 方法' },
|
|
81
|
+
'UNLINK /mock/:id/test': { aa: 1, bb: 'UNLINK 方法' },
|
|
82
|
+
'PURGE /mock/:id/test': { aa: 1, bb: 'PURGE 方法' },
|
|
70
83
|
'/mock/video/test': (req, res) => {
|
|
71
84
|
res.json({ aa: 1, bb: 'asdf' });
|
|
72
85
|
},
|
|
73
86
|
'/mock/image/test': (req, res) => {
|
|
74
87
|
res.json({ aa: 1, bb: 'yyds' });
|
|
75
|
-
}
|
|
88
|
+
}
|
|
76
89
|
};
|
|
77
90
|
```
|
package/bin/mock-service-cli
CHANGED
|
@@ -11,13 +11,13 @@ process.title = 'mock-service-cli';
|
|
|
11
11
|
if (argv.h || argv.help) {
|
|
12
12
|
console.log(
|
|
13
13
|
[
|
|
14
|
-
'usage:
|
|
14
|
+
'usage: mock-service-cli [options]',
|
|
15
15
|
'',
|
|
16
16
|
'options:',
|
|
17
17
|
' -p --port Port to use. If 0, look for open port. [8090]',
|
|
18
|
-
' -d
|
|
18
|
+
' -d Specify mock directory, default [./mock] directory,',
|
|
19
19
|
' Also watch js files changes and support hot reload',
|
|
20
|
-
' -f --file Specify the input data source, support javascript
|
|
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
|
'',
|
|
@@ -71,15 +71,17 @@ const watchMockFiles = function (watchDir) {
|
|
|
71
71
|
|
|
72
72
|
nodemon
|
|
73
73
|
.on('start', function () {
|
|
74
|
-
log.info('nodemon: mockServer has started');
|
|
74
|
+
// log.info('nodemon: mockServer has started');
|
|
75
75
|
})
|
|
76
76
|
.on('quit', function () {
|
|
77
|
-
log.info('nodemon: mockServer has quit');
|
|
77
|
+
// log.info('nodemon: mockServer has quit');
|
|
78
78
|
process.exit();
|
|
79
79
|
})
|
|
80
80
|
.on('restart', function (files) {
|
|
81
81
|
process.env.RESTARTED = true;
|
|
82
|
-
log.info(
|
|
82
|
+
log.info(
|
|
83
|
+
[colors.green('\nnodemon: mockServer restarted due to: '), files, colors.green(' have changed'), '\n'].join('')
|
|
84
|
+
);
|
|
83
85
|
});
|
|
84
86
|
};
|
|
85
87
|
|
package/lib/mockServer.js
CHANGED
|
@@ -8,8 +8,13 @@ const express = require('express'), // 引入express
|
|
|
8
8
|
const ifaces = os.networkInterfaces();
|
|
9
9
|
const { dateFormat, logger } = require('./utils');
|
|
10
10
|
|
|
11
|
+
const methodRegExp = new RegExp('(GET|POST|PUT|DELETE|HEAD|PATCH|OPTIONS|COPY|LINK|UNLINK|PURGE) (.*)', 'i');
|
|
12
|
+
|
|
11
13
|
const app = express();
|
|
12
14
|
const log = logger(process.env.SILENT);
|
|
15
|
+
|
|
16
|
+
let count = 0,
|
|
17
|
+
fileCount = 0; // 记录mock api个数,mock file个数
|
|
13
18
|
let done = false;
|
|
14
19
|
if (!process.env.PORT) {
|
|
15
20
|
portfinder.basePort = 8090;
|
|
@@ -37,7 +42,7 @@ const crossDomain = () => (req, res, next) => {
|
|
|
37
42
|
res.header('Access-Control-Allow-Credentials', true);
|
|
38
43
|
// res.header('Access-Control-Allow-Origin', 'http://localhost:8081');
|
|
39
44
|
res.header('Access-Control-Allow-Origin', '*');
|
|
40
|
-
res.header('Access-Control-Allow-Methods', 'GET,HEAD,OPTIONS,
|
|
45
|
+
res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,HEAD,PATCH,OPTIONS,COPY,LINK,UNLINK,PURGE');
|
|
41
46
|
// res.header(
|
|
42
47
|
// 'Access-Control-Allow-Headers',
|
|
43
48
|
// 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
|
|
@@ -57,13 +62,21 @@ const composeRoute = function (file) {
|
|
|
57
62
|
delete require.cache[require.resolve(file)];
|
|
58
63
|
const fileObject = require(path.resolve(__dirname, file));
|
|
59
64
|
|
|
60
|
-
log.info(colors.
|
|
65
|
+
log.info(colors.green(`Mockfile ${++fileCount}: `), file, colors.yellow('all API URL is follows: '));
|
|
61
66
|
Object.keys(fileObject).forEach(item => {
|
|
62
|
-
|
|
67
|
+
let reqMethod = 'get',
|
|
68
|
+
reqUrl = item;
|
|
69
|
+
// 支持(GET|POST|PUT|DELETE|HEAD|PATCH|OPTIONS|COPY|LINK|UNLINK|PURGE)常用方法, 默认GET请求
|
|
70
|
+
if (methodRegExp.exec(item)) {
|
|
71
|
+
const [, method, url] = methodRegExp.exec(item);
|
|
72
|
+
reqMethod = method.toLowerCase();
|
|
73
|
+
reqUrl = url;
|
|
74
|
+
}
|
|
75
|
+
log.info(colors.yellow(`path ${++count}: `), item, colors.blue(typeof fileObject[item]));
|
|
63
76
|
if (typeof fileObject[item] === 'function') {
|
|
64
|
-
app
|
|
77
|
+
app[reqMethod](reqUrl, fileObject[item]);
|
|
65
78
|
} else if (typeof fileObject[item] === 'object') {
|
|
66
|
-
app
|
|
79
|
+
app[reqMethod](reqUrl, function (req, res) {
|
|
67
80
|
res.json(fileObject[item]);
|
|
68
81
|
});
|
|
69
82
|
}
|
|
@@ -74,21 +87,26 @@ const composeRoute = function (file) {
|
|
|
74
87
|
* @param {*}
|
|
75
88
|
* @return {*}
|
|
76
89
|
*/
|
|
77
|
-
const parseMockFiles = function (specialDir = '../mock') {
|
|
90
|
+
const parseMockFiles = function (specialDir = '../mock', isRootDir = true) {
|
|
78
91
|
const files = fs.readdirSync(path.resolve(__dirname, specialDir), { withFileTypes: true });
|
|
79
92
|
for (let index = 0; index < files.length; index++) {
|
|
80
93
|
const el = files[index];
|
|
81
94
|
// 过滤目录
|
|
82
|
-
if (!el.isFile()
|
|
95
|
+
if (!el.isFile()) {
|
|
96
|
+
parseMockFiles(`${specialDir}/${el.name}`, false);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!el.name.endsWith('.js')) {
|
|
83
100
|
continue;
|
|
84
101
|
}
|
|
85
102
|
composeRoute(`${specialDir}/${el.name}`);
|
|
86
103
|
}
|
|
87
104
|
|
|
88
|
-
|
|
105
|
+
if (isRootDir) {
|
|
106
|
+
log.info(chalk.hex('#ce5b34bd')(`${files.length} mock file are parsed in total.`));
|
|
107
|
+
}
|
|
89
108
|
};
|
|
90
109
|
app.use(crossDomain());
|
|
91
|
-
|
|
92
110
|
if (process.env.SPECIFIED_FILE) {
|
|
93
111
|
composeRoute(process.env.SPECIFIED_FILE);
|
|
94
112
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mock-service-cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "🦅 Local mock server",
|
|
5
5
|
"main": "./lib/mockServer.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node ./bin/mock-service-cli",
|
|
11
|
-
"unit
|
|
11
|
+
"test:unit": "tap --reporter=spec test/*.test.js",
|
|
12
12
|
"test": "tap --cov --coverage-report=lcov --reporter=spec test/*.test.js ",
|
|
13
|
-
"test-watch": "tap --reporter=spec --watch test/*.test.js",
|
|
14
13
|
"coverage": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls -v",
|
|
14
|
+
"test-watch": "tap --reporter=spec --watch test/*.test.js",
|
|
15
15
|
"fix": "eslint --ext .js,.vue,.css --fix",
|
|
16
16
|
"prettier": "prettier -c --write \"**/*.{ts,js,jsx,css,less,scss,json}\"",
|
|
17
17
|
"release:prerelease": "standard-version --prerelease",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"doc"
|
|
27
27
|
],
|
|
28
28
|
"engines": {
|
|
29
|
-
"node": ">=
|
|
29
|
+
"node": ">=14"
|
|
30
30
|
},
|
|
31
31
|
"author": "chendq <deqiaochen@gmail.com>",
|
|
32
32
|
"keywords": [
|
|
@@ -45,16 +45,15 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"colors": "^1.4.0",
|
|
47
47
|
"deasync": "^0.1.23",
|
|
48
|
+
"express": "^4.17.1",
|
|
48
49
|
"minimist": "^1.2.5",
|
|
49
50
|
"nodemon": "^2.0.14",
|
|
50
|
-
"express": "^4.17.1",
|
|
51
51
|
"portfinder": "^1.0.28"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@commitlint/cli": "^8.3.5",
|
|
55
55
|
"@commitlint/config-conventional": "^8.3.4",
|
|
56
56
|
"babel-eslint": "^10.1.0",
|
|
57
|
-
"coveralls": "^3.1.0",
|
|
58
57
|
"eslint": "^7.0.0",
|
|
59
58
|
"eslint-config-populist": "^4.2.0",
|
|
60
59
|
"eslint-plugin-mocha": "^9.0.0",
|
|
@@ -64,6 +63,9 @@
|
|
|
64
63
|
"standard-version": "^8.0.0",
|
|
65
64
|
"tap": "^15.0.10"
|
|
66
65
|
},
|
|
66
|
+
"tap": {
|
|
67
|
+
"check-coverage": false
|
|
68
|
+
},
|
|
67
69
|
"husky": {
|
|
68
70
|
"hooks": {
|
|
69
71
|
"pre-commit": "lint-staged",
|