This repository has been archived by the owner on Mar 12, 2020. It is now read-only.
/
schema.go
108 lines (86 loc) · 2.14 KB
/
schema.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
package mill
import (
"bytes"
"encoding/json"
"github.com/golang/protobuf/jsonpb"
"github.com/textileio/go-textile/pb"
"github.com/textileio/go-textile/schema"
"github.com/xeipuuv/gojsonschema"
)
var pbMarshaler = jsonpb.Marshaler{
OrigName: true,
}
type Schema struct{}
func (m *Schema) ID() string {
return "/schema"
}
func (m *Schema) Encrypt() bool {
return false
}
func (m *Schema) Pin() bool {
return true
}
func (m *Schema) AcceptMedia(media string) error {
return accepts([]string{"application/json"}, media)
}
func (m *Schema) Options(add map[string]interface{}) (string, error) {
return hashOpts(make(map[string]string), add)
}
func (m *Schema) Mill(input []byte, name string) (*Result, error) {
var node pb.Node
if err := jsonpb.Unmarshal(bytes.NewReader(input), &node); err != nil {
return nil, err
}
if node.Mill == "" {
if len(node.Links) == 0 {
return nil, schema.ErrEmptySchema
}
for _, link := range node.Links {
if !schema.ValidateMill(link.Mill) {
return nil, schema.ErrSchemaInvalidMill
}
// extra check for json
if link.Mill == "/json" {
if link.JsonSchema == nil {
return nil, schema.ErrMissingJsonSchema
}
if err := validateJsonSchema(pb.ToMap(link.JsonSchema)); err != nil {
return nil, err
}
}
}
// ensure link steps are solvable
if _, err := schema.Steps(node.Links); err != nil {
return nil, err
}
} else {
if !schema.ValidateMill(node.Mill) {
return nil, schema.ErrSchemaInvalidMill
}
// extra check for json
if node.Mill == "/json" {
if node.JsonSchema == nil {
return nil, schema.ErrMissingJsonSchema
}
if err := validateJsonSchema(pb.ToMap(node.JsonSchema)); err != nil {
return nil, err
}
}
}
data, err := pbMarshaler.MarshalToString(&node)
if err != nil {
return nil, err
}
return &Result{File: []byte(data)}, nil
}
func validateJsonSchema(jschema map[string]interface{}) error {
data, err := json.Marshal(&jschema)
if err != nil {
return err
}
loader := gojsonschema.NewStringLoader(string(data))
if _, err := gojsonschema.NewSchema(loader); err != nil {
return schema.ErrBadJsonSchema
}
return nil
}