V0.38.4 full composition (#237)
Co-authored-by: gobha <jasafpro@gmail.com> Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
103
server/handlers/connection_types.go
Normal file
103
server/handlers/connection_types.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package handlers
|
||||
|
||||
// v0.38.4: Connection type discovery endpoint.
|
||||
// Returns merged connection types from all active packages.
|
||||
// Library declarations take precedence over non-library declarations.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"chat-switchboard/store"
|
||||
)
|
||||
|
||||
// ConnectionTypeEntry is a single connection type in the API response.
|
||||
type ConnectionTypeEntry struct {
|
||||
Type string `json:"type"`
|
||||
Label string `json:"label"`
|
||||
PackageID string `json:"package_id"`
|
||||
PackageTitle string `json:"package_title"`
|
||||
Fields map[string]map[string]string `json:"fields"`
|
||||
Scopes []string `json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// ConnectionTypeHandler serves GET /api/v1/connection-types.
|
||||
type ConnectionTypeHandler struct {
|
||||
stores store.Stores
|
||||
}
|
||||
|
||||
func NewConnectionTypeHandler(s store.Stores) *ConnectionTypeHandler {
|
||||
return &ConnectionTypeHandler{stores: s}
|
||||
}
|
||||
|
||||
// ListConnectionTypes returns all connection types declared by active packages.
|
||||
// Library packages take precedence when multiple packages declare the same type.
|
||||
func (h *ConnectionTypeHandler) ListConnectionTypes(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
pkgs, err := h.stores.Packages.List(ctx)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list packages"})
|
||||
return
|
||||
}
|
||||
|
||||
type entry struct {
|
||||
ct ConnectionTypeEntry
|
||||
isLibrary bool
|
||||
}
|
||||
seen := map[string]*entry{}
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Status != "active" || !pkg.Enabled {
|
||||
continue
|
||||
}
|
||||
connsRaw, ok := pkg.Manifest["connections"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
connsJSON, _ := json.Marshal(connsRaw)
|
||||
var conns []struct {
|
||||
Type string `json:"type"`
|
||||
Label string `json:"label"`
|
||||
Fields map[string]map[string]string `json:"fields"`
|
||||
Scopes []string `json:"scopes"`
|
||||
}
|
||||
if err := json.Unmarshal(connsJSON, &conns); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
isLib := pkg.Type == "library"
|
||||
for _, cd := range conns {
|
||||
if cd.Type == "" {
|
||||
continue
|
||||
}
|
||||
existing, exists := seen[cd.Type]
|
||||
// Library declarations take precedence
|
||||
if exists && !isLib && existing.isLibrary {
|
||||
continue
|
||||
}
|
||||
label := cd.Label
|
||||
if label == "" {
|
||||
label = cd.Type
|
||||
}
|
||||
seen[cd.Type] = &entry{
|
||||
ct: ConnectionTypeEntry{
|
||||
Type: cd.Type,
|
||||
Label: label,
|
||||
PackageID: pkg.ID,
|
||||
PackageTitle: pkg.Title,
|
||||
Fields: cd.Fields,
|
||||
Scopes: cd.Scopes,
|
||||
},
|
||||
isLibrary: isLib,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result := make([]ConnectionTypeEntry, 0, len(seen))
|
||||
for _, e := range seen {
|
||||
result = append(result, e.ct)
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"data": result})
|
||||
}
|
||||
Reference in New Issue
Block a user