mirror of
https://github.com/jwetzell/showbridge-go.git
synced 2026-04-26 21:05:30 +00:00
move schema to an internal package
This commit is contained in:
10
api.go
10
api.go
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
"github.com/jwetzell/showbridge-go/internal/config"
|
||||
"github.com/jwetzell/showbridge-go/internal/module"
|
||||
"github.com/jwetzell/showbridge-go/internal/processor"
|
||||
"github.com/jwetzell/showbridge-go/internal/route"
|
||||
"github.com/jwetzell/showbridge-go/internal/schema"
|
||||
)
|
||||
|
||||
func (r *Router) startAPIServer(config config.ApiConfig) {
|
||||
@@ -135,7 +135,7 @@ func (r *Router) handleConfigHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
func handleConfigSchema(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
schemaJSON, err := json.Marshal(config.ConfigSchema)
|
||||
schemaJSON, err := json.Marshal(schema.ConfigSchema)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -157,7 +157,7 @@ func handleConfigSchema(w http.ResponseWriter, req *http.Request) {
|
||||
func handleRoutesSchema(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
schemaJSON, err := json.Marshal(config.RoutesConfigSchema)
|
||||
schemaJSON, err := json.Marshal(schema.RoutesConfigSchema)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -179,7 +179,7 @@ func handleRoutesSchema(w http.ResponseWriter, req *http.Request) {
|
||||
func handleModulesSchema(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
schemaJSON, err := json.Marshal(module.GetModulesSchema())
|
||||
schemaJSON, err := json.Marshal(schema.GetModulesSchema())
|
||||
if err != nil {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -201,7 +201,7 @@ func handleModulesSchema(w http.ResponseWriter, req *http.Request) {
|
||||
func handleProcessorsSchema(w http.ResponseWriter, req *http.Request) {
|
||||
switch req.Method {
|
||||
case http.MethodGet:
|
||||
schemaJSON, err := json.Marshal(processor.GetProcessorsSchema())
|
||||
schemaJSON, err := json.Marshal(schema.GetProcessorsSchema())
|
||||
if err != nil {
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
)
|
||||
|
||||
type ApiConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
|
||||
var ApiConfigSchema = jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"enabled": {
|
||||
Type: "boolean",
|
||||
Description: "Whether the API server is enabled",
|
||||
Default: json.RawMessage(`false`),
|
||||
},
|
||||
"port": {
|
||||
Type: "integer",
|
||||
Description: "Port for the API server to listen on",
|
||||
},
|
||||
},
|
||||
Required: []string{"port"},
|
||||
}
|
||||
|
||||
@@ -1,28 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Api ApiConfig `json:"api"`
|
||||
Modules []ModuleConfig `json:"modules"`
|
||||
Routes []RouteConfig `json:"routes"`
|
||||
}
|
||||
|
||||
var ConfigSchema = jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/config.schema.json",
|
||||
Title: "Config",
|
||||
Description: "showbridge configuration",
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"api": &ApiConfigSchema,
|
||||
"modules": {
|
||||
Ref: "https://showbridge.io/modules.schema.json",
|
||||
},
|
||||
"routes": {
|
||||
Ref: "https://showbridge.io/routes.schema.json",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,29 +1,6 @@
|
||||
package config
|
||||
|
||||
import "github.com/google/jsonschema-go/jsonschema"
|
||||
|
||||
type RouteConfig struct {
|
||||
Input string `json:"input"`
|
||||
Processors []ProcessorConfig `json:"processors"`
|
||||
}
|
||||
|
||||
var RoutesConfigSchema = jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/routes.schema.json",
|
||||
Title: "Routes",
|
||||
Description: "route configurations",
|
||||
Type: "array",
|
||||
Items: &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"input": {
|
||||
Type: "string",
|
||||
MinLength: jsonschema.Ptr(1),
|
||||
},
|
||||
"processors": {
|
||||
Ref: "https://showbridge.io/processors.schema.json",
|
||||
},
|
||||
},
|
||||
Required: []string{"input"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -50,49 +50,3 @@ var (
|
||||
func CreateLogger(config config.ModuleConfig) *slog.Logger {
|
||||
return slog.Default().With("component", "module", "id", config.Id, "type", config.Type)
|
||||
}
|
||||
|
||||
func GetModulesSchema() *jsonschema.Schema {
|
||||
moduleRegistryMu.RLock()
|
||||
defer moduleRegistryMu.RUnlock()
|
||||
|
||||
schema := &jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/modules.schema.json",
|
||||
Title: "Modules",
|
||||
Description: "module configurations",
|
||||
Type: "array",
|
||||
}
|
||||
|
||||
moduleDefinitionSchemas := []*jsonschema.Schema{}
|
||||
for _, mod := range ModuleRegistry {
|
||||
moduleSchema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"id": {
|
||||
Type: "string",
|
||||
MinLength: jsonschema.Ptr(1),
|
||||
},
|
||||
"type": {
|
||||
Const: jsonschema.Ptr[any](mod.Type),
|
||||
},
|
||||
},
|
||||
Required: []string{"id", "type"},
|
||||
AdditionalProperties: nil,
|
||||
}
|
||||
if mod.Title != "" {
|
||||
moduleSchema.Title = mod.Title
|
||||
}
|
||||
if mod.Description != "" {
|
||||
moduleSchema.Description = mod.Description
|
||||
}
|
||||
if mod.ParamsSchema != nil {
|
||||
moduleSchema.Properties["params"] = mod.ParamsSchema
|
||||
moduleSchema.Required = append(moduleSchema.Required, "params")
|
||||
}
|
||||
moduleDefinitionSchemas = append(moduleDefinitionSchemas, moduleSchema)
|
||||
}
|
||||
schema.Items = &jsonschema.Schema{
|
||||
OneOf: moduleDefinitionSchemas,
|
||||
}
|
||||
return schema
|
||||
}
|
||||
|
||||
@@ -45,45 +45,3 @@ var (
|
||||
processorRegistryMu sync.RWMutex
|
||||
ProcessorRegistry = make(map[string]ProcessorRegistration)
|
||||
)
|
||||
|
||||
func GetProcessorsSchema() *jsonschema.Schema {
|
||||
processorRegistryMu.RLock()
|
||||
defer processorRegistryMu.RUnlock()
|
||||
|
||||
schema := &jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/processors.schema.json",
|
||||
Title: "Processors",
|
||||
Description: "processor configurations",
|
||||
Type: "array",
|
||||
}
|
||||
|
||||
processorDefinitionSchemas := []*jsonschema.Schema{}
|
||||
for _, proc := range ProcessorRegistry {
|
||||
processorSchema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"type": {
|
||||
Const: jsonschema.Ptr[any](proc.Type),
|
||||
},
|
||||
},
|
||||
Required: []string{"type"},
|
||||
AdditionalProperties: nil,
|
||||
}
|
||||
if proc.Title != "" {
|
||||
processorSchema.Title = proc.Title
|
||||
}
|
||||
if proc.Description != "" {
|
||||
processorSchema.Description = proc.Description
|
||||
}
|
||||
if proc.ParamsSchema != nil {
|
||||
processorSchema.Properties["params"] = proc.ParamsSchema
|
||||
processorSchema.Required = append(processorSchema.Required, "params")
|
||||
}
|
||||
processorDefinitionSchemas = append(processorDefinitionSchemas, processorSchema)
|
||||
}
|
||||
schema.Items = &jsonschema.Schema{
|
||||
OneOf: processorDefinitionSchemas,
|
||||
}
|
||||
return schema
|
||||
}
|
||||
|
||||
26
internal/schema/api.go
Normal file
26
internal/schema/api.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
)
|
||||
|
||||
var ApiConfigSchema = jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"enabled": {
|
||||
Type: "boolean",
|
||||
Description: "Whether the API server is enabled",
|
||||
Default: json.RawMessage(`false`),
|
||||
},
|
||||
"port": {
|
||||
Type: "integer",
|
||||
Description: "Port for the API server to listen on",
|
||||
Minimum: jsonschema.Ptr[float64](1024),
|
||||
Maximum: jsonschema.Ptr[float64](65535),
|
||||
Default: json.RawMessage(`8080`),
|
||||
},
|
||||
},
|
||||
Required: []string{"port"},
|
||||
}
|
||||
45
internal/schema/config.go
Normal file
45
internal/schema/config.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
"github.com/jwetzell/showbridge-go/internal/config"
|
||||
)
|
||||
|
||||
var ConfigSchema = jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/config.schema.json",
|
||||
Title: "Config",
|
||||
Description: "showbridge configuration",
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"api": &ApiConfigSchema,
|
||||
"modules": {
|
||||
Ref: "https://showbridge.io/modules.schema.json",
|
||||
},
|
||||
"routes": {
|
||||
Ref: "https://showbridge.io/routes.schema.json",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func ValidateConfig(config config.Config) error {
|
||||
resolvedSchema, err := GetResolvedConfigSchema()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsonMap := make(map[string]any)
|
||||
err = json.Unmarshal(jsonBytes, &jsonMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resolvedSchema.Validate(jsonMap)
|
||||
}
|
||||
50
internal/schema/modules.go
Normal file
50
internal/schema/modules.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
"github.com/jwetzell/showbridge-go/internal/module"
|
||||
)
|
||||
|
||||
func GetModulesSchema() *jsonschema.Schema {
|
||||
|
||||
schema := &jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/modules.schema.json",
|
||||
Title: "Modules",
|
||||
Description: "module configurations",
|
||||
Type: "array",
|
||||
}
|
||||
|
||||
moduleDefinitionSchemas := []*jsonschema.Schema{}
|
||||
for _, mod := range module.ModuleRegistry {
|
||||
moduleSchema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"id": {
|
||||
Type: "string",
|
||||
MinLength: jsonschema.Ptr(1),
|
||||
},
|
||||
"type": {
|
||||
Const: jsonschema.Ptr[any](mod.Type),
|
||||
},
|
||||
},
|
||||
Required: []string{"id", "type"},
|
||||
AdditionalProperties: nil,
|
||||
}
|
||||
if mod.Title != "" {
|
||||
moduleSchema.Title = mod.Title
|
||||
}
|
||||
if mod.Description != "" {
|
||||
moduleSchema.Description = mod.Description
|
||||
}
|
||||
if mod.ParamsSchema != nil {
|
||||
moduleSchema.Properties["params"] = mod.ParamsSchema
|
||||
moduleSchema.Required = append(moduleSchema.Required, "params")
|
||||
}
|
||||
moduleDefinitionSchemas = append(moduleDefinitionSchemas, moduleSchema)
|
||||
}
|
||||
schema.Items = &jsonschema.Schema{
|
||||
OneOf: moduleDefinitionSchemas,
|
||||
}
|
||||
return schema
|
||||
}
|
||||
46
internal/schema/processors.go
Normal file
46
internal/schema/processors.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
"github.com/jwetzell/showbridge-go/internal/processor"
|
||||
)
|
||||
|
||||
func GetProcessorsSchema() *jsonschema.Schema {
|
||||
|
||||
schema := &jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/processors.schema.json",
|
||||
Title: "Processors",
|
||||
Description: "processor configurations",
|
||||
Type: "array",
|
||||
}
|
||||
|
||||
processorDefinitionSchemas := []*jsonschema.Schema{}
|
||||
for _, proc := range processor.ProcessorRegistry {
|
||||
processorSchema := &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"type": {
|
||||
Const: jsonschema.Ptr[any](proc.Type),
|
||||
},
|
||||
},
|
||||
Required: []string{"type"},
|
||||
AdditionalProperties: nil,
|
||||
}
|
||||
if proc.Title != "" {
|
||||
processorSchema.Title = proc.Title
|
||||
}
|
||||
if proc.Description != "" {
|
||||
processorSchema.Description = proc.Description
|
||||
}
|
||||
if proc.ParamsSchema != nil {
|
||||
processorSchema.Properties["params"] = proc.ParamsSchema
|
||||
processorSchema.Required = append(processorSchema.Required, "params")
|
||||
}
|
||||
processorDefinitionSchemas = append(processorDefinitionSchemas, processorSchema)
|
||||
}
|
||||
schema.Items = &jsonschema.Schema{
|
||||
OneOf: processorDefinitionSchemas,
|
||||
}
|
||||
return schema
|
||||
}
|
||||
24
internal/schema/routes.go
Normal file
24
internal/schema/routes.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package schema
|
||||
|
||||
import "github.com/google/jsonschema-go/jsonschema"
|
||||
|
||||
var RoutesConfigSchema = jsonschema.Schema{
|
||||
Schema: "https://json-schema.org/draft/2020-12/schema",
|
||||
ID: "https://showbridge.io/routes.schema.json",
|
||||
Title: "Routes",
|
||||
Description: "route configurations",
|
||||
Type: "array",
|
||||
Items: &jsonschema.Schema{
|
||||
Type: "object",
|
||||
Properties: map[string]*jsonschema.Schema{
|
||||
"input": {
|
||||
Type: "string",
|
||||
MinLength: jsonschema.Ptr(1),
|
||||
},
|
||||
"processors": {
|
||||
Ref: "https://showbridge.io/processors.schema.json",
|
||||
},
|
||||
},
|
||||
Required: []string{"input"},
|
||||
},
|
||||
}
|
||||
27
internal/schema/schema.go
Normal file
27
internal/schema/schema.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/google/jsonschema-go/jsonschema"
|
||||
)
|
||||
|
||||
func GetResolvedConfigSchema() (*jsonschema.Resolved, error) {
|
||||
configSchema := ConfigSchema
|
||||
|
||||
return configSchema.Resolve(&jsonschema.ResolveOptions{
|
||||
Loader: func(uri *url.URL) (*jsonschema.Schema, error) {
|
||||
switch uri.String() {
|
||||
case "https://showbridge.io/modules.schema.json":
|
||||
return GetModulesSchema(), nil
|
||||
case "https://showbridge.io/processors.schema.json":
|
||||
return GetProcessorsSchema(), nil
|
||||
case "https://showbridge.io/routes.schema.json":
|
||||
return &RoutesConfigSchema, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown schema reference: %s", uri.String())
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user