Update gitignore (sorry)

This commit is contained in:
olcxja 2026-05-10 14:02:17 +02:00
commit cca8b02fea
6604 changed files with 1219661 additions and 4 deletions

View file

@ -0,0 +1,14 @@
import { BitbucketOptions, UpdateInfo } from "builder-util-runtime";
import { AppUpdater } from "../AppUpdater";
import { ResolvedUpdateFileInfo } from "../main";
import { Provider, ProviderRuntimeOptions } from "./Provider";
export declare class BitbucketProvider extends Provider<UpdateInfo> {
private readonly configuration;
private readonly updater;
private readonly baseUrl;
constructor(configuration: BitbucketOptions, updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions);
private get channel();
getLatestVersion(): Promise<UpdateInfo>;
resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo>;
toString(): string;
}

View file

@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BitbucketProvider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const util_1 = require("../util");
const Provider_1 = require("./Provider");
class BitbucketProvider extends Provider_1.Provider {
constructor(configuration, updater, runtimeOptions) {
super({
...runtimeOptions,
isUseMultipleRangeRequest: false,
});
this.configuration = configuration;
this.updater = updater;
const { owner, slug } = configuration;
this.baseUrl = util_1.newBaseUrl(`https://api.bitbucket.org/2.0/repositories/${owner}/${slug}/downloads`);
}
get channel() {
return this.updater.channel || this.configuration.channel || "latest";
}
async getLatestVersion() {
const cancellationToken = new builder_util_runtime_1.CancellationToken();
const channelFile = util_1.getChannelFilename(this.getCustomChannelName(this.channel));
const channelUrl = util_1.newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery);
try {
const updateInfo = await this.httpRequest(channelUrl, undefined, cancellationToken);
return Provider_1.parseUpdateInfo(updateInfo, channelFile, channelUrl);
}
catch (e) {
throw builder_util_runtime_1.newError(`Unable to find latest version on ${this.toString()}, please ensure release exists: ${e.stack || e.message}`, "ERR_UPDATER_LATEST_VERSION_NOT_FOUND");
}
}
resolveFiles(updateInfo) {
return Provider_1.resolveFiles(updateInfo, this.baseUrl);
}
toString() {
const { owner, slug } = this.configuration;
return `Bitbucket (owner: ${owner}, slug: ${slug}, channel: ${this.channel})`;
}
}
exports.BitbucketProvider = BitbucketProvider;
//# sourceMappingURL=BitbucketProvider.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"BitbucketProvider.js","sourceRoot":"","sources":["../../src/providers/BitbucketProvider.ts"],"names":[],"mappings":";;;AAAA,+DAAgG;AAGhG,kCAAwE;AACxE,yCAA4F;AAE5F,MAAa,iBAAkB,SAAQ,mBAAoB;IAGzD,YAA6B,aAA+B,EAAmB,OAAmB,EAAE,cAAsC;QACxI,KAAK,CAAC;YACJ,GAAG,cAAc;YACjB,yBAAyB,EAAE,KAAK;SACjC,CAAC,CAAA;QAJyB,kBAAa,GAAb,aAAa,CAAkB;QAAmB,YAAO,GAAP,OAAO,CAAY;QAKhG,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,aAAa,CAAA;QACrC,IAAI,CAAC,OAAO,GAAG,iBAAU,CAAC,8CAA8C,KAAK,IAAI,IAAI,YAAY,CAAC,CAAA;IACpG,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,QAAQ,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,iBAAiB,GAAG,IAAI,wCAAiB,EAAE,CAAA;QACjD,MAAM,WAAW,GAAG,yBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QAC/E,MAAM,UAAU,GAAG,qBAAc,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;QAC5F,IAAI;YACF,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAA;YACnF,OAAO,0BAAe,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;SAC5D;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,+BAAQ,CAAC,oCAAoC,IAAI,CAAC,QAAQ,EAAE,mCAAmC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,sCAAsC,CAAC,CAAA;SACrK;IACH,CAAC;IAED,YAAY,CAAC,UAAsB;QACjC,OAAO,uBAAY,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAED,QAAQ;QACN,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,aAAa,CAAA;QAC1C,OAAO,qBAAqB,KAAK,WAAW,IAAI,cAAc,IAAI,CAAC,OAAO,GAAG,CAAA;IAC/E,CAAC;CACF;AApCD,8CAoCC","sourcesContent":["import { CancellationToken, BitbucketOptions, newError, UpdateInfo } from \"builder-util-runtime\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { ResolvedUpdateFileInfo } from \"../main\"\nimport { getChannelFilename, newBaseUrl, newUrlFromBase } from \"../util\"\nimport { parseUpdateInfo, Provider, ProviderRuntimeOptions, resolveFiles } from \"./Provider\"\n\nexport class BitbucketProvider extends Provider<UpdateInfo> {\n private readonly baseUrl: URL\n\n constructor(private readonly configuration: BitbucketOptions, private readonly updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions) {\n super({\n ...runtimeOptions,\n isUseMultipleRangeRequest: false,\n })\n const { owner, slug } = configuration\n this.baseUrl = newBaseUrl(`https://api.bitbucket.org/2.0/repositories/${owner}/${slug}/downloads`)\n }\n\n private get channel(): string {\n return this.updater.channel || this.configuration.channel || \"latest\"\n }\n\n async getLatestVersion(): Promise<UpdateInfo> {\n const cancellationToken = new CancellationToken()\n const channelFile = getChannelFilename(this.getCustomChannelName(this.channel))\n const channelUrl = newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery)\n try {\n const updateInfo = await this.httpRequest(channelUrl, undefined, cancellationToken)\n return parseUpdateInfo(updateInfo, channelFile, channelUrl)\n } catch (e) {\n throw newError(`Unable to find latest version on ${this.toString()}, please ensure release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo> {\n return resolveFiles(updateInfo, this.baseUrl)\n }\n\n toString() {\n const { owner, slug } = this.configuration\n return `Bitbucket (owner: ${owner}, slug: ${slug}, channel: ${this.channel})`\n }\n}\n"]}

View file

@ -0,0 +1,13 @@
import { GenericServerOptions, UpdateInfo } from "builder-util-runtime";
import { AppUpdater } from "../AppUpdater";
import { ResolvedUpdateFileInfo } from "../main";
import { Provider, ProviderRuntimeOptions } from "./Provider";
export declare class GenericProvider extends Provider<UpdateInfo> {
private readonly configuration;
private readonly updater;
private readonly baseUrl;
constructor(configuration: GenericServerOptions, updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions);
private get channel();
getLatestVersion(): Promise<UpdateInfo>;
resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo>;
}

View file

@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GenericProvider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const util_1 = require("../util");
const Provider_1 = require("./Provider");
class GenericProvider extends Provider_1.Provider {
constructor(configuration, updater, runtimeOptions) {
super(runtimeOptions);
this.configuration = configuration;
this.updater = updater;
this.baseUrl = util_1.newBaseUrl(this.configuration.url);
}
get channel() {
const result = this.updater.channel || this.configuration.channel;
return result == null ? this.getDefaultChannelName() : this.getCustomChannelName(result);
}
async getLatestVersion() {
const channelFile = util_1.getChannelFilename(this.channel);
const channelUrl = util_1.newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery);
for (let attemptNumber = 0;; attemptNumber++) {
try {
return Provider_1.parseUpdateInfo(await this.httpRequest(channelUrl), channelFile, channelUrl);
}
catch (e) {
if (e instanceof builder_util_runtime_1.HttpError && e.statusCode === 404) {
throw builder_util_runtime_1.newError(`Cannot find channel "${channelFile}" update info: ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
}
else if (e.code === "ECONNREFUSED") {
if (attemptNumber < 3) {
await new Promise((resolve, reject) => {
try {
setTimeout(resolve, 1000 * attemptNumber);
}
catch (e) {
reject(e);
}
});
continue;
}
}
throw e;
}
}
}
resolveFiles(updateInfo) {
return Provider_1.resolveFiles(updateInfo, this.baseUrl);
}
}
exports.GenericProvider = GenericProvider;
//# sourceMappingURL=GenericProvider.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"GenericProvider.js","sourceRoot":"","sources":["../../src/providers/GenericProvider.ts"],"names":[],"mappings":";;;AAAA,+DAA4F;AAG5F,kCAAwE;AACxE,yCAA4F;AAE5F,MAAa,eAAgB,SAAQ,mBAAoB;IAGvD,YAA6B,aAAmC,EAAmB,OAAmB,EAAE,cAAsC;QAC5I,KAAK,CAAC,cAAc,CAAC,CAAA;QADM,kBAAa,GAAb,aAAa,CAAsB;QAAmB,YAAO,GAAP,OAAO,CAAY;QAFrF,YAAO,GAAG,iBAAU,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;IAI7D,CAAC;IAED,IAAY,OAAO;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAA;QACjE,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAC1F,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,WAAW,GAAG,yBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACpD,MAAM,UAAU,GAAG,qBAAc,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;QAC5F,KAAK,IAAI,aAAa,GAAG,CAAC,GAAI,aAAa,EAAE,EAAE;YAC7C,IAAI;gBACF,OAAO,0BAAe,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;aACpF;YAAC,OAAO,CAAC,EAAE;gBACV,IAAI,CAAC,YAAY,gCAAS,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EAAE;oBAClD,MAAM,+BAAQ,CAAC,wBAAwB,WAAW,kBAAkB,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,oCAAoC,CAAC,CAAA;iBAClI;qBAAM,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE;oBACpC,IAAI,aAAa,GAAG,CAAC,EAAE;wBACrB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;4BACpC,IAAI;gCACF,UAAU,CAAC,OAAO,EAAE,IAAI,GAAG,aAAa,CAAC,CAAA;6BAC1C;4BAAC,OAAO,CAAC,EAAE;gCACV,MAAM,CAAC,CAAC,CAAC,CAAA;6BACV;wBACH,CAAC,CAAC,CAAA;wBACF,SAAQ;qBACT;iBACF;gBACD,MAAM,CAAC,CAAA;aACR;SACF;IACH,CAAC;IAED,YAAY,CAAC,UAAsB;QACjC,OAAO,uBAAY,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;CACF;AAzCD,0CAyCC","sourcesContent":["import { GenericServerOptions, HttpError, newError, UpdateInfo } from \"builder-util-runtime\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { ResolvedUpdateFileInfo } from \"../main\"\nimport { getChannelFilename, newBaseUrl, newUrlFromBase } from \"../util\"\nimport { parseUpdateInfo, Provider, ProviderRuntimeOptions, resolveFiles } from \"./Provider\"\n\nexport class GenericProvider extends Provider<UpdateInfo> {\n private readonly baseUrl = newBaseUrl(this.configuration.url)\n\n constructor(private readonly configuration: GenericServerOptions, private readonly updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions) {\n super(runtimeOptions)\n }\n\n private get channel(): string {\n const result = this.updater.channel || this.configuration.channel\n return result == null ? this.getDefaultChannelName() : this.getCustomChannelName(result)\n }\n\n async getLatestVersion(): Promise<UpdateInfo> {\n const channelFile = getChannelFilename(this.channel)\n const channelUrl = newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery)\n for (let attemptNumber = 0; ; attemptNumber++) {\n try {\n return parseUpdateInfo(await this.httpRequest(channelUrl), channelFile, channelUrl)\n } catch (e) {\n if (e instanceof HttpError && e.statusCode === 404) {\n throw newError(`Cannot find channel \"${channelFile}\" update info: ${e.stack || e.message}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n } else if (e.code === \"ECONNREFUSED\") {\n if (attemptNumber < 3) {\n await new Promise((resolve, reject) => {\n try {\n setTimeout(resolve, 1000 * attemptNumber)\n } catch (e) {\n reject(e)\n }\n })\n continue\n }\n }\n throw e\n }\n }\n }\n\n resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo> {\n return resolveFiles(updateInfo, this.baseUrl)\n }\n}\n"]}

View file

@ -0,0 +1,29 @@
/// <reference types="node" />
import { GithubOptions, ReleaseNoteInfo, UpdateInfo, XElement } from "builder-util-runtime";
import * as semver from "semver";
import { URL } from "url";
import { AppUpdater } from "../AppUpdater";
import { ResolvedUpdateFileInfo } from "../main";
import { Provider, ProviderRuntimeOptions } from "./Provider";
interface GithubUpdateInfo extends UpdateInfo {
tag: string;
}
export declare abstract class BaseGitHubProvider<T extends UpdateInfo> extends Provider<T> {
protected readonly options: GithubOptions;
protected readonly baseUrl: URL;
protected readonly baseApiUrl: URL;
protected constructor(options: GithubOptions, defaultHost: string, runtimeOptions: ProviderRuntimeOptions);
protected computeGithubBasePath(result: string): string;
}
export declare class GitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {
protected readonly options: GithubOptions;
private readonly updater;
constructor(options: GithubOptions, updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions);
getLatestVersion(): Promise<GithubUpdateInfo>;
private getLatestTagName;
private get basePath();
resolveFiles(updateInfo: GithubUpdateInfo): Array<ResolvedUpdateFileInfo>;
private getBaseDownloadPath;
}
export declare function computeReleaseNotes(currentVersion: semver.SemVer, isFullChangelog: boolean, feed: XElement, latestRelease: any): string | Array<ReleaseNoteInfo> | null;
export {};

View file

@ -0,0 +1,191 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.computeReleaseNotes = exports.GitHubProvider = exports.BaseGitHubProvider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const semver = require("semver");
const url_1 = require("url");
const util_1 = require("../util");
const Provider_1 = require("./Provider");
const hrefRegExp = /\/tag\/([^/]+)$/;
class BaseGitHubProvider extends Provider_1.Provider {
constructor(options, defaultHost, runtimeOptions) {
super({
...runtimeOptions,
/* because GitHib uses S3 */
isUseMultipleRangeRequest: false,
});
this.options = options;
this.baseUrl = util_1.newBaseUrl(builder_util_runtime_1.githubUrl(options, defaultHost));
const apiHost = defaultHost === "github.com" ? "api.github.com" : defaultHost;
this.baseApiUrl = util_1.newBaseUrl(builder_util_runtime_1.githubUrl(options, apiHost));
}
computeGithubBasePath(result) {
// https://github.com/electron-userland/electron-builder/issues/1903#issuecomment-320881211
const host = this.options.host;
return host && !["github.com", "api.github.com"].includes(host) ? `/api/v3${result}` : result;
}
}
exports.BaseGitHubProvider = BaseGitHubProvider;
class GitHubProvider extends BaseGitHubProvider {
constructor(options, updater, runtimeOptions) {
super(options, "github.com", runtimeOptions);
this.options = options;
this.updater = updater;
}
async getLatestVersion() {
var _a, _b, _c, _d;
const cancellationToken = new builder_util_runtime_1.CancellationToken();
const feedXml = (await this.httpRequest(util_1.newUrlFromBase(`${this.basePath}.atom`, this.baseUrl), {
accept: "application/xml, application/atom+xml, text/xml, */*",
}, cancellationToken));
const feed = builder_util_runtime_1.parseXml(feedXml);
// noinspection TypeScriptValidateJSTypes
let latestRelease = feed.element("entry", false, `No published versions on GitHub`);
let tag = null;
try {
if (this.updater.allowPrerelease) {
const currentChannel = ((_a = this.updater) === null || _a === void 0 ? void 0 : _a.channel) || ((_b = semver.prerelease(this.updater.currentVersion)) === null || _b === void 0 ? void 0 : _b[0]) || null;
if (currentChannel === null) {
// noinspection TypeScriptValidateJSTypes
tag = hrefRegExp.exec(latestRelease.element("link").attribute("href"))[1];
}
else {
for (const element of feed.getElements("entry")) {
// noinspection TypeScriptValidateJSTypes
const hrefElement = hrefRegExp.exec(element.element("link").attribute("href"));
// If this is null then something is wrong and skip this release
if (hrefElement === null)
continue;
// This Release's Tag
const hrefTag = hrefElement[1];
//Get Channel from this release's tag
const hrefChannel = ((_c = semver.prerelease(hrefTag)) === null || _c === void 0 ? void 0 : _c[0]) || null;
const shouldFetchVersion = !currentChannel || ["alpha", "beta"].includes(currentChannel);
const isCustomChannel = !["alpha", "beta"].includes(String(hrefChannel));
// Allow moving from alpha to beta but not down
const channelMismatch = currentChannel === "beta" && hrefChannel === "alpha";
if (shouldFetchVersion && !isCustomChannel && !channelMismatch) {
tag = hrefTag;
break;
}
const isNextPreRelease = hrefChannel && hrefChannel === currentChannel;
if (isNextPreRelease) {
tag = hrefTag;
break;
}
}
}
}
else {
tag = await this.getLatestTagName(cancellationToken);
for (const element of feed.getElements("entry")) {
// noinspection TypeScriptValidateJSTypes
if (hrefRegExp.exec(element.element("link").attribute("href"))[1] === tag) {
latestRelease = element;
break;
}
}
}
}
catch (e) {
throw builder_util_runtime_1.newError(`Cannot parse releases feed: ${e.stack || e.message},\nXML:\n${feedXml}`, "ERR_UPDATER_INVALID_RELEASE_FEED");
}
if (tag == null) {
throw builder_util_runtime_1.newError(`No published versions on GitHub`, "ERR_UPDATER_NO_PUBLISHED_VERSIONS");
}
let rawData;
let channelFile = "";
let channelFileUrl = "";
const fetchData = async (channelName) => {
channelFile = util_1.getChannelFilename(channelName);
channelFileUrl = util_1.newUrlFromBase(this.getBaseDownloadPath(String(tag), channelFile), this.baseUrl);
const requestOptions = this.createRequestOptions(channelFileUrl);
try {
return (await this.executor.request(requestOptions, cancellationToken));
}
catch (e) {
if (e instanceof builder_util_runtime_1.HttpError && e.statusCode === 404) {
throw builder_util_runtime_1.newError(`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
}
throw e;
}
};
try {
const channel = this.updater.allowPrerelease ? this.getCustomChannelName(String(((_d = semver.prerelease(tag)) === null || _d === void 0 ? void 0 : _d[0]) || "latest")) : this.getDefaultChannelName();
rawData = await fetchData(channel);
}
catch (e) {
if (this.updater.allowPrerelease) {
// Allow fallback to `latest.yml`
rawData = await fetchData(this.getDefaultChannelName());
}
else {
throw e;
}
}
const result = Provider_1.parseUpdateInfo(rawData, channelFile, channelFileUrl);
if (result.releaseName == null) {
result.releaseName = latestRelease.elementValueOrEmpty("title");
}
if (result.releaseNotes == null) {
result.releaseNotes = computeReleaseNotes(this.updater.currentVersion, this.updater.fullChangelog, feed, latestRelease);
}
return {
tag: tag,
...result,
};
}
async getLatestTagName(cancellationToken) {
const options = this.options;
// do not use API for GitHub to avoid limit, only for custom host or GitHub Enterprise
const url = options.host == null || options.host === "github.com"
? util_1.newUrlFromBase(`${this.basePath}/latest`, this.baseUrl)
: new url_1.URL(`${this.computeGithubBasePath(`/repos/${options.owner}/${options.repo}/releases`)}/latest`, this.baseApiUrl);
try {
const rawData = await this.httpRequest(url, { Accept: "application/json" }, cancellationToken);
if (rawData == null) {
return null;
}
const releaseInfo = JSON.parse(rawData);
return releaseInfo.tag_name;
}
catch (e) {
throw builder_util_runtime_1.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");
}
}
get basePath() {
return `/${this.options.owner}/${this.options.repo}/releases`;
}
resolveFiles(updateInfo) {
// still replace space to - due to backward compatibility
return Provider_1.resolveFiles(updateInfo, this.baseUrl, p => this.getBaseDownloadPath(updateInfo.tag, p.replace(/ /g, "-")));
}
getBaseDownloadPath(tag, fileName) {
return `${this.basePath}/download/${tag}/${fileName}`;
}
}
exports.GitHubProvider = GitHubProvider;
function getNoteValue(parent) {
const result = parent.elementValueOrEmpty("content");
// GitHub reports empty notes as <content>No content.</content>
return result === "No content." ? "" : result;
}
function computeReleaseNotes(currentVersion, isFullChangelog, feed, latestRelease) {
if (!isFullChangelog) {
return getNoteValue(latestRelease);
}
const releaseNotes = [];
for (const release of feed.getElements("entry")) {
// noinspection TypeScriptValidateJSTypes
const versionRelease = /\/tag\/v?([^/]+)$/.exec(release.element("link").attribute("href"))[1];
if (semver.lt(currentVersion, versionRelease)) {
releaseNotes.push({
version: versionRelease,
note: getNoteValue(release),
});
}
}
return releaseNotes.sort((a, b) => semver.rcompare(a.version, b.version));
}
exports.computeReleaseNotes = computeReleaseNotes;
//# sourceMappingURL=GitHubProvider.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,14 @@
import { KeygenOptions, UpdateInfo } from "builder-util-runtime";
import { AppUpdater } from "../AppUpdater";
import { ResolvedUpdateFileInfo } from "../main";
import { Provider, ProviderRuntimeOptions } from "./Provider";
export declare class KeygenProvider extends Provider<UpdateInfo> {
private readonly configuration;
private readonly updater;
private readonly baseUrl;
constructor(configuration: KeygenOptions, updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions);
private get channel();
getLatestVersion(): Promise<UpdateInfo>;
resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo>;
toString(): string;
}

View file

@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.KeygenProvider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const util_1 = require("../util");
const Provider_1 = require("./Provider");
class KeygenProvider extends Provider_1.Provider {
constructor(configuration, updater, runtimeOptions) {
super({
...runtimeOptions,
isUseMultipleRangeRequest: false,
});
this.configuration = configuration;
this.updater = updater;
this.baseUrl = util_1.newBaseUrl(`https://api.keygen.sh/v1/accounts/${this.configuration.account}/artifacts?product=${this.configuration.product}`);
}
get channel() {
return this.updater.channel || this.configuration.channel || "stable";
}
async getLatestVersion() {
const cancellationToken = new builder_util_runtime_1.CancellationToken();
const channelFile = util_1.getChannelFilename(this.getCustomChannelName(this.channel));
const channelUrl = util_1.newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery);
try {
const updateInfo = await this.httpRequest(channelUrl, {
Accept: "application/vnd.api+json",
"Keygen-Version": "1.1",
}, cancellationToken);
return Provider_1.parseUpdateInfo(updateInfo, channelFile, channelUrl);
}
catch (e) {
throw builder_util_runtime_1.newError(`Unable to find latest version on ${this.toString()}, please ensure release exists: ${e.stack || e.message}`, "ERR_UPDATER_LATEST_VERSION_NOT_FOUND");
}
}
resolveFiles(updateInfo) {
return Provider_1.resolveFiles(updateInfo, this.baseUrl);
}
toString() {
const { account, product, platform } = this.configuration;
return `Keygen (account: ${account}, product: ${product}, platform: ${platform}, channel: ${this.channel})`;
}
}
exports.KeygenProvider = KeygenProvider;
//# sourceMappingURL=KeygenProvider.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"KeygenProvider.js","sourceRoot":"","sources":["../../src/providers/KeygenProvider.ts"],"names":[],"mappings":";;;AAAA,+DAA6F;AAG7F,kCAAwE;AACxE,yCAA4F;AAE5F,MAAa,cAAe,SAAQ,mBAAoB;IAGtD,YAA6B,aAA4B,EAAmB,OAAmB,EAAE,cAAsC;QACrI,KAAK,CAAC;YACJ,GAAG,cAAc;YACjB,yBAAyB,EAAE,KAAK;SACjC,CAAC,CAAA;QAJyB,kBAAa,GAAb,aAAa,CAAe;QAAmB,YAAO,GAAP,OAAO,CAAY;QAK7F,IAAI,CAAC,OAAO,GAAG,iBAAU,CAAC,qCAAqC,IAAI,CAAC,aAAa,CAAC,OAAO,sBAAsB,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAA;IAC9I,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,IAAI,QAAQ,CAAA;IACvE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,iBAAiB,GAAG,IAAI,wCAAiB,EAAE,CAAA;QACjD,MAAM,WAAW,GAAG,yBAAkB,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;QAC/E,MAAM,UAAU,GAAG,qBAAc,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;QAC5F,IAAI;YACF,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,WAAW,CACvC,UAAU,EACV;gBACE,MAAM,EAAE,0BAA0B;gBAClC,gBAAgB,EAAE,KAAK;aACxB,EACD,iBAAiB,CAClB,CAAA;YACD,OAAO,0BAAe,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;SAC5D;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,+BAAQ,CAAC,oCAAoC,IAAI,CAAC,QAAQ,EAAE,mCAAmC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,sCAAsC,CAAC,CAAA;SACrK;IACH,CAAC;IAED,YAAY,CAAC,UAAsB;QACjC,OAAO,uBAAY,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAED,QAAQ;QACN,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,CAAA;QACzD,OAAO,oBAAoB,OAAO,cAAc,OAAO,eAAe,QAAQ,cAAc,IAAI,CAAC,OAAO,GAAG,CAAA;IAC7G,CAAC;CACF;AA1CD,wCA0CC","sourcesContent":["import { CancellationToken, KeygenOptions, newError, UpdateInfo } from \"builder-util-runtime\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { ResolvedUpdateFileInfo } from \"../main\"\nimport { getChannelFilename, newBaseUrl, newUrlFromBase } from \"../util\"\nimport { parseUpdateInfo, Provider, ProviderRuntimeOptions, resolveFiles } from \"./Provider\"\n\nexport class KeygenProvider extends Provider<UpdateInfo> {\n private readonly baseUrl: URL\n\n constructor(private readonly configuration: KeygenOptions, private readonly updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions) {\n super({\n ...runtimeOptions,\n isUseMultipleRangeRequest: false,\n })\n this.baseUrl = newBaseUrl(`https://api.keygen.sh/v1/accounts/${this.configuration.account}/artifacts?product=${this.configuration.product}`)\n }\n\n private get channel(): string {\n return this.updater.channel || this.configuration.channel || \"stable\"\n }\n\n async getLatestVersion(): Promise<UpdateInfo> {\n const cancellationToken = new CancellationToken()\n const channelFile = getChannelFilename(this.getCustomChannelName(this.channel))\n const channelUrl = newUrlFromBase(channelFile, this.baseUrl, this.updater.isAddNoCacheQuery)\n try {\n const updateInfo = await this.httpRequest(\n channelUrl,\n {\n Accept: \"application/vnd.api+json\",\n \"Keygen-Version\": \"1.1\",\n },\n cancellationToken\n )\n return parseUpdateInfo(updateInfo, channelFile, channelUrl)\n } catch (e) {\n throw newError(`Unable to find latest version on ${this.toString()}, please ensure release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo> {\n return resolveFiles(updateInfo, this.baseUrl)\n }\n\n toString() {\n const { account, product, platform } = this.configuration\n return `Keygen (account: ${account}, product: ${product}, platform: ${platform}, channel: ${this.channel})`\n }\n}\n"]}

View file

@ -0,0 +1,27 @@
/// <reference types="node" />
import { GithubOptions, UpdateInfo } from "builder-util-runtime";
import { OutgoingHttpHeaders, RequestOptions } from "http";
import { AppUpdater } from "../AppUpdater";
import { URL } from "url";
import { BaseGitHubProvider } from "./GitHubProvider";
import { ResolvedUpdateFileInfo } from "../main";
import { ProviderRuntimeOptions } from "./Provider";
export interface PrivateGitHubUpdateInfo extends UpdateInfo {
assets: Array<Asset>;
}
export declare class PrivateGitHubProvider extends BaseGitHubProvider<PrivateGitHubUpdateInfo> {
private readonly updater;
private readonly token;
constructor(options: GithubOptions, updater: AppUpdater, token: string, runtimeOptions: ProviderRuntimeOptions);
protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions;
getLatestVersion(): Promise<PrivateGitHubUpdateInfo>;
get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null;
private configureHeaders;
private getLatestVersionInfo;
private get basePath();
resolveFiles(updateInfo: PrivateGitHubUpdateInfo): Array<ResolvedUpdateFileInfo>;
}
export interface Asset {
name: string;
url: string;
}

View file

@ -0,0 +1,94 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrivateGitHubProvider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const js_yaml_1 = require("js-yaml");
const path = require("path");
const url_1 = require("url");
const util_1 = require("../util");
const GitHubProvider_1 = require("./GitHubProvider");
const Provider_1 = require("./Provider");
class PrivateGitHubProvider extends GitHubProvider_1.BaseGitHubProvider {
constructor(options, updater, token, runtimeOptions) {
super(options, "api.github.com", runtimeOptions);
this.updater = updater;
this.token = token;
}
createRequestOptions(url, headers) {
const result = super.createRequestOptions(url, headers);
result.redirect = "manual";
return result;
}
async getLatestVersion() {
const cancellationToken = new builder_util_runtime_1.CancellationToken();
const channelFile = util_1.getChannelFilename(this.getDefaultChannelName());
const releaseInfo = await this.getLatestVersionInfo(cancellationToken);
const asset = releaseInfo.assets.find(it => it.name === channelFile);
if (asset == null) {
// html_url must be always, but just to be sure
throw builder_util_runtime_1.newError(`Cannot find ${channelFile} in the release ${releaseInfo.html_url || releaseInfo.name}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
}
const url = new url_1.URL(asset.url);
let result;
try {
result = js_yaml_1.load((await this.httpRequest(url, this.configureHeaders("application/octet-stream"), cancellationToken)));
}
catch (e) {
if (e instanceof builder_util_runtime_1.HttpError && e.statusCode === 404) {
throw builder_util_runtime_1.newError(`Cannot find ${channelFile} in the latest release artifacts (${url}): ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
}
throw e;
}
;
result.assets = releaseInfo.assets;
return result;
}
get fileExtraDownloadHeaders() {
return this.configureHeaders("application/octet-stream");
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
configureHeaders(accept) {
return {
accept,
authorization: `token ${this.token}`,
};
}
async getLatestVersionInfo(cancellationToken) {
const allowPrerelease = this.updater.allowPrerelease;
let basePath = this.basePath;
if (!allowPrerelease) {
basePath = `${basePath}/latest`;
}
const url = util_1.newUrlFromBase(basePath, this.baseUrl);
try {
const version = JSON.parse((await this.httpRequest(url, this.configureHeaders("application/vnd.github.v3+json"), cancellationToken)));
if (allowPrerelease) {
return version.find(it => it.prerelease) || version[0];
}
else {
return version;
}
}
catch (e) {
throw builder_util_runtime_1.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");
}
}
get basePath() {
return this.computeGithubBasePath(`/repos/${this.options.owner}/${this.options.repo}/releases`);
}
resolveFiles(updateInfo) {
return Provider_1.getFileList(updateInfo).map(it => {
const name = path.posix.basename(it.url).replace(/ /g, "-");
const asset = updateInfo.assets.find(it => it != null && it.name === name);
if (asset == null) {
throw builder_util_runtime_1.newError(`Cannot find asset "${name}" in: ${JSON.stringify(updateInfo.assets, null, 2)}`, "ERR_UPDATER_ASSET_NOT_FOUND");
}
return {
url: new url_1.URL(asset.url),
info: it,
};
});
}
}
exports.PrivateGitHubProvider = PrivateGitHubProvider;
//# sourceMappingURL=PrivateGitHubProvider.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,35 @@
/// <reference types="node" />
import { CancellationToken, UpdateFileInfo, UpdateInfo } from "builder-util-runtime";
import { OutgoingHttpHeaders, RequestOptions } from "http";
import { URL } from "url";
import { ElectronHttpExecutor } from "../electronHttpExecutor";
import { ResolvedUpdateFileInfo } from "../main";
export declare type ProviderPlatform = "darwin" | "linux" | "win32";
export interface ProviderRuntimeOptions {
isUseMultipleRangeRequest: boolean;
platform: ProviderPlatform;
executor: ElectronHttpExecutor;
}
export declare abstract class Provider<T extends UpdateInfo> {
private readonly runtimeOptions;
private requestHeaders;
protected readonly executor: ElectronHttpExecutor;
protected constructor(runtimeOptions: ProviderRuntimeOptions);
get isUseMultipleRangeRequest(): boolean;
private getChannelFilePrefix;
protected getDefaultChannelName(): string;
protected getCustomChannelName(channel: string): string;
get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null;
setRequestHeaders(value: OutgoingHttpHeaders | null): void;
abstract getLatestVersion(): Promise<T>;
abstract resolveFiles(updateInfo: T): Array<ResolvedUpdateFileInfo>;
/**
* Method to perform API request only to resolve update info, but not to download update.
*/
protected httpRequest(url: URL, headers?: OutgoingHttpHeaders | null, cancellationToken?: CancellationToken): Promise<string | null>;
protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions;
}
export declare function findFile(files: Array<ResolvedUpdateFileInfo>, extension: string, not?: Array<string>): ResolvedUpdateFileInfo | null | undefined;
export declare function parseUpdateInfo(rawData: string | null, channelFile: string, channelFileUrl: URL): UpdateInfo;
export declare function getFileList(updateInfo: UpdateInfo): Array<UpdateFileInfo>;
export declare function resolveFiles(updateInfo: UpdateInfo, baseUrl: URL, pathTransformer?: (p: string) => string): Array<ResolvedUpdateFileInfo>;

View file

@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveFiles = exports.getFileList = exports.parseUpdateInfo = exports.findFile = exports.Provider = void 0;
const builder_util_runtime_1 = require("builder-util-runtime");
const js_yaml_1 = require("js-yaml");
const util_1 = require("../util");
class Provider {
constructor(runtimeOptions) {
this.runtimeOptions = runtimeOptions;
this.requestHeaders = null;
this.executor = runtimeOptions.executor;
}
get isUseMultipleRangeRequest() {
return this.runtimeOptions.isUseMultipleRangeRequest !== false;
}
getChannelFilePrefix() {
if (this.runtimeOptions.platform === "linux") {
const arch = process.env["TEST_UPDATER_ARCH"] || process.arch;
const archSuffix = arch === "x64" ? "" : `-${arch}`;
return "-linux" + archSuffix;
}
else {
return this.runtimeOptions.platform === "darwin" ? "-mac" : "";
}
}
// due to historical reasons for windows we use channel name without platform specifier
getDefaultChannelName() {
return this.getCustomChannelName("latest");
}
getCustomChannelName(channel) {
return `${channel}${this.getChannelFilePrefix()}`;
}
get fileExtraDownloadHeaders() {
return null;
}
setRequestHeaders(value) {
this.requestHeaders = value;
}
/**
* Method to perform API request only to resolve update info, but not to download update.
*/
httpRequest(url, headers, cancellationToken) {
return this.executor.request(this.createRequestOptions(url, headers), cancellationToken);
}
createRequestOptions(url, headers) {
const result = {};
if (this.requestHeaders == null) {
if (headers != null) {
result.headers = headers;
}
}
else {
result.headers = headers == null ? this.requestHeaders : { ...this.requestHeaders, ...headers };
}
builder_util_runtime_1.configureRequestUrl(url, result);
return result;
}
}
exports.Provider = Provider;
function findFile(files, extension, not) {
if (files.length === 0) {
throw builder_util_runtime_1.newError("No files provided", "ERR_UPDATER_NO_FILES_PROVIDED");
}
const result = files.find(it => it.url.pathname.toLowerCase().endsWith(`.${extension}`));
if (result != null) {
return result;
}
else if (not == null) {
return files[0];
}
else {
return files.find(fileInfo => !not.some(ext => fileInfo.url.pathname.toLowerCase().endsWith(`.${ext}`)));
}
}
exports.findFile = findFile;
function parseUpdateInfo(rawData, channelFile, channelFileUrl) {
if (rawData == null) {
throw builder_util_runtime_1.newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): rawData: null`, "ERR_UPDATER_INVALID_UPDATE_INFO");
}
let result;
try {
result = js_yaml_1.load(rawData);
}
catch (e) {
throw builder_util_runtime_1.newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}, rawData: ${rawData}`, "ERR_UPDATER_INVALID_UPDATE_INFO");
}
return result;
}
exports.parseUpdateInfo = parseUpdateInfo;
function getFileList(updateInfo) {
const files = updateInfo.files;
if (files != null && files.length > 0) {
return files;
}
// noinspection JSDeprecatedSymbols
if (updateInfo.path != null) {
// noinspection JSDeprecatedSymbols
return [
{
url: updateInfo.path,
sha2: updateInfo.sha2,
sha512: updateInfo.sha512,
},
];
}
else {
throw builder_util_runtime_1.newError(`No files provided: ${builder_util_runtime_1.safeStringifyJson(updateInfo)}`, "ERR_UPDATER_NO_FILES_PROVIDED");
}
}
exports.getFileList = getFileList;
function resolveFiles(updateInfo, baseUrl, pathTransformer = (p) => p) {
const files = getFileList(updateInfo);
const result = files.map(fileInfo => {
if (fileInfo.sha2 == null && fileInfo.sha512 == null) {
throw builder_util_runtime_1.newError(`Update info doesn't contain nor sha256 neither sha512 checksum: ${builder_util_runtime_1.safeStringifyJson(fileInfo)}`, "ERR_UPDATER_NO_CHECKSUM");
}
return {
url: util_1.newUrlFromBase(pathTransformer(fileInfo.url), baseUrl),
info: fileInfo,
};
});
const packages = updateInfo.packages;
const packageInfo = packages == null ? null : packages[process.arch] || packages.ia32;
if (packageInfo != null) {
;
result[0].packageInfo = {
...packageInfo,
path: util_1.newUrlFromBase(pathTransformer(packageInfo.path), baseUrl).href,
};
}
return result;
}
exports.resolveFiles = resolveFiles;
//# sourceMappingURL=Provider.js.map

File diff suppressed because one or more lines are too long