2023-02-28 15:50:35 +01:00
|
|
|
package spec
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
|
2023-02-28 15:50:35 +01:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/qri-io/jsonschema"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Validator struct {
|
2024-03-12 16:22:35 +01:00
|
|
|
repo datastore.SpecDefinitionRepository
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
func (v *Validator) Validate(ctx context.Context, spec Spec) error {
|
|
|
|
name := spec.SpecDefinitionName()
|
|
|
|
|
|
|
|
version := spec.SpecDefinitionVersion()
|
|
|
|
if version == "" {
|
|
|
|
version = DefaultVersion
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
specDef, err := v.repo.Get(ctx, name, version)
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, datastore.ErrNotFound) {
|
|
|
|
return errors.WithStack(ErrUnknownSchema)
|
|
|
|
}
|
2023-02-28 15:50:35 +01:00
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
2023-02-28 15:50:35 +01:00
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
schema := &jsonschema.Schema{}
|
|
|
|
if err := json.Unmarshal(specDef.Schema, schema); err != nil {
|
|
|
|
return errors.WithStack(err)
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
|
2023-03-02 13:05:24 +01:00
|
|
|
state := schema.Validate(ctx, map[string]any(spec.SpecData()))
|
2023-02-28 15:50:35 +01:00
|
|
|
if !state.IsValid() {
|
2023-03-02 13:05:24 +01:00
|
|
|
return errors.WithStack(&ValidationError{*state.Errs})
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
|
2023-03-02 13:05:24 +01:00
|
|
|
return nil
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
func NewValidator(repo datastore.SpecDefinitionRepository) *Validator {
|
2023-02-28 15:50:35 +01:00
|
|
|
return &Validator{
|
2024-03-12 16:22:35 +01:00
|
|
|
repo: repo,
|
2023-02-28 15:50:35 +01:00
|
|
|
}
|
|
|
|
}
|