package forwardplugin import ( "encoding/json" "fmt" "strings" ) func ValidateAndNormalizePlugins(entries []PluginEntry) ([]PluginEntry, error) { if len(entries) == 0 { return nil, nil } out := make([]PluginEntry, 0, len(entries)) for i, e := range entries { typ := strings.TrimSpace(e.Type) if typ == "" { return nil, fmt.Errorf("plugins[%d].type 不能为空", i) } factory, ok := getFactory(typ) if !ok { return nil, fmt.Errorf("未知插件类型: %s", typ) } cfg := e.Config if len(cfg) == 0 { cfg = json.RawMessage("{}") } p, err := factory(cfg) if err != nil { return nil, fmt.Errorf("plugins[%d]: %w", i, err) } if err := p.ValidateConfig(cfg); err != nil { return nil, fmt.Errorf("plugins[%d]: %w", i, err) } normalized, err := normalizeConfig(cfg, p) if err != nil { return nil, fmt.Errorf("plugins[%d]: %w", i, err) } out = append(out, PluginEntry{ Type: typ, Enabled: e.Enabled, Config: normalized, }) } return out, nil } func normalizeConfig(raw json.RawMessage, p Plugin) (json.RawMessage, error) { if norm, ok := p.(ConfigNormalizer); ok { return norm.NormalizeConfig(raw) } return raw, nil } type ConfigNormalizer interface { NormalizeConfig(raw json.RawMessage) (json.RawMessage, error) } func BuildChain(entries []PluginEntry) (*Chain, error) { plugins := make([]Plugin, 0, len(entries)) for _, e := range entries { if !e.Enabled { continue } factory, ok := getFactory(e.Type) if !ok { return nil, fmt.Errorf("未知插件类型: %s", e.Type) } cfg := e.Config if len(cfg) == 0 { cfg = json.RawMessage("{}") } p, err := factory(cfg) if err != nil { return nil, err } plugins = append(plugins, p) } return &Chain{plugins: plugins}, nil } func PluginsJSON(entries []PluginEntry) string { if len(entries) == 0 { return "[]" } b, _ := json.Marshal(entries) return string(b) }