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,694 @@
1
+ /* 全局样式变量 */
2
+ :root {
3
+ --primary-color: #1890ff;
4
+ --primary-hover: #40a9ff;
5
+ --primary-active: #096dd9;
6
+ --success-color: #52c41a;
7
+ --warning-color: #faad14;
8
+ --error-color: #f5222d;
9
+ --font-color: #262626;
10
+ --text-secondary: #595959;
11
+ --text-light: #8c8c8c;
12
+ --border-color: #f0f0f0;
13
+ --border-radius: 8px;
14
+ --card-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
15
+ --transition-time: 0.3s;
16
+ }
17
+
18
+ .interface-management-container {
19
+ padding: 24px;
20
+ background: #fff;
21
+ border-radius: var(--border-radius);
22
+ box-shadow: var(--card-shadow);
23
+ }
24
+
25
+ .page-header {
26
+ display: flex;
27
+ justify-content: space-between;
28
+ align-items: center;
29
+ margin-bottom: 32px;
30
+ padding-bottom: 20px;
31
+ border-bottom: 1px solid var(--border-color);
32
+ }
33
+
34
+ .interface-management-header {
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
38
+ margin-bottom: 32px;
39
+ padding-bottom: 20px;
40
+ border-bottom: 1px solid var(--border-color);
41
+ }
42
+
43
+ .feature-selector {
44
+ display: flex;
45
+ align-items: center;
46
+ background: #f9f9f9;
47
+ padding: 8px 16px;
48
+ border-radius: var(--border-radius);
49
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
50
+ transition: all var(--transition-time);
51
+ }
52
+
53
+ .feature-selector:hover {
54
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
55
+ }
56
+
57
+ .feature-selector span {
58
+ margin-right: 12px;
59
+ font-weight: 600;
60
+ color: var(--text-secondary);
61
+ }
62
+
63
+ .interface-list-container {
64
+ margin-top: 24px;
65
+ }
66
+
67
+ .action-buttons {
68
+ display: flex;
69
+ justify-content: flex-start;
70
+ gap: 12px;
71
+ }
72
+
73
+ .test-interface-container {
74
+ padding: 20px;
75
+ background: #f9f9f9;
76
+ border-radius: var(--border-radius);
77
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
78
+ margin-top: 24px;
79
+ }
80
+
81
+ .test-result {
82
+ margin-top: 24px;
83
+ padding: 20px;
84
+ border-radius: var(--border-radius);
85
+ background-color: #fff;
86
+ border: 1px solid var(--border-color);
87
+ box-shadow: var(--card-shadow);
88
+ }
89
+
90
+ .result-header {
91
+ display: flex;
92
+ justify-content: space-between;
93
+ align-items: center;
94
+ margin-bottom: 20px;
95
+ padding-bottom: 12px;
96
+ border-bottom: 1px solid var(--border-color);
97
+ }
98
+
99
+ .result-header h3 {
100
+ margin: 0;
101
+ font-size: 18px;
102
+ font-weight: 600;
103
+ color: var(--font-color);
104
+ }
105
+
106
+ .status {
107
+ font-size: 14px;
108
+ padding: 4px 12px;
109
+ border-radius: 20px;
110
+ font-weight: 500;
111
+ display: inline-flex;
112
+ align-items: center;
113
+ gap: 6px;
114
+ }
115
+
116
+ .status.success {
117
+ background-color: #f6ffed;
118
+ border: 1px solid #b7eb8f;
119
+ color: var(--success-color);
120
+ }
121
+
122
+ .status.error {
123
+ background-color: #fff2f0;
124
+ border: 1px solid #ffccc7;
125
+ color: var(--error-color);
126
+ }
127
+
128
+ .result-content {
129
+ display: flex;
130
+ flex-direction: column;
131
+ gap: 12px;
132
+ }
133
+
134
+ .result-item {
135
+ display: flex;
136
+ align-items: flex-start;
137
+ padding: 8px 12px;
138
+ background: #fafafa;
139
+ border-radius: 6px;
140
+ transition: background-color var(--transition-time);
141
+ }
142
+
143
+ .result-item:hover {
144
+ background: #f0f0f0;
145
+ }
146
+
147
+ .result-item .label {
148
+ font-weight: 600;
149
+ width: 120px;
150
+ flex-shrink: 0;
151
+ color: var(--text-secondary);
152
+ }
153
+
154
+ .result-item .value {
155
+ word-break: break-all;
156
+ color: var(--font-color);
157
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
158
+ }
159
+
160
+ .result-body {
161
+ margin-top: 16px;
162
+ }
163
+
164
+ .result-body .label {
165
+ font-weight: 600;
166
+ margin-bottom: 12px;
167
+ color: var(--text-secondary);
168
+ }
169
+
170
+ .result-body pre {
171
+ margin: 0;
172
+ padding: 16px;
173
+ background-color: #f5f5f5;
174
+ border-radius: var(--border-radius);
175
+ max-height: 400px;
176
+ overflow: auto;
177
+ white-space: pre-wrap;
178
+ word-wrap: break-word;
179
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
180
+ font-size: 14px;
181
+ line-height: 1.6;
182
+ border: 1px solid #e8e8e8;
183
+ }
184
+
185
+ .result-error {
186
+ color: var(--error-color);
187
+ padding: 12px 16px;
188
+ background-color: #fff2f0;
189
+ border-radius: var(--border-radius);
190
+ border-left: 4px solid var(--error-color);
191
+ }
192
+
193
+ .breadcrumb {
194
+ display: flex;
195
+ align-items: center;
196
+ font-size: 14px;
197
+ margin-bottom: 16px;
198
+ }
199
+
200
+ .breadcrumb .link {
201
+ color: var(--primary-color);
202
+ cursor: pointer;
203
+ transition: color var(--transition-time);
204
+ }
205
+
206
+ .breadcrumb .link:hover {
207
+ color: var(--primary-hover);
208
+ text-decoration: underline;
209
+ }
210
+
211
+ .breadcrumb .separator {
212
+ margin: 0 12px;
213
+ color: #d9d9d9;
214
+ }
215
+
216
+ .breadcrumb .current {
217
+ color: var(--text-secondary);
218
+ font-weight: 500;
219
+ }
220
+
221
+ .add-button {
222
+ background: linear-gradient(to right, var(--primary-color), var(--primary-hover));
223
+ color: white;
224
+ border: none;
225
+ border-radius: var(--border-radius);
226
+ padding: 0 20px;
227
+ height: 40px;
228
+ cursor: pointer;
229
+ font-size: 15px;
230
+ font-weight: 500;
231
+ display: flex;
232
+ align-items: center;
233
+ gap: 8px;
234
+ transition: all var(--transition-time);
235
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.35);
236
+ }
237
+
238
+ .add-button:hover {
239
+ background: linear-gradient(to right, var(--primary-hover), var(--primary-active));
240
+ transform: translateY(-2px);
241
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.5);
242
+ }
243
+
244
+ .feature-details {
245
+ background-color: white;
246
+ border-radius: var(--border-radius);
247
+ box-shadow: var(--card-shadow);
248
+ padding: 24px;
249
+ margin-bottom: 24px;
250
+ border-left: 4px solid var(--primary-color);
251
+ }
252
+
253
+ .feature-name {
254
+ display: flex;
255
+ align-items: center;
256
+ gap: 16px;
257
+ margin-bottom: 12px;
258
+ }
259
+
260
+ .feature-name h1 {
261
+ font-size: 22px;
262
+ font-weight: 600;
263
+ color: var(--font-color);
264
+ margin: 0;
265
+ }
266
+
267
+ .status-badge {
268
+ font-size: 13px;
269
+ padding: 4px 12px;
270
+ border-radius: 20px;
271
+ font-weight: 500;
272
+ display: inline-flex;
273
+ align-items: center;
274
+ gap: 6px;
275
+ }
276
+
277
+ .status-badge.active {
278
+ background-color: #f6ffed;
279
+ color: var(--success-color);
280
+ border: 1px solid #b7eb8f;
281
+ }
282
+
283
+ .status-badge.inactive {
284
+ background-color: #fff1f0;
285
+ color: var(--error-color);
286
+ border: 1px solid #ffa39e;
287
+ }
288
+
289
+ .feature-description {
290
+ color: var(--text-secondary);
291
+ font-size: 15px;
292
+ margin: 0;
293
+ line-height: 1.6;
294
+ }
295
+
296
+ .interface-table {
297
+ width: 100%;
298
+ border-collapse: collapse;
299
+ border-radius: var(--border-radius);
300
+ overflow: hidden;
301
+ box-shadow: var(--card-shadow);
302
+ }
303
+
304
+ .interface-table th,
305
+ .interface-table td {
306
+ padding: 16px;
307
+ text-align: left;
308
+ border-bottom: 1px solid var(--border-color);
309
+ }
310
+
311
+ .interface-table th {
312
+ background-color: #fafafa;
313
+ color: var(--text-secondary);
314
+ font-weight: 600;
315
+ font-size: 14px;
316
+ text-transform: uppercase;
317
+ letter-spacing: 0.5px;
318
+ }
319
+
320
+ .interface-table tr:hover {
321
+ background-color: #f5f5f5;
322
+ }
323
+
324
+ .interface-table tr.inactive {
325
+ color: var(--text-light);
326
+ background-color: #f9f9f9;
327
+ opacity: 0.7;
328
+ }
329
+
330
+ .url-pattern {
331
+ font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
332
+ word-break: break-all;
333
+ padding: 4px 8px;
334
+ background: #f5f5f5;
335
+ border-radius: 4px;
336
+ display: inline-block;
337
+ max-width: 100%;
338
+ overflow: hidden;
339
+ text-overflow: ellipsis;
340
+ }
341
+
342
+ /* 接口状态开关 */
343
+ .status-switch {
344
+ position: relative;
345
+ display: inline-block;
346
+ width: 48px;
347
+ height: 24px;
348
+ }
349
+
350
+ .status-switch input {
351
+ opacity: 0;
352
+ width: 0;
353
+ height: 0;
354
+ }
355
+
356
+ .status-switch .slider {
357
+ position: absolute;
358
+ cursor: pointer;
359
+ top: 0;
360
+ left: 0;
361
+ right: 0;
362
+ bottom: 0;
363
+ background-color: #ccc;
364
+ transition: .4s;
365
+ border-radius: 24px;
366
+ }
367
+
368
+ .status-switch .slider:before {
369
+ position: absolute;
370
+ content: "";
371
+ height: 18px;
372
+ width: 18px;
373
+ left: 3px;
374
+ bottom: 3px;
375
+ background-color: white;
376
+ transition: .4s;
377
+ border-radius: 50%;
378
+ }
379
+
380
+ .status-switch input:checked + .slider {
381
+ background-color: var(--success-color);
382
+ }
383
+
384
+ .status-switch input:checked + .slider:before {
385
+ transform: translateX(24px);
386
+ }
387
+
388
+ /* 操作按钮 */
389
+ .action-button {
390
+ border: none;
391
+ border-radius: 6px;
392
+ padding: 6px 12px;
393
+ cursor: pointer;
394
+ font-size: 14px;
395
+ font-weight: 500;
396
+ display: inline-flex;
397
+ align-items: center;
398
+ gap: 6px;
399
+ transition: all var(--transition-time);
400
+ margin-right: 8px;
401
+ }
402
+
403
+ .test-button {
404
+ background-color: #e6f7ff;
405
+ color: var(--primary-color);
406
+ border: 1px solid #91d5ff;
407
+ }
408
+
409
+ .test-button:hover {
410
+ background-color: #bae7ff;
411
+ }
412
+
413
+ .edit-button {
414
+ background-color: #fcf6bd;
415
+ color: #d4b106;
416
+ border: 1px solid #ffd666;
417
+ }
418
+
419
+ .edit-button:hover {
420
+ background-color: #fff1b8;
421
+ }
422
+
423
+ .delete-button {
424
+ background-color: #fff2f0;
425
+ color: var(--error-color);
426
+ border: 1px solid #ffccc7;
427
+ }
428
+
429
+ .delete-button:hover {
430
+ background-color: #ffa39e;
431
+ color: #fff;
432
+ }
433
+
434
+ /* 空状态 */
435
+ .empty-data {
436
+ display: flex;
437
+ flex-direction: column;
438
+ align-items: center;
439
+ justify-content: center;
440
+ padding: 60px 20px;
441
+ background: #fafafa;
442
+ border-radius: var(--border-radius);
443
+ text-align: center;
444
+ margin-top: 24px;
445
+ }
446
+
447
+ .empty-icon {
448
+ font-size: 64px;
449
+ color: #d9d9d9;
450
+ margin-bottom: 24px;
451
+ }
452
+
453
+ .empty-text {
454
+ color: var(--text-secondary);
455
+ font-size: 16px;
456
+ margin-bottom: 24px;
457
+ }
458
+
459
+ .create-interface-button {
460
+ background: linear-gradient(to right, var(--primary-color), var(--primary-hover));
461
+ color: white;
462
+ border: none;
463
+ border-radius: var(--border-radius);
464
+ padding: 0 24px;
465
+ height: 44px;
466
+ cursor: pointer;
467
+ font-size: 16px;
468
+ font-weight: 500;
469
+ display: flex;
470
+ align-items: center;
471
+ gap: 8px;
472
+ transition: all var(--transition-time);
473
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.35);
474
+ }
475
+
476
+ .create-interface-button:hover {
477
+ background: linear-gradient(to right, var(--primary-hover), var(--primary-active));
478
+ transform: translateY(-2px);
479
+ box-shadow: 0 4px 12px rgba(24, 144, 255, 0.5);
480
+ }
481
+
482
+ /* 加载状态 */
483
+ .loading {
484
+ display: flex;
485
+ justify-content: center;
486
+ align-items: center;
487
+ padding: 40px;
488
+ font-size: 16px;
489
+ color: var(--text-secondary);
490
+ }
491
+
492
+ /* 错误容器样式 */
493
+ .error-container {
494
+ display: flex;
495
+ flex-direction: column;
496
+ align-items: center;
497
+ justify-content: center;
498
+ height: 300px;
499
+ color: #8c8c8c;
500
+ }
501
+
502
+ .error-icon {
503
+ font-size: 48px;
504
+ margin-bottom: 16px;
505
+ }
506
+
507
+ .error-message {
508
+ font-size: 16px;
509
+ margin-bottom: 24px;
510
+ }
511
+
512
+ .back-button {
513
+ height: 36px;
514
+ padding: 0 20px;
515
+ background-color: #1890ff;
516
+ color: white;
517
+ border: none;
518
+ border-radius: 4px;
519
+ cursor: pointer;
520
+ font-size: 14px;
521
+ }
522
+
523
+ .back-button:hover {
524
+ background-color: #40a9ff;
525
+ }
526
+
527
+ /* 模态框样式 */
528
+ .modal-overlay {
529
+ position: fixed;
530
+ top: 0;
531
+ left: 0;
532
+ right: 0;
533
+ bottom: 0;
534
+ background-color: rgba(0, 0, 0, 0.5);
535
+ display: flex;
536
+ align-items: center;
537
+ justify-content: center;
538
+ z-index: 1000;
539
+ }
540
+
541
+ .modal {
542
+ background-color: white;
543
+ border-radius: 4px;
544
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
545
+ width: 600px;
546
+ max-width: 90%;
547
+ max-height: 90vh;
548
+ overflow-y: auto;
549
+ }
550
+
551
+ .interface-modal {
552
+ width: 700px;
553
+ }
554
+
555
+ .modal-header {
556
+ display: flex;
557
+ justify-content: space-between;
558
+ align-items: center;
559
+ padding: 16px;
560
+ border-bottom: 1px solid #f0f0f0;
561
+ }
562
+
563
+ .modal-header h2 {
564
+ margin: 0;
565
+ font-size: 16px;
566
+ font-weight: 600;
567
+ color: #262626;
568
+ }
569
+
570
+ .close-button {
571
+ background: none;
572
+ border: none;
573
+ font-size: 20px;
574
+ color: #8c8c8c;
575
+ cursor: pointer;
576
+ }
577
+
578
+ .interface-form {
579
+ padding: 16px;
580
+ }
581
+
582
+ .form-row {
583
+ display: flex;
584
+ gap: 16px;
585
+ }
586
+
587
+ .form-row .form-group {
588
+ flex: 1;
589
+ }
590
+
591
+ .form-group {
592
+ margin-bottom: 16px;
593
+ }
594
+
595
+ .form-group label {
596
+ display: block;
597
+ margin-bottom: 8px;
598
+ font-weight: 500;
599
+ color: #262626;
600
+ }
601
+
602
+ .response-header {
603
+ display: flex;
604
+ justify-content: space-between;
605
+ align-items: center;
606
+ margin-bottom: 8px;
607
+ }
608
+
609
+ .format-button {
610
+ background-color: #f0f5ff;
611
+ color: #597ef7;
612
+ border: none;
613
+ border-radius: 4px;
614
+ padding: 4px 8px;
615
+ cursor: pointer;
616
+ font-size: 12px;
617
+ }
618
+
619
+ .format-button:hover {
620
+ background-color: #d6e4ff;
621
+ }
622
+
623
+ .checkbox-label,
624
+ .radio-label {
625
+ display: flex;
626
+ align-items: center;
627
+ gap: 8px;
628
+ font-weight: normal;
629
+ color: #262626;
630
+ margin-bottom: 8px;
631
+ }
632
+
633
+ .radio-group {
634
+ display: flex;
635
+ gap: 24px;
636
+ }
637
+
638
+ .form-group input[type="text"],
639
+ .form-group input[type="number"],
640
+ .form-group select {
641
+ width: 100%;
642
+ height: 32px;
643
+ padding: 0 12px;
644
+ border: 1px solid #d9d9d9;
645
+ border-radius: 4px;
646
+ font-size: 14px;
647
+ }
648
+
649
+ .form-group textarea {
650
+ width: 100%;
651
+ padding: 8px 12px;
652
+ border: 1px solid #d9d9d9;
653
+ border-radius: 4px;
654
+ font-size: 14px;
655
+ resize: vertical;
656
+ font-family: monospace;
657
+ }
658
+
659
+ .help-text {
660
+ font-size: 12px;
661
+ color: #8c8c8c;
662
+ margin-top: 4px;
663
+ display: block;
664
+ }
665
+
666
+ .form-actions {
667
+ display: flex;
668
+ justify-content: flex-end;
669
+ gap: 8px;
670
+ margin-top: 24px;
671
+ padding-top: 16px;
672
+ border-top: 1px solid #f0f0f0;
673
+ }
674
+
675
+ .cancel-button {
676
+ height: 32px;
677
+ padding: 0 16px;
678
+ background-color: white;
679
+ border: 1px solid #d9d9d9;
680
+ border-radius: 4px;
681
+ cursor: pointer;
682
+ font-size: 14px;
683
+ }
684
+
685
+ .submit-button {
686
+ height: 32px;
687
+ padding: 0 16px;
688
+ background-color: #1890ff;
689
+ color: white;
690
+ border: none;
691
+ border-radius: 4px;
692
+ cursor: pointer;
693
+ font-size: 14px;
694
+ }