Files
summercms/cabana/registry.go
2026-09-26 21:33:43 +02:00

74 lines
1.9 KiB
Go

package cabana
import (
"fmt"
"strings"
"git.golem15.com/golem15/summercms/pact"
"git.golem15.com/golem15/summercms/party"
)
type controllerRef struct {
plugin party.Plugin
ctl pact.AdminController
}
func collectControllers(plugins []party.Plugin) ([]controllerRef, error) {
var out []controllerRef
for _, p := range plugins {
src, ok := p.(pact.HasAdminControllers)
if !ok || p == nil {
continue
}
for _, ctl := range src.AdminControllers() {
if ctl == nil {
continue
}
id := ctl.ID()
if id != p.ID() && !strings.HasPrefix(id, p.ID()+".") {
return nil, fmt.Errorf("cabana: controller %s is not owned by plugin %s", id, p.ID())
}
out = append(out, controllerRef{plugin: p, ctl: ctl})
}
}
return out, nil
}
func compileRegistry(items []controllerRef) (*Registry, error) {
byID := make(map[string]*CompiledController, len(items))
for _, item := range items {
id := item.ctl.ID()
if _, exists := byID[id]; exists {
return nil, fmt.Errorf("cabana: duplicate admin controller %s", id)
}
assets, ok := item.plugin.(pact.AdminAssets)
if !ok || assets == nil || assets.AdminFS() == nil {
return nil, fmt.Errorf("cabana: plugin %s has admin controllers but no AdminFS", item.plugin.ID())
}
list, err := compileList(item.plugin.ID(), item.ctl, assets.AdminFS())
if err != nil {
return nil, err
}
form, err := compileFormIfPresent(item.plugin.ID(), item.ctl, assets.AdminFS())
if err != nil {
return nil, err
}
relations, err := compileRelations(item.plugin.ID(), item.ctl, assets.AdminFS(), form)
if err != nil {
return nil, err
}
compiled := &CompiledController{
PluginID: item.plugin.ID(),
Controller: item.ctl,
List: list,
Form: form,
Relations: relations,
}
if err := BindWritableFields(compiled); err != nil {
return nil, err
}
byID[id] = compiled
}
return &Registry{byID: byID}, nil
}