whistle.mock-plugins 1.3.1 → 1.4.0-beta.2

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 (70) hide show
  1. package/VERSION.md +29 -0
  2. package/app/cgi-bin/interfaces.js +2 -0
  3. package/app/cgi-bin/settings.js +1 -0
  4. package/app/cgi-bin/stats.js +22 -12
  5. package/app/cgi-bin/webdav.js +56 -0
  6. package/app/public/index.html +1 -1
  7. package/app/public/js/11.index.js +2 -0
  8. package/app/public/js/11.index.js.LICENSE.txt +5 -0
  9. package/app/public/js/704.index.js +2 -0
  10. package/app/public/js/704.index.js.LICENSE.txt +1 -0
  11. package/app/public/js/798.index.js +2 -0
  12. package/app/public/js/798.index.js.LICENSE.txt +53 -0
  13. package/app/public/js/807.index.js +2 -0
  14. package/app/public/js/807.index.js.LICENSE.txt +1 -0
  15. package/app/public/js/968.index.js +2 -0
  16. package/app/public/js/968.index.js.LICENSE.txt +12 -0
  17. package/app/public/js/index.js +1 -1
  18. package/app/public/js/index.js.LICENSE.txt +0 -173
  19. package/lib/routes/settings.js +1 -0
  20. package/lib/webdav-sync.js +806 -0
  21. package/package.json +9 -2
  22. package/API.md +0 -247
  23. package/COLUMN_RESIZE_IMPLEMENTATION.md +0 -162
  24. package/FEATURE_ENHANCEMENT.md +0 -157
  25. package/TEST_GUIDE.md +0 -156
  26. package/data/features.json +0 -1
  27. package/data/interfaces.json +0 -1
  28. package/index.html +0 -52
  29. package/initialize.js +0 -32
  30. package/public/bundle.js +0 -2
  31. package/public/bundle.js.LICENSE.txt +0 -38
  32. package/public/index.html +0 -1
  33. package/public/plugin.mock-plugin.html +0 -14
  34. package/rules.txt +0 -22
  35. package/ui/src/App.css +0 -173
  36. package/ui/src/components/AppLayout.js +0 -407
  37. package/ui/src/components/FeatureCard.js +0 -58
  38. package/ui/src/components/KeyboardShortcutsHelp.js +0 -58
  39. package/ui/src/components/Layout.js +0 -94
  40. package/ui/src/components/MainNav.js +0 -42
  41. package/ui/src/components/PageContainer.js +0 -16
  42. package/ui/src/components/VersionModal.js +0 -99
  43. package/ui/src/components/interface-management/DataManagementDrawer.js +0 -115
  44. package/ui/src/components/interface-management/DataManagementModal.js +0 -110
  45. package/ui/src/components/interface-management/InterfaceTestModal.js +0 -313
  46. package/ui/src/components/interface-management/PreviewModal.js +0 -48
  47. package/ui/src/components/interface-management/README.md +0 -184
  48. package/ui/src/components/interface-management/RealResponseRecorder.js +0 -165
  49. package/ui/src/components/interface-management/ResponseContentEditor.js +0 -645
  50. package/ui/src/components/interface-management/constants.js +0 -36
  51. package/ui/src/components/interface-management/index.js +0 -7
  52. package/ui/src/components/interface-management/utils.js +0 -103
  53. package/ui/src/hooks/useKeyboardShortcuts.js +0 -99
  54. package/ui/src/index.html +0 -14
  55. package/ui/src/index.js +0 -50
  56. package/ui/src/pages/InterfaceManagementV2.js +0 -2351
  57. package/ui/src/pages/MockDataV2.js +0 -1089
  58. package/ui/src/pages/Settings.js +0 -299
  59. package/ui/src/pages/Sniffer.js +0 -521
  60. package/ui/src/pages/Stats.js +0 -288
  61. package/ui/src/services/del_api.js +0 -192
  62. package/ui/src/styles/app-layout.css +0 -373
  63. package/ui/src/styles/cyber-theme.css +0 -1234
  64. package/ui/src/styles/earth-theme.css +0 -618
  65. package/ui/src/styles/global.css +0 -224
  66. package/ui/src/styles/interface-management.css +0 -1321
  67. package/ui/src/styles/mock-data.css +0 -1185
  68. package/ui/src/styles/settings.css +0 -252
  69. package/ui/src/styles/version-modal.css +0 -116
  70. package/webpack.config.js +0 -54
@@ -1,165 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { Button, Input, message, Space, Tabs, Tag } from 'antd';
3
- import { DownloadOutlined, ThunderboltOutlined, CopyOutlined } from '@ant-design/icons';
4
- import axios from 'axios';
5
-
6
- const { TextArea } = Input;
7
-
8
- /**
9
- * JSON 转 Mock.js 模板
10
- * 简单转换:字符串 -> '@string', 数字 -> '@integer(1,100)', 布尔 -> '@boolean'
11
- * 保留对象结构
12
- */
13
- const jsonToMockTemplate = (obj, depth = 0) => {
14
- if (obj === null) return null;
15
- if (typeof obj === 'string') {
16
- // 保留特定格式字符串的提示
17
- if (/^\d{4}-\d{2}-\d{2}/.test(obj)) return '@date';
18
- if (/^\d{4}-\d{2}-\d{2}T/.test(obj)) return '@datetime';
19
- if (/^https?:\/\//.test(obj)) return '@url';
20
- if (/^\w+@\w+\.\w+/.test(obj)) return '@email';
21
- if (/^1[3-9]\d{9}$/.test(obj)) return '@string("number", 11)';
22
- return '@csentence(3, 10)';
23
- }
24
- if (typeof obj === 'number') {
25
- if (Number.isInteger(obj)) return '@integer(1, 999)';
26
- return '@float(1, 100, 2, 2)';
27
- }
28
- if (typeof obj === 'boolean') return '@boolean';
29
- if (Array.isArray(obj)) {
30
- if (obj.length === 0) return [];
31
- const template = jsonToMockTemplate(obj[0], depth + 1);
32
- // 用 |1-5 表示数组长度随机
33
- return [template];
34
- }
35
- if (typeof obj === 'object') {
36
- const result = {};
37
- for (const [key, value] of Object.entries(obj)) {
38
- result[key] = jsonToMockTemplate(value, depth + 1);
39
- }
40
- return result;
41
- }
42
- return obj;
43
- };
44
-
45
- const RealResponseRecorder = ({ urlPattern, onApply }) => {
46
- const [fetchUrl, setFetchUrl] = useState('');
47
- const [loading, setLoading] = useState(false);
48
- const [response, setResponse] = useState(null);
49
- const [activeTab, setActiveTab] = useState('preview');
50
-
51
- const handleFetch = async () => {
52
- const targetUrl = fetchUrl.trim() || urlPattern;
53
- if (!targetUrl) {
54
- message.warning('请输入目标 URL');
55
- return;
56
- }
57
- setLoading(true);
58
- try {
59
- const res = await axios.post('/cgi-bin/proxy-fetch', {
60
- url: targetUrl,
61
- method: 'GET',
62
- });
63
- if (res.data.code === 0) {
64
- setResponse(res.data.data);
65
- setActiveTab('preview');
66
- message.success('抓取成功');
67
- } else {
68
- throw new Error(res.data.message);
69
- }
70
- } catch (err) {
71
- message.error('抓取失败: ' + (err.response?.data?.message || err.message));
72
- } finally {
73
- setLoading(false);
74
- }
75
- };
76
-
77
- const handleGenerateMock = () => {
78
- if (!response?.body) return;
79
- try {
80
- const json = JSON.parse(response.body);
81
- const template = jsonToMockTemplate(json);
82
- const mockTemplate = JSON.stringify(template, null, 2);
83
- onApply?.(mockTemplate);
84
- message.success('Mock 模板已生成');
85
- } catch (e) {
86
- message.error('响应不是 JSON,无法生成模板: ' + e.message);
87
- }
88
- };
89
-
90
- const handleCopy = () => {
91
- if (response?.body) {
92
- navigator.clipboard.writeText(response.body);
93
- message.success('已复制');
94
- }
95
- };
96
-
97
- return (
98
- <div style={{ padding: '16px 0' }}>
99
- <Space direction="vertical" style={{ width: '100%' }}>
100
- <Space style={{ width: '100%' }}>
101
- <Input
102
- placeholder={urlPattern || '输入真实接口 URL'}
103
- value={fetchUrl}
104
- onChange={(e) => setFetchUrl(e.target.value)}
105
- style={{ width: 400 }}
106
- onPressEnter={handleFetch}
107
- />
108
- <Button
109
- type="primary"
110
- icon={<ThunderboltOutlined />}
111
- loading={loading}
112
- onClick={handleFetch}
113
- >
114
- 抓取真实响应
115
- </Button>
116
- </Space>
117
-
118
- {response && (
119
- <>
120
- <Space>
121
- <Tag color={response.status >= 200 && response.status < 300 ? 'success' : 'error'}>
122
- {response.status} {response.statusText}
123
- </Tag>
124
- <Button size="small" icon={<CopyOutlined />} onClick={handleCopy}>
125
- 复制原文
126
- </Button>
127
- <Button size="small" icon={<DownloadOutlined />} onClick={handleGenerateMock} type="primary">
128
- 生成 Mock 模板
129
- </Button>
130
- </Space>
131
-
132
- <Tabs activeKey={activeTab} onChange={setActiveTab}>
133
- <Tabs.TabPane tab="响应预览" key="preview">
134
- <TextArea
135
- value={response.body}
136
- readOnly
137
- rows={12}
138
- style={{ fontFamily: 'monospace', fontSize: 12 }}
139
- />
140
- </Tabs.TabPane>
141
- <Tabs.TabPane tab="生成的 Mock 模板" key="mock">
142
- <TextArea
143
- value={(() => {
144
- try {
145
- const json = JSON.parse(response.body);
146
- const template = jsonToMockTemplate(json);
147
- return JSON.stringify(template, null, 2);
148
- } catch (e) {
149
- return '// 响应不是 JSON,无法生成模板\n' + response.body;
150
- }
151
- })()}
152
- readOnly
153
- rows={12}
154
- style={{ fontFamily: 'monospace', fontSize: 12 }}
155
- />
156
- </Tabs.TabPane>
157
- </Tabs>
158
- </>
159
- )}
160
- </Space>
161
- </div>
162
- );
163
- };
164
-
165
- export default RealResponseRecorder;