whistle.mock-plugins 1.4.0-beta.0 → 1.4.0-beta.3
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/VERSION.md +21 -0
- package/app/cgi-bin/interfaces.js +2 -0
- package/app/cgi-bin/stats.js +22 -12
- package/app/public/index.html +1 -1
- package/app/public/js/11.index.js +2 -0
- package/app/public/js/11.index.js.LICENSE.txt +5 -0
- package/app/public/js/296.index.js +2 -0
- package/app/public/js/296.index.js.LICENSE.txt +12 -0
- package/app/public/js/704.index.js +2 -0
- package/app/public/js/704.index.js.LICENSE.txt +1 -0
- package/app/public/js/807.index.js +2 -0
- package/app/public/js/807.index.js.LICENSE.txt +1 -0
- package/app/public/js/810.index.js +2 -0
- package/app/public/js/810.index.js.LICENSE.txt +53 -0
- package/app/public/js/index.js +1 -1
- package/app/public/js/index.js.LICENSE.txt +0 -185
- package/package.json +9 -2
- package/API.md +0 -247
- package/COLUMN_RESIZE_IMPLEMENTATION.md +0 -162
- package/FEATURE_ENHANCEMENT.md +0 -157
- package/TEST_GUIDE.md +0 -156
- package/data/features.json +0 -1
- package/data/interfaces.json +0 -1
- package/index.html +0 -52
- package/initialize.js +0 -32
- package/public/bundle.js +0 -2
- package/public/bundle.js.LICENSE.txt +0 -38
- package/public/index.html +0 -1
- package/public/plugin.mock-plugin.html +0 -14
- package/rules.txt +0 -22
- package/test/api-error.test.js +0 -29
- package/test/webdav-sync.test.js +0 -428
- package/ui/src/App.css +0 -173
- package/ui/src/components/AppLayout.js +0 -407
- package/ui/src/components/FeatureCard.js +0 -58
- package/ui/src/components/KeyboardShortcutsHelp.js +0 -58
- package/ui/src/components/Layout.js +0 -94
- package/ui/src/components/MainNav.js +0 -42
- package/ui/src/components/PageContainer.js +0 -16
- package/ui/src/components/VersionModal.js +0 -99
- package/ui/src/components/WebDavSyncModal.js +0 -516
- package/ui/src/components/interface-management/DataManagementDrawer.js +0 -115
- package/ui/src/components/interface-management/DataManagementModal.js +0 -110
- package/ui/src/components/interface-management/InterfaceTestModal.js +0 -313
- package/ui/src/components/interface-management/PreviewModal.js +0 -48
- package/ui/src/components/interface-management/README.md +0 -184
- package/ui/src/components/interface-management/RealResponseRecorder.js +0 -165
- package/ui/src/components/interface-management/ResponseContentEditor.js +0 -645
- package/ui/src/components/interface-management/constants.js +0 -36
- package/ui/src/components/interface-management/index.js +0 -7
- package/ui/src/components/interface-management/utils.js +0 -103
- package/ui/src/hooks/useKeyboardShortcuts.js +0 -99
- package/ui/src/index.html +0 -14
- package/ui/src/index.js +0 -50
- package/ui/src/pages/InterfaceManagementV2.js +0 -2351
- package/ui/src/pages/MockDataV2.js +0 -1122
- package/ui/src/pages/Settings.js +0 -341
- package/ui/src/pages/Sniffer.js +0 -521
- package/ui/src/pages/Stats.js +0 -288
- package/ui/src/services/del_api.js +0 -192
- package/ui/src/styles/app-layout.css +0 -373
- package/ui/src/styles/cyber-theme.css +0 -1234
- package/ui/src/styles/earth-theme.css +0 -618
- package/ui/src/styles/global.css +0 -224
- package/ui/src/styles/interface-management.css +0 -1321
- package/ui/src/styles/mock-data.css +0 -1185
- package/ui/src/styles/settings.css +0 -252
- package/ui/src/styles/version-modal.css +0 -116
- package/ui/src/styles/webdav-sync.css +0 -408
- package/ui/src/utils/api-error.js +0 -57
- package/webpack.config.js +0 -54
package/VERSION.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# 🔄 版本更新记录
|
|
2
2
|
|
|
3
|
+
## 1.4.0-beta.3(2026-10-13)
|
|
4
|
+
|
|
5
|
+
- 响应下拉选择后直接切换默认响应并立即生效,无需额外保存接口;保留未保存草稿提示及失败回滚。
|
|
6
|
+
- 恢复默认布局移到工作台页头的布局菜单,收起模块树和窄屏下也可使用。
|
|
7
|
+
- 构建自动清理旧的前端分包,避免安装包包含过期产物。
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## 1.4.0-beta.2(2026-10-13)
|
|
11
|
+
|
|
12
|
+
- UI 3.0、新旧界面切换、工作台独立滚动与恢复默认布局反馈的 beta 发布。
|
|
13
|
+
- 与待审批 beta.1 功能一致,重新构建为独立版本;两个界面继续共用原有数据。
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## 1.4.0-beta.1(2026-10-13,待发布)
|
|
17
|
+
|
|
18
|
+
- 统一顶部导航、页面层级和四套主题,增加布局偏好与恢复入口。
|
|
19
|
+
- 接口页升级为模块 / 接口列表 / 详情三栏工作台;支持统一编辑、多响应管理、批量表格列设置和未保存草稿保护。
|
|
20
|
+
- 重整模块、嗅探、统计、设置页面;嗅探支持完整历史与追加响应,统计统一日期 / URL 筛选。
|
|
21
|
+
- 详细验收记录见仓库 `docs/ui-3.0-todo.md`。
|
|
22
|
+
|
|
23
|
+
|
|
3
24
|
## v1.4.0-beta.0
|
|
4
25
|
|
|
5
26
|
### ✨ Feature
|
|
@@ -191,6 +191,7 @@ module.exports = function(req, res) {
|
|
|
191
191
|
activeResponseId: interfaceData.activeResponseId !== undefined ? interfaceData.activeResponseId : interfacesData.interfaces[index].activeResponseId,
|
|
192
192
|
targetUrl: interfaceData.targetUrl,
|
|
193
193
|
customHeaders: interfaceData.customHeaders || {},
|
|
194
|
+
headers: interfaceData.headers || {},
|
|
194
195
|
paramMatchers: interfaceData.paramMatchers || [],
|
|
195
196
|
filePath: interfaceData.filePath,
|
|
196
197
|
httpStatus: interfaceData.httpStatus || 200,
|
|
@@ -226,6 +227,7 @@ module.exports = function(req, res) {
|
|
|
226
227
|
activeResponseId: interfaceData.activeResponseId || null,
|
|
227
228
|
targetUrl: interfaceData.targetUrl || '',
|
|
228
229
|
customHeaders: interfaceData.customHeaders || {},
|
|
230
|
+
headers: interfaceData.headers || {},
|
|
229
231
|
paramMatchers: interfaceData.paramMatchers || [],
|
|
230
232
|
filePath: interfaceData.filePath || '',
|
|
231
233
|
httpStatus: interfaceData.httpStatus || 200,
|
package/app/cgi-bin/stats.js
CHANGED
|
@@ -14,18 +14,30 @@ module.exports = (req, res) => {
|
|
|
14
14
|
const type = req.query.type || 'overview';
|
|
15
15
|
|
|
16
16
|
if (!fs.existsSync(LOGS_FILE)) {
|
|
17
|
-
return res.json({ code: 0, data: { logs: [],
|
|
17
|
+
return res.json({ code: 0, data: { logs: [], timeline: {}, topInterfaces: [], topFeatures: [] } });
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const logsData = fs.readJsonSync(LOGS_FILE);
|
|
21
21
|
const logs = logsData.logs || [];
|
|
22
22
|
|
|
23
|
-
// 只取最近 7 天的日志做统计(避免数据量过大)
|
|
24
23
|
const now = new Date();
|
|
25
|
-
const
|
|
24
|
+
const dayKey = value => {
|
|
25
|
+
const date = new Date(value);
|
|
26
|
+
return `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`;
|
|
27
|
+
};
|
|
28
|
+
const parseDay = value => {
|
|
29
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value || '')) return null;
|
|
30
|
+
const date = new Date(`${value}T00:00:00`);
|
|
31
|
+
return Number.isFinite(date.getTime()) && dayKey(date) === value ? date : null;
|
|
32
|
+
};
|
|
33
|
+
const start = req.query.startDate ? parseDay(req.query.startDate) : new Date(now.getFullYear(),now.getMonth(),now.getDate()-6);
|
|
34
|
+
const end = req.query.endDate ? parseDay(req.query.endDate) : new Date(now.getFullYear(),now.getMonth(),now.getDate());
|
|
35
|
+
if (!start || !end || start > end || end-start > 366*86400000) return res.status(400).json({code:400,message:'请选择有效的日期范围(最多 366 天)'});
|
|
36
|
+
const endExclusive = new Date(end); endExclusive.setDate(endExclusive.getDate()+1);
|
|
37
|
+
const filterUrl = String(req.query.url || '').toLowerCase();
|
|
26
38
|
const recentLogs = logs.filter(log => {
|
|
27
39
|
const t = new Date(log.timestamp);
|
|
28
|
-
return t >=
|
|
40
|
+
return t >= start && t < endExclusive && (!filterUrl || String(log.url || '').toLowerCase().includes(filterUrl));
|
|
29
41
|
});
|
|
30
42
|
|
|
31
43
|
// 分离命中和未命中
|
|
@@ -69,7 +81,7 @@ module.exports = (req, res) => {
|
|
|
69
81
|
const id = log.interfaceId || log.interfaceName || 'unknown';
|
|
70
82
|
const name = log.interfaceName || id;
|
|
71
83
|
if (!interfaceHitMap[id]) {
|
|
72
|
-
interfaceHitMap[id] = { id, name, count: 0 };
|
|
84
|
+
interfaceHitMap[id] = { id, name, featureId: log.featureId, count: 0 };
|
|
73
85
|
}
|
|
74
86
|
interfaceHitMap[id].count++;
|
|
75
87
|
});
|
|
@@ -80,7 +92,7 @@ module.exports = (req, res) => {
|
|
|
80
92
|
// Top 10 命中功能模块
|
|
81
93
|
const featureHitMap = {};
|
|
82
94
|
hitLogs.forEach(log => {
|
|
83
|
-
const id = log.
|
|
95
|
+
const id = log.featureId || log.featureName || 'unknown';
|
|
84
96
|
const name = log.featureName || '未分类';
|
|
85
97
|
if (!featureHitMap[id]) {
|
|
86
98
|
featureHitMap[id] = { id, name, count: 0 };
|
|
@@ -98,13 +110,11 @@ module.exports = (req, res) => {
|
|
|
98
110
|
case 'timeline': {
|
|
99
111
|
// 最近 7 天每天的命中数
|
|
100
112
|
const timeline = {};
|
|
101
|
-
for (let
|
|
102
|
-
|
|
103
|
-
const key = d.toISOString().slice(0, 10);
|
|
104
|
-
timeline[key] = 0;
|
|
113
|
+
for (let date = new Date(start); date <= end; date.setDate(date.getDate()+1)) {
|
|
114
|
+
timeline[dayKey(date)] = 0;
|
|
105
115
|
}
|
|
106
116
|
hitLogs.forEach(log => {
|
|
107
|
-
const key =
|
|
117
|
+
const key = dayKey(log.timestamp);
|
|
108
118
|
if (timeline[key] !== undefined) {
|
|
109
119
|
timeline[key]++;
|
|
110
120
|
}
|
|
@@ -120,7 +130,7 @@ module.exports = (req, res) => {
|
|
|
120
130
|
|
|
121
131
|
if (filterDate) {
|
|
122
132
|
filteredLogs = filteredLogs.filter(log => {
|
|
123
|
-
const logDate =
|
|
133
|
+
const logDate = dayKey(log.timestamp);
|
|
124
134
|
return logDate === filterDate;
|
|
125
135
|
});
|
|
126
136
|
}
|
package/app/public/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Whistle Mock Plugin</title><
|
|
1
|
+
<!doctype html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Whistle Mock Plugin</title><script defer="defer" src="/js/index.js"></script></head><body><div id="root"></div></body></html>
|