UNPKG

9.29 kBJavaScriptView Raw
1var fs, getDescriptions, getSchemas, isAllowedTypeless, mergeAllOf, path, refParser, renderCapabilities, renderMessage, renderMessages, renderProperty, schemas;
2
3fs = require('fs');
4
5path = require('path');
6
7refParser = require('json-schema-ref-parser');
8
9schemas = null;
10
11getSchemas = function(callback) {
12 var dir, filename, i, jsonFile, len, name, ref, schema;
13 if (!schemas) {
14 schemas = {};
15 dir = './schema/json/';
16 ref = fs.readdirSync(dir);
17 for (i = 0, len = ref.length; i < len; i++) {
18 jsonFile = ref[i];
19 if (jsonFile !== '.' && jsonFile !== '..') {
20 name = jsonFile.split('.')[0];
21 filename = path.join(dir, jsonFile);
22 schema = JSON.parse(fs.readFileSync(filename));
23 schemas[name] = schema;
24 }
25 }
26 }
27 return refParser.dereference(schemas, callback);
28};
29
30mergeAllOf = function(obj) {
31 var i, key, len, mergeObj, newObj, prop, propName, ref, value;
32 if (!obj) {
33 return obj;
34 }
35 if (!(typeof obj === "object" && (obj.length == null))) {
36 return obj;
37 }
38 newObj = {};
39 for (key in obj) {
40 value = obj[key];
41 if (key === 'allOf') {
42 ref = obj[key];
43 for (i = 0, len = ref.length; i < len; i++) {
44 mergeObj = ref[i];
45 for (propName in mergeObj) {
46 prop = mergeObj[propName];
47 if (newObj[propName] == null) {
48 newObj[propName] = prop;
49 }
50 }
51 }
52 }
53 newObj[key] = mergeAllOf(value);
54 }
55 return newObj;
56};
57
58// transforms schemas into format better suited to be added to docs
59getDescriptions = function(schemas) {
60 var categories, category, desc, event, i, key, len, message, messages, protocol, protocols, ref, ref1, schema, value;
61 desc = {};
62 protocols = {
63 runtime: ['input', 'output'],
64 graph: ['input'],
65 component: ['input', 'output'],
66 network: ['input', 'output'],
67 trace: ['input', 'output']
68 };
69 for (protocol in protocols) {
70 categories = protocols[protocol];
71 messages = {};
72 desc[protocol] = {
73 title: schemas[protocol].title,
74 description: schemas[protocol].description,
75 messages: messages
76 };
77 for (i = 0, len = categories.length; i < len; i++) {
78 category = categories[i];
79 ref = schemas[protocol][category];
80 for (event in ref) {
81 schema = ref[event];
82 message = {
83 id: schema.id,
84 description: schema.description
85 };
86 if (schema.allOf != null) {
87 ref1 = schema.allOf[1].properties.payload;
88 //console.log 'sc', schema.allOf[1].properties
89 for (key in ref1) {
90 value = ref1[key];
91 message[key] = value;
92 }
93 }
94 //if event == 'error'
95 // console.log 'm', message
96 messages[event] = mergeAllOf(message);
97 }
98 }
99 }
100 return desc;
101};
102
103isAllowedTypeless = function(name, parent) {
104 if (parent.id === 'port_definition' && name === 'default') {
105 return true;
106 }
107 if (parent.id === 'input/packet' && name === 'payload') {
108 return true;
109 }
110 if (parent.id === 'output/packet' && name === 'payload') {
111 return true;
112 }
113 if (parent.id === 'output/packetsent' && name === 'payload') {
114 return true;
115 }
116 return false;
117};
118
119renderProperty = function(name, def, parent) {
120 var classes, description, example, isOptional, ref, ref1, ref2, ref3, ref4, ref5, ref6, type;
121 if (!def.description) {
122 throw new Error(`Property ${name} is missing .description`);
123 }
124 if (!isAllowedTypeless(name, parent)) {
125 if (!def.type) {
126 throw new Error(`Property ${name} is missing .type`);
127 }
128 }
129 if (!parent) {
130 throw new Error(`Parent schema not specified for ${name}`);
131 }
132 if (parent.type === 'array') {
133 if (!((ref = parent.items) != null ? (ref1 = ref.required) != null ? ref1.length : void 0 : void 0)) {
134 throw new Error(`.required array not specified for ${name} of ${parent.id} (array)`);
135 }
136 } else {
137 if (((ref2 = parent.required) != null ? ref2.length : void 0) == null) {
138 console.log(JSON.stringify(parent, null, 2));
139 throw new Error(`.required array not specified for ${name} of ${parent.id}`);
140 }
141 }
142 isOptional = (parent.type === 'array' && ((ref3 = parent.required) != null ? ref3.indexOf(name) : void 0) === -1) || ((ref4 = parent.items) != null ? (ref5 = ref4.required) != null ? ref5.indexOf(name) : void 0 : void 0) === -1;
143 classes = "property";
144 if (isOptional) {
145 classes += " optional";
146 }
147 name = `<label class='${classes} name'>${name}</label>`;
148 type = `<label class='${classes} type'>${def.type || 'any'}</label>`;
149 if ((ref6 = def.enum) != null ? ref6.length : void 0) {
150 def.description += ` (one of: ${def.enum.join(', ')})`;
151 }
152 description = `<label class='${classes} description'>${def.description}</label>`;
153 example = "";
154 if (def.example != null) {
155 example = `<code class='${classes} example'>${JSON.stringify(def.example)}</code>`;
156 }
157 return name + type + description + example;
158};
159
160renderMessage = function(messageType, message, protocolName) {
161 var anchorUrl, itemProp, itemPropName, itemSubProp, itemSubPropName, items, line, lines, messageId, messageProp, messagePropName, p, ref, ref1, ref2, ref3, subProp, subPropName;
162 lines = [];
163 p = function(line) {
164 return lines.push(line);
165 };
166 messageId = `${protocolName}-${messageType}`;
167 anchorUrl = '#' + messageId;
168 p(`<h3 id='${messageId}' class='message name'><a href='${anchorUrl}'>${messageType}</a></h3>`);
169 p(`<p>${message.description}</p>`);
170 p("<ul class='message properties'>");
171 ref = message.properties;
172 for (messagePropName in ref) {
173 messageProp = ref[messagePropName];
174 line = `<li>${renderProperty(messagePropName, messageProp, message)}</li>`;
175 items = messageProp.items;
176 if (messageProp.type === 'object' && (messageProp.properties != null)) {
177 p(line);
178 p("<ul class='properties'>");
179 ref1 = messageProp.properties;
180 for (subPropName in ref1) {
181 subProp = ref1[subPropName];
182 p(`<li>${renderProperty(subPropName, subProp, messageProp)}</li>`);
183 }
184 p("</ul>");
185 } else if ((items != null ? items.type : void 0) === 'object') {
186 line += "Each item contains:";
187 p(line);
188 p("<ul class='properties'>");
189 ref2 = items.properties;
190 for (itemPropName in ref2) {
191 itemProp = ref2[itemPropName];
192 if (itemProp.type === 'object') {
193 p(`<li>${renderProperty(itemPropName, itemProp, messageProp)}</li>`);
194 p("<ul class='properties'>");
195 ref3 = itemProp.properties;
196 for (itemSubPropName in ref3) {
197 itemSubProp = ref3[itemSubPropName];
198 p(`<li>${renderProperty(itemSubPropName, itemSubProp, itemProp)}</li>`);
199 }
200 p("</ul>");
201 } else {
202 p(`<li>${renderProperty(itemPropName, itemProp, messageProp)}</li>`);
203 }
204 }
205 p("</ul>");
206 } else {
207 p(line);
208 }
209 }
210 p("</ul>");
211 return lines;
212};
213
214renderCapabilities = function() {
215 var enumDescription, i, j, k, len, len1, len2, lines, messageUrl, name, p, ref, ref1, ref2, schema, tv4;
216 tv4 = require('../schema/index.js');
217 schema = tv4.getSchema('/shared/capabilities');
218 lines = [];
219 p = function(line) {
220 return lines.push(line);
221 };
222 p("<section class='capabilities'>");
223 ref = schema.items._enumDescriptions;
224 for (i = 0, len = ref.length; i < len; i++) {
225 enumDescription = ref[i];
226 p(`<h4 class='capability name'>${enumDescription.name}</h4>`);
227 p(`<p>${enumDescription.description}</p>`);
228 p("<h5 class='capability messages header'>input messages</h5>");
229 p("<ul class='capability messages'>");
230 ref1 = enumDescription.inputs;
231 for (j = 0, len1 = ref1.length; j < len1; j++) {
232 name = ref1[j];
233 messageUrl = "#" + name.replace(':', '-');
234 p(`<li><a href='${messageUrl}'>${name}</a></li>`);
235 }
236 p("</ul>");
237 p("<h5 class='capability messages header'>output messages</h5>");
238 p("<ul class='capability messages'>");
239 ref2 = enumDescription.outputs;
240 for (k = 0, len2 = ref2.length; k < len2; k++) {
241 name = ref2[k];
242 messageUrl = "#" + name.replace(':', '-');
243 p(`<li><a href='${messageUrl}'>${name}</a></li>`);
244 }
245 p("</ul>");
246 }
247 p("</section>");
248 return lines.join('\n');
249};
250
251renderMessages = function(callback) {
252 return getSchemas(function(err, schemas) {
253 var descriptions, lines, m, message, messageType, p, protocol, protocolProps, ref;
254 if (err) {
255 return callback(err);
256 }
257 descriptions = getDescriptions(schemas);
258 lines = [];
259 p = function(line) {
260 return lines.push(line);
261 };
262 for (protocol in descriptions) {
263 protocolProps = descriptions[protocol];
264 p(`<h2 class='protocol name' id='${protocol}-protocol'>${protocolProps.title}</h2>`);
265 p(`<p class='protocol description'>${protocolProps.description}</p>`);
266 ref = protocolProps.messages;
267 for (messageType in ref) {
268 message = ref[messageType];
269 m = renderMessage(messageType, message, protocol);
270 lines = lines.concat(m);
271 }
272 }
273 return callback(null, lines.join('\n'));
274 });
275};
276
277module.exports = {
278 renderMessages: renderMessages,
279 renderCapabilities: renderCapabilities,
280 getSchemas: getSchemas
281};