whistle.mock-plugins 1.2.2-beta.23 → 1.2.2-beta.28

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.
@@ -72,6 +72,8 @@
72
72
 
73
73
  /**![appstore](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ2NCAxNDRIMTYwYy04LjggMC0xNiA3LjItMTYgMTZ2MzA0YzAgOC44IDcuMiAxNiAxNiAxNmgzMDRjOC44IDAgMTYtNy4yIDE2LTE2VjE2MGMwLTguOC03LjItMTYtMTYtMTZ6bS01MiAyNjhIMjEyVjIxMmgyMDB2MjAwem00NTItMjY4SDU2MGMtOC44IDAtMTYgNy4yLTE2IDE2djMwNGMwIDguOCA3LjIgMTYgMTYgMTZoMzA0YzguOCAwIDE2LTcuMiAxNi0xNlYxNjBjMC04LjgtNy4yLTE2LTE2LTE2em0tNTIgMjY4SDYxMlYyMTJoMjAwdjIwMHpNNDY0IDU0NEgxNjBjLTguOCAwLTE2IDcuMi0xNiAxNnYzMDRjMCA4LjggNy4yIDE2IDE2IDE2aDMwNGM4LjggMCAxNi03LjIgMTYtMTZWNTYwYzAtOC44LTcuMi0xNi0xNi0xNnptLTUyIDI2OEgyMTJWNjEyaDIwMHYyMDB6bTQ1Mi0yNjhINTYwYy04LjggMC0xNiA3LjItMTYgMTZ2MzA0YzAgOC44IDcuMiAxNiAxNiAxNmgzMDRjOC44IDAgMTYtNy4yIDE2LTE2VjU2MGMwLTguOC03LjItMTYtMTYtMTZ6bS01MiAyNjhINjEyVjYxMmgyMDB2MjAweiIgLz48L3N2Zz4=) */
74
74
 
75
+ /**![bar-chart](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4OCA3OTJIMjAwVjE2OGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2Njg4YzAgNC40IDMuNiA4IDggOGg3NTJjNC40IDAgOC0zLjYgOC04di01NmMwLTQuNC0zLjYtOC04LTh6bS02MDAtODBoNTZjNC40IDAgOC0zLjYgOC04VjU2MGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2MTQ0YzAgNC40IDMuNiA4IDggOHptMTUyIDBoNTZjNC40IDAgOC0zLjYgOC04VjM4NGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2MzIwYzAgNC40IDMuNiA4IDggOHptMTUyIDBoNTZjNC40IDAgOC0zLjYgOC04VjQ2MmMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2MjQyYzAgNC40IDMuNiA4IDggOHptMTUyIDBoNTZjNC40IDAgOC0zLjYgOC04VjMwNGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2NDAwYzAgNC40IDMuNiA4IDggOHoiIC8+PC9zdmc+) */
76
+
75
77
  /**![bars](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxMiAxOTJIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHptMCAyODRIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHptMCAyODRIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHpNMTA0IDIyOGE1NiA1NiAwIDEwMTEyIDAgNTYgNTYgMCAxMC0xMTIgMHptMCAyODRhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMTAtMTEyIDB6bTAgMjg0YTU2IDU2IDAgMTAxMTIgMCA1NiA1NiAwIDEwLTExMiAweiIgLz48L3N2Zz4=) */
76
78
 
77
79
  /**![calendar](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg4MCAxODRINzEydi02NGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2NjRIMzg0di02NGMwLTQuNC0zLjYtOC04LThoLTU2Yy00LjQgMC04IDMuNi04IDh2NjRIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY2NjRjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjIxNmMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDY1NkgxODRWNDYwaDY1NnYzODB6TTE4NCAzOTJWMjU2aDEyOHY0OGMwIDQuNCAzLjYgOCA4IDhoNTZjNC40IDAgOC0zLjYgOC04di00OGgyNTZ2NDhjMCA0LjQgMy42IDggOCA4aDU2YzQuNCAwIDgtMy42IDgtOHYtNDhoMTI4djEzNkgxODR6IiAvPjwvc3ZnPg==) */
@@ -86,6 +88,10 @@
86
88
 
87
89
  /**![check](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxMiAxOTBoLTY5LjljLTkuOCAwLTE5LjEgNC41LTI1LjEgMTIuMkw0MDQuNyA3MjQuNSAyMDcgNDc0YTMyIDMyIDAgMDAtMjUuMS0xMi4ySDExMmMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlsMjczLjkgMzQ3YzEyLjggMTYuMiAzNy40IDE2LjIgNTAuMyAwbDQ4OC40LTYxOC45YzQuMS01LjEuNC0xMi44LTYuMy0xMi44eiIgLz48L3N2Zz4=) */
88
90
 
91
+ /**![clear](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHN0eWxlIC8+PC9kZWZzPjxwYXRoIGQ9Ik04OTkuMSA4NjkuNmwtNTMtMzA1LjZIODY0YzE0LjQgMCAyNi0xMS42IDI2LTI2VjM0NmMwLTE0LjQtMTEuNi0yNi0yNi0yNkg2MThWMTM4YzAtMTQuNC0xMS42LTI2LTI2LTI2SDQzMmMtMTQuNCAwLTI2IDExLjYtMjYgMjZ2MTgySDE2MGMtMTQuNCAwLTI2IDExLjYtMjYgMjZ2MTkyYzAgMTQuNCAxMS42IDI2IDI2IDI2aDE3LjlsLTUzIDMwNS42YTI1Ljk1IDI1Ljk1IDAgMDAyNS42IDMwLjRoNzIzYzEuNSAwIDMtLjEgNC40LS40YTI1Ljg4IDI1Ljg4IDAgMDAyMS4yLTMwek0yMDQgMzkwaDI3MlYxODJoNzJ2MjA4aDI3MnYxMDRIMjA0VjM5MHptNDY4IDQ0MFY2NzRjMC00LjQtMy42LTgtOC04aC00OGMtNC40IDAtOCAzLjYtOCA4djE1Nkg0MTZWNjc0YzAtNC40LTMuNi04LTgtOGgtNDhjLTQuNCAwLTggMy42LTggOHYxNTZIMjAyLjhsNDUuMS0yNjBINzc2bDQ1LjEgMjYwSDY3MnoiIC8+PC9zdmc+) */
92
+
93
+ /**![clock-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PHBhdGggZD0iTTY4Ni43IDYzOC42TDU0NC4xIDUzNS41VjI4OGMwLTQuNC0zLjYtOC04LThINDg4Yy00LjQgMC04IDMuNi04IDh2Mjc1LjRjMCAyLjYgMS4yIDUgMy4zIDYuNWwxNjUuNCAxMjAuNmMzLjYgMi42IDguNiAxLjggMTEuMi0xLjdsMjguNi0zOWMyLjYtMy43IDEuOC04LjctMS44LTExLjJ6IiAvPjwvc3ZnPg==) */
94
+
89
95
  /**![close-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNTEyIDY0YzI0Ny40IDAgNDQ4IDIwMC42IDQ0OCA0NDhTNzU5LjQgOTYwIDUxMiA5NjAgNjQgNzU5LjQgNjQgNTEyIDI2NC42IDY0IDUxMiA2NHptMTI3Ljk4IDI3NC44MmgtLjA0bC0uMDguMDZMNTEyIDQ2Ni43NSAzODQuMTQgMzM4Ljg4Yy0uMDQtLjA1LS4wNi0uMDYtLjA4LS4wNmEuMTIuMTIgMCAwMC0uMDcgMGMtLjAzIDAtLjA1LjAxLS4wOS4wNWwtNDUuMDIgNDUuMDJhLjIuMiAwIDAwLS4wNS4wOS4xMi4xMiAwIDAwMCAuMDd2LjAyYS4yNy4yNyAwIDAwLjA2LjA2TDQ2Ni43NSA1MTIgMzM4Ljg4IDYzOS44NmMtLjA1LjA0LS4wNi4wNi0uMDYuMDhhLjEyLjEyIDAgMDAwIC4wN2MwIC4wMy4wMS4wNS4wNS4wOWw0NS4wMiA0NS4wMmEuMi4yIDAgMDAuMDkuMDUuMTIuMTIgMCAwMC4wNyAwYy4wMiAwIC4wNC0uMDEuMDgtLjA1TDUxMiA1NTcuMjVsMTI3Ljg2IDEyNy44N2MuMDQuMDQuMDYuMDUuMDguMDVhLjEyLjEyIDAgMDAuMDcgMGMuMDMgMCAuMDUtLjAxLjA5LS4wNWw0NS4wMi00NS4wMmEuMi4yIDAgMDAuMDUtLjA5LjEyLjEyIDAgMDAwLS4wN3YtLjAyYS4yNy4yNyAwIDAwLS4wNS0uMDZMNTU3LjI1IDUxMmwxMjcuODctMTI3Ljg2Yy4wNC0uMDQuMDUtLjA2LjA1LS4wOGEuMTIuMTIgMCAwMDAtLjA3YzAtLjAzLS4wMS0uMDUtLjA1LS4wOWwtNDUuMDItNDUuMDJhLjIuMiAwIDAwLS4wOS0uMDUuMTIuMTIgMCAwMC0uMDcgMHoiIC8+PC9zdmc+) */
90
96
 
91
97
  /**![close](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNzk5Ljg2IDE2Ni4zMWMuMDIgMCAuMDQuMDIuMDguMDZsNTcuNjkgNTcuN2MuMDQuMDMuMDUuMDUuMDYuMDhhLjEyLjEyIDAgMDEwIC4wNmMwIC4wMy0uMDIuMDUtLjA2LjA5TDU2OS45MyA1MTJsMjg3LjcgMjg3LjdjLjA0LjA0LjA1LjA2LjA2LjA5YS4xMi4xMiAwIDAxMCAuMDdjMCAuMDItLjAyLjA0LS4wNi4wOGwtNTcuNyA1Ny42OWMtLjAzLjA0LS4wNS4wNS0uMDcuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMyAwLS4wNS0uMDItLjA5LS4wNkw1MTIgNTY5LjkzbC0yODcuNyAyODcuN2MtLjA0LjA0LS4wNi4wNS0uMDkuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMiAwLS4wNC0uMDItLjA4LS4wNmwtNTcuNjktNTcuN2MtLjA0LS4wMy0uMDUtLjA1LS4wNi0uMDdhLjEyLjEyIDAgMDEwLS4wN2MwLS4wMy4wMi0uMDUuMDYtLjA5TDQ1NC4wNyA1MTJsLTI4Ny43LTI4Ny43Yy0uMDQtLjA0LS4wNS0uMDYtLjA2LS4wOWEuMTIuMTIgMCAwMTAtLjA3YzAtLjAyLjAyLS4wNC4wNi0uMDhsNTcuNy01Ny42OWMuMDMtLjA0LjA1LS4wNS4wNy0uMDZhLjEyLjEyIDAgMDEuMDcgMGMuMDMgMCAuMDUuMDIuMDkuMDZMNTEyIDQ1NC4wN2wyODcuNy0yODcuN2MuMDQtLjA0LjA2LS4wNS4wOS0uMDZhLjEyLjEyIDAgMDEuMDcgMHoiIC8+PC9zdmc+) */
@@ -136,6 +142,8 @@
136
142
 
137
143
  /**![fullscreen](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI5MCAyMzYuNGw0My45LTQzLjlhOC4wMSA4LjAxIDAgMDAtNC43LTEzLjZMMTY5IDE2MGMtNS4xLS42LTkuNSAzLjctOC45IDguOUwxNzkgMzI5LjFjLjggNi42IDguOSA5LjQgMTMuNiA0LjdsNDMuNy00My43TDM3MCA0MjMuN2MzLjEgMy4xIDguMiAzLjEgMTEuMyAwbDQyLjQtNDIuM2MzLjEtMy4xIDMuMS04LjIgMC0xMS4zTDI5MCAyMzYuNHptMzUyLjcgMTg3LjNjMy4xIDMuMSA4LjIgMy4xIDExLjMgMGwxMzMuNy0xMzMuNiA0My43IDQzLjdhOC4wMSA4LjAxIDAgMDAxMy42LTQuN0w4NjMuOSAxNjljLjYtNS4xLTMuNy05LjUtOC45LTguOUw2OTQuOCAxNzljLTYuNi44LTkuNCA4LjktNC43IDEzLjZsNDMuOSA0My45TDYwMC4zIDM3MGE4LjAzIDguMDMgMCAwMDAgMTEuM2w0Mi40IDQyLjR6TTg0NSA2OTQuOWMtLjgtNi42LTguOS05LjQtMTMuNi00LjdsLTQzLjcgNDMuN0w2NTQgNjAwLjNhOC4wMyA4LjAzIDAgMDAtMTEuMyAwbC00Mi40IDQyLjNhOC4wMyA4LjAzIDAgMDAwIDExLjNMNzM0IDc4Ny42bC00My45IDQzLjlhOC4wMSA4LjAxIDAgMDA0LjcgMTMuNkw4NTUgODY0YzUuMS42IDkuNS0zLjcgOC45LTguOUw4NDUgNjk0Ljl6bS00NjMuNy05NC42YTguMDMgOC4wMyAwIDAwLTExLjMgMEwyMzYuMyA3MzMuOWwtNDMuNy00My43YTguMDEgOC4wMSAwIDAwLTEzLjYgNC43TDE2MC4xIDg1NWMtLjYgNS4xIDMuNyA5LjUgOC45IDguOUwzMjkuMiA4NDVjNi42LS44IDkuNC04LjkgNC43LTEzLjZMMjkwIDc4Ny42IDQyMy43IDY1NGMzLjEtMy4xIDMuMS04LjIgMC0xMS4zbC00Mi40LTQyLjR6IiAvPjwvc3ZnPg==) */
138
144
 
145
+ /**![history](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUzNi4xIDI3M0g0ODhjLTQuNCAwLTggMy42LTggOHYyNzUuM2MwIDIuNiAxLjIgNSAzLjMgNi41bDE2NS4zIDEyMC43YzMuNiAyLjYgOC42IDEuOSAxMS4yLTEuN2wyOC42LTM5YzIuNy0zLjcgMS45LTguNy0xLjctMTEuMkw1NDQuMSA1MjguNVYyODFjMC00LjQtMy42LTgtOC04em0yMTkuOCA3NS4ybDE1Ni44IDM4LjNjNSAxLjIgOS45LTIuNiA5LjktNy43bC44LTE2MS41YzAtNi43LTcuNy0xMC41LTEyLjktNi4zTDc1Mi45IDMzNC4xYTggOCAwIDAwMyAxNC4xem0xNjcuNyAzMDEuMWwtNTYuNy0xOS41YTggOCAwIDAwLTEwLjEgNC44Yy0xLjkgNS4xLTMuOSAxMC4xLTYgMTUuMS0xNy44IDQyLjEtNDMuMyA4MC03NS45IDExMi41YTM1MyAzNTMgMCAwMS0xMTIuNSA3NS45IDM1Mi4xOCAzNTIuMTggMCAwMS0xMzcuNyAyNy44Yy00Ny44IDAtOTQuMS05LjMtMTM3LjctMjcuOGEzNTMgMzUzIDAgMDEtMTEyLjUtNzUuOWMtMzIuNS0zMi41LTU4LTcwLjQtNzUuOS0xMTIuNUEzNTMuNDQgMzUzLjQ0IDAgMDExNzEgNTEyYzAtNDcuOCA5LjMtOTQuMiAyNy44LTEzNy44IDE3LjgtNDIuMSA0My4zLTgwIDc1LjktMTEyLjVhMzUzIDM1MyAwIDAxMTEyLjUtNzUuOUM0MzAuNiAxNjcuMyA0NzcgMTU4IDUyNC44IDE1OHM5NC4xIDkuMyAxMzcuNyAyNy44QTM1MyAzNTMgMCAwMTc3NSAyNjEuN2MxMC4yIDEwLjMgMTkuOCAyMSAyOC42IDMyLjNsNTkuOC00Ni44Qzc4NC43IDE0Ni42IDY2Mi4yIDgxLjkgNTI0LjYgODIgMjg1IDgyLjEgOTIuNiAyNzYuNyA5NSA1MTYuNCA5Ny40IDc1MS45IDI4OC45IDk0MiA1MjQuOCA5NDJjMTg1LjUgMCAzNDMuNS0xMTcuNiA0MDMuNy0yODIuMyAxLjUtNC4yLS43LTguOS00LjktMTAuNHoiIC8+PC9zdmc+) */
146
+
139
147
  /**![holder](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMwMCAyNzYuNWE1NiA1NiAwIDEwNTYtOTcgNTYgNTYgMCAwMC01NiA5N3ptMCAyODRhNTYgNTYgMCAxMDU2LTk3IDU2IDU2IDAgMDAtNTYgOTd6TTY0MCAyMjhhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMDAtMTEyIDB6bTAgMjg0YTU2IDU2IDAgMTAxMTIgMCA1NiA1NiAwIDAwLTExMiAwek0zMDAgODQ0LjVhNTYgNTYgMCAxMDU2LTk3IDU2IDU2IDAgMDAtNTYgOTd6TTY0MCA3OTZhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMDAtMTEyIDB6IiAvPjwvc3ZnPg==) */
140
148
 
141
149
  /**![info-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PHBhdGggZD0iTTQ2NCAzMzZhNDggNDggMCAxMDk2IDAgNDggNDggMCAxMC05NiAwem03MiAxMTJoLTQ4Yy00LjQgMC04IDMuNi04IDh2MjcyYzAgNC40IDMuNiA4IDggOGg0OGM0LjQgMCA4LTMuNiA4LThWNDU2YzAtNC40LTMuNi04LTgtOHoiIC8+PC9zdmc+) */
@@ -166,10 +174,20 @@
166
174
 
167
175
  /**![right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTc2NS43IDQ4Ni44TDMxNC45IDEzNC43QTcuOTcgNy45NyAwIDAwMzAyIDE0MXY3Ny4zYzAgNC45IDIuMyA5LjYgNi4xIDEyLjZsMzYwIDI4MS4xLTM2MCAyODEuMWMtMy45IDMtNi4xIDcuNy02LjEgMTIuNlY4ODNjMCA2LjcgNy43IDEwLjQgMTIuOSA2LjNsNDUwLjgtMzUyLjFhMzEuOTYgMzEuOTYgMCAwMDAtNTAuNHoiIC8+PC9zdmc+) */
168
176
 
177
+ /**![rise](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxNyAyMTEuMWwtMTk5LjIgMjRjLTYuNi44LTkuNCA4LjktNC43IDEzLjZsNTkuMyA1OS4zLTIyNiAyMjYtMTAxLjgtMTAxLjdjLTYuMy02LjMtMTYuNC02LjItMjIuNiAwTDEwMC4zIDc1NC4xYTguMDMgOC4wMyAwIDAwMCAxMS4zbDQ1IDQ1LjJjMy4xIDMuMSA4LjIgMy4xIDExLjMgMEw0MzMuMyA1MzQgNTM1IDYzNS43YzYuMyA2LjIgMTYuNCA2LjIgMjIuNiAwTDgyOSAzNjQuNWw1OS4zIDU5LjNhOC4wMSA4LjAxIDAgMDAxMy42LTQuN2wyNC0xOTkuMmMuNy01LjEtMy43LTkuNS04LjktOC44eiIgLz48L3N2Zz4=) */
178
+
179
+ /**![save](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg5My4zIDI5My4zTDczMC43IDEzMC43Yy03LjUtNy41LTE2LjctMTMtMjYuNy0xNlYxMTJIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY3MzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjMzOC41YzAtMTctNi43LTMzLjItMTguNy00NS4yek0zODQgMTg0aDI1NnYxMDRIMzg0VjE4NHptNDU2IDY1NkgxODRWMTg0aDEzNnYxMzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoMzIwYzE3LjcgMCAzMi0xNC4zIDMyLTMyVjIwNS44bDEzNiAxMzZWODQwek01MTIgNDQyYy03OS41IDAtMTQ0IDY0LjUtMTQ0IDE0NHM2NC41IDE0NCAxNDQgMTQ0IDE0NC02NC41IDE0NC0xNDQtNjQuNS0xNDQtMTQ0LTE0NHptMCAyMjRjLTQ0LjIgMC04MC0zNS44LTgwLTgwczM1LjgtODAgODAtODAgODAgMzUuOCA4MCA4MC0zNS44IDgwLTgwIDgweiIgLz48L3N2Zz4=) */
180
+
169
181
  /**![search](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkwOS42IDg1NC41TDY0OS45IDU5NC44QzY5MC4yIDU0Mi43IDcxMiA0NzkgNzEyIDQxMmMwLTgwLjItMzEuMy0xNTUuNC04Ny45LTIxMi4xLTU2LjYtNTYuNy0xMzItODcuOS0yMTIuMS04Ny45cy0xNTUuNSAzMS4zLTIxMi4xIDg3LjlDMTQzLjIgMjU2LjUgMTEyIDMzMS44IDExMiA0MTJjMCA4MC4xIDMxLjMgMTU1LjUgODcuOSAyMTIuMUMyNTYuNSA2ODAuOCAzMzEuOCA3MTIgNDEyIDcxMmM2NyAwIDEzMC42LTIxLjggMTgyLjctNjJsMjU5LjcgMjU5LjZhOC4yIDguMiAwIDAwMTEuNiAwbDQzLjYtNDMuNWE4LjIgOC4yIDAgMDAwLTExLjZ6TTU3MC40IDU3MC40QzUyOCA2MTIuNyA0NzEuOCA2MzYgNDEyIDYzNnMtMTE2LTIzLjMtMTU4LjQtNjUuNkMyMTEuMyA1MjggMTg4IDQ3MS44IDE4OCA0MTJzMjMuMy0xMTYuMSA2NS42LTE1OC40QzI5NiAyMTEuMyAzNTIuMiAxODggNDEyIDE4OHMxMTYuMSAyMy4yIDE1OC40IDY1LjZTNjM2IDM1Mi4yIDYzNiA0MTJzLTIzLjMgMTE2LjEtNjUuNiAxNTguNHoiIC8+PC9zdmc+) */
170
182
 
183
+ /**![send](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHN0eWxlIC8+PC9kZWZzPjxwYXRoIGQ9Ik05MzEuNCA0OTguOUw5NC45IDc5LjVjLTMuNC0xLjctNy4zLTIuMS0xMS0xLjJhMTUuOTkgMTUuOTkgMCAwMC0xMS43IDE5LjNsODYuMiAzNTIuMmMxLjMgNS4zIDUuMiA5LjYgMTAuNCAxMS4zbDE0Ny43IDUwLjctMTQ3LjYgNTAuN2MtNS4yIDEuOC05LjEgNi0xMC4zIDExLjNMNzIuMiA5MjYuNWMtLjkgMy43LS41IDcuNiAxLjIgMTAuOSAzLjkgNy45IDEzLjUgMTEuMSAyMS41IDcuMmw4MzYuNS00MTdjMy4xLTEuNSA1LjYtNC4xIDcuMi03LjEgMy45LTggLjctMTcuNi03LjItMjEuNnpNMTcwLjggODI2LjNsNTAuMy0yMDUuNiAyOTUuMi0xMDEuM2MyLjMtLjggNC4yLTIuNiA1LTUgMS40LTQuMi0uOC04LjctNS0xMC4yTDIyMS4xIDQwMyAxNzEgMTk4LjJsNjI4IDMxNC45LTYyOC4yIDMxMy4yeiIgLz48L3N2Zz4=) */
184
+
171
185
  /**![setting](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkyNC44IDYyNS43bC02NS41LTU2YzMuMS0xOSA0LjctMzguNCA0LjctNTcuOHMtMS42LTM4LjgtNC43LTU3LjhsNjUuNS01NmEzMi4wMyAzMi4wMyAwIDAwOS4zLTM1LjJsLS45LTIuNmE0NDMuNzQgNDQzLjc0IDAgMDAtNzkuNy0xMzcuOWwtMS44LTIuMWEzMi4xMiAzMi4xMiAwIDAwLTM1LjEtOS41bC04MS4zIDI4LjljLTMwLTI0LjYtNjMuNS00NC05OS43LTU3LjZsLTE1LjctODVhMzIuMDUgMzIuMDUgMCAwMC0yNS44LTI1LjdsLTIuNy0uNWMtNTIuMS05LjQtMTA2LjktOS40LTE1OSAwbC0yLjcuNWEzMi4wNSAzMi4wNSAwIDAwLTI1LjggMjUuN2wtMTUuOCA4NS40YTM1MS44NiAzNTEuODYgMCAwMC05OSA1Ny40bC04MS45LTI5LjFhMzIgMzIgMCAwMC0zNS4xIDkuNWwtMS44IDIuMWE0NDYuMDIgNDQ2LjAyIDAgMDAtNzkuNyAxMzcuOWwtLjkgMi42Yy00LjUgMTIuNS0uOCAyNi41IDkuMyAzNS4ybDY2LjMgNTYuNmMtMy4xIDE4LjgtNC42IDM4LTQuNiA1Ny4xIDAgMTkuMiAxLjUgMzguNCA0LjYgNTcuMUw5OSA2MjUuNWEzMi4wMyAzMi4wMyAwIDAwLTkuMyAzNS4ybC45IDIuNmMxOC4xIDUwLjQgNDQuOSA5Ni45IDc5LjcgMTM3LjlsMS44IDIuMWEzMi4xMiAzMi4xMiAwIDAwMzUuMSA5LjVsODEuOS0yOS4xYzI5LjggMjQuNSA2My4xIDQzLjkgOTkgNTcuNGwxNS44IDg1LjRhMzIuMDUgMzIuMDUgMCAwMDI1LjggMjUuN2wyLjcuNWE0NDkuNCA0NDkuNCAwIDAwMTU5IDBsMi43LS41YTMyLjA1IDMyLjA1IDAgMDAyNS44LTI1LjdsMTUuNy04NWEzNTAgMzUwIDAgMDA5OS43LTU3LjZsODEuMyAyOC45YTMyIDMyIDAgMDAzNS4xLTkuNWwxLjgtMi4xYzM0LjgtNDEuMSA2MS42LTg3LjUgNzkuNy0xMzcuOWwuOS0yLjZjNC41LTEyLjMuOC0yNi4zLTkuMy0zNXpNNzg4LjMgNDY1LjljMi41IDE1LjEgMy44IDMwLjYgMy44IDQ2LjFzLTEuMyAzMS0zLjggNDYuMWwtNi42IDQwLjEgNzQuNyA2My45YTM3MC4wMyAzNzAuMDMgMCAwMS00Mi42IDczLjZMNzIxIDcwMi44bC0zMS40IDI1LjhjLTIzLjkgMTkuNi01MC41IDM1LTc5LjMgNDUuOGwtMzguMSAxNC4zLTE3LjkgOTdhMzc3LjUgMzc3LjUgMCAwMS04NSAwbC0xNy45LTk3LjItMzcuOC0xNC41Yy0yOC41LTEwLjgtNTUtMjYuMi03OC43LTQ1LjdsLTMxLjQtMjUuOS05My40IDMzLjJjLTE3LTIyLjktMzEuMi00Ny42LTQyLjYtNzMuNmw3NS41LTY0LjUtNi41LTQwYy0yLjQtMTQuOS0zLjctMzAuMy0zLjctNDUuNSAwLTE1LjMgMS4yLTMwLjYgMy43LTQ1LjVsNi41LTQwLTc1LjUtNjQuNWMxMS4zLTI2LjEgMjUuNi01MC43IDQyLjYtNzMuNmw5My40IDMzLjIgMzEuNC0yNS45YzIzLjctMTkuNSA1MC4yLTM0LjkgNzguNy00NS43bDM3LjktMTQuMyAxNy45LTk3LjJjMjguMS0zLjIgNTYuOC0zLjIgODUgMGwxNy45IDk3IDM4LjEgMTQuM2MyOC43IDEwLjggNTUuNCAyNi4yIDc5LjMgNDUuOGwzMS40IDI1LjggOTIuOC0zMi45YzE3IDIyLjkgMzEuMiA0Ny42IDQyLjYgNzMuNkw3ODEuOCA0MjZsNi41IDM5Ljl6TTUxMiAzMjZjLTk3LjIgMC0xNzYgNzguOC0xNzYgMTc2czc4LjggMTc2IDE3NiAxNzYgMTc2LTc4LjggMTc2LTE3Ni03OC44LTE3Ni0xNzYtMTc2em03OS4yIDI1NS4yQTExMS42IDExMS42IDAgMDE1MTIgNjE0Yy0yOS45IDAtNTgtMTEuNy03OS4yLTMyLjhBMTExLjYgMTExLjYgMCAwMTQwMCA1MDJjMC0yOS45IDExLjctNTggMzIuOC03OS4yQzQ1NCA0MDEuNiA0ODIuMSAzOTAgNTEyIDM5MGMyOS45IDAgNTggMTEuNiA3OS4yIDMyLjhBMTExLjYgMTExLjYgMCAwMTYyNCA1MDJjMCAyOS45LTExLjcgNTgtMzIuOCA3OS4yeiIgLz48L3N2Zz4=) */
172
186
 
173
187
  /**![sort-ascending](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTgzOS42IDQzMy44TDc0OSAxNTAuNWE5LjI0IDkuMjQgMCAwMC04LjktNi41aC03Ny40Yy00LjEgMC03LjYgMi42LTguOSA2LjVsLTkxLjMgMjgzLjNjLS4zLjktLjUgMS45LS41IDIuOSAwIDUuMSA0LjIgOS4zIDkuMyA5LjNoNTYuNGM0LjIgMCA3LjgtMi44IDktNi44bDE3LjUtNjEuNmg4OWwxNy4zIDYxLjVjMS4xIDQgNC44IDYuOCA5IDYuOGg2MS4yYzEgMCAxLjktLjEgMi44LS40IDIuNC0uOCA0LjMtMi40IDUuNS00LjYgMS4xLTIuMiAxLjMtNC43LjYtNy4xek02NjMuMyAzMjUuNWwzMi44LTExNi45aDYuM2wzMi4xIDExNi45aC03MS4yem0xNDMuNSA0OTIuOUg2NzcuMnYtLjRsMTMyLjYtMTg4LjljMS4xLTEuNiAxLjctMy40IDEuNy01LjR2LTM2LjRjMC01LjEtNC4yLTkuMy05LjMtOS4zaC0yMDRjLTUuMSAwLTkuMyA0LjItOS4zIDkuM3Y0M2MwIDUuMSA0LjIgOS4zIDkuMyA5LjNoMTIyLjZ2LjRMNTg3LjcgODI4LjlhOS4zNSA5LjM1IDAgMDAtMS43IDUuNHYzNi40YzAgNS4xIDQuMiA5LjMgOS4zIDkuM2gyMTEuNGM1LjEgMCA5LjMtNC4yIDkuMy05LjN2LTQzYTkuMiA5LjIgMCAwMC05LjItOS4zek00MTYgNzAyaC03NlYxNzJjMC00LjQtMy42LTgtOC04aC01NmMtNC40IDAtOCAzLjYtOCA4djUzMGgtNzZjLTYuNyAwLTEwLjUgNy44LTYuMyAxM2wxMTIgMTQxLjlhOCA4IDAgMDAxMi42IDBsMTEyLTE0MS45YzQuMS01LjIuNC0xMy02LjMtMTN6IiAvPjwvc3ZnPg==) */
174
188
 
189
+ /**![swap-right](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg3My4xIDU5Ni4ybC0xNjQtMjA4QTMyIDMyIDAgMDA2ODQgMzc2aC02NC44Yy02LjcgMC0xMC40IDcuNy02LjMgMTNsMTQ0LjMgMTgzSDE1MmMtNC40IDAtOCAzLjYtOCA4djYwYzAgNC40IDMuNiA4IDggOGg2OTUuOWMyNi44IDAgNDEuNy0zMC44IDI1LjItNTEuOHoiIC8+PC9zdmc+) */
190
+
191
+ /**![thunderbolt](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg0OCAzNTkuM0g2MjcuN0w4MjUuOCAxMDljNC4xLTUuMy40LTEzLTYuMy0xM0g0MzZjLTIuOCAwLTUuNSAxLjUtNi45IDRMMTcwIDU0Ny41Yy0zLjEgNS4zLjcgMTIgNi45IDEyaDE3NC40bC04OS40IDM1Ny42Yy0xLjkgNy44IDcuNSAxMy4zIDEzLjMgNy43TDg1My41IDM3M2M1LjItNC45IDEuNy0xMy43LTUuNS0xMy43ek0zNzguMiA3MzIuNWw2MC4zLTI0MUgyODEuMWwxODkuNi0zMjcuNGgyMjQuNkw0ODcgNDI3LjRoMjExTDM3OC4yIDczMi41eiIgLz48L3N2Zz4=) */
192
+
175
193
  /**![unordered-list](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxMiAxOTJIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHptMCAyODRIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHptMCAyODRIMzI4Yy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDU4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHpNMTA0IDIyOGE1NiA1NiAwIDEwMTEyIDAgNTYgNTYgMCAxMC0xMTIgMHptMCAyODRhNTYgNTYgMCAxMDExMiAwIDU2IDU2IDAgMTAtMTEyIDB6bTAgMjg0YTU2IDU2IDAgMTAxMTIgMCA1NiA1NiAwIDEwLTExMiAweiIgLz48L3N2Zz4=) */
@@ -529,6 +529,31 @@ const ruleManager = {
529
529
  if (this.dataManager && typeof this.dataManager.logRequest === 'function') {
530
530
  const parsedUrl = url.parse(req.url);
531
531
  try {
532
+ // 获取功能模块名称
533
+ let featureName = '';
534
+ if (interfaceObj.featureId) {
535
+ try {
536
+ const features = await this.dataManager.getFeatures();
537
+ const feature = features.find(f => f.id === interfaceObj.featureId);
538
+ if (feature && feature.name) {
539
+ featureName = feature.name;
540
+ }
541
+ } catch (err) {
542
+ this.log(`[规则处理器] 获取功能模块信息失败: ${err.message}`);
543
+ }
544
+ }
545
+
546
+ // 获取实际命中的响应名称
547
+ let responseName = '';
548
+ if (result && result.mockInfo && result.mockInfo.responseName) {
549
+ responseName = result.mockInfo.responseName;
550
+ } else {
551
+ const headerResponse = res.getHeader('X-Whistle-Mock-Response');
552
+ if (headerResponse) {
553
+ responseName = headerResponse;
554
+ }
555
+ }
556
+
532
557
  this.dataManager.logRequest({
533
558
  type: 'mock_hit',
534
559
  eventType: 'mock_hit',
@@ -541,6 +566,8 @@ const ruleManager = {
541
566
  proxyType: proxyType,
542
567
  interfaceName: interfaceObj.name,
543
568
  interfaceId: interfaceObj.id,
569
+ featureName: featureName,
570
+ responseName: responseName,
544
571
  responseData: result,
545
572
  responseTime: new Date().toISOString(),
546
573
  contentType: res.getHeader('Content-Type') || config.contentType
package/lib/ui-server.js CHANGED
@@ -32,7 +32,17 @@ app.use(bodyParser.urlencoded({ extended: true, limit: '100mb'}));
32
32
  app.use(bodyParser.json({ limit: '100mb' }));
33
33
 
34
34
  // 处理CGI请求
35
- app.all('/cgi-bin/*', function(req, res) {
35
+ app.all('/cgi-bin/*', async function(req, res) {
36
+ // CORS 预检处理
37
+ if (req.method === 'OPTIONS') {
38
+ res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
39
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
40
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
41
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
42
+ res.status(204).end();
43
+ return;
44
+ }
45
+
36
46
  if (req.headers.origin) {
37
47
  res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
38
48
  res.setHeader('Access-Control-Allow-Credentials', true);
@@ -63,10 +73,16 @@ app.all('/cgi-bin/*', function(req, res) {
63
73
  }
64
74
 
65
75
  try {
66
- // 提供数据目录给CGI处理程序
67
- controller.call({ dataDir: DATA_DIR }, req, res);
76
+ // 提供数据目录给CGI处理程序(支持 async controller)
77
+ const result = controller.call({ dataDir: DATA_DIR }, req, res);
78
+ if (result && typeof result.then === 'function') {
79
+ await result;
80
+ }
68
81
  } catch(e) {
69
- res.status(500).end(e.stack);
82
+ console.error('[ui-server] CGI 执行错误:', e.message || e);
83
+ if (!res.headersSent) {
84
+ res.status(500).json({ code: 500, message: e.message || 'Internal Server Error' });
85
+ }
70
86
  }
71
87
  });
72
88
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whistle.mock-plugins",
3
- "version": "1.2.2-beta.23",
3
+ "version": "1.2.2-beta.28",
4
4
  "description": "Whistle 插件,用于快速创建 API 模拟数据",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
package/ui/src/App.css CHANGED
@@ -170,4 +170,4 @@
170
170
  width: 100%;
171
171
  justify-content: flex-start;
172
172
  }
173
- }
173
+ }
@@ -1,5 +1,5 @@
1
- import React, { useState } from 'react';
2
- import { Layout, Menu, Button, Breadcrumb, Typography, Space, theme, Divider, Badge } from 'antd';
1
+ import React, { useState, useMemo, useEffect } from 'react';
2
+ import { Layout, Menu, Button, Breadcrumb, Space, ConfigProvider, theme } from 'antd';
3
3
  import {
4
4
  AppstoreOutlined,
5
5
  ApiOutlined,
@@ -7,21 +7,89 @@ import {
7
7
  FileTextOutlined,
8
8
  MenuFoldOutlined,
9
9
  MenuUnfoldOutlined,
10
- ExperimentOutlined
10
+ ExperimentOutlined,
11
+ BarChartOutlined,
12
+ ThunderboltOutlined
11
13
  } from '@ant-design/icons';
12
14
  import { Link, useLocation } from 'react-router-dom';
13
15
  import VersionModal from './VersionModal';
16
+ import KeyboardShortcutsHelp from './KeyboardShortcutsHelp';
17
+ import { useKeyboardShortcuts } from '../hooks/useKeyboardShortcuts';
14
18
  import '../styles/app-layout.css';
15
19
 
16
20
  const { Header, Content, Sider } = Layout;
17
- const { Title, Text } = Typography;
18
21
 
19
22
  const AppLayout = ({ children }) => {
20
23
  const location = useLocation();
21
24
  const currentPath = location.pathname;
22
25
  const [collapsed, setCollapsed] = useState(false);
23
26
  const [versionModalVisible, setVersionModalVisible] = useState(false);
24
- const { token } = theme.useToken();
27
+ const [shortcutsHelpVisible, setShortcutsHelpVisible] = useState(false);
28
+
29
+ // 注册全局键盘快捷键
30
+ useKeyboardShortcuts();
31
+
32
+ // 监听快捷键帮助事件
33
+ useEffect(() => {
34
+ const handleHelp = () => setShortcutsHelpVisible(true);
35
+ window.addEventListener('keyboard-shortcuts-help', handleHelp);
36
+ return () => window.removeEventListener('keyboard-shortcuts-help', handleHelp);
37
+ }, []);
38
+
39
+ // 赛博朋克主题开关
40
+ const [enableCyber, setEnableCyber] = useState(() => {
41
+ return localStorage.getItem('cyberTheme') !== 'false';
42
+ });
43
+
44
+ useEffect(() => {
45
+ document.body.classList.toggle('cyber-theme', enableCyber);
46
+ }, [enableCyber]);
47
+
48
+ useEffect(() => {
49
+ const handleStorage = () => {
50
+ setEnableCyber(localStorage.getItem('cyberTheme') !== 'false');
51
+ };
52
+ window.addEventListener('storage', handleStorage);
53
+ return () => window.removeEventListener('storage', handleStorage);
54
+ }, []);
55
+
56
+ const cyberTheme = useMemo(() => ({
57
+ token: {
58
+ colorPrimary: '#00f0ff',
59
+ colorPrimaryHover: '#33f3ff',
60
+ colorPrimaryActive: '#00c2cc',
61
+ colorSuccess: '#00ff41',
62
+ colorWarning: '#f0e800',
63
+ colorError: '#ff4d4f',
64
+ colorInfo: '#00f0ff',
65
+ colorText: '#e0e0e0',
66
+ colorTextSecondary: '#a0a0a0',
67
+ colorTextTertiary: '#6b7280',
68
+ colorBorder: '#1a1a2e',
69
+ colorBorderSecondary: '#1a1a2e',
70
+ colorBgBase: '#050508',
71
+ colorBgContainer: '#0f0f1a',
72
+ colorBgElevated: '#141420',
73
+ colorBgLayout: '#0a0a12',
74
+ colorBgSpotlight: '#141420',
75
+ borderRadius: 6,
76
+ borderRadiusSM: 4,
77
+ borderRadiusLG: 8,
78
+ wireframe: false,
79
+ fontFamily: "'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
80
+ fontFamilyCode: "'Share Tech Mono', 'SFMono-Regular', Consolas, monospace",
81
+ },
82
+ algorithm: theme.darkAlgorithm,
83
+ }), []);
84
+
85
+ const lightTheme = useMemo(() => ({
86
+ token: {
87
+ borderRadius: 6,
88
+ borderRadiusSM: 4,
89
+ borderRadiusLG: 8,
90
+ },
91
+ algorithm: theme.defaultAlgorithm,
92
+ }), []);
25
93
 
26
94
  // 版本弹窗控制方法
27
95
  const showVersionModal = () => setVersionModalVisible(true);
@@ -31,6 +99,8 @@ const AppLayout = ({ children }) => {
31
99
  const getSelectedKeys = () => {
32
100
  if (currentPath === '/' || currentPath === '#/') return ['1'];
33
101
  if (currentPath.startsWith('/interface') || currentPath.includes('/interface')) return ['2'];
102
+ if (currentPath === '/stats' || currentPath.includes('/stats')) return ['4'];
103
+ if (currentPath === '/sniffer' || currentPath.includes('/sniffer')) return ['5'];
34
104
  if (currentPath === '/settings' || currentPath.includes('/settings')) return ['3'];
35
105
  return [];
36
106
  };
@@ -48,6 +118,10 @@ const AppLayout = ({ children }) => {
48
118
  if (currentPath.includes('/interface/') && currentPath !== '/interface/') {
49
119
  breadcrumbs.push({ path: currentPath, title: '功能接口详情' });
50
120
  }
121
+ } else if (currentPath === '/stats') {
122
+ breadcrumbs.push({ path: '/stats', title: '请求统计' });
123
+ } else if (currentPath === '/sniffer') {
124
+ breadcrumbs.push({ path: '/sniffer', title: '接口嗅探' });
51
125
  } else if (currentPath === '/settings') {
52
126
  breadcrumbs.push({ path: '/settings', title: '系统设置' });
53
127
  }
@@ -59,6 +133,8 @@ const AppLayout = ({ children }) => {
59
133
  const getPageTitle = () => {
60
134
  if (currentPath === '/' || currentPath === '#/') return '功能模块管理';
61
135
  if (currentPath.startsWith('/interface')) return '接口配置管理';
136
+ if (currentPath === '/stats') return '请求统计';
137
+ if (currentPath === '/sniffer') return '接口嗅探';
62
138
  if (currentPath === '/settings') return '系统设置';
63
139
  return 'Whistle Mock Plugin';
64
140
  };
@@ -75,6 +151,16 @@ const AppLayout = ({ children }) => {
75
151
  icon: <ApiOutlined />,
76
152
  label: <Link to="/interface">接口管理</Link>,
77
153
  },
154
+ {
155
+ key: '4',
156
+ icon: <BarChartOutlined />,
157
+ label: <Link to="/stats">请求统计</Link>,
158
+ },
159
+ {
160
+ key: '5',
161
+ icon: <ThunderboltOutlined />,
162
+ label: <Link to="/sniffer">接口嗅探</Link>,
163
+ },
78
164
  {
79
165
  key: '3',
80
166
  icon: <SettingOutlined />,
@@ -83,88 +169,136 @@ const AppLayout = ({ children }) => {
83
169
  ];
84
170
 
85
171
  const breadcrumbs = getBreadcrumbs();
86
- const colorBgContainer = token.colorBgContainer;
87
- const colorBgLayout = token.colorBgLayout;
88
- const borderRadius = token.borderRadius;
89
172
 
90
173
  return (
91
- <Layout className="app-layout">
92
- {/* 顶部导航栏 */}
93
- <Header className="app-header" style={{ background: colorBgContainer }}>
94
- <div className="header-left">
95
- <div className="logo-container">
96
- <div className="logo-icon-group">
97
- <ExperimentOutlined className="logo-icon logo-icon-secondary" />
174
+ <ConfigProvider theme={enableCyber ? cyberTheme : lightTheme}>
175
+ <Layout className="app-layout">
176
+ {/* 顶部导航栏 */}
177
+ <Header className="app-header" style={{ background: enableCyber ? '#0f0f1a' : '#ffffff', borderBottom: enableCyber ? '1px solid #1a1a2e' : '1px solid #f0f0f0' }}>
178
+ <div className="header-left">
179
+ <div className="logo-container">
180
+ <div className="logo-icon-group">
181
+ <ExperimentOutlined className="logo-icon logo-icon-secondary" style={{ color: enableCyber ? '#00ff41' : '#52c41a' }} />
182
+ </div>
183
+ <div
184
+ className="logo-text"
185
+ style={enableCyber ? {
186
+ background: 'linear-gradient(135deg, #00f0ff, #00ff41)',
187
+ WebkitBackgroundClip: 'text',
188
+ WebkitTextFillColor: 'transparent',
189
+ } : {
190
+ background: 'linear-gradient(135deg, #1890ff, #52c41a)',
191
+ WebkitBackgroundClip: 'text',
192
+ WebkitTextFillColor: 'transparent',
193
+ }}
194
+ >
195
+ MockMaster
196
+ </div>
98
197
  </div>
99
- <div className="logo-text">MockMaster</div>
198
+ <Button
199
+ type="text"
200
+ icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
201
+ onClick={() => setCollapsed(!collapsed)}
202
+ className="collapse-button"
203
+ />
100
204
  </div>
101
- <Button
102
- type="text"
103
- icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
104
- onClick={() => setCollapsed(!collapsed)}
105
- className="collapse-button"
106
- />
107
- </div>
108
- <div className="header-right">
109
- <Space>
110
- <Button
111
- type="text"
112
- size="small"
113
- className="version-button"
114
- onClick={showVersionModal}
115
- >
116
- <Text type="secondary">v{__APP_VERSION__}</Text>
117
- </Button>
118
- </Space>
119
- </div>
120
- </Header>
121
-
122
- <Layout>
123
- {/* 侧边导航 */}
124
- <Sider
125
- width={220}
126
- className="app-sider"
127
- collapsed={collapsed}
128
- collapsible
129
- trigger={null}
130
- style={{ background: colorBgContainer }}
131
- >
132
- <Menu
133
- mode="inline"
134
- selectedKeys={getSelectedKeys()}
135
- items={menuItems}
136
- style={{
137
- height: '100%',
138
- borderRight: 0,
139
- padding: '8px',
140
- }}
141
- />
142
- </Sider>
205
+ <div className="header-right">
206
+ <Space>
207
+ <Button
208
+ type="text"
209
+ size="small"
210
+ className="version-button"
211
+ onClick={showVersionModal}
212
+ >
213
+ <span style={{ color: enableCyber ? '#6b7280' : '#000000d9', fontFamily: "'Share Tech Mono', monospace" }}>
214
+ v{__APP_VERSION__}
215
+ </span>
216
+ </Button>
217
+ </Space>
218
+ </div>
219
+ </Header>
143
220
 
144
- {/* 主内容区 */}
145
- <Layout className="app-content-wrapper" style={{ padding: 0, background: colorBgLayout }}>
146
- {/* 内容区 */}
147
- <Content
148
- className="app-content"
149
- style={{
150
- background: colorBgContainer,
151
- padding: 24,
152
- borderRadius: borderRadius,
153
- minHeight: 280,
154
- }}
221
+ <Layout>
222
+ {/* 侧边导航 */}
223
+ <Sider
224
+ width={220}
225
+ className="app-sider"
226
+ collapsed={collapsed}
227
+ collapsible
228
+ trigger={null}
229
+ style={{ background: enableCyber ? '#0f0f1a' : '#ffffff' }}
155
230
  >
156
- {children}
157
- </Content>
231
+ <Menu
232
+ mode="inline"
233
+ selectedKeys={getSelectedKeys()}
234
+ items={menuItems}
235
+ style={{
236
+ height: '100%',
237
+ borderRight: 0,
238
+ padding: '8px',
239
+ background: enableCyber ? '#0f0f1a' : '#ffffff',
240
+ }}
241
+ />
242
+ </Sider>
243
+
244
+ {/* 主内容区 */}
245
+ <Layout className="app-content-wrapper" style={{ padding: 0, background: enableCyber ? '#0a0a12' : '#f5f5f5' }}>
246
+ {/* 面包屑和标题 */}
247
+ <div style={{ padding: '16px 24px 0' }}>
248
+ <Breadcrumb className="app-breadcrumb" style={{ marginBottom: 16 }}>
249
+ {breadcrumbs.map((crumb, index) => (
250
+ <Breadcrumb.Item key={index}>
251
+ {index < breadcrumbs.length - 1 ? (
252
+ <Link to={crumb.path} style={{ color: enableCyber ? '#a0a0a0' : '#000000d9' }}>{crumb.title}</Link>
253
+ ) : (
254
+ <span style={{ color: enableCyber ? '#e0e0e0' : '#000000d9', fontWeight: 500 }}>{crumb.title}</span>
255
+ )}
256
+ </Breadcrumb.Item>
257
+ ))}
258
+ </Breadcrumb>
259
+ <h1 style={{
260
+ margin: 0,
261
+ fontSize: 22,
262
+ fontWeight: 700,
263
+ color: enableCyber ? '#e0e0e0' : '#000000d9',
264
+ fontFamily: enableCyber ? "'Orbitron', sans-serif" : undefined,
265
+ letterSpacing: enableCyber ? '0.5px' : undefined,
266
+ }}>
267
+ {getPageTitle()}
268
+ </h1>
269
+ </div>
270
+
271
+ {/* 内容区 */}
272
+ <Content
273
+ className="app-content"
274
+ style={{
275
+ background: enableCyber ? '#0f0f1a' : '#ffffff',
276
+ padding: 24,
277
+ borderRadius: 6,
278
+ minHeight: 280,
279
+ margin: '16px 24px 24px',
280
+ border: enableCyber ? '1px solid #1a1a2e' : '1px solid #f0f0f0',
281
+ }}
282
+ >
283
+ {children}
284
+ </Content>
285
+ </Layout>
158
286
  </Layout>
287
+
288
+ {/* 版本信息弹窗 */}
289
+ <VersionModal
290
+ visible={versionModalVisible}
291
+ onCancel={hideVersionModal}
292
+ />
293
+
294
+ {/* 快捷键帮助弹窗 */}
295
+ <KeyboardShortcutsHelp
296
+ visible={shortcutsHelpVisible}
297
+ onClose={() => setShortcutsHelpVisible(false)}
298
+ />
159
299
  </Layout>
160
-
161
- {/* 版本信息弹窗 */}
162
- <VersionModal
163
- visible={versionModalVisible}
164
- onCancel={hideVersionModal}
165
- />
166
- </Layout>
300
+ </ConfigProvider>
167
301
  );
168
302
  };
169
303
 
170
- export default AppLayout;
304
+ export default AppLayout;
@@ -6,7 +6,7 @@ const FeatureCard = ({ feature }) => {
6
6
 
7
7
  // 生成随机的主题色(实际项目中可能会根据某种规则来确定)
8
8
  const getRandomColor = () => {
9
- const colors = ['#1890ff', '#13c2c2', '#52c41a', '#faad14', '#722ed1'];
9
+ const colors = ['#00f0ff', '#00ff41', '#f0e800', '#ff00a0', '#bd00ff'];
10
10
  return colors[Math.floor(Math.random() * colors.length)];
11
11
  };
12
12
 
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { Modal, Table } from 'antd';
3
+ import { getShortcutsList } from '../hooks/useKeyboardShortcuts';
4
+
5
+ const KeyboardShortcutsHelp = ({ visible, onClose }) => {
6
+ const shortcuts = getShortcutsList();
7
+
8
+ const columns = [
9
+ {
10
+ title: '快捷键',
11
+ dataIndex: 'key',
12
+ key: 'key',
13
+ width: 180,
14
+ render: (text) => (
15
+ <kbd style={{
16
+ display: 'inline-block',
17
+ padding: '4px 8px',
18
+ fontSize: '12px',
19
+ fontFamily: 'monospace',
20
+ lineHeight: 1,
21
+ color: '#333',
22
+ background: '#f5f5f5',
23
+ border: '1px solid #d9d9d9',
24
+ borderRadius: '4px',
25
+ boxShadow: '0 1px 0 rgba(0,0,0,0.1)',
26
+ }}>
27
+ {text}
28
+ </kbd>
29
+ ),
30
+ },
31
+ {
32
+ title: '功能',
33
+ dataIndex: 'desc',
34
+ key: 'desc',
35
+ },
36
+ ];
37
+
38
+ return (
39
+ <Modal
40
+ title="⌨️ 键盘快捷键"
41
+ open={visible}
42
+ onCancel={onClose}
43
+ footer={null}
44
+ width={480}
45
+ >
46
+ <Table
47
+ dataSource={shortcuts.map((s, i) => ({ ...s, id: i }))}
48
+ columns={columns}
49
+ rowKey="id"
50
+ pagination={false}
51
+ size="small"
52
+ showHeader={false}
53
+ />
54
+ </Modal>
55
+ );
56
+ };
57
+
58
+ export default KeyboardShortcutsHelp;
@@ -22,22 +22,20 @@ const PreviewModal = ({
22
22
  <div style={{
23
23
  marginBottom: '16px',
24
24
  padding: '8px',
25
- background: '#f9f9f9',
26
25
  borderRadius: '4px',
27
- borderLeft: '4px solid #1890ff'
26
+ borderLeft: '4px solid #00f0ff'
28
27
  }}>
29
28
  <div style={{ fontWeight: 'bold', marginBottom: '4px' }}>描述:</div>
30
- <div>{previewContent.description}</div>
29
+ <div style={{ opacity: 0.7 }}>{previewContent.description}</div>
31
30
  </div>
32
31
  )}
33
32
 
34
33
  <div style={{
35
34
  maxHeight: '60vh',
36
35
  overflow: 'auto',
37
- backgroundColor: '#f5f5f5',
38
36
  padding: '16px',
39
37
  borderRadius: '4px',
40
- fontFamily: 'monospace'
38
+ fontFamily: "'Share Tech Mono', monospace",
41
39
  }}>
42
40
  <pre style={{ margin: 0, whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>
43
41
  {previewContent?.content}
@@ -47,4 +45,4 @@ const PreviewModal = ({
47
45
  );
48
46
  };
49
47
 
50
- export default PreviewModal;
48
+ export default PreviewModal;