UNPKG

6.44 kBtext/coffeescriptView Raw
1fs = require 'fs'
2path = require 'path'
3refParser = require 'json-schema-ref-parser'
4
5schemas = null
6getSchemas = (callback) ->
7 unless schemas
8 schemas = {}
9 dir = './schema/json/'
10 for jsonFile in fs.readdirSync dir
11 if jsonFile not in ['.', '..']
12 name = jsonFile.split('.')[0]
13 filename = path.join dir, jsonFile
14 schema = JSON.parse fs.readFileSync filename
15 schemas[name] = schema
16 refParser.dereference schemas, callback
17
18mergeAllOf = (obj) ->
19 return obj unless obj
20 unless typeof obj is "object" and not obj.length?
21 return obj
22
23 newObj = {}
24 for key, value of obj
25 if key is 'allOf'
26 for mergeObj in obj[key]
27 for propName, prop of mergeObj
28 newObj[propName] ?= prop
29
30 newObj[key] = mergeAllOf value
31
32 return newObj
33
34# transforms schemas into format better suited to be added to docs
35getDescriptions = (schemas) ->
36
37 desc = {}
38 protocols =
39 runtime: ['input', 'output']
40 graph: ['input']
41 component: ['input', 'output']
42 network: ['input', 'output']
43 trace: ['input', 'output']
44
45 for protocol, categories of protocols
46 messages = {}
47 desc[protocol] =
48 title: schemas[protocol].title
49 description: schemas[protocol].description
50 messages: messages
51
52 for category in categories
53 for event, schema of schemas[protocol][category]
54 message =
55 id: schema.id
56 description: schema.description
57
58 if schema.allOf?
59 #console.log 'sc', schema.allOf[1].properties
60 for key, value of schema.allOf[1].properties.payload
61 message[key] = value
62
63 #if event == 'error'
64 # console.log 'm', message
65 messages[event] = mergeAllOf message
66
67 return desc
68
69isAllowedTypeless = (name, parent) ->
70 return true if parent.id is 'port_definition' and name is 'default'
71 return true if parent.id is 'input/packet' and name is 'payload'
72 return true if parent.id is 'output/packet' and name is 'payload'
73 return true if parent.id is 'output/packetsent' and name is 'payload'
74 false
75
76renderProperty = (name, def, parent) ->
77 throw new Error("Property #{name} is missing .description") if not def.description
78 unless isAllowedTypeless name, parent
79 throw new Error("Property #{name} is missing .type") if not def.type
80 throw new Error("Parent schema not specified for #{name}") if not parent
81 if parent.type == 'array'
82 if not parent.items?.required?.length
83 throw new Error(".required array not specified for #{name} of #{parent.id} (array)")
84 else
85 if not parent.required?.length?
86 console.log(JSON.stringify(parent, null, 2))
87 throw new Error(".required array not specified for #{name} of #{parent.id}")
88
89 isOptional = (parent.type == 'array' and parent.required?.indexOf(name) == -1) or parent.items?.required?.indexOf(name) == -1
90 classes = "property"
91 classes += " optional" if isOptional
92 name = "<label class='#{classes} name'>#{name}</label>"
93 type = "<label class='#{classes} type'>#{def.type or 'any'}</label>"
94
95 if def.enum?.length
96 def.description += " (one of: #{def.enum.join(', ')})"
97
98 description = "<label class='#{classes} description'>#{def.description}</label>"
99 example = ""
100 example = "<code class='#{classes} example'>#{JSON.stringify(def.example)}</code>" if def.example?
101 return name + type + description + example
102
103renderMessage = (messageType, message, protocolName) ->
104
105 lines = []
106 p = (line) -> lines.push line
107
108 messageId = "#{protocolName}-#{messageType}"
109 anchorUrl = '#'+messageId
110
111 p "<h3 id='#{messageId}' class='message name'><a href='#{anchorUrl}'>#{messageType}</a></h3>"
112 p "<p>#{message.description}</p>"
113
114 p "<ul class='message properties'>"
115 for messagePropName, messageProp of message.properties
116 line = "<li>#{renderProperty(messagePropName, messageProp, message)}</li>"
117 items = messageProp.items
118
119 if messageProp.type is 'object' and messageProp.properties?
120 p line
121 p "<ul class='properties'>"
122 for subPropName, subProp of messageProp.properties
123 p "<li>#{renderProperty(subPropName, subProp, messageProp)}</li>"
124 p "</ul>"
125
126 else if items?.type is 'object'
127 line += "Each item contains:"
128 p line
129
130 p "<ul class='properties'>"
131 for itemPropName, itemProp of items.properties
132 if itemProp.type is 'object'
133 p "<li>#{renderProperty(itemPropName, itemProp, messageProp)}</li>"
134
135 p "<ul class='properties'>"
136 for itemSubPropName, itemSubProp of itemProp.properties
137 p "<li>#{renderProperty(itemSubPropName, itemSubProp, itemProp)}</li>"
138 p "</ul>"
139
140 else
141 p "<li>#{renderProperty(itemPropName, itemProp, messageProp)}</li>"
142 p "</ul>"
143
144 else
145 p line
146 p "</ul>"
147
148 return lines
149
150renderCapabilities = () ->
151 tv4 = require '../schema/index.js'
152 schema = tv4.getSchema '/shared/capabilities'
153
154 lines = []
155 p = (line) -> lines.push line
156
157 p "<section class='capabilities'>"
158 for enumDescription in schema.items._enumDescriptions
159 p "<h4 class='capability name'>#{enumDescription.name}</h4>"
160 p "<p>#{enumDescription.description}</p>"
161
162 p "<h5 class='capability messages header'>input messages</h5>"
163 p "<ul class='capability messages'>"
164 for name in enumDescription.inputs
165 messageUrl = "#"+name.replace(':', '-')
166 p "<li><a href='#{messageUrl}'>#{name}</a></li>"
167 p "</ul>"
168
169 p "<h5 class='capability messages header'>output messages</h5>"
170 p "<ul class='capability messages'>"
171 for name in enumDescription.outputs
172 messageUrl = "#"+name.replace(':', '-')
173 p "<li><a href='#{messageUrl}'>#{name}</a></li>"
174 p "</ul>"
175
176 p "</section>"
177
178 return lines.join('\n')
179
180renderMessages = (callback) ->
181 getSchemas (err, schemas) ->
182 return callback err if err
183 descriptions = getDescriptions schemas
184
185 lines = []
186 p = (line) -> lines.push line
187
188 for protocol, protocolProps of descriptions
189 p "<h2 class='protocol name' id='#{protocol}-protocol'>#{protocolProps.title}</h2>"
190 p "<p class='protocol description'>#{protocolProps.description}</p>"
191
192 for messageType, message of protocolProps.messages
193 m = renderMessage messageType, message, protocol
194 lines = lines.concat m
195
196 callback null, lines.join('\n')
197
198module.exports =
199 renderMessages: renderMessages
200 renderCapabilities: renderCapabilities
201 getSchemas: getSchemas