-
Notifications
You must be signed in to change notification settings - Fork 0
/
spaceapi_validator.go
122 lines (105 loc) · 3.24 KB
/
spaceapi_validator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Package spaceapivalidator provides a validator for the SpaceAPI schemas
// check spaceapi.io for more information
package spaceapivalidator
import (
"encoding/json"
"errors"
"fmt"
"github.com/xeipuuv/gojsonschema"
"strings"
)
//go:generate go run scripts/generate.go
type spaceAPIVersion struct {
API interface{} `json:"api"`
APICompatibility []string `json:"api_compatibility"`
}
// ResultError tells you whats wrong with specific attributes of your SpaceApi file
type ResultError struct {
Field string `json:"field"`
Context string `json:"context"`
Description string `json:"description"`
}
// VersionValidationResult validation result per version
type VersionValidationResult struct {
Version string `json:"version"`
Valid bool `json:"valid"`
Errors []ResultError `json:"errors"`
}
// ValidationResult tells you if the provided string is a valid SpaceApi schema
// and if not tells you what needs to be fixed
type ValidationResult struct {
Valid bool `json:"valid"`
Schemas []VersionValidationResult `json:"version_validation"`
Errors []ResultError `json:"errors"`
}
// Validate a string to match jsonschema of SpaceApi
func Validate(document string) (ValidationResult, error) {
myResult := ValidationResult{ Valid: true }
if document == "" {
return myResult, errors.New("document is empty")
}
documentLoader := gojsonschema.NewStringLoader(document)
suppliedVersion := spaceAPIVersion{}
err := json.Unmarshal([]byte(document), &suppliedVersion)
if err != nil {
return myResult, err
}
versionList := getVersionList(suppliedVersion)
for _, version := range versionList {
schemaString, found := SpaceAPISchemas[version]
if !found {
// Version not found. Thus, we cannot validate. Show an
// error for the declared "api_compatibilty" and continue.
myResult.Valid = false
invalidVersionErrors := []ResultError{
{
"api_compatibility",
"(root).api_compatibility",
fmt.Sprintf("Endpoint declares compatibility with schema version %s, which isn't supported", version),
},
}
myResult.Schemas = append(myResult.Schemas, VersionValidationResult{
version,
false,
invalidVersionErrors,
})
myResult.Errors = append(myResult.Errors, invalidVersionErrors...)
continue
}
var schema = gojsonschema.NewStringLoader(schemaString)
result, err := gojsonschema.Validate(schema, documentLoader)
if err != nil {
myResult.Valid = false
return myResult, err
}
var myErrors []ResultError
for _, error := range result.Errors() {
myErrors = append(myErrors, ResultError{
error.Field(),
error.Context().String(),
error.Description(),
})
}
myResult.Schemas = append(myResult.Schemas, VersionValidationResult{
version,
result.Valid(),
myErrors,
})
myResult.Errors = append(myResult.Errors, myErrors...)
if !result.Valid() {
myResult.Valid = false
}
}
return myResult, err
}
func getVersionList(suppliedVersion spaceAPIVersion) []string {
versionList := suppliedVersion.APICompatibility
oldVersion := strings.Replace(fmt.Sprintf("%v", suppliedVersion.API), "0.", "", 1)
if oldVersion != "<nil>" {
versionList = append(versionList, oldVersion)
}
if len(versionList) == 0 {
versionList = []string{"14"}
}
return versionList
}