This repository has been archived by the owner on Jul 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanifest-parser.go
153 lines (125 loc) · 3.3 KB
/
manifest-parser.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package vitgo
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
)
type manifestNode struct {
key string
nodeType reflect.Kind
value reflect.Value
children []*manifestNode
}
type manifestTarget struct {
File string `json:"file"`
Source string `json:"src"`
IsEntry bool `json:"isEntry"`
Imports []string `json:"imports"`
CSS []string `json:"css"`
Nodes []*manifestNode
}
func (n *manifestNode) subKey(key string) *manifestNode {
if len(n.children) == 0 {
return nil
}
for _, leaf := range n.children {
if leaf.key == key {
return leaf
}
}
return nil
}
// forked from: https://yourbasic.org/golang/json-example
func (m *manifestTarget) parseWithoutReflection(jsonData []byte) (*VitGo, error) {
var v interface{}
json.Unmarshal(jsonData, &v)
topNode := manifestNode{
key: "top",
}
m.Nodes = append(m.Nodes, &topNode)
m.siftCollections(&topNode, "", "", v)
// Get entry point
entry := (*manifestNode)(nil)
vgo := &VitGo{}
for _, leaf := range topNode.children {
if leaf.subKey("isEntry") != nil {
entry = leaf
vgo.MainModule = leaf.subKey("file").value.String()
break
}
}
if entry == nil {
return nil, ErrNoEntryPoint
}
imports := entry.subKey("imports")
if imports == nil || len(imports.children) == 0 {
// return nil, errors.New("expected code to have js dependencies")
// turns out this will become optional as of Vite 2.9, so:
} else {
for _, child := range imports.children {
// these have a level of indirection for some reason
deref := topNode.subKey(child.value.String())
if deref == nil {
return nil, ErrNoInputFile
}
item := deref.subKey("file")
if item == nil {
return nil, ErrManifestBadlyFormed
}
vgo.Imports = append(vgo.Imports, item.value.String())
}
}
css := entry.subKey("css")
if css == nil || len(css.children) == 0 {
// not an error, since CSS is optional
return vgo, nil
}
for _, child := range css.children {
vgo.CSSModule = append(vgo.CSSModule, child.value.String())
}
return vgo, nil
}
func (m *manifestTarget) siftCollections(leaf *manifestNode, indent, key string, v interface{}) {
data, ok := v.(map[string]interface{})
if ok {
leaf.nodeType = reflect.Map
for k, v := range data {
child := &manifestNode{
key: k,
}
leaf.children = append(leaf.children, child)
m.processInterface(child, indent, k, v)
}
} else if arrayData, ok := v.([]interface{}); ok {
leaf.nodeType = reflect.Slice
for i, v := range arrayData {
child := &manifestNode{}
leaf.children = append(leaf.children, child)
m.processInterface(child, indent, strconv.Itoa(i), v)
}
} else {
m.processInterface(leaf, indent, key, v)
}
}
// call this for recurisve structures.
func (m *manifestTarget) processInterface(leaf *manifestNode, indent, k string, v interface{}) {
// Cover types we know we get in JSON
switch v := v.(type) {
case string:
leaf.nodeType = reflect.String
leaf.value = reflect.ValueOf(v)
case float64:
leaf.nodeType = reflect.Float64
leaf.value = reflect.ValueOf(v)
case bool:
leaf.nodeType = reflect.Bool
leaf.value = reflect.ValueOf(v)
case []interface{}:
m.siftCollections(leaf, indent+" ", k, v)
case map[string]interface{}:
m.siftCollections(leaf, indent+" ", k, v)
default:
fmt.Printf("%s %s ?? %T (unknown)", indent, k, v)
}
}