...
This commit is contained in:
173
pkg/servers/ui/controllers/openrpc_controller.go
Normal file
173
pkg/servers/ui/controllers/openrpc_controller.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
|
||||
orpcmodels "git.ourworld.tf/herocode/heroagent/pkg/openrpc/models"
|
||||
uimodels "git.ourworld.tf/herocode/heroagent/pkg/servers/ui/models"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// OpenRPCController handles requests related to OpenRPC specifications
|
||||
type OpenRPCController struct {
|
||||
openrpcManager uimodels.OpenRPCUIManager
|
||||
}
|
||||
|
||||
// NewOpenRPCController creates a new instance of OpenRPCController
|
||||
func NewOpenRPCController(openrpcManager uimodels.OpenRPCUIManager) *OpenRPCController {
|
||||
return &OpenRPCController{
|
||||
openrpcManager: openrpcManager,
|
||||
}
|
||||
}
|
||||
|
||||
// OpenRPCPageData represents the data needed for the OpenRPC UI pages
|
||||
type OpenRPCPageData struct {
|
||||
Title string
|
||||
Specs []string
|
||||
SelectedSpec string
|
||||
Methods []string
|
||||
SelectedMethod string
|
||||
Method *orpcmodels.Method
|
||||
SocketPath string
|
||||
ExampleParams string
|
||||
Result string
|
||||
Error string
|
||||
}
|
||||
|
||||
// ShowOpenRPCUI renders the OpenRPC UI page
|
||||
func (c *OpenRPCController) ShowOpenRPCUI(ctx *fiber.Ctx) error {
|
||||
// Get query parameters
|
||||
selectedSpec := ctx.Query("spec", "")
|
||||
selectedMethod := ctx.Query("method", "")
|
||||
socketPath := ctx.Query("socketPath", "")
|
||||
|
||||
// Get all specs
|
||||
specs := c.openrpcManager.ListSpecs()
|
||||
|
||||
// Initialize page data using fiber.Map instead of struct
|
||||
pageData := fiber.Map{
|
||||
"Title": "OpenRPC UI",
|
||||
"SpecList": specs,
|
||||
"SelectedSpec": selectedSpec,
|
||||
"SocketPath": socketPath,
|
||||
}
|
||||
|
||||
// If a spec is selected, get its methods
|
||||
if selectedSpec != "" {
|
||||
methods := c.openrpcManager.ListMethods(selectedSpec)
|
||||
pageData["Methods"] = methods
|
||||
pageData["SelectedMethod"] = selectedMethod
|
||||
|
||||
// If a method is selected, get its details
|
||||
if selectedMethod != "" {
|
||||
method := c.openrpcManager.GetMethod(selectedSpec, selectedMethod)
|
||||
if method != nil {
|
||||
pageData["Method"] = method
|
||||
|
||||
// Generate example parameters if available
|
||||
if len(method.Examples) > 0 {
|
||||
exampleParams, err := json.MarshalIndent(method.Examples[0].Params, "", " ")
|
||||
if err == nil {
|
||||
pageData["ExampleParams"] = string(exampleParams)
|
||||
}
|
||||
} else if len(method.Params) > 0 {
|
||||
// Generate example from parameter schema
|
||||
exampleParams := generateExampleParams(method.Params)
|
||||
jsonParams, err := json.MarshalIndent(exampleParams, "", " ")
|
||||
if err == nil {
|
||||
pageData["ExampleParams"] = string(jsonParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.Render("pages/rpcui", pageData)
|
||||
}
|
||||
|
||||
// ExecuteRPC handles RPC execution requests
|
||||
func (c *OpenRPCController) ExecuteRPC(ctx *fiber.Ctx) error {
|
||||
// Parse request
|
||||
var request struct {
|
||||
Spec string `json:"spec"`
|
||||
Method string `json:"method"`
|
||||
SocketPath string `json:"socketPath"`
|
||||
Params json.RawMessage `json:"params"`
|
||||
}
|
||||
|
||||
if err := ctx.BodyParser(&request); err != nil {
|
||||
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Invalid request: " + err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// Validate request
|
||||
if request.Spec == "" || request.Method == "" || request.SocketPath == "" {
|
||||
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Missing required fields: spec, method, or socketPath",
|
||||
})
|
||||
}
|
||||
|
||||
// Parse params
|
||||
var params interface{}
|
||||
if len(request.Params) > 0 {
|
||||
if err := json.Unmarshal(request.Params, ¶ms); err != nil {
|
||||
return ctx.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Invalid parameters: " + err.Error(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Execute RPC
|
||||
result, err := c.openrpcManager.ExecuteRPC(request.Spec, request.Method, request.SocketPath, params)
|
||||
if err != nil {
|
||||
log.Printf("Error executing RPC: %v", err)
|
||||
return ctx.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
// Return result
|
||||
return ctx.JSON(fiber.Map{
|
||||
"result": result,
|
||||
})
|
||||
}
|
||||
|
||||
// generateExampleParams generates example parameters from parameter schemas
|
||||
func generateExampleParams(params []orpcmodels.Parameter) map[string]interface{} {
|
||||
example := make(map[string]interface{})
|
||||
|
||||
for _, param := range params {
|
||||
example[param.Name] = generateExampleValue(param.Schema)
|
||||
}
|
||||
|
||||
return example
|
||||
}
|
||||
|
||||
// generateExampleValue generates an example value from a schema
|
||||
func generateExampleValue(schema orpcmodels.SchemaObject) interface{} {
|
||||
switch schema.Type {
|
||||
case "string":
|
||||
return "example"
|
||||
case "number":
|
||||
return 0
|
||||
case "integer":
|
||||
return 0
|
||||
case "boolean":
|
||||
return false
|
||||
case "array":
|
||||
if schema.Items != nil {
|
||||
return []interface{}{generateExampleValue(*schema.Items)}
|
||||
}
|
||||
return []interface{}{}
|
||||
case "object":
|
||||
obj := make(map[string]interface{})
|
||||
for name, propSchema := range schema.Properties {
|
||||
obj[name] = generateExampleValue(propSchema)
|
||||
}
|
||||
return obj
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user