diff --git a/package.json b/package.json index 0826d5484b4..1aa3ccbf38d 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "7zip-bin": "^2.3.4", "archiver": "^2.1.0", "async-exit-hook": "^2.0.1", - "aws-sdk": "^2.166.0", + "aws-sdk": "^2.167.0", "bluebird-lst": "^1.0.5", "chalk": "^2.3.0", "chromium-pickle-js": "^0.2.0", diff --git a/packages/electron-publisher-s3/package.json b/packages/electron-publisher-s3/package.json index 07b81145fdc..49b2c7eadd9 100644 --- a/packages/electron-publisher-s3/package.json +++ b/packages/electron-publisher-s3/package.json @@ -12,7 +12,7 @@ ], "dependencies": { "fs-extra-p": "^4.4.5", - "aws-sdk": "^2.166.0", + "aws-sdk": "^2.167.0", "mime": "^2.0.3", "electron-publish": "~0.0.0-semantic-release", "builder-util": "^0.0.0-semantic-release", diff --git a/packages/electron-updater/src/AppUpdater.ts b/packages/electron-updater/src/AppUpdater.ts index 8a6528a4043..71a718e5c43 100644 --- a/packages/electron-updater/src/AppUpdater.ts +++ b/packages/electron-updater/src/AppUpdater.ts @@ -1,5 +1,5 @@ import BluebirdPromise from "bluebird-lst" -import { AllPublishOptions, asArray, BaseS3Options, BintrayOptions, CancellationToken, GenericServerOptions, getS3LikeProviderBaseUrl, GithubOptions, PublishConfiguration, UpdateInfo, UUID } from "builder-util-runtime" +import { AllPublishOptions, asArray, CancellationToken, PublishConfiguration, UpdateInfo, UUID } from "builder-util-runtime" import { randomBytes } from "crypto" import { Notification } from "electron" import isDev from "electron-is-dev" @@ -11,12 +11,10 @@ import { Lazy } from "lazy-val" import * as path from "path" import { eq as isVersionsEqual, gt as isVersionGreaterThan, prerelease as getVersionPreleaseComponents, valid as parseVersion } from "semver" import "source-map-support/register" -import { BintrayProvider } from "./BintrayProvider" import { ElectronHttpExecutor } from "./electronHttpExecutor" import { GenericProvider } from "./GenericProvider" -import { GitHubProvider } from "./GitHubProvider" import { Logger, Provider, UpdateCheckResult, UpdaterSignal } from "./main" -import { PrivateGitHubProvider } from "./PrivateGitHubProvider" +import { createClient } from "./providerFactory" export abstract class AppUpdater extends EventEmitter { /** @@ -48,6 +46,34 @@ export abstract class AppUpdater extends EventEmitter { */ readonly currentVersion: string + private _channel: string | null = null + + /** + * Get the update channel. Not applicable for GitHub. Doesn't return `channel` from the update configuration, only if was previously set. + */ + get channel(): string | null { + return this._channel + } + + /** + * Set the update channel. Not applicable for GitHub. Overrides `channel` in the update configuration. + * + * `allowDowngrade` will be automatically set to `true`. If this behavior is not suitable for you, simple set `allowDowngrade` explicitly after. + */ + set channel(value: string | null) { + if (this._channel != null) { + if (typeof value !== "string") { + throw new Error(`Channel must be a string, but got: ${value}`) + } + else if (value.length === 0) { + throw new Error(`Channel must be not an empty string`) + } + } + + this._channel = value + this.allowDowngrade = true + } + /** * The request headers. */ @@ -104,7 +130,8 @@ export abstract class AppUpdater extends EventEmitter { protected updateInfo: UpdateInfo | null - protected readonly httpExecutor: ElectronHttpExecutor + /** @internal */ + readonly httpExecutor: ElectronHttpExecutor constructor(options: AllPublishOptions | null | undefined, app?: any) { super() @@ -155,14 +182,14 @@ export abstract class AppUpdater extends EventEmitter { */ setFeedURL(options: PublishConfiguration | AllPublishOptions) { // https://github.com/electron-userland/electron-builder/issues/1105 - let client: Provider + let provider: Provider if (typeof options === "string") { - client = new GenericProvider({provider: "generic", url: options}, this.httpExecutor) + provider = new GenericProvider({provider: "generic", url: options}, this.httpExecutor) } else { - client = this.createClient(options) + provider = createClient(options, this) } - this.clientPromise = BluebirdPromise.resolve(client) + this.clientPromise = Promise.resolve(provider) } /** @@ -242,7 +269,7 @@ export abstract class AppUpdater extends EventEmitter { private async doCheckForUpdates(): Promise { if (this.clientPromise == null) { - this.clientPromise = this.configOnDisk.value.then(it => this.createClient(it)) + this.clientPromise = this.configOnDisk.value.then(it => createClient(it, this)) } const client = await this.clientPromise @@ -347,42 +374,6 @@ export abstract class AppUpdater extends EventEmitter { return this.computeFinalHeaders({Accept: "*/*"}) } - private createClient(data: string | PublishConfiguration) { - if (typeof data === "string") { - throw new Error("Please pass PublishConfiguration object") - } - - const provider = (data as PublishConfiguration).provider - switch (provider) { - case "github": - const githubOptions = data as GithubOptions - const token = (githubOptions.private ? process.env.GH_TOKEN : null) || githubOptions.token - if (token == null) { - return new GitHubProvider(githubOptions, this, this.httpExecutor) - } - else { - return new PrivateGitHubProvider(githubOptions, token, this.httpExecutor) - } - - case "s3": - case "spaces": - return new GenericProvider({ - provider: "generic", - url: getS3LikeProviderBaseUrl(data), - channel: (data as BaseS3Options).channel || "" - }, this.httpExecutor) - - case "generic": - return new GenericProvider(data as GenericServerOptions, this.httpExecutor) - - case "bintray": - return new BintrayProvider(data as BintrayOptions, this.httpExecutor) - - default: - throw new Error(`Unsupported provider: ${provider}`) - } - } - private async getOrCreateStagingUserId(): Promise { const file = path.join(this.app.getPath("userData"), ".updaterId") try { diff --git a/packages/electron-updater/src/GenericProvider.ts b/packages/electron-updater/src/GenericProvider.ts index fdc4519f169..bab67bdb412 100644 --- a/packages/electron-updater/src/GenericProvider.ts +++ b/packages/electron-updater/src/GenericProvider.ts @@ -1,13 +1,18 @@ -import { GenericServerOptions, HttpError, HttpExecutor, UpdateInfo } from "builder-util-runtime" +import { GenericServerOptions, HttpError, UpdateInfo } from "builder-util-runtime" +import { AppUpdater } from "./AppUpdater" import { getChannelFilename, getCustomChannelName, getDefaultChannelName, isUseOldMacProvider, newBaseUrl, newUrlFromBase, Provider, ResolvedUpdateFileInfo } from "./main" import { parseUpdateInfo, resolveFiles } from "./Provider" export class GenericProvider extends Provider { private readonly baseUrl = newBaseUrl(this.configuration.url) - private readonly channel = this.configuration.channel ? getCustomChannelName(this.configuration.channel) : getDefaultChannelName() - constructor(private readonly configuration: GenericServerOptions, executor: HttpExecutor) { - super(executor) + constructor(private readonly configuration: GenericServerOptions, private readonly updater: AppUpdater) { + super(updater.httpExecutor) + } + + private get channel(): string { + const result = this.updater.channel || this.configuration.channel + return result == null ? getDefaultChannelName() : getCustomChannelName(result) } async getLatestVersion(): Promise { diff --git a/packages/electron-updater/src/providerFactory.ts b/packages/electron-updater/src/providerFactory.ts new file mode 100644 index 00000000000..a14b0050522 --- /dev/null +++ b/packages/electron-updater/src/providerFactory.ts @@ -0,0 +1,43 @@ +import { AllPublishOptions, BaseS3Options, BintrayOptions, GenericServerOptions, getS3LikeProviderBaseUrl, GithubOptions, PublishConfiguration } from "builder-util-runtime" +import { AppUpdater } from "./AppUpdater" +import { BintrayProvider } from "./BintrayProvider" +import { GenericProvider } from "./GenericProvider" +import { GitHubProvider } from "./GitHubProvider" +import { PrivateGitHubProvider } from "./PrivateGitHubProvider" + +export function createClient(data: PublishConfiguration | AllPublishOptions, updater: AppUpdater) { + if (typeof data === "string") { + throw new Error("Please pass PublishConfiguration object") + } + + const httpExecutor = updater.httpExecutor + const provider = data.provider + switch (provider) { + case "github": + const githubOptions = data as GithubOptions + const token = (githubOptions.private ? process.env.GH_TOKEN : null) || githubOptions.token + if (token == null) { + return new GitHubProvider(githubOptions, updater, httpExecutor) + } + else { + return new PrivateGitHubProvider(githubOptions, token, httpExecutor) + } + + case "s3": + case "spaces": + return new GenericProvider({ + provider: "generic", + url: getS3LikeProviderBaseUrl(data), + channel: (data as BaseS3Options).channel || "" + }, updater) + + case "generic": + return new GenericProvider(data as GenericServerOptions, updater) + + case "bintray": + return new BintrayProvider(data as BintrayOptions, httpExecutor) + + default: + throw new Error(`Unsupported provider: ${provider}`) + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 09e812c7607..45c9e5f013c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -430,9 +430,9 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sdk@^2.166.0: - version "2.166.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.166.0.tgz#132e969b9fac950a0a897b43f46412cc3d14d4d8" +aws-sdk@^2.167.0: + version "2.167.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.167.0.tgz#f207dff7f7e9a7883d3b69bd22513444968a36bd" dependencies: buffer "4.9.1" crypto-browserify "1.0.9"