whistle.mock-plugins 1.0.6-beta.2 → 1.0.6-beta.21

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.
@@ -69,12 +69,16 @@
69
69
 
70
70
  /**![check-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0xOTMuNSAzMDEuN2wtMjEwLjYgMjkyYTMxLjggMzEuOCAwIDAxLTUxLjcgMEwzMTguNSA0ODQuOWMtMy44LTUuMyAwLTEyLjcgNi41LTEyLjdoNDYuOWMxMC4yIDAgMTkuOSA0LjkgMjUuOSAxMy4zbDcxLjIgOTguOCAxNTcuMi0yMThjNi04LjMgMTUuNi0xMy4zIDI1LjktMTMuM0g2OTljNi41IDAgMTAuMyA3LjQgNi41IDEyLjd6IiAvPjwvc3ZnPg==) */
71
71
 
72
+ /**![check-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTY5OSAzNTNoLTQ2LjljLTEwLjIgMC0xOS45IDQuOS0yNS45IDEzLjNMNDY5IDU4NC4zbC03MS4yLTk4LjhjLTYtOC4zLTE1LjYtMTMuMy0yNS45LTEzLjNIMzI1Yy02LjUgMC0xMC4zIDcuNC02LjUgMTIuN2wxMjQuNiAxNzIuOGEzMS44IDMxLjggMCAwMDUxLjcgMGwyMTAuNi0yOTJjMy45LTUuMy4xLTEyLjctNi40LTEyLjd6IiAvPjxwYXRoIGQ9Ik01MTIgNjRDMjY0LjYgNjQgNjQgMjY0LjYgNjQgNTEyczIwMC42IDQ0OCA0NDggNDQ4IDQ0OC0yMDAuNiA0NDgtNDQ4Uzc1OS40IDY0IDUxMiA2NHptMCA4MjBjLTIwNS40IDAtMzcyLTE2Ni42LTM3Mi0zNzJzMTY2LjYtMzcyIDM3Mi0zNzIgMzcyIDE2Ni42IDM3MiAzNzItMTY2LjYgMzcyLTM3MiAzNzJ6IiAvPjwvc3ZnPg==) */
73
+
72
74
  /**![check](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkxMiAxOTBoLTY5LjljLTkuOCAwLTE5LjEgNC41LTI1LjEgMTIuMkw0MDQuNyA3MjQuNSAyMDcgNDc0YTMyIDMyIDAgMDAtMjUuMS0xMi4ySDExMmMtNi43IDAtMTAuNCA3LjctNi4zIDEyLjlsMjczLjkgMzQ3YzEyLjggMTYuMiAzNy40IDE2LjIgNTAuMyAwbDQ4OC40LTYxOC45YzQuMS01LjEuNC0xMi44LTYuMy0xMi44eiIgLz48L3N2Zz4=) */
73
75
 
74
76
  /**![close-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNTEyIDY0YzI0Ny40IDAgNDQ4IDIwMC42IDQ0OCA0NDhTNzU5LjQgOTYwIDUxMiA5NjAgNjQgNzU5LjQgNjQgNTEyIDI2NC42IDY0IDUxMiA2NHptMTI3Ljk4IDI3NC44MmgtLjA0bC0uMDguMDZMNTEyIDQ2Ni43NSAzODQuMTQgMzM4Ljg4Yy0uMDQtLjA1LS4wNi0uMDYtLjA4LS4wNmEuMTIuMTIgMCAwMC0uMDcgMGMtLjAzIDAtLjA1LjAxLS4wOS4wNWwtNDUuMDIgNDUuMDJhLjIuMiAwIDAwLS4wNS4wOS4xMi4xMiAwIDAwMCAuMDd2LjAyYS4yNy4yNyAwIDAwLjA2LjA2TDQ2Ni43NSA1MTIgMzM4Ljg4IDYzOS44NmMtLjA1LjA0LS4wNi4wNi0uMDYuMDhhLjEyLjEyIDAgMDAwIC4wN2MwIC4wMy4wMS4wNS4wNS4wOWw0NS4wMiA0NS4wMmEuMi4yIDAgMDAuMDkuMDUuMTIuMTIgMCAwMC4wNyAwYy4wMiAwIC4wNC0uMDEuMDgtLjA1TDUxMiA1NTcuMjVsMTI3Ljg2IDEyNy44N2MuMDQuMDQuMDYuMDUuMDguMDVhLjEyLjEyIDAgMDAuMDcgMGMuMDMgMCAuMDUtLjAxLjA5LS4wNWw0NS4wMi00NS4wMmEuMi4yIDAgMDAuMDUtLjA5LjEyLjEyIDAgMDAwLS4wN3YtLjAyYS4yNy4yNyAwIDAwLS4wNS0uMDZMNTU3LjI1IDUxMmwxMjcuODctMTI3Ljg2Yy4wNC0uMDQuMDUtLjA2LjA1LS4wOGEuMTIuMTIgMCAwMDAtLjA3YzAtLjAzLS4wMS0uMDUtLjA1LS4wOWwtNDUuMDItNDUuMDJhLjIuMiAwIDAwLS4wOS0uMDUuMTIuMTIgMCAwMC0uMDcgMHoiIC8+PC9zdmc+) */
75
77
 
76
78
  /**![close](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdmlld0JveD0iNjQgNjQgODk2IDg5NiIgZm9jdXNhYmxlPSJmYWxzZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNzk5Ljg2IDE2Ni4zMWMuMDIgMCAuMDQuMDIuMDguMDZsNTcuNjkgNTcuN2MuMDQuMDMuMDUuMDUuMDYuMDhhLjEyLjEyIDAgMDEwIC4wNmMwIC4wMy0uMDIuMDUtLjA2LjA5TDU2OS45MyA1MTJsMjg3LjcgMjg3LjdjLjA0LjA0LjA1LjA2LjA2LjA5YS4xMi4xMiAwIDAxMCAuMDdjMCAuMDItLjAyLjA0LS4wNi4wOGwtNTcuNyA1Ny42OWMtLjAzLjA0LS4wNS4wNS0uMDcuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMyAwLS4wNS0uMDItLjA5LS4wNkw1MTIgNTY5LjkzbC0yODcuNyAyODcuN2MtLjA0LjA0LS4wNi4wNS0uMDkuMDZhLjEyLjEyIDAgMDEtLjA3IDBjLS4wMiAwLS4wNC0uMDItLjA4LS4wNmwtNTcuNjktNTcuN2MtLjA0LS4wMy0uMDUtLjA1LS4wNi0uMDdhLjEyLjEyIDAgMDEwLS4wN2MwLS4wMy4wMi0uMDUuMDYtLjA5TDQ1NC4wNyA1MTJsLTI4Ny43LTI4Ny43Yy0uMDQtLjA0LS4wNS0uMDYtLjA2LS4wOWEuMTIuMTIgMCAwMTAtLjA3YzAtLjAyLjAyLS4wNC4wNi0uMDhsNTcuNy01Ny42OWMuMDMtLjA0LjA1LS4wNS4wNy0uMDZhLjEyLjEyIDAgMDEuMDcgMGMuMDMgMCAuMDUuMDIuMDkuMDZMNTEyIDQ1NC4wN2wyODcuNy0yODcuN2MuMDQtLjA0LjA2LS4wNS4wOS0uMDZhLjEyLjEyIDAgMDEuMDcgMHoiIC8+PC9zdmc+) */
77
79
 
80
+ /**![code](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxNiA2NzNjMCA0LjQgMy40IDggNy41IDhoMTg1YzQuMSAwIDcuNS0zLjYgNy41LTh2LTQ4YzAtNC40LTMuNC04LTcuNS04aC0xODVjLTQuMSAwLTcuNSAzLjYtNy41IDh2NDh6bS0xOTQuOSA2LjFsMTkyLTE2MWMzLjgtMy4yIDMuOC05LjEgMC0xMi4zbC0xOTItMTYwLjlBNy45NSA3Ljk1IDAgMDAzMDggMzUxdjYyLjdjMCAyLjQgMSA0LjYgMi45IDYuMUw0MjAuNyA1MTJsLTEwOS44IDkyLjJhOC4xIDguMSAwIDAwLTIuOSA2LjFWNjczYzAgNi44IDcuOSAxMC41IDEzLjEgNi4xek04ODAgMTEySDE0NGMtMTcuNyAwLTMyIDE0LjMtMzIgMzJ2NzM2YzAgMTcuNyAxNC4zIDMyIDMyIDMyaDczNmMxNy43IDAgMzItMTQuMyAzMi0zMlYxNDRjMC0xNy43LTE0LjMtMzItMzItMzJ6bS00MCA3MjhIMTg0VjE4NGg2NTZ2NjU2eiIgLz48L3N2Zz4=) */
81
+
78
82
  /**![copy](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTgzMiA2NEgyOTZjLTQuNCAwLTggMy42LTggOHY1NmMwIDQuNCAzLjYgOCA4IDhoNDk2djY4OGMwIDQuNCAzLjYgOCA4IDhoNTZjNC40IDAgOC0zLjYgOC04Vjk2YzAtMTcuNy0xNC4zLTMyLTMyLTMyek03MDQgMTkySDE5MmMtMTcuNyAwLTMyIDE0LjMtMzIgMzJ2NTMwLjdjMCA4LjUgMy40IDE2LjYgOS40IDIyLjZsMTczLjMgMTczLjNjMi4yIDIuMiA0LjcgNCA3LjQgNS41djEuOWg0LjJjMy41IDEuMyA3LjIgMiAxMSAySDcwNGMxNy43IDAgMzItMTQuMyAzMi0zMlYyMjRjMC0xNy43LTE0LjMtMzItMzItMzJ6TTM1MCA4NTYuMkwyNjMuOSA3NzBIMzUwdjg2LjJ6TTY2NCA4ODhINDE0Vjc0NmMwLTIyLjEtMTcuOS00MC00MC00MEgyMzJWMjY0aDQzMnY2MjR6IiAvPjwvc3ZnPg==) */
79
83
 
80
84
  /**![dashboard](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTkyNC44IDM4NS42YTQ0Ni43IDQ0Ni43IDAgMDAtOTYtMTQyLjQgNDQ2LjcgNDQ2LjcgMCAwMC0xNDIuNC05NkM2MzEuMSAxMjMuOCA1NzIuNSAxMTIgNTEyIDExMnMtMTE5LjEgMTEuOC0xNzQuNCAzNS4yYTQ0Ni43IDQ0Ni43IDAgMDAtMTQyLjQgOTYgNDQ2LjcgNDQ2LjcgMCAwMC05NiAxNDIuNEM3NS44IDQ0MC45IDY0IDQ5OS41IDY0IDU2MGMwIDEzMi43IDU4LjMgMjU3LjcgMTU5LjkgMzQzLjFsMS43IDEuNGM1LjggNC44IDEzLjEgNy41IDIwLjYgNy41aDUzMS43YzcuNSAwIDE0LjgtMi43IDIwLjYtNy41bDEuNy0xLjRDOTAxLjcgODE3LjcgOTYwIDY5Mi43IDk2MCA1NjBjMC02MC41LTExLjktMTE5LjEtMzUuMi0xNzQuNHpNNzYxLjQgODM2SDI2Mi42QTM3MS4xMiAzNzEuMTIgMCAwMTE0MCA1NjBjMC05OS40IDM4LjctMTkyLjggMTA5LTI2MyA3MC4zLTcwLjMgMTYzLjctMTA5IDI2My0xMDkgOTkuNCAwIDE5Mi44IDM4LjcgMjYzIDEwOSA3MC4zIDcwLjMgMTA5IDE2My43IDEwOSAyNjMgMCAxMDUuNi00NC41IDIwNS41LTEyMi42IDI3NnpNNjIzLjUgNDIxLjVhOC4wMyA4LjAzIDAgMDAtMTEuMyAwTDUyNy43IDUwNmMtMTguNy01LTM5LjQtLjItNTQuMSAxNC41YTU1Ljk1IDU1Ljk1IDAgMDAwIDc5LjIgNTUuOTUgNTUuOTUgMCAwMDc5LjIgMCA1NS44NyA1NS44NyAwIDAwMTQuNS01NC4xbDg0LjUtODQuNWMzLjEtMy4xIDMuMS04LjIgMC0xMS4zbC0yOC4zLTI4LjN6TTQ5MCAzMjBoNDRjNC40IDAgOC0zLjYgOC04di04MGMwLTQuNC0zLjYtOC04LThoLTQ0Yy00LjQgMC04IDMuNi04IDh2ODBjMCA0LjQgMy42IDggOCA4em0yNjAgMjE4djQ0YzAgNC40IDMuNiA4IDggOGg4MGM0LjQgMCA4LTMuNiA4LTh2LTQ0YzAtNC40LTMuNi04LTgtOGgtODBjLTQuNCAwLTggMy42LTggOHptMTIuNy0xOTcuMmwtMzEuMS0zMS4xYTguMDMgOC4wMyAwIDAwLTExLjMgMGwtNTYuNiA1Ni42YTguMDMgOC4wMyAwIDAwMCAxMS4zbDMxLjEgMzEuMWMzLjEgMy4xIDguMiAzLjEgMTEuMyAwbDU2LjYtNTYuNmMzLjEtMy4xIDMuMS04LjIgMC0xMS4zem0tNDU4LjYtMzEuMWE4LjAzIDguMDMgMCAwMC0xMS4zIDBsLTMxLjEgMzEuMWE4LjAzIDguMDMgMCAwMDAgMTEuM2w1Ni42IDU2LjZjMy4xIDMuMSA4LjIgMy4xIDExLjMgMGwzMS4xLTMxLjFjMy4xLTMuMSAzLjEtOC4yIDAtMTEuM2wtNTYuNi01Ni42ek0yNjIgNTMwaC04MGMtNC40IDAtOCAzLjYtOCA4djQ0YzAgNC40IDMuNiA4IDggOGg4MGM0LjQgMCA4LTMuNiA4LTh2LTQ0YzAtNC40LTMuNi04LTgtOHoiIC8+PC9zdmc+) */
@@ -103,6 +107,8 @@
103
107
 
104
108
  /**![eye](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTk0Mi4yIDQ4Ni4yQzg0Ny40IDI4Ni41IDcwNC4xIDE4NiA1MTIgMTg2Yy0xOTIuMiAwLTMzNS40IDEwMC41LTQzMC4yIDMwMC4zYTYwLjMgNjAuMyAwIDAwMCA1MS41QzE3Ni42IDczNy41IDMxOS45IDgzOCA1MTIgODM4YzE5Mi4yIDAgMzM1LjQtMTAwLjUgNDMwLjItMzAwLjMgNy43LTE2LjIgNy43LTM1IDAtNTEuNXpNNTEyIDc2NmMtMTYxLjMgMC0yNzkuNC04MS44LTM2Mi43LTI1NEMyMzIuNiAzMzkuOCAzNTAuNyAyNTggNTEyIDI1OGMxNjEuMyAwIDI3OS40IDgxLjggMzYyLjcgMjU0Qzc5MS41IDY4NC4yIDY3My40IDc2NiA1MTIgNzY2em0tNC00MzBjLTk3LjIgMC0xNzYgNzguOC0xNzYgMTc2czc4LjggMTc2IDE3NiAxNzYgMTc2LTc4LjggMTc2LTE3Ni03OC44LTE3Ni0xNzYtMTc2em0wIDI4OGMtNjEuOSAwLTExMi01MC4xLTExMi0xMTJzNTAuMS0xMTIgMTEyLTExMiAxMTIgNTAuMSAxMTIgMTEyLTUwLjEgMTEyLTExMiAxMTJ6IiAvPjwvc3ZnPg==) */
105
109
 
110
+ /**![file-text](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1NC42IDI4OC42TDYzOS40IDczLjRjLTYtNi0xNC4xLTkuNC0yMi42LTkuNEgxOTJjLTE3LjcgMC0zMiAxNC4zLTMyIDMydjgzMmMwIDE3LjcgMTQuMyAzMiAzMiAzMmg2NDBjMTcuNyAwIDMyLTE0LjMgMzItMzJWMzExLjNjMC04LjUtMy40LTE2LjctOS40LTIyLjd6TTc5MC4yIDMyNkg2MDJWMTM3LjhMNzkwLjIgMzI2em0xLjggNTYySDIzMlYxMzZoMzAydjIxNmE0MiA0MiAwIDAwNDIgNDJoMjE2djQ5NHpNNTA0IDYxOEgzMjBjLTQuNCAwLTggMy42LTggOHY0OGMwIDQuNCAzLjYgOCA4IDhoMTg0YzQuNCAwIDgtMy42IDgtOHYtNDhjMC00LjQtMy42LTgtOC04ek0zMTIgNDkwdjQ4YzAgNC40IDMuNiA4IDggOGgzODRjNC40IDAgOC0zLjYgOC04di00OGMwLTQuNC0zLjYtOC04LThIMzIwYy00LjQgMC04IDMuNi04IDh6IiAvPjwvc3ZnPg==) */
111
+
106
112
  /**![file](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTg1NC42IDI4OC42TDYzOS40IDczLjRjLTYtNi0xNC4xLTkuNC0yMi42LTkuNEgxOTJjLTE3LjcgMC0zMiAxNC4zLTMyIDMydjgzMmMwIDE3LjcgMTQuMyAzMiAzMiAzMmg2NDBjMTcuNyAwIDMyLTE0LjMgMzItMzJWMzExLjNjMC04LjUtMy40LTE2LjctOS40LTIyLjd6TTc5MC4yIDMyNkg2MDJWMTM3LjhMNzkwLjIgMzI2em0xLjggNTYySDIzMlYxMzZoMzAydjIxNmE0MiA0MiAwIDAwNDIgNDJoMjE2djQ5NHoiIC8+PC9zdmc+) */
107
113
 
108
114
  /**![filter](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTM0OSA4MzhjMCAxNy43IDE0LjIgMzIgMzEuOCAzMmgyNjIuNGMxNy42IDAgMzEuOC0xNC4zIDMxLjgtMzJWNjQySDM0OXYxOTZ6bTUzMS4xLTY4NEgxNDMuOWMtMjQuNSAwLTM5LjggMjYuNy0yNy41IDQ4bDIyMS4zIDM3NmgzNDguOGwyMjEuMy0zNzZjMTIuMS0yMS4zLTMuMi00OC0yNy43LTQ4eiIgLz48L3N2Zz4=) */
@@ -127,12 +133,12 @@
127
133
 
128
134
  /**![menu-unfold](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwOCA0NDJoNDgwYzQuNCAwIDgtMy42IDgtOHYtNTZjMC00LjQtMy42LTgtOC04SDQwOGMtNC40IDAtOCAzLjYtOCA4djU2YzAgNC40IDMuNiA4IDggOHptLTggMjA0YzAgNC40IDMuNiA4IDggOGg0ODBjNC40IDAgOC0zLjYgOC04di01NmMwLTQuNC0zLjYtOC04LThINDA4Yy00LjQgMC04IDMuNi04IDh2NTZ6bTUwNC00ODZIMTIwYy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDc4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHptMCA2MzJIMTIwYy00LjQgMC04IDMuNi04IDh2NTZjMCA0LjQgMy42IDggOCA4aDc4NGM0LjQgMCA4LTMuNiA4LTh2LTU2YzAtNC40LTMuNi04LTgtOHpNMTQyLjQgNjQyLjFMMjk4LjcgNTE5YTguODQgOC44NCAwIDAwMC0xMy45TDE0Mi40IDM4MS45Yy01LjgtNC42LTE0LjQtLjUtMTQuNCA2Ljl2MjQ2LjNhOC45IDguOSAwIDAwMTQuNCA3eiIgLz48L3N2Zz4=) */
129
135
 
130
- /**![minus-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTY5NiA0ODBIMzI4Yy00LjQgMC04IDMuNi04IDh2NDhjMCA0LjQgMy42IDggOCA4aDM2OGM0LjQgMCA4LTMuNiA4LTh2LTQ4YzAtNC40LTMuNi04LTgtOHoiIC8+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PC9zdmc+) */
131
-
132
136
  /**![minus-square](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMyOCA1NDRoMzY4YzQuNCAwIDgtMy42IDgtOHYtNDhjMC00LjQtMy42LTgtOC04SDMyOGMtNC40IDAtOCAzLjYtOCA4djQ4YzAgNC40IDMuNiA4IDggOHoiIC8+PHBhdGggZD0iTTg4MCAxMTJIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY3MzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjE0NGMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDcyOEgxODRWMTg0aDY1NnY2NTZ6IiAvPjwvc3ZnPg==) */
133
137
 
134
138
  /**![play-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PHBhdGggZD0iTTcxOS40IDQ5OS4xbC0yOTYuMS0yMTVBMTUuOSAxNS45IDAgMDAzOTggMjk3djQzMGMwIDEzLjEgMTQuOCAyMC41IDI1LjMgMTIuOWwyOTYuMS0yMTVhMTUuOSAxNS45IDAgMDAwLTI1Ljh6bS0yNTcuNiAxMzRWMzkwLjlMNjI4LjUgNTEyIDQ2MS44IDYzMy4xeiIgLz48L3N2Zz4=) */
135
139
 
140
+ /**![plus-circle](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTY5NiA0ODBINTQ0VjMyOGMwLTQuNC0zLjYtOC04LThoLTQ4Yy00LjQgMC04IDMuNi04IDh2MTUySDMyOGMtNC40IDAtOCAzLjYtOCA4djQ4YzAgNC40IDMuNiA4IDggOGgxNTJ2MTUyYzAgNC40IDMuNiA4IDggOGg0OGM0LjQgMCA4LTMuNiA4LThWNTQ0aDE1MmM0LjQgMCA4LTMuNiA4LTh2LTQ4YzAtNC40LTMuNi04LTgtOHoiIC8+PHBhdGggZD0iTTUxMiA2NEMyNjQuNiA2NCA2NCAyNjQuNiA2NCA1MTJzMjAwLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMC42IDQ0OC00NDhTNzU5LjQgNjQgNTEyIDY0em0wIDgyMGMtMjA1LjQgMC0zNzItMTY2LjYtMzcyLTM3MnMxNjYuNi0zNzIgMzcyLTM3MiAzNzIgMTY2LjYgMzcyIDM3Mi0xNjYuNiAzNzItMzcyIDM3MnoiIC8+PC9zdmc+) */
141
+
136
142
  /**![plus-square](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMyOCA1NDRoMTUydjE1MmMwIDQuNCAzLjYgOCA4IDhoNDhjNC40IDAgOC0zLjYgOC04VjU0NGgxNTJjNC40IDAgOC0zLjYgOC04di00OGMwLTQuNC0zLjYtOC04LThINTQ0VjMyOGMwLTQuNC0zLjYtOC04LThoLTQ4Yy00LjQgMC04IDMuNi04IDh2MTUySDMyOGMtNC40IDAtOCAzLjYtOCA4djQ4YzAgNC40IDMuNiA4IDggOHoiIC8+PHBhdGggZD0iTTg4MCAxMTJIMTQ0Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnY3MzZjMCAxNy43IDE0LjMgMzIgMzIgMzJoNzM2YzE3LjcgMCAzMi0xNC4zIDMyLTMyVjE0NGMwLTE3LjctMTQuMy0zMi0zMi0zMnptLTQwIDcyOEgxODRWMTg0aDY1NnY2NTZ6IiAvPjwvc3ZnPg==) */
137
143
 
138
144
  /**![plus](data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTAiIGhlaWdodD0iNTAiIGZpbGw9IiNjYWNhY2EiIHZpZXdCb3g9IjY0IDY0IDg5NiA4OTYiIGZvY3VzYWJsZT0iZmFsc2UiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ4MiAxNTJoNjBxOCAwIDggOHY3MDRxMCA4LTggOGgtNjBxLTggMC04LThWMTYwcTAtOCA4LTh6IiAvPjxwYXRoIGQ9Ik0xOTIgNDc0aDY3MnE4IDAgOCA4djYwcTAgOC04IDhIMTYwcS04IDAtOC04di02MHEwLTggOC04eiIgLz48L3N2Zz4=) */
package/lib/models.js CHANGED
@@ -15,6 +15,15 @@
15
15
  * @property {string} updatedAt - 最后更新时间,ISO 字符串格式
16
16
  */
17
17
 
18
+ /**
19
+ * 响应内容数据模型
20
+ * @typedef {Object} Response
21
+ * @property {string} id - 响应唯一标识符
22
+ * @property {string} name - 响应名称
23
+ * @property {string} description - 响应描述
24
+ * @property {string} content - 响应内容,使用 Mock.js 语法
25
+ */
26
+
18
27
  /**
19
28
  * 接口数据模型
20
29
  * @typedef {Object} Interface
@@ -23,7 +32,9 @@
23
32
  * @property {string} name - 接口名称
24
33
  * @property {string} urlPattern - URL 匹配规则,支持精确匹配、通配符和正则表达式
25
34
  * @property {string} proxyType - 代理类型,可选值: 'response'(数据模板), 'redirect'(URL重定向), 'file'(文件代理)
26
- * @property {string} responseContent - 响应内容,使用 Mock.js 语法
35
+ * @property {string} responseContent - 响应内容,使用 Mock.js 语法(向后兼容)
36
+ * @property {Array<Response>} responses - 多个响应内容,可选择不同响应
37
+ * @property {string} activeResponseId - 当前激活的响应ID
27
38
  * @property {string} targetUrl - 重定向目标 URL,仅在 proxyType='redirect' 时有效
28
39
  * @property {string} filePath - 文件路径,仅在 proxyType='file' 时有效
29
40
  * @property {number} httpStatus - HTTP 状态码
@@ -15,6 +15,109 @@ const DATA_DIR = storage.DATA_DIR;
15
15
  // 确保数据目录存在
16
16
  fs.ensureDirSync(DATA_DIR);
17
17
 
18
+ // 处理接口数据,确保兼容多响应格式
19
+ const processInterfaceData = (data) => {
20
+ const result = { ...data };
21
+
22
+ // 调试日志
23
+ console.log('=== 开始处理接口数据 ===');
24
+ console.log('原始数据:', JSON.stringify({
25
+ name: result.name,
26
+ hasResponses: !!result.responses,
27
+ responsesType: typeof result.responses,
28
+ responsesLength: result.responses ? result.responses.length : 0,
29
+ responses: result.responses,
30
+ responseContent: !!result.responseContent,
31
+ activeResponseId: result.activeResponseId
32
+ }, null, 2));
33
+
34
+ // 处理 responses 数组
35
+ if (result.responses && Array.isArray(result.responses) && result.responses.length > 0) {
36
+ console.log('发现 responses 数组,直接处理多响应数据');
37
+
38
+ // 确保每个响应都有合法的 id, name 和 content
39
+ result.responses = result.responses.map((resp, index) => {
40
+ console.log(`处理响应 ${index}:`, resp);
41
+
42
+ if (!resp.id) {
43
+ resp.id = Math.random().toString(36).substring(2, 15);
44
+ console.log(`为响应 ${index} 添加 ID:`, resp.id);
45
+ }
46
+ if (!resp.name) {
47
+ resp.name = `响应 ${index + 1}`;
48
+ console.log(`为响应 ${index} 添加默认名称:`, resp.name);
49
+ }
50
+
51
+ const processedResp = {
52
+ id: resp.id,
53
+ name: resp.name,
54
+ description: resp.description || '',
55
+ content: resp.content || '{}'
56
+ };
57
+
58
+ console.log(`处理后的响应 ${index}:`, processedResp);
59
+ return processedResp;
60
+ });
61
+
62
+ console.log('处理后的响应数组长度:', result.responses.length);
63
+ console.log('所有处理后的响应:', result.responses);
64
+
65
+ // 如果有响应但没有设置 activeResponseId,默认使用第一个
66
+ if (!result.activeResponseId) {
67
+ result.activeResponseId = result.responses[0].id;
68
+ console.log('设置默认激活响应:', result.activeResponseId);
69
+ }
70
+
71
+ // 确保 responseContent 字段始终存在(向后兼容)
72
+ const activeResponse = result.activeResponseId
73
+ ? result.responses.find(r => r.id === result.activeResponseId)
74
+ : result.responses[0];
75
+
76
+ if (activeResponse) {
77
+ result.responseContent = activeResponse.content;
78
+ console.log('设置 responseContent 为当前激活响应内容');
79
+ }
80
+
81
+ } else if (result.responseContent) {
82
+ // 如果没有提供 responses 但有 responseContent,创建默认响应(向后兼容)
83
+ console.log('创建默认响应,因为没有 responses 数组但有 responseContent');
84
+ result.responses = [{
85
+ id: Math.random().toString(36).substring(2, 15),
86
+ name: '默认响应',
87
+ description: '',
88
+ content: result.responseContent
89
+ }];
90
+ result.activeResponseId = result.responses[0].id;
91
+ console.log('创建的默认响应:', result.responses[0]);
92
+
93
+ } else {
94
+ // 如果既没有 responses 也没有 responseContent,创建一个空的默认响应
95
+ console.log('创建空的默认响应');
96
+ result.responses = [{
97
+ id: Math.random().toString(36).substring(2, 15),
98
+ name: '默认响应',
99
+ description: '',
100
+ content: '{}'
101
+ }];
102
+ result.activeResponseId = result.responses[0].id;
103
+ result.responseContent = '{}';
104
+ console.log('创建的空默认响应:', result.responses[0]);
105
+ }
106
+
107
+ // 最终日志
108
+ console.log('=== 处理后的最终接口数据 ===');
109
+ console.log('最终数据:', JSON.stringify({
110
+ name: result.name,
111
+ responsesLength: result.responses.length,
112
+ responses: result.responses,
113
+ activeResponseId: result.activeResponseId,
114
+ hasResponseContent: !!result.responseContent
115
+ }, null, 2));
116
+ console.log('=== 接口数据处理完成 ===\n');
117
+
118
+ return result;
119
+ };
120
+
18
121
  // 初始化路由
19
122
  const initRouter = () => {
20
123
  const router = express.Router();
@@ -25,33 +128,69 @@ const initRouter = () => {
25
128
  // 获取所有接口
26
129
  router.get('/interfaces', (req, res) => {
27
130
  try {
131
+ const { featureId } = req.query;
132
+
28
133
  // 读取所有功能
29
134
  const featuresFile = path.join(DATA_DIR, 'features.json');
30
135
  if (!fs.existsSync(featuresFile)) {
31
- return res.json([]);
136
+ return res.json({ code: 0, data: [] });
32
137
  }
33
138
 
34
139
  const features = fs.readJsonSync(featuresFile);
35
140
  let allInterfaces = [];
36
141
 
37
- // 读取每个功能的接口
38
- features.forEach(feature => {
39
- const interfacesFile = path.join(DATA_DIR, `interfaces-${feature.id}.json`);
142
+ if (featureId) {
143
+ // 获取特定功能的接口
144
+ const interfacesFile = path.join(DATA_DIR, `interfaces-${featureId}.json`);
40
145
  if (fs.existsSync(interfacesFile)) {
41
146
  const interfaces = fs.readJsonSync(interfacesFile);
42
- // 添加功能名称到接口数据中
43
- const interfacesWithFeature = interfaces.map(item => ({
44
- ...item,
45
- featureName: feature.name
46
- }));
47
- allInterfaces = allInterfaces.concat(interfacesWithFeature);
147
+ console.log('=== 获取接口:从文件读取的原始数据 ===');
148
+ console.log(`文件路径: ${interfacesFile}`);
149
+ console.log('原始接口数据:', JSON.stringify(interfaces, null, 2));
150
+
151
+ const processedInterfaces = interfaces.map((item, index) => {
152
+ console.log(`=== 处理接口 ${index}: ${item.name} ===`);
153
+ console.log('处理前的接口数据:', JSON.stringify(item, null, 2));
154
+
155
+ // 确保每个接口都经过数据处理
156
+ const processed = processInterfaceData(item);
157
+ console.log('处理后的接口数据:', JSON.stringify(processed, null, 2));
158
+
159
+ const feature = features.find(f => f.id === featureId);
160
+ const result = {
161
+ ...processed,
162
+ featureName: feature ? feature.name : '未知功能'
163
+ };
164
+
165
+ console.log('最终接口数据:', JSON.stringify(result, null, 2));
166
+ return result;
167
+ });
168
+ allInterfaces = processedInterfaces;
48
169
  }
49
- });
170
+ } else {
171
+ // 读取每个功能的接口
172
+ features.forEach(feature => {
173
+ const interfacesFile = path.join(DATA_DIR, `interfaces-${feature.id}.json`);
174
+ if (fs.existsSync(interfacesFile)) {
175
+ const interfaces = fs.readJsonSync(interfacesFile);
176
+ // 确保每个接口都经过数据处理
177
+ const processedInterfaces = interfaces.map(item => {
178
+ const processed = processInterfaceData(item);
179
+ return {
180
+ ...processed,
181
+ featureName: feature.name
182
+ };
183
+ });
184
+ allInterfaces = allInterfaces.concat(processedInterfaces);
185
+ }
186
+ });
187
+ }
50
188
 
51
- res.json(allInterfaces);
189
+ console.log(`获取接口列表成功,共 ${allInterfaces.length} 个接口`);
190
+ res.json({ code: 0, data: allInterfaces });
52
191
  } catch (err) {
53
192
  console.error('获取接口列表失败:', err);
54
- res.status(500).json({ error: '获取接口列表失败' });
193
+ res.status(500).json({ code: 1, message: '获取接口列表失败: ' + err.message });
55
194
  }
56
195
  });
57
196
 
@@ -61,7 +200,7 @@ const initRouter = () => {
61
200
  // 读取所有功能
62
201
  const featuresFile = path.join(DATA_DIR, 'features.json');
63
202
  if (!fs.existsSync(featuresFile)) {
64
- return res.status(404).json({ error: '接口不存在' });
203
+ return res.status(404).json({ code: 1, message: '接口不存在' });
65
204
  }
66
205
 
67
206
  const features = fs.readJsonSync(featuresFile);
@@ -74,8 +213,10 @@ const initRouter = () => {
74
213
  const interfaces = fs.readJsonSync(interfacesFile);
75
214
  const found = interfaces.find(item => item.id === req.params.id);
76
215
  if (found) {
216
+ // 确保数据经过处理
217
+ const processed = processInterfaceData(found);
77
218
  foundInterface = {
78
- ...found,
219
+ ...processed,
79
220
  featureName: feature.name
80
221
  };
81
222
  break;
@@ -84,127 +225,204 @@ const initRouter = () => {
84
225
  }
85
226
 
86
227
  if (!foundInterface) {
87
- return res.status(404).json({ error: '接口不存在' });
228
+ return res.status(404).json({ code: 1, message: '接口不存在' });
88
229
  }
89
230
 
90
- res.json(foundInterface);
231
+ console.log(`获取接口详情成功: ${foundInterface.name},响应数量: ${foundInterface.responses ? foundInterface.responses.length : 0}`);
232
+ res.json({ code: 0, data: foundInterface });
91
233
  } catch (err) {
92
234
  console.error('获取接口详情失败:', err);
93
- res.status(500).json({ error: '获取接口详情失败' });
235
+ res.status(500).json({ code: 1, message: '获取接口详情失败: ' + err.message });
94
236
  }
95
237
  });
96
238
 
97
239
  // 创建接口
98
240
  router.post('/interfaces', (req, res) => {
99
241
  try {
100
- const { featureId, path: interfacePath, method, status, delay, description, headers, responseBody } = req.body;
242
+ const interfaceData = req.body;
101
243
 
102
- if (!featureId || !interfacePath || !method) {
103
- return res.status(400).json({ error: '功能ID、路径和请求方法为必填项' });
244
+ if (!interfaceData.featureId || !interfaceData.urlPattern) {
245
+ return res.status(400).json({
246
+ code: 1,
247
+ message: '功能ID和URL匹配规则为必填项'
248
+ });
104
249
  }
105
250
 
106
251
  // 检查功能是否存在
107
252
  const featuresFile = path.join(DATA_DIR, 'features.json');
108
253
  if (!fs.existsSync(featuresFile)) {
109
- return res.status(404).json({ error: '功能不存在' });
254
+ return res.status(404).json({
255
+ code: 1,
256
+ message: '功能不存在'
257
+ });
110
258
  }
111
259
 
112
260
  const features = fs.readJsonSync(featuresFile);
113
- const feature = features.find(f => f.id === featureId);
261
+ const feature = features.find(f => f.id === interfaceData.featureId);
114
262
  if (!feature) {
115
- return res.status(404).json({ error: '功能不存在' });
263
+ return res.status(404).json({
264
+ code: 1,
265
+ message: '功能不存在'
266
+ });
116
267
  }
117
268
 
118
269
  // 读取接口列表
119
- const interfacesFile = path.join(DATA_DIR, `interfaces-${featureId}.json`);
270
+ const interfacesFile = path.join(DATA_DIR, `interfaces-${interfaceData.featureId}.json`);
120
271
  const interfaces = fs.existsSync(interfacesFile)
121
272
  ? fs.readJsonSync(interfacesFile)
122
273
  : [];
123
274
 
275
+ // 处理接口数据,确保兼容多响应格式
276
+ console.log('=== 创建接口:开始处理数据 ===');
277
+ console.log('接收到的接口数据:', JSON.stringify(interfaceData, null, 2));
278
+ const processedData = processInterfaceData(interfaceData);
279
+ console.log('处理后的接口数据:', JSON.stringify(processedData, null, 2));
280
+
124
281
  // 创建新接口
125
282
  const newInterface = {
126
283
  id: uuidv4(),
127
- featureId,
128
- path: interfacePath,
129
- method,
130
- status: status || 200,
131
- delay: delay || 0,
132
- description: description || '',
133
- headers: headers || { 'Content-Type': 'application/json' },
134
- responseBody: responseBody || {},
284
+ ...processedData,
135
285
  createdAt: new Date().toISOString(),
136
286
  updatedAt: new Date().toISOString()
137
287
  };
138
288
 
289
+ console.log('=== 创建接口:准备保存的完整接口数据 ===');
290
+ console.log('完整的新接口数据:', JSON.stringify(newInterface, null, 2));
291
+
139
292
  interfaces.push(newInterface);
140
293
 
141
294
  // 保存接口列表
142
295
  fs.writeJsonSync(interfacesFile, interfaces, { spaces: 2 });
296
+ console.log('接口数据已保存到文件:', interfacesFile);
297
+
298
+ // 验证保存后从文件读取的数据
299
+ const savedInterfaces = fs.readJsonSync(interfacesFile);
300
+ const savedInterface = savedInterfaces.find(item => item.id === newInterface.id);
301
+ console.log('=== 创建接口:验证保存后的数据 ===');
302
+ console.log('从文件读取的保存后数据:', JSON.stringify(savedInterface, null, 2));
143
303
 
144
- res.status(201).json(newInterface);
304
+ // 更新功能模块的接口数量
305
+ const featureIndex = features.findIndex(f => f.id === interfaceData.featureId);
306
+ features[featureIndex].interfaceCount = interfaces.length;
307
+ features[featureIndex].updatedAt = new Date().toISOString();
308
+ fs.writeJsonSync(featuresFile, features, { spaces: 2 });
309
+
310
+ console.log('=== 创建接口:准备返回的数据 ===');
311
+ console.log('返回给前端的数据:', JSON.stringify(newInterface, null, 2));
312
+
313
+ res.json({
314
+ code: 0,
315
+ message: '接口创建成功',
316
+ data: newInterface
317
+ });
145
318
  } catch (err) {
146
319
  console.error('创建接口失败:', err);
147
- res.status(500).json({ error: '创建接口失败' });
320
+ res.status(500).json({
321
+ code: 1,
322
+ message: '创建接口失败: ' + err.message
323
+ });
148
324
  }
149
325
  });
150
326
 
151
327
  // 更新接口
152
- router.put('/interfaces/:id', (req, res) => {
328
+ router.put('/interfaces', (req, res) => {
153
329
  try {
154
- const { featureId, path: interfacePath, method, status, delay, description, headers, responseBody } = req.body;
330
+ const { id } = req.query;
331
+ const interfaceData = req.body;
332
+
333
+ if (!id) {
334
+ return res.status(400).json({
335
+ code: 1,
336
+ message: '接口ID为必填项'
337
+ });
338
+ }
155
339
 
156
- if (!featureId) {
157
- return res.status(400).json({ error: '功能ID为必填项' });
340
+ if (!interfaceData.featureId) {
341
+ return res.status(400).json({
342
+ code: 1,
343
+ message: '功能ID为必填项'
344
+ });
158
345
  }
159
346
 
160
347
  // 检查功能是否存在
161
348
  const featuresFile = path.join(DATA_DIR, 'features.json');
162
349
  if (!fs.existsSync(featuresFile)) {
163
- return res.status(404).json({ error: '功能不存在' });
350
+ return res.status(404).json({
351
+ code: 1,
352
+ message: '功能不存在'
353
+ });
164
354
  }
165
355
 
166
356
  const features = fs.readJsonSync(featuresFile);
167
- const feature = features.find(f => f.id === featureId);
357
+ const feature = features.find(f => f.id === interfaceData.featureId);
168
358
  if (!feature) {
169
- return res.status(404).json({ error: '功能不存在' });
359
+ return res.status(404).json({
360
+ code: 1,
361
+ message: '功能不存在'
362
+ });
170
363
  }
171
364
 
172
365
  // 读取接口列表
173
- const interfacesFile = path.join(DATA_DIR, `interfaces-${featureId}.json`);
366
+ const interfacesFile = path.join(DATA_DIR, `interfaces-${interfaceData.featureId}.json`);
174
367
  if (!fs.existsSync(interfacesFile)) {
175
- return res.status(404).json({ error: '接口不存在' });
368
+ return res.status(404).json({
369
+ code: 1,
370
+ message: '接口不存在'
371
+ });
176
372
  }
177
373
 
178
374
  const interfaces = fs.readJsonSync(interfacesFile);
179
- const index = interfaces.findIndex(item => item.id === req.params.id);
375
+ const index = interfaces.findIndex(item => item.id === id);
180
376
 
181
377
  if (index === -1) {
182
- return res.status(404).json({ error: '接口不存在' });
378
+ return res.status(404).json({
379
+ code: 1,
380
+ message: '接口不存在'
381
+ });
183
382
  }
184
383
 
384
+ // 处理接口数据,确保兼容多响应格式
385
+ console.log('=== 更新接口:开始处理数据 ===');
386
+ console.log('接收到的接口数据:', JSON.stringify(interfaceData, null, 2));
387
+ const processedData = processInterfaceData(interfaceData);
388
+ console.log('处理后的接口数据:', JSON.stringify(processedData, null, 2));
389
+
185
390
  // 更新接口
186
391
  const updatedInterface = {
187
392
  ...interfaces[index],
188
- featureId,
189
- path: interfacePath !== undefined ? interfacePath : interfaces[index].path,
190
- method: method !== undefined ? method : interfaces[index].method,
191
- status: status !== undefined ? status : interfaces[index].status,
192
- delay: delay !== undefined ? delay : interfaces[index].delay,
193
- description: description !== undefined ? description : interfaces[index].description,
194
- headers: headers !== undefined ? headers : interfaces[index].headers,
195
- responseBody: responseBody !== undefined ? responseBody : interfaces[index].responseBody,
393
+ ...processedData,
196
394
  updatedAt: new Date().toISOString()
197
395
  };
198
396
 
397
+ console.log('=== 更新接口:准备保存的完整接口数据 ===');
398
+ console.log('完整的更新接口数据:', JSON.stringify(updatedInterface, null, 2));
399
+
199
400
  interfaces[index] = updatedInterface;
200
401
 
201
402
  // 保存接口列表
202
403
  fs.writeJsonSync(interfacesFile, interfaces, { spaces: 2 });
404
+ console.log('接口数据已保存到文件:', interfacesFile);
203
405
 
204
- res.json(updatedInterface);
406
+ // 验证保存后从文件读取的数据
407
+ const savedInterfaces = fs.readJsonSync(interfacesFile);
408
+ const savedInterface = savedInterfaces.find(item => item.id === id);
409
+ console.log('=== 更新接口:验证保存后的数据 ===');
410
+ console.log('从文件读取的保存后数据:', JSON.stringify(savedInterface, null, 2));
411
+
412
+ console.log('=== 更新接口:准备返回的数据 ===');
413
+ console.log('返回给前端的数据:', JSON.stringify(updatedInterface, null, 2));
414
+
415
+ res.json({
416
+ code: 0,
417
+ message: '接口更新成功',
418
+ data: updatedInterface
419
+ });
205
420
  } catch (err) {
206
421
  console.error('更新接口失败:', err);
207
- res.status(500).json({ error: '更新接口失败' });
422
+ res.status(500).json({
423
+ code: 1,
424
+ message: '更新接口失败: ' + err.message
425
+ });
208
426
  }
209
427
  });
210
428
 
@@ -231,20 +231,6 @@ const ruleManager = {
231
231
  // 只记录关键信息
232
232
  this.log(`[规则处理器] 处理请求,接口: ${interfaceObj.name}, 代理类型: ${proxyType}`);
233
233
 
234
- // 添加CORS支持 - 设置跨域相关的响应头
235
- res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
236
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH');
237
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, Accept');
238
- res.setHeader('Access-Control-Allow-Credentials', 'true');
239
- res.setHeader('Access-Control-Max-Age', '86400'); // 24小时
240
-
241
- // 处理预检请求
242
- if (req.method === 'OPTIONS') {
243
- res.statusCode = 204; // No Content
244
- res.end();
245
- return { handled: true };
246
- }
247
-
248
234
  // 设置响应头
249
235
  let headers = config.headers;
250
236
  if (typeof headers === 'string') {
@@ -280,6 +266,11 @@ const ruleManager = {
280
266
  result = await this.handleUrlRedirect(interfaceObj, req, res);
281
267
  }
282
268
  else if (proxyType === 'data_template' || proxyType === 'response') {
269
+ // 添加CORS支持 - 设置跨域相关的响应头
270
+ const origin = req.headers.origin || req.headers.host;
271
+ res.setHeader('Access-Control-Allow-Origin', origin || '*');
272
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
273
+
283
274
  result = await this.handleDataTemplate(interfaceObj, req, res);
284
275
  }
285
276
  else if (proxyType === 'file_proxy' || proxyType === 'file') {
@@ -381,7 +372,29 @@ const ruleManager = {
381
372
  async handleDataTemplate(interfaceObj, req, res) {
382
373
  // 兼容不同的字段命名
383
374
  const config = interfaceObj.config || interfaceObj;
384
- const template = config.responseContent || config.template || '{}';
375
+
376
+ // 支持多响应系统
377
+ let template = '';
378
+
379
+ // 检查是否有多响应配置
380
+ if (config.responses && Array.isArray(config.responses) && config.responses.length > 0) {
381
+ // 获取当前激活的响应
382
+ const activeResponseId = config.activeResponseId;
383
+ const activeResponse = activeResponseId
384
+ ? config.responses.find(r => r.id === activeResponseId)
385
+ : config.responses[0];
386
+
387
+ if (activeResponse) {
388
+ this.log(`[规则处理器] 使用响应: ${activeResponse.name || '未命名'}`);
389
+ template = activeResponse.content;
390
+ }
391
+ }
392
+
393
+ // 如果没有找到响应内容,回退到传统字段
394
+ if (!template) {
395
+ template = config.responseContent || config.template || '{}';
396
+ this.log(`[规则处理器] 使用传统响应内容`);
397
+ }
385
398
 
386
399
  if (!template) {
387
400
  res.end(JSON.stringify({ error: 'No template specified' }));
@@ -399,8 +412,20 @@ const ruleManager = {
399
412
 
400
413
  // 发送数据
401
414
  res.end(JSON.stringify(mockData));
402
- return { mockData };
415
+
416
+ // 返回处理结果,包含响应信息
417
+ return {
418
+ mockData,
419
+ mockInfo: {
420
+ delay: parseInt(config.responseDelay || config.delay || 0, 10),
421
+ timestamp: new Date().toISOString(),
422
+ responseName: config.responses && config.activeResponseId
423
+ ? (config.responses.find(r => r.id === config.activeResponseId)?.name || '未命名')
424
+ : '默认响应'
425
+ }
426
+ };
403
427
  } catch (err) {
428
+ this.log(`[规则处理器] 模板解析错误: ${err.message}`);
404
429
  res.end(JSON.stringify({ error: 'Template parsing error', message: err.message }));
405
430
  return { error: 'Template parsing error', message: err.message };
406
431
  }