// Copyright 2024 Matthew Rich . All rights reserved. package resource import ( _ "encoding/json" "errors" "fmt" "github.com/xeipuuv/gojsonschema" "strings" "embed" "net/http" "log/slog" "decl/internal/folio" ) //go:embed schemas/config/*.schema.json //go:embed schemas/*.schema.json var schemaFiles embed.FS var schemaFilesUri folio.URI = "file://resource/schemas/*.schema.json" func init() { folio.DocumentRegistry.Schemas[schemaFilesUri] = schemaFiles folio.DocumentRegistry.DefaultSchema = schemaFilesUri } 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))} //return &Schema{schema: gojsonschema.NewReferenceLoader(path)} } func (s *Schema) Validate(source string) error { // loader := gojsonschema.NewGoLoader(source) 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") } schemaErrors.WriteString(source) 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 }