aloy-mock 1.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.
Files changed (40) hide show
  1. package/README.md +2 -0
  2. package/app.js +65 -0
  3. package/bin/m2 +22 -0
  4. package/bin/www +91 -0
  5. package/mock/_alive/index.js +8 -0
  6. package/mock/cgi-bin/get-data/index.js +8 -0
  7. package/mock/cgi-bin/rules/select/index.js +8 -0
  8. package/mock/cgi-bin/rules/unselect/index.js +8 -0
  9. package/mock/favicon.ico/index.js +8 -0
  10. package/mock/index.js +8 -0
  11. package/mock/javascripts/jshint/2.13.4/jshint.min.js/index.js +8 -0
  12. package/mock/jian-j/csp-task/external/trade/appoint/getTradeAppointList/index.js +8 -0
  13. package/mock/jian-j/eva-training/external/mock/task/list/index.js +69 -0
  14. package/mock/jian-j/eva-training/external/practice/public/stylesheets/style.css/index.js +8 -0
  15. package/mock/jian-j/eva-training/external/practice/task/create/index.js +9 -0
  16. package/mock/jian-j/eva-training/external/practice/task/detail/index.js +65 -0
  17. package/mock/jian-j/eva-training/external/practice/task/list/index.js +33 -0
  18. package/mock/jian-j/eva-training/external/practice/task/test/index.js +7 -0
  19. package/mock/jian-j/eva-training/external/task/audit/list/index.js +49 -0
  20. package/mock/jian-j/eva-training/external/task/audit/mock/detail/index.js +17 -0
  21. package/mock/jian-j/eva-training/external/task/audit/submit/index.js +8 -0
  22. package/mock/jian-j/favicon.ico/index.js +8 -0
  23. package/mock/jian-j/jian-service/evaluate/arrive/index.js +8 -0
  24. package/mock/jian-j/jian-service/evaluate/forward/index.js +8 -0
  25. package/mock/jian-j/jian-service/evaluate/start/index.js +8 -0
  26. package/mock/jian-j/stylesheets/style.css/index.js +8 -0
  27. package/nodemon.json +17 -0
  28. package/package.json +25 -0
  29. package/public/javascripts/codemirror/5.65.5/codemirror.min.js +2 -0
  30. package/public/javascripts/codemirror/5.65.5/javascript-lint.min.js +2 -0
  31. package/public/javascripts/codemirror/5.65.5/javascript.min.js +2 -0
  32. package/public/javascripts/codemirror/5.65.5/lint.min.js +2 -0
  33. package/public/javascripts/jshint/2.13.4/jshint.min.js +2 -0
  34. package/public/stylesheets/codemirror/5.65.5/codemirror.css +339 -0
  35. package/public/stylesheets/codemirror/5.65.5/lint.css +81 -0
  36. package/public/stylesheets/style.css +31 -0
  37. package/routes/index.js +96 -0
  38. package/views/error.jade +6 -0
  39. package/views/index.jade +83 -0
  40. package/views/layout.jade +9 -0
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # mock服务
2
+
package/app.js ADDED
@@ -0,0 +1,65 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const express = require('express');
4
+ const createError = require('http-errors');
5
+ const cookieParser = require('cookie-parser');
6
+ const logger = require('morgan');
7
+ const indexRouter = require('./routes/index');
8
+ const app = express();
9
+
10
+ function setGloalVars(req, res, next) {
11
+ res.locals.PUBLIC_PATH = 'http://127.0.0.1:' + app.locals.settings.port;
12
+ res.locals.HANDLE_TYPE = '__MOCK_SERVER_NAVIGATE_SAVE__';
13
+ next();
14
+ }
15
+
16
+ app.all('*', function (req, res, next) {
17
+ const origin = req.headers.origin;
18
+ console.log('app.getPOrt: ', app.locals.settings.port)
19
+ fs.mkdirSync(path.resolve(__dirname, `./mock/${req.path}`), { recursive: true });
20
+ if (/guazi(?:-cloud|-apps)?\.com/.test(origin)) {
21
+ res.header("Access-Control-Allow-Origin", origin); //允许的访问域
22
+ }
23
+ res.header("Access-Control-Allow-Credentials", "true"); //服务端允许携带cookie
24
+ res.header("Access-Control-Allow-Headers", "*"); //访问头
25
+ res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); //访问方法
26
+ res.header("Content-Security-Policy", " upgrade-insecure-requests");
27
+ res.header("X-Powered-By", ' 3.2.1');
28
+ if (req.method == 'OPTIONS') {
29
+ res.header("Access-Control-Max-Age", 86400);
30
+ res.sendStatus(204); //让options请求快速返回.
31
+ }
32
+ else {
33
+ next();
34
+ }
35
+ });
36
+
37
+ app.set('views', path.join(__dirname, 'views'));
38
+ app.set('view engine', 'jade');
39
+
40
+ app.use(setGloalVars);
41
+ app.use(logger('dev'));
42
+ app.use(express.json());
43
+ app.use(express.urlencoded({ extended: false }));
44
+ app.use(cookieParser());
45
+ app.use(express.static(path.join(__dirname, 'public')));
46
+
47
+ app.use('/', indexRouter);
48
+
49
+ // catch 404 and forward to error handler
50
+ app.use(function(req, res, next) {
51
+ next(createError(404));
52
+ });
53
+
54
+ // error handler
55
+ app.use(function(err, req, res, next) {
56
+ // set locals, only providing error in development
57
+ res.locals.message = err.message;
58
+ res.locals.error = req.app.get('env') === 'development' ? err : {};
59
+
60
+ // render the error page
61
+ res.status(err.status || 500);
62
+ res.render('error');
63
+ });
64
+
65
+ module.exports = app;
package/bin/m2 ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ const { exec } = require('child_process');
3
+ // 获取命令行参数,除了第一个参数(即 node 的路径)
4
+ const args = process.argv.slice(2);
5
+ console.log('m2:args: ', args);
6
+ // 执行 package.json 中的 scripts 命令
7
+ switch (args[0]) {
8
+ case 'start':
9
+ exec('npm run start', (error, stdout, stderr) => {
10
+ if (error) {
11
+ console.error(`exec error: ${error}`);
12
+ return;
13
+ }
14
+ console.log(`stdout: ${stdout}`);
15
+ console.error(`stderr: ${stderr}`);
16
+ });
17
+ break;
18
+ // 可以添加更多的 case 来处理不同的 scripts 命令
19
+ default:
20
+ console.log('Unknown command');
21
+ process.exit(1);
22
+ }
package/bin/www ADDED
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Module dependencies.
5
+ */
6
+
7
+ var app = require('../app');
8
+ var debug = require('debug')('code-coverage-middleware:server');
9
+ var http = require('http');
10
+
11
+ /**
12
+ * Get port from environment and store in Express.
13
+ */
14
+ var args = process.argv.slice(2);
15
+ var port = normalizePort(process.env.PORT || '80')
16
+ console.log("process.env.PORT-------------->", process.env.PORT, '-->args: ', args, process.argv);
17
+ app.set('port', port);
18
+
19
+ /**
20
+ * Create HTTP server.
21
+ */
22
+
23
+ var server = http.createServer(app);
24
+
25
+ /**
26
+ * Listen on provided port, on all network interfaces.
27
+ */
28
+
29
+ server.listen(port);
30
+ server.on('error', onError);
31
+ server.on('listening', onListening);
32
+
33
+ /**
34
+ * Normalize a port into a number, string, or false.
35
+ */
36
+
37
+ function normalizePort(val) {
38
+ var port = parseInt(val, 10);
39
+
40
+ if (isNaN(port)) {
41
+ // named pipe
42
+ return val;
43
+ }
44
+
45
+ if (port >= 0) {
46
+ // port number
47
+ return port;
48
+ }
49
+
50
+ return false;
51
+ }
52
+
53
+ /**
54
+ * Event listener for HTTP server "error" event.
55
+ */
56
+
57
+ function onError(error) {
58
+ if (error.syscall !== 'listen') {
59
+ throw error;
60
+ }
61
+
62
+ var bind = typeof port === 'string'
63
+ ? 'Pipe ' + port
64
+ : 'Port ' + port;
65
+
66
+ // handle specific listen errors with friendly messages
67
+ switch (error.code) {
68
+ case 'EACCES':
69
+ console.log(bind + ' requires elevated privileges');
70
+ process.exit(1);
71
+ break;
72
+ case 'EADDRINUSE':
73
+ console.log(bind + ' is already in use');
74
+ process.exit(1);
75
+ break;
76
+ default:
77
+ throw error;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Event listener for HTTP server "listening" event.
83
+ */
84
+
85
+ function onListening() {
86
+ var addr = server.address();
87
+ var bind = typeof addr === 'string'
88
+ ? 'pipe ' + addr
89
+ : 'port ' + addr.port;
90
+ debug('Listening on ' + bind);
91
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
package/mock/index.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,69 @@
1
+ module.exports = (param) => {
2
+ const { tableType, pageSize = 10, currentPage = 1 } = param.query || {};
3
+ const unEvaluateTotal = 41;
4
+ const unPubTotal = 39;
5
+ const mockedTotal = 2;
6
+ const totals = {
7
+ un_evaluate: unEvaluateTotal,
8
+ un_pub: unPubTotal,
9
+ mocked: mockedTotal,
10
+ };
11
+ const total = totals[tableType] || 21;
12
+ const totalPage = Math.ceil(total/pageSize);
13
+ const taskStatusDesc = {
14
+ un_evaluate: {
15
+ label: "待评估",
16
+ buttonInfo: {
17
+ "showForward": 1, // 展示“开始前往”按钮
18
+ },
19
+ },
20
+ un_pub: {
21
+ label: "待上架",
22
+ buttonInfo: {
23
+ "showUpdateReport": 1, // 展示“提交结果”按钮
24
+ },
25
+ },
26
+ mocked: {
27
+ label: "已实战",
28
+ buttonInfo: {
29
+ "showQueryReport": 1 // 展示“查看报告”按钮
30
+ },
31
+ },
32
+ };
33
+ const { label, buttonInfo } = taskStatusDesc[tableType] || {};
34
+ return {
35
+ code: 0,
36
+ data: {
37
+ total,
38
+ currentPage,
39
+ pageSize,
40
+ remindRemark: "通过门槛:7天内完成5个练习工单 当前进度:2/5",
41
+ // emptyRemind: tableType === 'mocked' ? '当前无实战工单,完成练习工单任务后可由师父指派实战工单' : '',
42
+ unEvaluateTotal, // 待评估总数
43
+ unPubTotal, // 待上架总数;
44
+ mockedTotal, // 已实战总数
45
+ list: Array.from({length: currentPage < totalPage ? pageSize : total % pageSize }, (_, i) => {
46
+ const index = (currentPage - 1) * pageSize + i + 1;
47
+ return {
48
+ "clueId": `1234567_${index}`, // 车源号
49
+ "carTitle": `奥迪 A${index}`, // 车型信息
50
+ "carCondition": `2015年上牌 ${index}万公里`,
51
+ "evaluateAddress": "北京通州区物资学院", // 地址信息
52
+ "status": tableType,
53
+ "statusDesc": label, // 右上角状态
54
+ "evaluateAddressLngLat": "116.439914,40.004528", // 坐标, 查看点位时使用
55
+ "evaluateTime": "2024-12-12 12:00:00", // 预约评估时间
56
+ buttonInfo,
57
+ // "buttonInfo": { // 按钮详情
58
+ // "showForward": 1, // 展示“开始前往”按钮
59
+ // "showArrive": 1, // 展示“到达”按钮
60
+ // "showEvaluate": 1, // 展示“开始评估“按钮
61
+ "showUpdateReport": 1, // 展示“提交结果”按钮
62
+ // "showQueryReport": 1 // 展示“查看报告”按钮
63
+ // }
64
+ }
65
+ }),
66
+ },
67
+ }
68
+ };
69
+
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ taskId: '1',
6
+ },
7
+ message: '',
8
+ }
9
+ }
@@ -0,0 +1,65 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ taskId: '4',
6
+ clueId: '123456',
7
+ currentModule: 'selfIntroduction',
8
+ steps: [{ //自我介绍部分
9
+ stepName: '第一步',
10
+ "moduleType": "selfIntroduction",
11
+ "title": "自我介绍",
12
+ "scriptContent": "这里是自我介绍话术内容示例", //重点说明,话术
13
+ "url": "https://example.com/self-introduction-recording", //录音url
14
+ "asrContent": "对应的asr内容示例", //录音asr内容
15
+ "reason": "", //驳回内容,备注
16
+ "auditStatusDesc": "驳回", //审核结果描述
17
+ "auditStatus":"reject" //审核结果
18
+ },
19
+ { //隐私告知
20
+ stepName: '第二步',
21
+ "moduleType": "privacyNotice",
22
+ "title": "隐私告知",
23
+ "scriptContent": "隐私告知话术内容示例",
24
+ "url": "https://example.com/privacy-notice-recording",
25
+ "asrContent": "对应asr内容示例",
26
+ "reason": "",
27
+ "auditStatusDesc": "驳回",
28
+ "auditStatus":"reject"
29
+ },
30
+ { //实车检测
31
+ stepName: '第三步',
32
+ "moduleType": "evaluateCheck",
33
+ "title": "实车检测",
34
+ "scriptContent": "实车检测话术内容示例",
35
+ "reportUrl": "https://example.com/evaluate-check-report",
36
+ "reason": "",
37
+ "auditStatusDesc": "驳回",
38
+ "auditStatus":"reject"
39
+ },
40
+ { //报告解读
41
+ stepName: '第四步',
42
+ "moduleType": "reportInterpretation",
43
+ "title": "报告解读",
44
+ "scriptContent": "报告解读话术内容示例",
45
+ "url": "https://example.com/report-interpretation-recording",
46
+ "asrContent": "对应asr内容示例",
47
+ "reason": "",
48
+ "auditStatusDesc": "驳回",
49
+ "auditStatus":"reject"
50
+ },
51
+ { //交易铺垫
52
+ stepName: '第五步',
53
+ "moduleType": "transactionPreparation",
54
+ "title": "交易铺垫",
55
+ "scriptContent": "交易铺垫话术内容示例",
56
+ "url": "https://example.com/transaction-preparation-recording",
57
+ "asrContent": "对应asr内容示例",
58
+ "reason": "",
59
+ "auditStatusDesc": "驳回",
60
+ "auditStatus":"reject"
61
+ }]
62
+ }
63
+
64
+ }
65
+ };
@@ -0,0 +1,33 @@
1
+ module.exports = (param) => {
2
+ const { pageSize = 10, currentPage = 1 } = param.query || {};
3
+ const total = 21;
4
+ const totalPage = Math.ceil(total/pageSize);
5
+ const taskStatus = ['un_complete', 'un_open', 'completed'];
6
+ const taskStatusDesc = ['未完成', '未开启', '已完成'];
7
+ return {
8
+ code: 0,
9
+ data: {
10
+ total,
11
+ currentPage,
12
+ pageSize,
13
+ remindRemark: "7天内完成5个练习工单 当前进度:1/51",
14
+ showCreate: 1,
15
+ list: Array.from({length: currentPage < totalPage ? pageSize : total % pageSize }, (_, i) => {
16
+ const index = (currentPage - 1) * pageSize + i + 1;
17
+ const status = taskStatus[index%3];
18
+ const statusDesc = taskStatusDesc[index%3];
19
+ return {
20
+ "taskId" : "123445678888_" + index, // 工单id, 唯一值
21
+ "taskTitle": "新手工单" + index, // 标题
22
+ "taskStatus": status, // 工单状态, un_complete 未完成, un_open 未开启, completed 已完成
23
+ "taskStatusDesc": statusDesc,
24
+ "sopStatusDesc": "不通过", // sop完成状态
25
+ "sopRejectReason": "未按照标准执行", // sop驳回原因,驳回状态存在
26
+ "evaluateCheckStatusDesc": "不通过", // 检车完成状态
27
+ "evaluateRejectReason": "拆拔不到位", // 检车驳回原因, 驳回状态存在
28
+ "clueId": 12345661 // 车源号
29
+ }
30
+ }),
31
+ },
32
+ };
33
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "code": 0,
3
+ "data": {
4
+ "name": "1333333"
5
+ },
6
+ "message": ""
7
+ }
@@ -0,0 +1,49 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ const { pageSize = 10, currentPage = 1, taskType, tableType } = query || {};
3
+ const taskStatus = ['reject', 'un_audit', 'pass'];
4
+ const taskStatusDesc = ['驳回', '未审批', '通过'];
5
+ const titles = {
6
+ practice: {
7
+ title: '新手工单',
8
+ totals: {
9
+ audited: 12,
10
+ un_audit: 16,
11
+ },
12
+ },
13
+ mock: {
14
+ title: '实战工单',
15
+ totals: {
16
+ audited: 12,
17
+ un_audit: 26,
18
+ },
19
+ showMaster: true,
20
+ }
21
+ }
22
+ const { title, showMaster, totals } = titles[taskType];
23
+ const total = totals[tableType];
24
+ const totalPage = Math.ceil(total/pageSize);
25
+ return {
26
+ code: 0,
27
+ data: {
28
+ total,
29
+ currentPage,
30
+ pageSize,
31
+ list: Array.from({length: currentPage < totalPage ? pageSize : total % pageSize }, (_, i) => {
32
+ const index = (currentPage - 1) * pageSize + i + 1;
33
+ const status = taskStatus[index%3];
34
+ const statusDesc = taskStatusDesc[index%3];
35
+ return {
36
+ "taskId" : `123445678888-${index}`, // 工单id, 唯一值
37
+ "clueId": 11234343 + index, // 车源号
38
+ "taskTitle": title + index, // 标题
39
+ "auditStatus": status, // 工单状态, reject 驳回, un_audit, 未审批, pass 通过
40
+ "auditStatusDesc": statusDesc,
41
+ "auditRejectReason": "未按照标准执行", // 驳回原因, 驳回状态存在
42
+ "evaluatorName": "评估师", // 评估师名称
43
+ "masterName": showMaster ? "许师傅" : '' // 师傅名称
44
+ }
45
+ }),
46
+ },
47
+ }
48
+ }
49
+
@@ -0,0 +1,17 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ "taskId" : "123445678888", // 工单id, 唯一值
6
+ "auditStatus": 'un_audit',
7
+ "auditRejectReason": '',
8
+ "clueId": 11234343, // 实战工单车源号, 徒弟的工单
9
+ "realClueId": 2323443434, // 真实工单车源号, 师傅的工单
10
+ "mockReportUrl": "https://che-web.guazi.com/#/newReport?version_tag=check&report_type=check&clue_id=143142659", // 徒弟查看报告链接
11
+ "realReportUrl": "https://che-web.guazi.com/#/newReport?version_tag=check&report_type=check&clue_id=143142659", // 师傅的报告链接
12
+ "reportDiffUrl": "https://bm-task.guazi.com/report-contrast?clue_id=143040009&left_check_id=0&right_check_id=5579979" // 报告比对url
13
+ },
14
+ message: '',
15
+ }
16
+ }
17
+
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = ({ method, query, params, body }) => {
2
+ return {
3
+ code: 0,
4
+ data: {
5
+ },
6
+ message: '',
7
+ }
8
+ }
package/nodemon.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "restartable": "rs",
3
+ "ignore": [
4
+ ".git",
5
+ "node_modules/**/node_modules",
6
+ "public/"
7
+ ],
8
+ "watch": [
9
+ "./"
10
+ ],
11
+ "exec": "NODE_ENV=development node ./bin/www",
12
+ "events": [
13
+ "change"
14
+ ],
15
+ "log": true,
16
+ "legacy-watch": false
17
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "aloy-mock",
3
+ "version": "1.0.0",
4
+ "bin": {
5
+ "m2": "./bin/m2"
6
+ },
7
+ "scripts": {
8
+ "preinstall": "chmod +x ./bin/cli",
9
+ "start": "nodemon"
10
+ },
11
+ "dependencies": {
12
+ "body-parser": "^1.20.3",
13
+ "cookie-parser": "~1.4.4",
14
+ "debug": "~2.6.9",
15
+ "express": "~4.16.1",
16
+ "http-errors": "~1.6.3",
17
+ "jade": "~1.11.0",
18
+ "morgan": "~1.9.1"
19
+ },
20
+ "devDependencies": {
21
+ "async": "*",
22
+ "nodemon": "^3.1.9"
23
+ },
24
+ "license": "MIT"
25
+ }