Plugin settings (#4143)

* Add backend support for plugin settings
* Add plugin settings config
* Add UI support for plugin settings
This commit is contained in:
WithoutPants
2023-10-18 14:09:13 +11:00
committed by GitHub
parent 06d8353f4f
commit 2b8718100b
24 changed files with 445 additions and 57 deletions

View File

@@ -59,6 +59,9 @@ type Config struct {
// Javascript files that will be injected into the stash UI.
UI UIConfig `yaml:"ui"`
// Settings that will be used to configure the plugin.
Settings map[string]SettingConfig `yaml:"settings"`
}
type UIConfig struct {
@@ -87,6 +90,14 @@ func (c UIConfig) getJavascriptFiles(parent Config) []string {
return ret
}
type SettingConfig struct {
// defaults to string
Type PluginSettingTypeEnum `yaml:"type"`
// defaults to key name
DisplayName string `yaml:"displayName"`
Description string `yaml:"description"`
}
func (c Config) getPluginTasks(includePlugin bool) []*PluginTask {
var ret []*PluginTask
@@ -133,6 +144,28 @@ func convertHooks(hooks []HookTriggerEnum) []string {
return ret
}
func (c Config) getPluginSettings() []PluginSetting {
ret := []PluginSetting{}
for k, o := range c.Settings {
t := o.Type
if t == "" {
t = PluginSettingTypeEnumString
}
s := PluginSetting{
Name: k,
DisplayName: o.DisplayName,
Description: o.Description,
Type: t,
}
ret = append(ret, s)
}
return ret
}
func (c Config) getName() string {
if c.Name != "" {
return c.Name
@@ -154,6 +187,7 @@ func (c Config) toPlugin() *Plugin {
Javascript: c.UI.getJavascriptFiles(c),
CSS: c.UI.getCSSFiles(c),
},
Settings: c.getPluginSettings(),
}
}
@@ -211,6 +245,20 @@ func (c Config) getExecCommand(task *OperationConfig) []string {
return ret
}
func (c Config) valid() error {
if c.Interface != "" && !c.Interface.Valid() {
return fmt.Errorf("invalid interface type %s", c.Interface)
}
for k, o := range c.Settings {
if o.Type != "" && !o.Type.IsValid() {
return fmt.Errorf("invalid type %s for setting %s", k, o.Type)
}
}
return nil
}
type interfaceEnum string
// Valid interfaceEnum values
@@ -292,8 +340,8 @@ func loadPluginFromYAML(reader io.Reader) (*Config, error) {
ret.Interface = InterfaceEnumRaw
}
if !ret.Interface.Valid() {
return nil, fmt.Errorf("invalid interface type %s", ret.Interface)
if err := ret.valid(); err != nil {
return nil, err
}
return ret, nil

View File

@@ -24,14 +24,15 @@ import (
)
type Plugin struct {
ID string `json:"id"`
Name string `json:"name"`
Description *string `json:"description"`
URL *string `json:"url"`
Version *string `json:"version"`
Tasks []*PluginTask `json:"tasks"`
Hooks []*PluginHook `json:"hooks"`
UI PluginUI `json:"ui"`
ID string `json:"id"`
Name string `json:"name"`
Description *string `json:"description"`
URL *string `json:"url"`
Version *string `json:"version"`
Tasks []*PluginTask `json:"tasks"`
Hooks []*PluginHook `json:"hooks"`
UI PluginUI `json:"ui"`
Settings []PluginSetting `json:"settings"`
Enabled bool `json:"enabled"`
}
@@ -44,6 +45,15 @@ type PluginUI struct {
CSS []string `json:"css"`
}
type PluginSetting struct {
Name string `json:"name"`
// defaults to string
Type PluginSettingTypeEnum `json:"type"`
// defaults to key name
DisplayName string `json:"displayName"`
Description string `json:"description"`
}
type ServerConfig interface {
GetHost() string
GetPort() int

50
pkg/plugin/setting.go Normal file
View File

@@ -0,0 +1,50 @@
package plugin
import (
"fmt"
"io"
"strconv"
)
type PluginSettingTypeEnum string
const (
PluginSettingTypeEnumString PluginSettingTypeEnum = "STRING"
PluginSettingTypeEnumNumber PluginSettingTypeEnum = "NUMBER"
PluginSettingTypeEnumBoolean PluginSettingTypeEnum = "BOOLEAN"
)
var AllPluginSettingTypeEnum = []PluginSettingTypeEnum{
PluginSettingTypeEnumString,
PluginSettingTypeEnumNumber,
PluginSettingTypeEnumBoolean,
}
func (e PluginSettingTypeEnum) IsValid() bool {
switch e {
case PluginSettingTypeEnumString, PluginSettingTypeEnumNumber, PluginSettingTypeEnumBoolean:
return true
}
return false
}
func (e PluginSettingTypeEnum) String() string {
return string(e)
}
func (e *PluginSettingTypeEnum) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}
*e = PluginSettingTypeEnum(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid PluginSettingTypeEnum", str)
}
return nil
}
func (e PluginSettingTypeEnum) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}