RestApi.common.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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');
  3. exports.transform = function (model) {
  4. var _fileNameWithoutExt = common.path.getFileNameWithoutExtension(model._path);
  5. model._jsonPath = _fileNameWithoutExt + ".swagger.json";
  6. model.title = model.title || model.name;
  7. model.docurl = model.docurl || common.getImproveTheDocHref(model, model._gitContribute, model._gitUrlPattern);
  8. model.sourceurl = model.sourceurl || common.getViewSourceHref(model, null, model._gitUrlPattern);
  9. model.htmlId = common.getHtmlId(model.uid);
  10. if (model.children) {
  11. for (var i = 0; i < model.children.length; i++) {
  12. var child = model.children[i];
  13. child.docurl = child.docurl || common.getImproveTheDocHref(child, model._gitContribute, model._gitUrlPattern);
  14. if (child.operation) {
  15. child.operation = child.operation.toUpperCase();
  16. }
  17. child.path = appendQueryParamsToPath(child.path, child.parameters);
  18. child.sourceurl = child.sourceurl || common.getViewSourceHref(child, null, model._gitUrlPattern);
  19. child.conceptual = child.conceptual || ''; // set to empty incase mustache looks up
  20. child.summary = child.summary || ''; // set to empty incase mustache looks up
  21. child.description = child.description || ''; // set to empty incase mustache looks up
  22. child.footer = child.footer || ''; // set to empty incase mustache looks up
  23. child.remarks = child.remarks || ''; // set to empty incase mustache looks up
  24. child.htmlId = common.getHtmlId(child.uid);
  25. formatExample(child.responses);
  26. resolveAllOf(child);
  27. transformReference(child);
  28. };
  29. if (!model.tags || model.tags.length === 0) {
  30. var childTags = [];
  31. for (var i = 0; i < model.children.length; i++) {
  32. var child = model.children[i];
  33. if (child.tags && child.tags.length > 0) {
  34. for (var k = 0; k < child.tags.length; k++) {
  35. // for each tag in child, add unique tag string into childTags
  36. if (childTags.indexOf(child.tags[k]) === -1) {
  37. childTags.push(child.tags[k]);
  38. }
  39. }
  40. }
  41. }
  42. // sort alphabetically
  43. childTags.sort();
  44. if (childTags.length > 0) {
  45. model.tags = [];
  46. for (var i = 0; i < childTags.length; i++) {
  47. // add tags into model
  48. model.tags.push({ "name": childTags[i] });
  49. }
  50. }
  51. }
  52. if (model.tags) {
  53. for (var i = 0; i < model.tags.length; i++) {
  54. var children = getChildrenByTag(model.children, model.tags[i].name);
  55. if (children) {
  56. // set children into tag section
  57. model.tags[i].children = children;
  58. }
  59. model.tags[i].conceptual = model.tags[i].conceptual || ''; // set to empty incase mustache looks up
  60. if (model.tags[i]["x-bookmark-id"]) {
  61. model.tags[i].htmlId = model.tags[i]["x-bookmark-id"];
  62. } else if (model.tags[i].uid) {
  63. model.tags[i].htmlId = common.getHtmlId(model.tags[i].uid);
  64. }
  65. }
  66. for (var i = 0; i < model.children.length; i++) {
  67. var child = model.children[i];
  68. if (child.includedInTags) {
  69. // set child to undefined, which is already moved to tag section
  70. model.children[i] = undefined;
  71. if (!model.isTagLayout) {
  72. // flags to indicate the model is tag layout
  73. model.isTagLayout = true;
  74. }
  75. }
  76. }
  77. // remove undefined child
  78. model.children = model.children.filter(function (o) { return o; });
  79. }
  80. }
  81. return model;
  82. function getChildrenByTag(children, tag) {
  83. if (!children) return;
  84. return children.filter(function (child) {
  85. if (child.tags && child.tags.indexOf(tag) > -1) {
  86. child.includedInTags = true;
  87. return true;
  88. }
  89. })
  90. }
  91. function formatExample(responses) {
  92. if (!responses) return;
  93. for (var i = responses.length - 1; i >= 0; i--) {
  94. var examples = responses[i].examples;
  95. if (!examples) continue;
  96. for (var j = examples.length - 1; j >= 0; j--) {
  97. var content = examples[j].content;
  98. if (!content) continue;
  99. var mimeType = examples[j].mimeType;
  100. if (mimeType === 'application/json') {
  101. try {
  102. var json = JSON.parse(content)
  103. responses[i].examples[j].content = JSON.stringify(json, null, ' ');
  104. } catch (e) {
  105. console.warn("example is not a valid JSON object.");
  106. }
  107. }
  108. }
  109. }
  110. }
  111. function resolveAllOf(obj) {
  112. if (Array.isArray(obj)) {
  113. for (var i = 0; i < obj.length; i++) {
  114. resolveAllOf(obj[i]);
  115. }
  116. }
  117. else if (typeof obj === "object") {
  118. for (var key in obj) {
  119. if (obj.hasOwnProperty(key)) {
  120. if (key === "allOf" && Array.isArray(obj[key])) {
  121. // find 'allOf' array and process
  122. processAllOfArray(obj[key], obj);
  123. // delete 'allOf' value
  124. delete obj[key];
  125. } else {
  126. resolveAllOf(obj[key]);
  127. }
  128. }
  129. }
  130. }
  131. }
  132. function processAllOfArray(allOfArray, originalObj) {
  133. // for each object in 'allOf' array, merge the values to those in the same level with 'allOf'
  134. for (var i = 0; i < allOfArray.length; i++) {
  135. var item = allOfArray[i];
  136. for (var key in item) {
  137. if (originalObj.hasOwnProperty(key)) {
  138. mergeObjByKey(originalObj[key], item[key]);
  139. } else {
  140. originalObj[key] = item[key];
  141. }
  142. }
  143. }
  144. }
  145. function mergeObjByKey(targetObj, sourceObj) {
  146. for (var key in sourceObj) {
  147. // merge only when target object doesn't define the key
  148. if (!targetObj.hasOwnProperty(key)) {
  149. targetObj[key] = sourceObj[key];
  150. }
  151. }
  152. }
  153. function transformReference(obj) {
  154. if (Array.isArray(obj)) {
  155. for (var i = 0; i < obj.length; i++) {
  156. transformReference(obj[i]);
  157. }
  158. }
  159. else if (typeof obj === "object") {
  160. for (var key in obj) {
  161. if (obj.hasOwnProperty(key)) {
  162. if (key === "schema") {
  163. // transform schema.properties from obj to key value pair
  164. transformProperties(obj[key]);
  165. } else {
  166. transformReference(obj[key]);
  167. }
  168. }
  169. }
  170. }
  171. }
  172. function transformProperties(obj) {
  173. if (obj.properties) {
  174. if (obj.required && Array.isArray(obj.required)) {
  175. for (var i = 0; i < obj.required.length; i++) {
  176. var field = obj.required[i];
  177. if (obj.properties[field]) {
  178. // add required field as property
  179. obj.properties[field].required = true;
  180. }
  181. }
  182. delete obj.required;
  183. }
  184. var array = [];
  185. for (var key in obj.properties) {
  186. if (obj.properties.hasOwnProperty(key)) {
  187. var value = obj.properties[key];
  188. // set description to null incase mustache looks up
  189. value.description = value.description || null;
  190. transformPropertiesValue(value);
  191. array.push({ key: key, value: value });
  192. }
  193. }
  194. obj.properties = array;
  195. }
  196. }
  197. function transformPropertiesValue(obj) {
  198. if (obj.type === "array" && obj.items) {
  199. // expand array to transformProperties
  200. obj.items.properties = obj.items.properties || null;
  201. obj.items['x-internal-ref-name'] = obj.items['x-internal-ref-name'] || null;
  202. obj.items['x-internal-loop-ref-name'] = obj.items['x-internal-loop-ref-name'] || null;
  203. transformProperties(obj.items);
  204. } else if (obj.properties && !obj.items) {
  205. // fill obj.properties into obj.items.properties, to be rendered in the same way with array
  206. obj.items = {};
  207. obj.items.properties = obj.properties || null;
  208. delete obj.properties;
  209. if (obj.required) {
  210. obj.items.required = obj.required;
  211. delete obj.required;
  212. }
  213. obj.items['x-internal-ref-name'] = obj['x-internal-ref-name'] || null;
  214. obj.items['x-internal-loop-ref-name'] = obj['x-internal-loop-ref-name'] || null;
  215. transformProperties(obj.items);
  216. }
  217. }
  218. function appendQueryParamsToPath(path, parameters) {
  219. if (!path || !parameters) return path;
  220. var requiredQueryParams = parameters.filter(function (p) { return p.in === 'query' && p.required; });
  221. if (requiredQueryParams.length > 0) {
  222. path = formatParams(path, requiredQueryParams, true);
  223. }
  224. var optionalQueryParams = parameters.filter(function (p) { return p.in === 'query' && !p.required; });
  225. if (optionalQueryParams.length > 0) {
  226. path += "[";
  227. path = formatParams(path, optionalQueryParams, requiredQueryParams.length === 0);
  228. path += "]";
  229. }
  230. return path;
  231. }
  232. function formatParams(path, parameters, isFirst) {
  233. for (var i = 0; i < parameters.length; i++) {
  234. if (i === 0 && isFirst) {
  235. path += "?";
  236. } else {
  237. path += "&";
  238. }
  239. path += parameters[i].name;
  240. }
  241. return path;
  242. }
  243. }
  244. exports.getBookmarks = function (model) {
  245. if (!model) return null;
  246. var bookmarks = {};
  247. bookmarks[model.uid] = "";
  248. if (model.tags) {
  249. model.tags.forEach(function (tag) {
  250. if (tag.uid) {
  251. bookmarks[tag.uid] = tag["x-bookmark-id"] ? tag["x-bookmark-id"] : common.getHtmlId(tag.uid);
  252. }
  253. if (tag.children) {
  254. tag.children.forEach(function (child) {
  255. if (child.uid) {
  256. bookmarks[child.uid] = common.getHtmlId(child.uid);
  257. }
  258. })
  259. }
  260. })
  261. }
  262. if (model.children) {
  263. model.children.forEach(function (child) {
  264. if (child.uid) {
  265. bookmarks[child.uid] = common.getHtmlId(child.uid);
  266. }
  267. });
  268. }
  269. return bookmarks;
  270. }