GitHubProvider.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.computeReleaseNotes = computeReleaseNotes;
  6. exports.GitHubProvider = exports.BaseGitHubProvider = void 0;
  7. function _bluebirdLst() {
  8. const data = require("bluebird-lst");
  9. _bluebirdLst = function () {
  10. return data;
  11. };
  12. return data;
  13. }
  14. function _builderUtilRuntime() {
  15. const data = require("builder-util-runtime");
  16. _builderUtilRuntime = function () {
  17. return data;
  18. };
  19. return data;
  20. }
  21. function semver() {
  22. const data = _interopRequireWildcard(require("semver"));
  23. semver = function () {
  24. return data;
  25. };
  26. return data;
  27. }
  28. function _url() {
  29. const data = require("url");
  30. _url = function () {
  31. return data;
  32. };
  33. return data;
  34. }
  35. function _main() {
  36. const data = require("./main");
  37. _main = function () {
  38. return data;
  39. };
  40. return data;
  41. }
  42. function _Provider() {
  43. const data = require("./Provider");
  44. _Provider = function () {
  45. return data;
  46. };
  47. return data;
  48. }
  49. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
  50. const hrefRegExp = /\/tag\/v?([^\/]+)$/;
  51. class BaseGitHubProvider extends _main().Provider {
  52. constructor(options, defaultHost, executor) {
  53. super(executor, false
  54. /* because GitHib uses S3 */
  55. );
  56. this.options = options;
  57. this.baseUrl = (0, _main().newBaseUrl)((0, _builderUtilRuntime().githubUrl)(options, defaultHost));
  58. const apiHost = defaultHost === "github.com" ? "api.github.com" : defaultHost;
  59. this.baseApiUrl = (0, _main().newBaseUrl)((0, _builderUtilRuntime().githubUrl)(options, apiHost));
  60. }
  61. computeGithubBasePath(result) {
  62. // https://github.com/electron-userland/electron-builder/issues/1903#issuecomment-320881211
  63. const host = this.options.host;
  64. return host != null && host !== "github.com" && host !== "api.github.com" ? `/api/v3${result}` : result;
  65. }
  66. }
  67. exports.BaseGitHubProvider = BaseGitHubProvider;
  68. class GitHubProvider extends BaseGitHubProvider {
  69. constructor(options, updater, executor) {
  70. super(options, "github.com", executor);
  71. this.options = options;
  72. this.updater = updater;
  73. }
  74. getLatestVersion() {
  75. var _this = this;
  76. return (0, _bluebirdLst().coroutine)(function* () {
  77. const cancellationToken = new (_builderUtilRuntime().CancellationToken)();
  78. const feedXml = yield _this.httpRequest((0, _main().newUrlFromBase)(`${_this.basePath}.atom`, _this.baseUrl), {
  79. Accept: "application/xml, application/atom+xml, text/xml, */*"
  80. }, cancellationToken);
  81. const feed = (0, _builderUtilRuntime().parseXml)(feedXml);
  82. let latestRelease = feed.element("entry", false, `No published versions on GitHub`);
  83. let version;
  84. try {
  85. if (_this.updater.allowPrerelease) {
  86. // noinspection TypeScriptValidateJSTypes
  87. version = latestRelease.element("link").attribute("href").match(hrefRegExp)[1];
  88. } else {
  89. version = yield _this.getLatestVersionString(cancellationToken);
  90. for (const element of feed.getElements("entry")) {
  91. if (element.element("link").attribute("href").match(hrefRegExp)[1] === version) {
  92. latestRelease = element;
  93. break;
  94. }
  95. }
  96. }
  97. } catch (e) {
  98. throw (0, _builderUtilRuntime().newError)(`Cannot parse releases feed: ${e.stack || e.message},\nXML:\n${feedXml}`, "ERR_UPDATER_INVALID_RELEASE_FEED");
  99. }
  100. if (version == null) {
  101. throw (0, _builderUtilRuntime().newError)(`No published versions on GitHub`, "ERR_UPDATER_NO_PUBLISHED_VERSIONS");
  102. }
  103. const channelFile = (0, _main().getChannelFilename)((0, _main().getDefaultChannelName)());
  104. const channelFileUrl = (0, _main().newUrlFromBase)(_this.getBaseDownloadPath(version, channelFile), _this.baseUrl);
  105. const requestOptions = _this.createRequestOptions(channelFileUrl);
  106. let rawData;
  107. try {
  108. rawData = yield _this.executor.request(requestOptions, cancellationToken);
  109. } catch (e) {
  110. if (!_this.updater.allowPrerelease && e instanceof _builderUtilRuntime().HttpError && e.statusCode === 404) {
  111. throw (0, _builderUtilRuntime().newError)(`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
  112. }
  113. throw e;
  114. }
  115. const result = (0, _Provider().parseUpdateInfo)(rawData, channelFile, channelFileUrl);
  116. if ((0, _main().isUseOldMacProvider)()) {
  117. result.releaseJsonUrl = `${(0, _builderUtilRuntime().githubUrl)(_this.options)}/${requestOptions.path}`;
  118. }
  119. if (result.releaseName == null) {
  120. result.releaseName = latestRelease.elementValueOrEmpty("title");
  121. }
  122. if (result.releaseNotes == null) {
  123. result.releaseNotes = computeReleaseNotes(_this.updater.currentVersion, _this.updater.fullChangelog, feed, latestRelease);
  124. }
  125. return result;
  126. })();
  127. }
  128. getLatestVersionString(cancellationToken) {
  129. var _this2 = this;
  130. return (0, _bluebirdLst().coroutine)(function* () {
  131. const options = _this2.options; // do not use API for GitHub to avoid limit, only for custom host or GitHub Enterprise
  132. const url = options.host == null || options.host === "github.com" ? (0, _main().newUrlFromBase)(`${_this2.basePath}/latest`, _this2.baseUrl) : new (_url().URL)(`${_this2.computeGithubBasePath(`/repos/${options.owner}/${options.repo}/releases`)}/latest`, _this2.baseApiUrl);
  133. try {
  134. const rawData = yield _this2.httpRequest(url, {
  135. Accept: "application/json"
  136. }, cancellationToken);
  137. if (rawData == null) {
  138. return null;
  139. }
  140. const releaseInfo = JSON.parse(rawData);
  141. return releaseInfo.tag_name.startsWith("v") ? releaseInfo.tag_name.substring(1) : releaseInfo.tag_name;
  142. } catch (e) {
  143. throw (0, _builderUtilRuntime().newError)(`Unable to find latest version on GitHub (${url}), please ensure a production release exists: ${e.stack || e.message}`, "ERR_UPDATER_LATEST_VERSION_NOT_FOUND");
  144. }
  145. })();
  146. }
  147. get basePath() {
  148. return `/${this.options.owner}/${this.options.repo}/releases`;
  149. }
  150. resolveFiles(updateInfo) {
  151. // still replace space to - due to backward compatibility
  152. return (0, _Provider().resolveFiles)(updateInfo, this.baseUrl, p => this.getBaseDownloadPath(updateInfo.version, p.replace(/ /g, "-")));
  153. }
  154. getBaseDownloadPath(version, fileName) {
  155. return `${this.basePath}/download/${this.options.vPrefixedTagName === false ? "" : "v"}${version}/${fileName}`;
  156. }
  157. }
  158. exports.GitHubProvider = GitHubProvider;
  159. function getNoteValue(parent) {
  160. const result = parent.elementValueOrEmpty("content"); // GitHub reports empty notes as <content>No content.</content>
  161. return result === "No content." ? "" : result;
  162. }
  163. function computeReleaseNotes(currentVersion, isFullChangelog, feed, latestRelease) {
  164. if (!isFullChangelog) {
  165. return getNoteValue(latestRelease);
  166. }
  167. const releaseNotes = [];
  168. for (const release of feed.getElements("entry")) {
  169. // noinspection TypeScriptValidateJSTypes
  170. const versionRelease = release.element("link").attribute("href").match(/\/tag\/v?([^\/]+)$/)[1];
  171. if (semver().lt(currentVersion, versionRelease)) {
  172. releaseNotes.push({
  173. version: versionRelease,
  174. note: getNoteValue(release)
  175. });
  176. }
  177. }
  178. return releaseNotes.sort((a, b) => semver().rcompare(a.version, b.version));
  179. }
  180. //# sourceMappingURL=GitHubProvider.js.map