common.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
  2. exports.path = {};
  3. exports.path.getFileNameWithoutExtension = getFileNameWithoutExtension;
  4. exports.path.getDirectoryName = getDirectoryName;
  5. exports.getHtmlId = getHtmlId;
  6. exports.getViewSourceHref = getViewSourceHref;
  7. exports.getImproveTheDocHref = getImproveTheDocHref;
  8. exports.processSeeAlso = processSeeAlso;
  9. exports.isAbsolutePath = isAbsolutePath;
  10. exports.isRelativePath = isRelativePath;
  11. function getFileNameWithoutExtension(path) {
  12. if (!path || path[path.length - 1] === '/' || path[path.length - 1] === '\\') return '';
  13. var fileName = path.split('\\').pop().split('/').pop();
  14. return fileName.slice(0, fileName.lastIndexOf('.'));
  15. }
  16. function getDirectoryName(path) {
  17. if (!path) return '';
  18. var index = path.lastIndexOf('/');
  19. return path.slice(0, index + 1);
  20. }
  21. function getHtmlId(input) {
  22. if (!input) return '';
  23. return input.replace(/\W/g, '_');
  24. }
  25. // Note: the parameter `gitContribute` won't be used in this function
  26. function getViewSourceHref(item, gitContribute, gitUrlPattern) {
  27. if (!item || !item.source || !item.source.remote) return '';
  28. return getRemoteUrl(item.source.remote, item.source.startLine - '0' + 1, null, gitUrlPattern);
  29. }
  30. function getImproveTheDocHref(item, gitContribute, gitUrlPattern) {
  31. if (!item) return '';
  32. if (!item.documentation || !item.documentation.remote) {
  33. return getNewFileUrl(item, gitContribute, gitUrlPattern);
  34. } else {
  35. return getRemoteUrl(item.documentation.remote, item.documentation.startLine + 1, gitContribute, gitUrlPattern);
  36. }
  37. }
  38. function processSeeAlso(item) {
  39. if (item.seealso) {
  40. for (var key in item.seealso) {
  41. addIsCref(item.seealso[key]);
  42. }
  43. }
  44. item.seealso = item.seealso || null;
  45. }
  46. function isAbsolutePath(path) {
  47. return /^(\w+:)?\/\//g.test(path);
  48. }
  49. function isRelativePath(path) {
  50. if (!path) return false;
  51. return !exports.isAbsolutePath(path);
  52. }
  53. var gitUrlPatternItems = {
  54. 'github': {
  55. // HTTPS form: https://github.com/{org}/{repo}.git
  56. // SSH form: [email protected]:{org}/{repo}.git
  57. // generate URL: https://github.com/{org}/{repo}/blob/{branch}/{path}
  58. 'testRegex': /^(https?:\/\/)?(\S+\@)?(\S+\.)?github\.com(\/|:).*/i,
  59. 'generateUrl': function (gitInfo) {
  60. var url = normalizeGitUrlToHttps(gitInfo.repo);
  61. url = getRepoWithoutGitExtension(url);
  62. url += '/blob' + '/' + gitInfo.branch + '/' + gitInfo.path;
  63. if (gitInfo.startLine && gitInfo.startLine > 0) {
  64. url += '/#L' + gitInfo.startLine;
  65. }
  66. return url;
  67. },
  68. 'generateNewFileUrl': function (gitInfo, uid) {
  69. var url = normalizeGitUrlToHttps(gitInfo.repo);
  70. url = getRepoWithoutGitExtension(url);
  71. url += '/new';
  72. url += '/' + gitInfo.branch;
  73. url += '/' + getOverrideFolder(gitInfo.apiSpecFolder);
  74. url += '/new?filename=' + getHtmlId(uid) + '.md';
  75. url += '&value=' + encodeURIComponent(getOverrideTemplate(uid));
  76. return url;
  77. }
  78. },
  79. 'vso': {
  80. // HTTPS form: https://{account}@dev.azure.com/{account}/{project}/_git/{repo}
  81. // HTTPS form: https://{user}.visualstudio.com/{org}/_git/{repo}
  82. // SSH form: [email protected]:v3/{account}/{project}/{repo}
  83. // SSH form: ssh://{user}@{user}.visualstudio.com:22/{org}/_git/{repo}
  84. // generated URL under branch: https://{account}@dev.azure.com/{account}/{project}/_git/{repo}?version=GB{branch}
  85. // generated URL under branch: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GB{branch}
  86. // generated URL under detached HEAD: https://{user}.visualstudio.com/{org}/_git/{repo}?path={path}&version=GC{commit}
  87. 'testRegex': /^(https?:\/\/)?(ssh:\/\/\S+\@)?(\S+@)?(\S+\.)?(dev\.azure|visualstudio)\.com(\/|:).*/i,
  88. 'generateUrl': function (gitInfo) {
  89. var url = normalizeGitUrlToHttps(gitInfo.repo);
  90. var branchPrefix = /[0-9a-fA-F]{40}/.test(gitInfo.branch) ? 'GC' : 'GB';
  91. url += '?path=' + gitInfo.path + '&version=' + branchPrefix + gitInfo.branch;
  92. if (gitInfo.startLine && gitInfo.startLine > 0) {
  93. url += '&line=' + gitInfo.startLine;
  94. }
  95. return url;
  96. },
  97. 'generateNewFileUrl': function (gitInfo, uid) {
  98. return '';
  99. }
  100. },
  101. 'bitbucket': {
  102. // HTTPS form: https://{user}@bitbucket.org/{org}/{repo}.git
  103. // SSH form: [email protected]:{org}/{repo}.git
  104. // generate URL: https://bitbucket.org/{org}/{repo}/src/{branch}/{path}
  105. 'testRegex': /^(https?:\/\/)?(\S+\@)?(\S+\.)?bitbucket\.org(\/|:).*/i,
  106. 'generateUrl': function (gitInfo) {
  107. var url = normalizeGitUrlToHttps(gitInfo.repo);
  108. url = getRepoWithoutGitExtension(url);
  109. url += '/src' + '/' + gitInfo.branch + '/' + gitInfo.path;
  110. if (gitInfo.startLine && gitInfo.startLine > 0) {
  111. url += '#lines-' + gitInfo.startLine;
  112. }
  113. return url;
  114. },
  115. 'generateNewFileUrl': function (gitInfo, uid) {
  116. return '';
  117. }
  118. }
  119. }
  120. function getRepoWithoutGitExtension(repo) {
  121. if (repo.substr(-4) === '.git') {
  122. repo = repo.substr(0, repo.length - 4);
  123. }
  124. return repo;
  125. }
  126. function normalizeGitUrlToHttps(repo) {
  127. var pos = repo.indexOf('@');
  128. if (pos == -1) return repo;
  129. return 'https://' + repo.substr(pos + 1).replace(/:[0-9]+/g, '').replace(/:/g, '/');
  130. }
  131. function getNewFileUrl(item, gitContribute, gitUrlPattern) {
  132. // do not support VSO for now
  133. if (!item.source) {
  134. return '';
  135. }
  136. var gitInfo = getGitInfo(gitContribute, item.source.remote);
  137. if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
  138. return '';
  139. }
  140. var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
  141. if (!patternName) return patternName;
  142. return gitUrlPatternItems[patternName].generateNewFileUrl(gitInfo, item.uid);
  143. }
  144. function getRemoteUrl(remote, startLine, gitContribute, gitUrlPattern) {
  145. var gitInfo = getGitInfo(gitContribute, remote);
  146. if (!gitInfo.repo || !gitInfo.branch || !gitInfo.path) {
  147. return '';
  148. }
  149. var patternName = getPatternName(gitInfo.repo, gitUrlPattern);
  150. if (!patternName) return '';
  151. gitInfo.startLine = startLine;
  152. return gitUrlPatternItems[patternName].generateUrl(gitInfo);
  153. }
  154. function getGitInfo(gitContribute, gitRemote) {
  155. // apiSpecFolder defines the folder contains overwrite files for MRef, the default value is apiSpec
  156. var defaultApiSpecFolder = 'apiSpec';
  157. var result = {};
  158. if (gitContribute && gitContribute.apiSpecFolder) {
  159. result.apiSpecFolder = gitContribute.apiSpecFolder;
  160. } else {
  161. result.apiSpecFolder = defaultApiSpecFolder;
  162. }
  163. mergeKey(gitContribute, gitRemote, result, 'repo');
  164. mergeKey(gitContribute, gitRemote, result, 'branch');
  165. mergeKey(gitContribute, gitRemote, result, 'path');
  166. return result;
  167. function mergeKey(source, sourceFallback, dest, key) {
  168. if (source && source.hasOwnProperty(key)) {
  169. dest[key] = source[key];
  170. } else if (sourceFallback && sourceFallback.hasOwnProperty(key)) {
  171. dest[key] = sourceFallback[key];
  172. }
  173. }
  174. }
  175. function getPatternName(repo, gitUrlPattern) {
  176. if (gitUrlPattern && gitUrlPattern.toLowerCase() in gitUrlPatternItems) {
  177. return gitUrlPattern.toLowerCase();
  178. } else {
  179. for (var p in gitUrlPatternItems) {
  180. if (gitUrlPatternItems[p].testRegex.test(repo)) {
  181. return p;
  182. }
  183. }
  184. }
  185. return '';
  186. }
  187. function getOverrideFolder(path) {
  188. if (!path) return "";
  189. path = path.replace(/\\/g, '/');
  190. if (path.charAt(path.length - 1) == '/') path = path.substring(0, path.length - 1);
  191. return path;
  192. }
  193. function getOverrideTemplate(uid) {
  194. if (!uid) return "";
  195. var content = "";
  196. content += "---\n";
  197. content += "uid: " + uid + "\n";
  198. content += "summary: '*You can override summary for the API here using *MARKDOWN* syntax'\n";
  199. content += "---\n";
  200. content += "\n";
  201. content += "*Please type below more information about this API:*\n";
  202. content += "\n";
  203. return content;
  204. }
  205. function addIsCref(seealso) {
  206. if (!seealso.linkType || seealso.linkType.toLowerCase() == "cref") {
  207. seealso.isCref = true;
  208. }
  209. }