whistle.mock-plugins 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 (68) hide show
  1. package/API.md +247 -0
  2. package/README.md +91 -0
  3. package/app/cgi-bin/features.js +285 -0
  4. package/app/cgi-bin/index.js +31 -0
  5. package/app/cgi-bin/interfaces.js +409 -0
  6. package/app/cgi-bin/logs.js +151 -0
  7. package/app/cgi-bin/test-interface.js +152 -0
  8. package/app/public/index.html +1 -0
  9. package/app/public/js/index.js +2 -0
  10. package/app/public/js/index.js.LICENSE.txt +150 -0
  11. package/app/util/index.js +24 -0
  12. package/index.html +52 -0
  13. package/initialize.js +32 -0
  14. package/lib/dataManager.js +500 -0
  15. package/lib/index.js +3 -0
  16. package/lib/models.js +64 -0
  17. package/lib/routes/features.js +213 -0
  18. package/lib/routes/interfaces.js +304 -0
  19. package/lib/routes/proxy.js +239 -0
  20. package/lib/ruleManager.js +551 -0
  21. package/lib/rules-server.js +267 -0
  22. package/lib/server.js +805 -0
  23. package/lib/storage.js +16 -0
  24. package/lib/ui-server.js +68 -0
  25. package/package.json +51 -0
  26. package/public/bundle.js +2 -0
  27. package/public/bundle.js.LICENSE.txt +38 -0
  28. package/public/index.html +1 -0
  29. package/public/plugin.mock-plugin.html +14 -0
  30. package/rules.txt +22 -0
  31. package/test/rulesServer.test.js +120 -0
  32. package/ui/src/App.css +173 -0
  33. package/ui/src/App.js +24 -0
  34. package/ui/src/components/AppLayout.js +149 -0
  35. package/ui/src/components/FeatureCard.js +53 -0
  36. package/ui/src/components/Layout.js +94 -0
  37. package/ui/src/components/MainNav.js +42 -0
  38. package/ui/src/components/PageContainer.js +16 -0
  39. package/ui/src/index.html +11 -0
  40. package/ui/src/index.js +43 -0
  41. package/ui/src/pages/FileProxy.js +235 -0
  42. package/ui/src/pages/FilesPage.js +292 -0
  43. package/ui/src/pages/Home.js +128 -0
  44. package/ui/src/pages/HomePage.js +195 -0
  45. package/ui/src/pages/InterfaceManagement.js +829 -0
  46. package/ui/src/pages/InterfacePage.js +342 -0
  47. package/ui/src/pages/MockData.js +472 -0
  48. package/ui/src/pages/Settings.js +192 -0
  49. package/ui/src/pages/SettingsPage.js +165 -0
  50. package/ui/src/pages/UrlRedirect.js +225 -0
  51. package/ui/src/pages/Welcome.js +155 -0
  52. package/ui/src/services/api.js +186 -0
  53. package/ui/src/styles/app-layout.css +337 -0
  54. package/ui/src/styles/feature-card.css +172 -0
  55. package/ui/src/styles/file-proxy.css +301 -0
  56. package/ui/src/styles/global.css +224 -0
  57. package/ui/src/styles/home.css +123 -0
  58. package/ui/src/styles/index.css +419 -0
  59. package/ui/src/styles/interface-management.css +694 -0
  60. package/ui/src/styles/layout.css +159 -0
  61. package/ui/src/styles/logs-page.css +427 -0
  62. package/ui/src/styles/main-nav.css +52 -0
  63. package/ui/src/styles/mock-data.css +850 -0
  64. package/ui/src/styles/page-container.css +11 -0
  65. package/ui/src/styles/settings.css +208 -0
  66. package/ui/src/styles/url-redirect.css +279 -0
  67. package/ui/src/styles/welcome.css +282 -0
  68. package/webpack.config.js +49 -0
@@ -0,0 +1,301 @@
1
+ .file-proxy-container {
2
+ height: 100%;
3
+ }
4
+
5
+ .page-header {
6
+ display: flex;
7
+ justify-content: space-between;
8
+ align-items: center;
9
+ margin-bottom: 16px;
10
+ }
11
+
12
+ .page-header h1 {
13
+ font-size: 20px;
14
+ font-weight: 600;
15
+ color: #262626;
16
+ margin: 0;
17
+ }
18
+
19
+ .add-button {
20
+ background-color: #1890ff;
21
+ color: white;
22
+ border: none;
23
+ border-radius: 4px;
24
+ padding: 0 16px;
25
+ height: 32px;
26
+ cursor: pointer;
27
+ font-size: 14px;
28
+ display: flex;
29
+ align-items: center;
30
+ }
31
+
32
+ .add-button:hover {
33
+ background-color: #40a9ff;
34
+ }
35
+
36
+ .proxy-list-container {
37
+ background-color: white;
38
+ border-radius: 4px;
39
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
40
+ overflow: hidden;
41
+ }
42
+
43
+ .proxy-table {
44
+ width: 100%;
45
+ border-collapse: collapse;
46
+ }
47
+
48
+ .proxy-table th,
49
+ .proxy-table td {
50
+ padding: 12px 16px;
51
+ text-align: left;
52
+ border-bottom: 1px solid #f0f0f0;
53
+ }
54
+
55
+ .proxy-table th {
56
+ background-color: #fafafa;
57
+ color: #8c8c8c;
58
+ font-weight: 500;
59
+ font-size: 14px;
60
+ }
61
+
62
+ .proxy-table tr:hover {
63
+ background-color: #fafafa;
64
+ }
65
+
66
+ .proxy-table tr.inactive {
67
+ color: #a6a6a6;
68
+ background-color: #f9f9f9;
69
+ }
70
+
71
+ .local-path {
72
+ font-family: monospace;
73
+ word-break: break-all;
74
+ }
75
+
76
+ .action-buttons {
77
+ display: flex;
78
+ gap: 8px;
79
+ }
80
+
81
+ .edit-button,
82
+ .delete-button {
83
+ border: none;
84
+ border-radius: 4px;
85
+ padding: 4px 8px;
86
+ cursor: pointer;
87
+ font-size: 12px;
88
+ }
89
+
90
+ .edit-button {
91
+ background-color: #e6f7ff;
92
+ color: #1890ff;
93
+ }
94
+
95
+ .edit-button:hover {
96
+ background-color: #bae7ff;
97
+ }
98
+
99
+ .delete-button {
100
+ background-color: #fff1f0;
101
+ color: #f5222d;
102
+ }
103
+
104
+ .delete-button:hover {
105
+ background-color: #ffccc7;
106
+ }
107
+
108
+ /* 切换开关样式 */
109
+ .switch {
110
+ position: relative;
111
+ display: inline-block;
112
+ width: 36px;
113
+ height: 20px;
114
+ }
115
+
116
+ .switch input {
117
+ opacity: 0;
118
+ width: 0;
119
+ height: 0;
120
+ }
121
+
122
+ .slider {
123
+ position: absolute;
124
+ cursor: pointer;
125
+ top: 0;
126
+ left: 0;
127
+ right: 0;
128
+ bottom: 0;
129
+ background-color: #ccc;
130
+ transition: .4s;
131
+ border-radius: 20px;
132
+ }
133
+
134
+ .slider:before {
135
+ position: absolute;
136
+ content: "";
137
+ height: 16px;
138
+ width: 16px;
139
+ left: 2px;
140
+ bottom: 2px;
141
+ background-color: white;
142
+ transition: .4s;
143
+ border-radius: 50%;
144
+ }
145
+
146
+ input:checked + .slider {
147
+ background-color: #1890ff;
148
+ }
149
+
150
+ input:checked + .slider:before {
151
+ transform: translateX(16px);
152
+ }
153
+
154
+ /* 空数据样式 */
155
+ .empty-data {
156
+ display: flex;
157
+ flex-direction: column;
158
+ align-items: center;
159
+ justify-content: center;
160
+ padding: 60px 0;
161
+ color: #8c8c8c;
162
+ }
163
+
164
+ .empty-icon {
165
+ font-size: 48px;
166
+ margin-bottom: 16px;
167
+ color: #d9d9d9;
168
+ }
169
+
170
+ .empty-text {
171
+ font-size: 16px;
172
+ margin-bottom: 24px;
173
+ color: #8c8c8c;
174
+ }
175
+
176
+ /* 模态框样式 */
177
+ .modal-overlay {
178
+ position: fixed;
179
+ top: 0;
180
+ left: 0;
181
+ right: 0;
182
+ bottom: 0;
183
+ background-color: rgba(0, 0, 0, 0.5);
184
+ display: flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ z-index: 1000;
188
+ }
189
+
190
+ .modal {
191
+ background-color: white;
192
+ border-radius: 4px;
193
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
194
+ width: 500px;
195
+ max-width: 90%;
196
+ max-height: 90vh;
197
+ overflow-y: auto;
198
+ }
199
+
200
+ .modal-header {
201
+ display: flex;
202
+ justify-content: space-between;
203
+ align-items: center;
204
+ padding: 16px;
205
+ border-bottom: 1px solid #f0f0f0;
206
+ }
207
+
208
+ .modal-header h2 {
209
+ margin: 0;
210
+ font-size: 16px;
211
+ font-weight: 600;
212
+ color: #262626;
213
+ }
214
+
215
+ .close-button {
216
+ background: none;
217
+ border: none;
218
+ font-size: 20px;
219
+ color: #8c8c8c;
220
+ cursor: pointer;
221
+ }
222
+
223
+ .proxy-form {
224
+ padding: 16px;
225
+ }
226
+
227
+ .form-group {
228
+ margin-bottom: 16px;
229
+ }
230
+
231
+ .form-group label {
232
+ display: block;
233
+ margin-bottom: 8px;
234
+ font-weight: 500;
235
+ color: #262626;
236
+ }
237
+
238
+ .form-group input {
239
+ width: 100%;
240
+ height: 32px;
241
+ padding: 0 12px;
242
+ border: 1px solid #d9d9d9;
243
+ border-radius: 4px;
244
+ font-size: 14px;
245
+ }
246
+
247
+ .file-input-group {
248
+ display: flex;
249
+ gap: 8px;
250
+ }
251
+
252
+ .file-input-group input {
253
+ flex: 1;
254
+ }
255
+
256
+ .browse-button {
257
+ height: 32px;
258
+ padding: 0 12px;
259
+ background-color: #f5f5f5;
260
+ border: 1px solid #d9d9d9;
261
+ border-radius: 4px;
262
+ cursor: pointer;
263
+ font-size: 14px;
264
+ display: flex;
265
+ align-items: center;
266
+ white-space: nowrap;
267
+ }
268
+
269
+ .help-text {
270
+ font-size: 12px;
271
+ color: #8c8c8c;
272
+ margin-top: 4px;
273
+ }
274
+
275
+ .form-actions {
276
+ display: flex;
277
+ justify-content: flex-end;
278
+ gap: 8px;
279
+ margin-top: 24px;
280
+ }
281
+
282
+ .cancel-button {
283
+ height: 32px;
284
+ padding: 0 16px;
285
+ background-color: white;
286
+ border: 1px solid #d9d9d9;
287
+ border-radius: 4px;
288
+ cursor: pointer;
289
+ font-size: 14px;
290
+ }
291
+
292
+ .submit-button {
293
+ height: 32px;
294
+ padding: 0 16px;
295
+ background-color: #1890ff;
296
+ color: white;
297
+ border: none;
298
+ border-radius: 4px;
299
+ cursor: pointer;
300
+ font-size: 14px;
301
+ }
@@ -0,0 +1,224 @@
1
+ /* 全局样式 */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
7
+ 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
8
+ 'Noto Color Emoji';
9
+ }
10
+
11
+ html, body, #root {
12
+ height: 100%;
13
+ width: 100%;
14
+ }
15
+
16
+ body {
17
+ background-color: #f5f7fa;
18
+ color: rgba(0, 0, 0, 0.85);
19
+ font-size: 14px;
20
+ line-height: 1.5715;
21
+ -webkit-font-smoothing: antialiased;
22
+ -moz-osx-font-smoothing: grayscale;
23
+ }
24
+
25
+ h1, h2, h3, h4, h5, h6 {
26
+ margin-top: 0;
27
+ margin-bottom: 0.5em;
28
+ color: rgba(0, 0, 0, 0.85);
29
+ font-weight: 500;
30
+ }
31
+
32
+ p {
33
+ margin-top: 0;
34
+ margin-bottom: 1em;
35
+ }
36
+
37
+ button, input {
38
+ font-size: 14px;
39
+ }
40
+
41
+ a {
42
+ color: #1890ff;
43
+ text-decoration: none;
44
+ transition: all 0.3s;
45
+ }
46
+
47
+ a:hover {
48
+ color: #40a9ff;
49
+ }
50
+
51
+ /* 辅助类 */
52
+ .text-center {
53
+ text-align: center;
54
+ }
55
+
56
+ .text-right {
57
+ text-align: right;
58
+ }
59
+
60
+ .text-left {
61
+ text-align: left;
62
+ }
63
+
64
+ .mb-0 {
65
+ margin-bottom: 0;
66
+ }
67
+
68
+ .mb-1 {
69
+ margin-bottom: 4px;
70
+ }
71
+
72
+ .mb-2 {
73
+ margin-bottom: 8px;
74
+ }
75
+
76
+ .mb-3 {
77
+ margin-bottom: 16px;
78
+ }
79
+
80
+ .mb-4 {
81
+ margin-bottom: 24px;
82
+ }
83
+
84
+ .mt-0 {
85
+ margin-top: 0;
86
+ }
87
+
88
+ .mt-1 {
89
+ margin-top: 4px;
90
+ }
91
+
92
+ .mt-2 {
93
+ margin-top: 8px;
94
+ }
95
+
96
+ .mt-3 {
97
+ margin-top: 16px;
98
+ }
99
+
100
+ .mt-4 {
101
+ margin-top: 24px;
102
+ }
103
+
104
+ .ml-1 {
105
+ margin-left: 4px;
106
+ }
107
+
108
+ .ml-2 {
109
+ margin-left: 8px;
110
+ }
111
+
112
+ .ml-3 {
113
+ margin-left: 16px;
114
+ }
115
+
116
+ .mr-1 {
117
+ margin-right: 4px;
118
+ }
119
+
120
+ .mr-2 {
121
+ margin-right: 8px;
122
+ }
123
+
124
+ .mr-3 {
125
+ margin-right: 16px;
126
+ }
127
+
128
+ .p-0 {
129
+ padding: 0;
130
+ }
131
+
132
+ .p-1 {
133
+ padding: 4px;
134
+ }
135
+
136
+ .p-2 {
137
+ padding: 8px;
138
+ }
139
+
140
+ .p-3 {
141
+ padding: 16px;
142
+ }
143
+
144
+ .p-4 {
145
+ padding: 24px;
146
+ }
147
+
148
+ /* 弹性布局 */
149
+ .d-flex {
150
+ display: flex;
151
+ }
152
+
153
+ .align-center {
154
+ align-items: center;
155
+ }
156
+
157
+ .justify-between {
158
+ justify-content: space-between;
159
+ }
160
+
161
+ .justify-center {
162
+ justify-content: center;
163
+ }
164
+
165
+ .flex-column {
166
+ flex-direction: column;
167
+ }
168
+
169
+ .flex-wrap {
170
+ flex-wrap: wrap;
171
+ }
172
+
173
+ .flex-1 {
174
+ flex: 1;
175
+ }
176
+
177
+ /* 颜色 */
178
+ .text-primary {
179
+ color: #1890ff;
180
+ }
181
+
182
+ .text-success {
183
+ color: #52c41a;
184
+ }
185
+
186
+ .text-warning {
187
+ color: #faad14;
188
+ }
189
+
190
+ .text-danger {
191
+ color: #ff4d4f;
192
+ }
193
+
194
+ .text-secondary {
195
+ color: rgba(0, 0, 0, 0.45);
196
+ }
197
+
198
+ .bg-white {
199
+ background-color: #fff;
200
+ }
201
+
202
+ .bg-light {
203
+ background-color: #f5f7fa;
204
+ }
205
+
206
+ /* 滚动条样式 */
207
+ ::-webkit-scrollbar {
208
+ width: 6px;
209
+ height: 6px;
210
+ }
211
+
212
+ ::-webkit-scrollbar-track {
213
+ background: #f1f1f1;
214
+ border-radius: 3px;
215
+ }
216
+
217
+ ::-webkit-scrollbar-thumb {
218
+ background: #c1c1c1;
219
+ border-radius: 3px;
220
+ }
221
+
222
+ ::-webkit-scrollbar-thumb:hover {
223
+ background: #a8a8a8;
224
+ }
@@ -0,0 +1,123 @@
1
+ .content-header {
2
+ margin-bottom: 20px;
3
+ display: flex;
4
+ justify-content: space-between;
5
+ align-items: center;
6
+ }
7
+
8
+ .content-title {
9
+ font-size: 1.5rem;
10
+ font-weight: bold;
11
+ color: #2c3e50;
12
+ }
13
+
14
+ .content-controls {
15
+ display: flex;
16
+ gap: 10px;
17
+ }
18
+
19
+ .view-toggle, .sort-select {
20
+ padding: 6px 12px;
21
+ border: 1px solid #ddd;
22
+ border-radius: 4px;
23
+ background-color: #fff;
24
+ cursor: pointer;
25
+ }
26
+
27
+ .view-toggle:hover,
28
+ .sort-select:hover {
29
+ border-color: #bbb;
30
+ }
31
+
32
+ .features-container {
33
+ margin-top: 20px;
34
+ }
35
+
36
+ .card-view {
37
+ display: grid;
38
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
39
+ gap: 20px;
40
+ }
41
+
42
+ .list-view {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 10px;
46
+ }
47
+
48
+ .list-view .feature-row {
49
+ display: flex;
50
+ justify-content: space-between;
51
+ align-items: center;
52
+ padding: 15px;
53
+ background-color: #fff;
54
+ border-radius: 4px;
55
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
56
+ }
57
+
58
+ .list-view .feature-info {
59
+ flex: 1;
60
+ }
61
+
62
+ .list-view .feature-title {
63
+ font-weight: 600;
64
+ font-size: 1.1rem;
65
+ color: #2c3e50;
66
+ margin-bottom: 5px;
67
+ }
68
+
69
+ .list-view .feature-description {
70
+ color: #666;
71
+ font-size: 14px;
72
+ }
73
+
74
+ .list-view .feature-status {
75
+ padding: 3px 8px;
76
+ border-radius: 12px;
77
+ font-size: 12px;
78
+ font-weight: 500;
79
+ margin-left: 10px;
80
+ }
81
+
82
+ .list-view .feature-actions {
83
+ display: flex;
84
+ gap: 10px;
85
+ }
86
+
87
+ .list-view .action-btn {
88
+ padding: 6px 12px;
89
+ font-size: 13px;
90
+ }
91
+
92
+ .empty-state {
93
+ text-align: center;
94
+ padding: 50px 20px;
95
+ margin-top: 50px;
96
+ }
97
+
98
+ .empty-state-icon {
99
+ font-size: 3rem;
100
+ color: #ddd;
101
+ margin-bottom: 20px;
102
+ }
103
+
104
+ .empty-state-text {
105
+ color: #999;
106
+ font-size: 1.1rem;
107
+ margin-bottom: 30px;
108
+ }
109
+
110
+ .create-first-btn {
111
+ padding: 10px 20px;
112
+ background-color: #1890ff;
113
+ color: white;
114
+ border: none;
115
+ border-radius: 4px;
116
+ cursor: pointer;
117
+ font-size: 16px;
118
+ transition: background-color 0.2s;
119
+ }
120
+
121
+ .create-first-btn:hover {
122
+ background-color: #40a9ff;
123
+ }