package plugin import ( "maps" "net/http" "connectrpc.com/connect" "git.dev.alexdunmow.com/block/core/rbac" ) // ServiceMount is a path + handler pair for an RPC service. type ServiceMount struct { Path string Handler http.Handler } // ConnectServiceBinding describes a plugin RPC service mounted with the core interceptor chain. type ConnectServiceBinding struct { name string build func(opts ...connect.HandlerOption) (string, http.Handler) methodRoles map[string]rbac.Role } // NewConnectServiceBinding creates a service binding whose handler is always // constructed by core with the supplied Connect handler options. func NewConnectServiceBinding[T any]( name string, svc T, constructor func(T, ...connect.HandlerOption) (string, http.Handler), methodRoles map[string]rbac.Role, ) ConnectServiceBinding { clonedRoles := make(map[string]rbac.Role, len(methodRoles)) maps.Copy(clonedRoles, methodRoles) return ConnectServiceBinding{ name: name, build: func(opts ...connect.HandlerOption) (string, http.Handler) { return constructor(svc, opts...) }, methodRoles: clonedRoles, } } func (b ConnectServiceBinding) Name() string { return b.name } func (b ConnectServiceBinding) Build(opts ...connect.HandlerOption) (string, http.Handler) { return b.build(opts...) } func (b ConnectServiceBinding) MethodRoles() map[string]rbac.Role { cloned := make(map[string]rbac.Role, len(b.methodRoles)) maps.Copy(cloned, b.methodRoles) return cloned } // ServiceRegistration bundles plugin RPC services with their RBAC method roles. type ServiceRegistration struct { Services []ConnectServiceBinding }