@@ -18,6 +18,7 @@ import (
1818type PluginsLoader interface {
1919 ReloadPlugin (ctx context.Context , name string , path * string , pluginConfig any ) error
2020 RemovePlugin (ctx context.Context , name string ) error
21+ GetPluginStatus () []schemas.PluginStatus
2122}
2223
2324// PluginsHandler is the handler for the plugins API
@@ -41,11 +42,13 @@ type CreatePluginRequest struct {
4142 Name string `json:"name"`
4243 Enabled bool `json:"enabled"`
4344 Config map [string ]any `json:"config"`
45+ Path * string `json:"path"`
4446}
4547
4648// UpdatePluginRequest is the request body for updating a plugin
4749type UpdatePluginRequest struct {
4850 Enabled bool `json:"enabled"`
51+ Path * string `json:"path"`
4952 Config map [string ]any `json:"config"`
5053}
5154
@@ -66,10 +69,64 @@ func (h *PluginsHandler) getPlugins(ctx *fasthttp.RequestCtx) {
6669 SendError (ctx , 500 , "Failed to retrieve plugins" , h .logger )
6770 return
6871 }
69-
72+ // Fetching status
73+ pluginStatus := h .pluginsLoader .GetPluginStatus ()
74+ // Creating ephemeral struct for the plugins
75+ finalPlugins := []struct {
76+ Name string `json:"name"`
77+ Enabled bool `json:"enabled"`
78+ Config any `json:"config"`
79+ IsCustom bool `json:"isCustom"`
80+ Path * string `json:"path"`
81+ Status schemas.PluginStatus `json:"status"`
82+ }{}
83+ // Iterating over plugin status to get the plugin info
84+ for _ ,pluginStatus := range pluginStatus {
85+ var pluginInfo * configstoreTables.TablePlugin
86+ for _ , plugin := range plugins {
87+ if plugin .Name == pluginStatus .Name {
88+ pluginInfo = plugin
89+ break
90+ }
91+ }
92+ if pluginInfo == nil {
93+ finalPlugins = append (finalPlugins , struct {
94+ Name string `json:"name"`
95+ Enabled bool `json:"enabled"`
96+ Config any `json:"config"`
97+ IsCustom bool `json:"isCustom"`
98+ Path * string `json:"path"`
99+ Status schemas.PluginStatus `json:"status"`
100+ }{
101+ Name : pluginStatus .Name ,
102+ Enabled : pluginStatus .Status != schemas .PluginStatusDisabled ,
103+ Config : map [string ]any {},
104+ IsCustom : false ,
105+ Path : nil ,
106+ Status : pluginStatus ,
107+ })
108+ continue
109+ }
110+ finalPlugins = append (finalPlugins , struct {
111+ Name string `json:"name"`
112+ Enabled bool `json:"enabled"`
113+ Config any `json:"config"`
114+ IsCustom bool `json:"isCustom"`
115+ Path * string `json:"path"`
116+ Status schemas.PluginStatus `json:"status"`
117+ }{
118+ Name : pluginInfo .Name ,
119+ Enabled : pluginInfo .Enabled ,
120+ Config : pluginInfo .Config ,
121+ IsCustom : pluginInfo .IsCustom ,
122+ Path : pluginInfo .Path ,
123+ Status : pluginStatus ,
124+ })
125+ }
126+ // Creating ephemeral struct
70127 SendJSON (ctx , map [string ]any {
71- "plugins" : plugins ,
72- "count" : len (plugins ),
128+ "plugins" : finalPlugins ,
129+ "count" : len (plugins ),
73130 }, h .logger )
74131}
75132
@@ -134,6 +191,8 @@ func (h *PluginsHandler) createPlugin(ctx *fasthttp.RequestCtx) {
134191 Name : request .Name ,
135192 Enabled : request .Enabled ,
136193 Config : request .Config ,
194+ Path : request .Path ,
195+ IsCustom : true ,
137196 }); err != nil {
138197 h .logger .Error ("failed to create plugin: %v" , err )
139198 SendError (ctx , 500 , "Failed to create plugin" , h .logger )
@@ -149,7 +208,7 @@ func (h *PluginsHandler) createPlugin(ctx *fasthttp.RequestCtx) {
149208
150209 // We reload the plugin if its enabled
151210 if request .Enabled {
152- if err := h .pluginsLoader .ReloadPlugin (ctx , request .Name , nil , request .Config ); err != nil {
211+ if err := h .pluginsLoader .ReloadPlugin (ctx , request .Name , request . Path , request .Config ); err != nil {
153212 h .logger .Error ("failed to load plugin: %v" , err )
154213 SendJSON (ctx , map [string ]any {
155214 "message" : fmt .Sprintf ("Plugin created successfully; but failed to load plugin with new config: %v" , err ),
@@ -188,16 +247,21 @@ func (h *PluginsHandler) updatePlugin(ctx *fasthttp.RequestCtx) {
188247 SendError (ctx , 400 , "Empty 'name' parameter not allowed" , h .logger )
189248 return
190249 }
191-
250+ var plugin * configstoreTables.TablePlugin
251+ var err error
192252 // Check if plugin exists
193- if _ , err := h .configStore .GetPlugin (ctx , name ); err != nil {
253+ plugin , err = h .configStore .GetPlugin (ctx , name )
254+ if err != nil {
194255 // If doesn't exist, create it
195256 if errors .Is (err , configstore .ErrNotFound ) {
196- if err := h . configStore . CreatePlugin ( ctx , & configstoreTables.TablePlugin {
257+ plugin = & configstoreTables.TablePlugin {
197258 Name : name ,
198259 Enabled : false ,
199260 Config : map [string ]any {},
200- }); err != nil {
261+ Path : nil ,
262+ IsCustom : true ,
263+ }
264+ if err := h .configStore .CreatePlugin (ctx , plugin ); err != nil {
201265 h .logger .Error ("failed to create plugin: %v" , err )
202266 SendError (ctx , 500 , "Failed to create plugin" , h .logger )
203267 return
@@ -209,24 +273,28 @@ func (h *PluginsHandler) updatePlugin(ctx *fasthttp.RequestCtx) {
209273 }
210274 }
211275
276+ // Unmarshalling the request body
212277 var request UpdatePluginRequest
213278 if err := json .Unmarshal (ctx .PostBody (), & request ); err != nil {
214279 h .logger .Error ("failed to unmarshal update plugin request: %v" , err )
215280 SendError (ctx , 400 , "Invalid request body" , h .logger )
216281 return
217282 }
218283
284+ // Updating the plugin
219285 if err := h .configStore .UpdatePlugin (ctx , & configstoreTables.TablePlugin {
220286 Name : name ,
221287 Enabled : request .Enabled ,
222288 Config : request .Config ,
289+ Path : request .Path ,
290+ IsCustom : plugin .IsCustom ,
223291 }); err != nil {
224292 h .logger .Error ("failed to update plugin: %v" , err )
225293 SendError (ctx , 500 , "Failed to update plugin" , h .logger )
226294 return
227295 }
228296
229- plugin , err : = h .configStore .GetPlugin (ctx , name )
297+ plugin , err = h .configStore .GetPlugin (ctx , name )
230298 if err != nil {
231299 if errors .Is (err , gorm .ErrRecordNotFound ) {
232300 SendError (ctx , fasthttp .StatusNotFound , "Plugin not found" , h .logger )
@@ -238,7 +306,7 @@ func (h *PluginsHandler) updatePlugin(ctx *fasthttp.RequestCtx) {
238306 }
239307 // We reload the plugin if its enabled, otherwise we stop it
240308 if request .Enabled {
241- if err := h .pluginsLoader .ReloadPlugin (ctx , name , nil , request .Config ); err != nil {
309+ if err := h .pluginsLoader .ReloadPlugin (ctx , name , request . Path , request .Config ); err != nil {
242310 h .logger .Error ("failed to load plugin: %v" , err )
243311 SendJSON (ctx , map [string ]any {
244312 "message" : fmt .Sprintf ("Plugin updated successfully; but failed to load plugin with new config: %v" , err ),
@@ -247,6 +315,7 @@ func (h *PluginsHandler) updatePlugin(ctx *fasthttp.RequestCtx) {
247315 return
248316 }
249317 } else {
318+ ctx .SetUserValue ("isDisabled" , true )
250319 if err := h .pluginsLoader .RemovePlugin (ctx , name ); err != nil {
251320 h .logger .Error ("failed to stop plugin: %v" , err )
252321 SendJSON (ctx , map [string ]any {
0 commit comments