1 // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
2 var common = require('./common.js');
4 exports.transform = function (model) {
5 var _fileNameWithoutExt = common.path.getFileNameWithoutExtension(model._path);
6 model._jsonPath = _fileNameWithoutExt + ".swagger.json";
7 model.title = model.title || model.name;
8 model.docurl = model.docurl || common.getImproveTheDocHref(model, model._gitContribute, model._gitUrlPattern);
9 model.sourceurl = model.sourceurl || common.getViewSourceHref(model, null, model._gitUrlPattern);
10 model.htmlId = common.getHtmlId(model.uid);
12 for (var i = 0; i < model.children.length; i++) {
13 var child = model.children[i];
14 child.docurl = child.docurl || common.getImproveTheDocHref(child, model._gitContribute, model._gitUrlPattern);
15 if (child.operation) {
16 child.operation = child.operation.toUpperCase();
18 child.path = appendQueryParamsToPath(child.path, child.parameters);
19 child.sourceurl = child.sourceurl || common.getViewSourceHref(child, null, model._gitUrlPattern);
20 child.conceptual = child.conceptual || ''; // set to empty incase mustache looks up
21 child.summary = child.summary || ''; // set to empty incase mustache looks up
22 child.description = child.description || ''; // set to empty incase mustache looks up
23 child.footer = child.footer || ''; // set to empty incase mustache looks up
24 child.remarks = child.remarks || ''; // set to empty incase mustache looks up
26 child.sinceTizen = child.sinceTizen || '';
27 child.precondition = child.precondition || '';
28 child.postcondition = child.postcondition || '';
29 child.feature = child.feature || '';
30 child.privlevel = child.privlevel || '';
31 child.privilege = child.privilege || '';
33 child.htmlId = common.getHtmlId(child.uid);
35 formatExample(child.responses);
37 transformReference(child);
39 if (!model.tags || model.tags.length === 0) {
41 for (var i = 0; i < model.children.length; i++) {
42 var child = model.children[i];
43 if (child.tags && child.tags.length > 0) {
44 for (var k = 0; k < child.tags.length; k++) {
45 // for each tag in child, add unique tag string into childTags
46 if (childTags.indexOf(child.tags[k]) === -1) {
47 childTags.push(child.tags[k]);
52 // sort alphabetically
54 if (childTags.length > 0) {
56 for (var i = 0; i < childTags.length; i++) {
57 // add tags into model
58 model.tags.push({ "name": childTags[i] });
63 for (var i = 0; i < model.tags.length; i++) {
64 var children = getChildrenByTag(model.children, model.tags[i].name);
66 // set children into tag section
67 model.tags[i].children = children;
69 model.tags[i].conceptual = model.tags[i].conceptual || ''; // set to empty incase mustache looks up
70 if (model.tags[i]["x-bookmark-id"]) {
71 model.tags[i].htmlId = model.tags[i]["x-bookmark-id"];
72 } else if (model.tags[i].uid) {
73 model.tags[i].htmlId = common.getHtmlId(model.tags[i].uid);
76 for (var i = 0; i < model.children.length; i++) {
77 var child = model.children[i];
78 if (child.includedInTags) {
79 // set child to undefined, which is already moved to tag section
80 model.children[i] = undefined;
81 if (!model.isTagLayout) {
82 // flags to indicate the model is tag layout
83 model.isTagLayout = true;
87 // remove undefined child
88 model.children = model.children.filter(function (o) { return o; });
94 function getChildrenByTag(children, tag) {
95 if (!children) return;
96 return children.filter(function (child) {
97 if (child.tags && child.tags.indexOf(tag) > -1) {
98 child.includedInTags = true;
104 function formatExample(responses) {
105 if (!responses) return;
106 for (var i = responses.length - 1; i >= 0; i--) {
107 var examples = responses[i].examples;
108 if (!examples) continue;
109 for (var j = examples.length - 1; j >= 0; j--) {
110 var content = examples[j].content;
111 if (!content) continue;
112 var mimeType = examples[j].mimeType;
113 if (mimeType === 'application/json') {
115 var json = JSON.parse(content)
116 responses[i].examples[j].content = JSON.stringify(json, null, ' ');
118 console.warn("example is not a valid JSON object.");
125 function resolveAllOf(obj) {
126 if (Array.isArray(obj)) {
127 for (var i = 0; i < obj.length; i++) {
128 resolveAllOf(obj[i]);
131 else if (typeof obj === "object") {
132 for (var key in obj) {
133 if (obj.hasOwnProperty(key)) {
134 if (key === "allOf" && Array.isArray(obj[key])) {
135 // find 'allOf' array and process
136 processAllOfArray(obj[key], obj);
137 // delete 'allOf' value
140 resolveAllOf(obj[key]);
147 function processAllOfArray(allOfArray, originalObj) {
148 // for each object in 'allOf' array, merge the values to those in the same level with 'allOf'
149 for (var i = 0; i < allOfArray.length; i++) {
150 var item = allOfArray[i];
151 for (var key in item) {
152 if (originalObj.hasOwnProperty(key)) {
153 mergeObjByKey(originalObj[key], item[key]);
155 originalObj[key] = item[key];
161 function mergeObjByKey(targetObj, sourceObj) {
162 for (var key in sourceObj) {
163 // merge only when target object doesn't define the key
164 if (!targetObj.hasOwnProperty(key)) {
165 targetObj[key] = sourceObj[key];
170 function transformReference(obj) {
171 if (Array.isArray(obj)) {
172 for (var i = 0; i < obj.length; i++) {
173 transformReference(obj[i]);
176 else if (typeof obj === "object") {
177 for (var key in obj) {
178 if (obj.hasOwnProperty(key)) {
179 if (key === "schema") {
180 // transform schema.properties from obj to key value pair
181 transformProperties(obj[key]);
183 transformReference(obj[key]);
190 function transformProperties(obj) {
191 if (obj.properties) {
192 if (obj.required && Array.isArray(obj.required)) {
193 for (var i = 0; i < obj.required.length; i++) {
194 var field = obj.required[i];
195 if (obj.properties[field]) {
196 // add required field as property
197 obj.properties[field].required = true;
203 for (var key in obj.properties) {
204 if (obj.properties.hasOwnProperty(key)) {
205 var value = obj.properties[key];
206 // set description to null incase mustache looks up
207 value.description = value.description || null;
209 transformPropertiesValue(value);
210 array.push({ key: key, value: value });
213 obj.properties = array;
217 function transformPropertiesValue(obj) {
218 if (obj.type === "array" && obj.items) {
219 // expand array to transformProperties
220 obj.items.properties = obj.items.properties || null;
221 obj.items['x-internal-ref-name'] = obj.items['x-internal-ref-name'] || null;
222 obj.items['x-internal-loop-ref-name'] = obj.items['x-internal-loop-ref-name'] || null;
223 transformProperties(obj.items);
224 } else if (obj.properties && !obj.items) {
225 // fill obj.properties into obj.items.properties, to be rendered in the same way with array
227 obj.items.properties = obj.properties || null;
228 delete obj.properties;
230 obj.items.required = obj.required;
233 obj.items['x-internal-ref-name'] = obj['x-internal-ref-name'] || null;
234 obj.items['x-internal-loop-ref-name'] = obj['x-internal-loop-ref-name'] || null;
235 transformProperties(obj.items);
239 function appendQueryParamsToPath(path, parameters) {
240 if (!path || !parameters) return path;
242 var requiredQueryParams = parameters.filter(function (p) { return p.in === 'query' && p.required; });
243 if (requiredQueryParams.length > 0) {
244 path = formatParams(path, requiredQueryParams, true);
247 var optionalQueryParams = parameters.filter(function (p) { return p.in === 'query' && !p.required; });
248 if (optionalQueryParams.length > 0) {
250 path = formatParams(path, optionalQueryParams, requiredQueryParams.length === 0);
256 function formatParams(path, parameters, isFirst) {
257 for (var i = 0; i < parameters.length; i++) {
258 if (i === 0 && isFirst) {
263 path += parameters[i].name;
269 exports.getBookmarks = function (model) {
270 if (!model) return null;
274 bookmarks[model.uid] = "";
276 model.tags.forEach(function (tag) {
278 bookmarks[tag.uid] = tag["x-bookmark-id"] ? tag["x-bookmark-id"] : common.getHtmlId(tag.uid);
281 tag.children.forEach(function (child) {
283 bookmarks[child.uid] = common.getHtmlId(child.uid);
289 if (model.children) {
290 model.children.forEach(function (child) {
292 bookmarks[child.uid] = common.getHtmlId(child.uid);