2024-07-01 21:54:18 +00:00
|
|
|
// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved.
|
|
|
|
|
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"github.com/xeipuuv/gojsonschema"
|
|
|
|
"strings"
|
|
|
|
"embed"
|
|
|
|
"net/http"
|
|
|
|
"log/slog"
|
2024-09-25 05:13:53 +00:00
|
|
|
"decl/internal/folio"
|
2024-07-01 21:54:18 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
//go:embed schemas/*.schema.json
|
|
|
|
var schemaFiles embed.FS
|
|
|
|
|
2024-09-25 05:13:53 +00:00
|
|
|
var schemaFilesUri folio.URI = "file://config/schemas/*.schema.json"
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
folio.DocumentRegistry.Schemas[schemaFilesUri] = schemaFiles
|
|
|
|
folio.DocumentRegistry.DefaultSchema = schemaFilesUri
|
|
|
|
}
|
|
|
|
|
2024-07-01 21:54:18 +00:00
|
|
|
type Schema struct {
|
|
|
|
schema gojsonschema.JSONLoader
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewSchema(name string) *Schema {
|
|
|
|
path := fmt.Sprintf("file://schemas/%s.schema.json", name)
|
|
|
|
|
|
|
|
return &Schema{schema: gojsonschema.NewReferenceLoaderFileSystem(path, http.FS(schemaFiles))}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schema) Validate(source string) error {
|
|
|
|
loader := gojsonschema.NewStringLoader(source)
|
|
|
|
result, err := gojsonschema.Validate(s.schema, loader)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
slog.Info("schema error", "source", source, "schema", s.schema, "result", result, "err", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
slog.Info("schema", "source", source, "schema", s.schema, "result", result, "err", err)
|
|
|
|
|
|
|
|
if !result.Valid() {
|
|
|
|
schemaErrors := strings.Builder{}
|
|
|
|
for _, err := range result.Errors() {
|
|
|
|
schemaErrors.WriteString(err.String() + "\n")
|
|
|
|
}
|
2024-09-25 05:13:53 +00:00
|
|
|
schemaErrors.WriteString(source)
|
2024-07-01 21:54:18 +00:00
|
|
|
return errors.New(schemaErrors.String())
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schema) ValidateSchema() error {
|
|
|
|
sl := gojsonschema.NewSchemaLoader()
|
|
|
|
sl.Validate = true
|
|
|
|
schemaErr := sl.AddSchemas(s.schema)
|
|
|
|
slog.Info("validate schema definition", "schemaloader", sl, "err", schemaErr)
|
|
|
|
return schemaErr
|
|
|
|
}
|