| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.NoOpLogger = exports.AppUpdater = void 0;
- function _bluebirdLst() {
- const data = require("bluebird-lst");
- _bluebirdLst = function () {
- return data;
- };
- return data;
- }
- function _builderUtilRuntime() {
- const data = require("builder-util-runtime");
- _builderUtilRuntime = function () {
- return data;
- };
- return data;
- }
- function _crypto() {
- const data = require("crypto");
- _crypto = function () {
- return data;
- };
- return data;
- }
- function _electron() {
- const data = require("electron");
- _electron = function () {
- return data;
- };
- return data;
- }
- function _electronIsDev() {
- const data = _interopRequireDefault(require("electron-is-dev"));
- _electronIsDev = function () {
- return data;
- };
- return data;
- }
- function _events() {
- const data = require("events");
- _events = function () {
- return data;
- };
- return data;
- }
- function _fsExtraP() {
- const data = require("fs-extra-p");
- _fsExtraP = function () {
- return data;
- };
- return data;
- }
- function _jsYaml() {
- const data = require("js-yaml");
- _jsYaml = function () {
- return data;
- };
- return data;
- }
- function _lazyVal() {
- const data = require("lazy-val");
- _lazyVal = function () {
- return data;
- };
- return data;
- }
- var path = _interopRequireWildcard(require("path"));
- function _semver() {
- const data = require("semver");
- _semver = function () {
- return data;
- };
- return data;
- }
- require("source-map-support/register");
- function _DownloadedUpdateHelper() {
- const data = require("./DownloadedUpdateHelper");
- _DownloadedUpdateHelper = function () {
- return data;
- };
- return data;
- }
- function _electronHttpExecutor() {
- const data = require("./electronHttpExecutor");
- _electronHttpExecutor = function () {
- return data;
- };
- return data;
- }
- function _GenericProvider() {
- const data = require("./providers/GenericProvider");
- _GenericProvider = function () {
- return data;
- };
- return data;
- }
- function _main() {
- const data = require("./main");
- _main = function () {
- return data;
- };
- return data;
- }
- function _providerFactory() {
- const data = require("./providerFactory");
- _providerFactory = function () {
- return data;
- };
- return data;
- }
- 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; } }
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- class AppUpdater extends _events().EventEmitter {
- constructor(options, app) {
- super();
- /**
- * Whether to automatically download an update when it is found.
- */
- this.autoDownload = true;
- /**
- * Whether to automatically install a downloaded update on app quit (if `quitAndInstall` was not called before).
- *
- * Applicable only on Windows and Linux.
- */
- this.autoInstallOnAppQuit = true;
- /**
- * *GitHub provider only.* Whether to allow update to pre-release versions. Defaults to `true` if application version contains prerelease components (e.g. `0.12.1-alpha.1`, here `alpha` is a prerelease component), otherwise `false`.
- *
- * If `true`, downgrade will be allowed (`allowDowngrade` will be set to `true`).
- */
- this.allowPrerelease = false;
- /**
- * *GitHub provider only.* Get all release notes (from current version to latest), not just the latest.
- * @default false
- */
- this.fullChangelog = false;
- /**
- * Whether to allow version downgrade (when a user from the beta channel wants to go back to the stable channel).
- *
- * Taken in account only if channel differs (pre-release version component in terms of semantic versioning).
- *
- * @default false
- */
- this.allowDowngrade = false;
- this._channel = null;
- /**
- * The request headers.
- */
- this.requestHeaders = null;
- this._logger = console; // noinspection JSUnusedGlobalSymbols
- /**
- * For type safety you can use signals, e.g. `autoUpdater.signals.updateDownloaded(() => {})` instead of `autoUpdater.on('update-available', () => {})`
- */
- this.signals = new (_main().UpdaterSignal)(this);
- this._appUpdateConfigPath = null;
- this.clientPromise = null;
- this.stagingUserIdPromise = new (_lazyVal().Lazy)(() => this.getOrCreateStagingUserId()); // public, allow to read old config for anyone
- /** @internal */
- this.configOnDisk = new (_lazyVal().Lazy)(() => this.loadUpdateConfig());
- this.checkForUpdatesPromise = null;
- this.updateInfo = null;
- this.on("error", error => {
- this._logger.error(`Error: ${error.stack || error.message}`);
- });
- if (app != null || global.__test_app != null) {
- this.app = app || global.__test_app;
- this.untilAppReady = Promise.resolve();
- this.httpExecutor = null;
- } else {
- this.app = require("electron").app;
- this.httpExecutor = new (_electronHttpExecutor().ElectronHttpExecutor)((authInfo, callback) => this.emit("login", authInfo, callback));
- this.untilAppReady = new Promise(resolve => {
- if (this.app.isReady()) {
- resolve();
- } else {
- this.app.on("ready", resolve);
- }
- });
- }
- this.downloadedUpdateHelper = new (_DownloadedUpdateHelper().DownloadedUpdateHelper)(path.join(this.app.getPath("userData"), "__update__"));
- const currentVersionString = this.app.getVersion();
- const currentVersion = (0, _semver().parse)(currentVersionString);
- if (currentVersion == null) {
- throw (0, _builderUtilRuntime().newError)(`App version is not a valid semver version: "${currentVersionString}"`, "ERR_UPDATER_INVALID_VERSION");
- }
- this.currentVersion = currentVersion;
- this.allowPrerelease = hasPrereleaseComponents(currentVersion);
- if (options != null) {
- this.setFeedURL(options);
- }
- }
- /**
- * Get the update channel. Not applicable for GitHub. Doesn't return `channel` from the update configuration, only if was previously set.
- */
- get channel() {
- 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) {
- if (this._channel != null) {
- // noinspection SuspiciousTypeOfGuard
- if (typeof value !== "string") {
- throw (0, _builderUtilRuntime().newError)(`Channel must be a string, but got: ${value}`, "ERR_UPDATER_INVALID_CHANNEL");
- } else if (value.length === 0) {
- throw (0, _builderUtilRuntime().newError)(`Channel must be not an empty string`, "ERR_UPDATER_INVALID_CHANNEL");
- }
- }
- this._channel = value;
- this.allowDowngrade = true;
- }
- /**
- * The logger. You can pass [electron-log](https://github.com/megahertz/electron-log), [winston](https://github.com/winstonjs/winston) or another logger with the following interface: `{ info(), warn(), error() }`.
- * Set it to `null` if you would like to disable a logging feature.
- */
- get logger() {
- return this._logger;
- }
- set logger(value) {
- this._logger = value == null ? new NoOpLogger() : value;
- } // noinspection JSUnusedGlobalSymbols
- /**
- * test only
- * @private
- */
- set updateConfigPath(value) {
- this.clientPromise = null;
- this._appUpdateConfigPath = value;
- this.configOnDisk = new (_lazyVal().Lazy)(() => this.loadUpdateConfig());
- }
- get provider() {
- return this.clientPromise;
- } //noinspection JSMethodCanBeStatic,JSUnusedGlobalSymbols
- getFeedURL() {
- return "Deprecated. Do not use it.";
- }
- /**
- * Configure update provider. If value is `string`, [GenericServerOptions](/configuration/publish.md#genericserveroptions) will be set with value as `url`.
- * @param options If you want to override configuration in the `app-update.yml`.
- */
- setFeedURL(options) {
- // https://github.com/electron-userland/electron-builder/issues/1105
- let provider;
- if (typeof options === "string") {
- provider = new (_GenericProvider().GenericProvider)({
- provider: "generic",
- url: options
- }, this, (0, _providerFactory().isUrlProbablySupportMultiRangeRequests)(options));
- } else {
- provider = (0, _providerFactory().createClient)(options, this);
- }
- this.clientPromise = Promise.resolve(provider);
- }
- /**
- * Asks the server whether there is an update.
- */
- checkForUpdates() {
- let checkForUpdatesPromise = this.checkForUpdatesPromise;
- if (checkForUpdatesPromise != null) {
- return checkForUpdatesPromise;
- }
- checkForUpdatesPromise = this._checkForUpdates();
- this.checkForUpdatesPromise = checkForUpdatesPromise;
- const nullizePromise = () => this.checkForUpdatesPromise = null;
- checkForUpdatesPromise.then(nullizePromise).catch(nullizePromise);
- return checkForUpdatesPromise;
- }
- checkForUpdatesAndNotify() {
- if (_electronIsDev().default) {
- return Promise.resolve(null);
- }
- const checkForUpdatesPromise = this.checkForUpdates();
- checkForUpdatesPromise.then(it => {
- const downloadPromise = it.downloadPromise;
- if (downloadPromise == null) {
- const debug = this._logger.debug;
- if (debug != null) {
- debug("checkForUpdatesAndNotify called, downloadPromise is null");
- }
- return;
- }
- downloadPromise.then(() => {
- new (_electron().Notification)({
- title: "A new update is ready to install",
- body: `${this.app.getName()} version ${it.updateInfo.version} is downloaded and will be automatically installed on exit`
- }).show();
- });
- });
- return checkForUpdatesPromise;
- }
- isStagingMatch(updateInfo) {
- var _this = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const rawStagingPercentage = updateInfo.stagingPercentage;
- let stagingPercentage = rawStagingPercentage;
- if (stagingPercentage == null) {
- return true;
- }
- stagingPercentage = parseInt(stagingPercentage, 10);
- if (isNaN(stagingPercentage)) {
- _this._logger.warn(`Staging percentage is NaN: ${rawStagingPercentage}`);
- return true;
- } // convert from user 0-100 to internal 0-1
- stagingPercentage = stagingPercentage / 100;
- const stagingUserId = yield _this.stagingUserIdPromise.value;
- const val = _builderUtilRuntime().UUID.parse(stagingUserId).readUInt32BE(12);
- const percentage = val / 0xFFFFFFFF;
- _this._logger.info(`Staging percentage: ${stagingPercentage}, percentage: ${percentage}, user id: ${stagingUserId}`);
- return percentage < stagingPercentage;
- })();
- }
- _checkForUpdates() {
- var _this2 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- try {
- yield _this2.untilAppReady;
- _this2._logger.info("Checking for update");
- _this2.emit("checking-for-update");
- return yield _this2.doCheckForUpdates();
- } catch (e) {
- _this2.emit("error", e, `Cannot check for updates: ${(e.stack || e).toString()}`);
- throw e;
- }
- })();
- }
- computeFinalHeaders(headers) {
- if (this.requestHeaders != null) {
- Object.assign(headers, this.requestHeaders);
- }
- return headers;
- }
- isUpdateAvailable(updateInfo) {
- var _this3 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const latestVersion = (0, _semver().parse)(updateInfo.version);
- if (latestVersion == null) {
- throw (0, _builderUtilRuntime().newError)(`This file could not be downloaded, or the latest version (from update server) does not have a valid semver version: "${latestVersion}"`, "ERR_UPDATER_INVALID_VERSION");
- }
- const currentVersion = _this3.currentVersion;
- if ((0, _semver().eq)(latestVersion, currentVersion)) {
- return false;
- }
- const isStagingMatch = yield _this3.isStagingMatch(updateInfo);
- if (!isStagingMatch) {
- return false;
- } // https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405033227
- // https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405030797
- const isLatestVersionNewer = (0, _semver().gt)(latestVersion, currentVersion);
- if (!_this3.allowDowngrade) {
- return isLatestVersionNewer;
- }
- const currentVersionPrereleaseComponent = (0, _semver().prerelease)(currentVersion);
- const latestVersionPrereleaseComponent = (0, _semver().prerelease)(latestVersion);
- if (currentVersionPrereleaseComponent === latestVersionPrereleaseComponent) {
- // allowDowngrade taken in account only if channel differs
- return isLatestVersionNewer;
- }
- return true;
- })();
- }
- getUpdateInfo() {
- var _this4 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- yield _this4.untilAppReady;
- if (_this4.clientPromise == null) {
- _this4.clientPromise = _this4.configOnDisk.value.then(it => (0, _providerFactory().createClient)(it, _this4));
- }
- const client = yield _this4.clientPromise;
- const stagingUserId = yield _this4.stagingUserIdPromise.value;
- client.setRequestHeaders(_this4.computeFinalHeaders({
- "x-user-staging-id": stagingUserId
- }));
- return yield client.getLatestVersion();
- })();
- }
- doCheckForUpdates() {
- var _this5 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const updateInfo = yield _this5.getUpdateInfo();
- if (!(yield _this5.isUpdateAvailable(updateInfo))) {
- _this5._logger.info(`Update for version ${_this5.currentVersion} is not available (latest version: ${updateInfo.version}, downgrade is ${_this5.allowDowngrade ? "allowed" : "disallowed"}).`);
- _this5.emit("update-not-available", updateInfo);
- return {
- versionInfo: updateInfo,
- updateInfo
- };
- }
- _this5.updateInfo = updateInfo;
- _this5.onUpdateAvailable(updateInfo);
- const cancellationToken = new (_builderUtilRuntime().CancellationToken)(); //noinspection ES6MissingAwait
- return {
- versionInfo: updateInfo,
- updateInfo,
- cancellationToken,
- downloadPromise: _this5.autoDownload ? _this5.downloadUpdate(cancellationToken) : null
- };
- })();
- }
- onUpdateAvailable(updateInfo) {
- this._logger.info(`Found version ${updateInfo.version} (url: ${(0, _builderUtilRuntime().asArray)(updateInfo.files).map(it => it.url).join(", ")})`);
- this.emit("update-available", updateInfo);
- }
- /**
- * Start downloading update manually. You can use this method if `autoDownload` option is set to `false`.
- * @returns {Promise<string>} Path to downloaded file.
- */
- downloadUpdate(cancellationToken = new (_builderUtilRuntime().CancellationToken)()) {
- var _this6 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const updateInfo = _this6.updateInfo;
- if (updateInfo == null) {
- const error = new Error("Please check update first");
- _this6.dispatchError(error);
- throw error;
- }
- _this6._logger.info(`Downloading update from ${(0, _builderUtilRuntime().asArray)(updateInfo.files).map(it => it.url).join(", ")}`);
- try {
- return yield _this6.doDownloadUpdate({
- updateInfo,
- requestHeaders: yield _this6.computeRequestHeaders(),
- cancellationToken
- });
- } catch (e) {
- _this6.dispatchError(e);
- throw e;
- }
- })();
- }
- dispatchError(e) {
- this.emit("error", e, (e.stack || e).toString());
- }
- loadUpdateConfig() {
- var _this7 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- if (_this7._appUpdateConfigPath == null) {
- _this7._appUpdateConfigPath = _electronIsDev().default ? path.join(_this7.app.getAppPath(), "dev-app-update.yml") : path.join(process.resourcesPath, "app-update.yml");
- }
- return (0, _jsYaml().safeLoad)((yield (0, _fsExtraP().readFile)(_this7._appUpdateConfigPath, "utf-8")));
- })();
- }
- computeRequestHeaders() {
- var _this8 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const fileExtraDownloadHeaders = (yield _this8.provider).fileExtraDownloadHeaders;
- if (fileExtraDownloadHeaders != null) {
- const requestHeaders = _this8.requestHeaders;
- return requestHeaders == null ? fileExtraDownloadHeaders : Object.assign({}, fileExtraDownloadHeaders, requestHeaders);
- }
- return _this8.computeFinalHeaders({
- accept: "*/*"
- });
- })();
- }
- getOrCreateStagingUserId() {
- var _this9 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const file = path.join(_this9.app.getPath("userData"), ".updaterId");
- try {
- const id = yield (0, _fsExtraP().readFile)(file, "utf-8");
- if (_builderUtilRuntime().UUID.check(id)) {
- return id;
- } else {
- _this9._logger.warn(`Staging user id file exists, but content was invalid: ${id}`);
- }
- } catch (e) {
- if (e.code !== "ENOENT") {
- _this9._logger.warn(`Couldn't read staging user ID, creating a blank one: ${e}`);
- }
- }
- const id = _builderUtilRuntime().UUID.v5((0, _crypto().randomBytes)(4096), _builderUtilRuntime().UUID.OID);
- _this9._logger.info(`Generated new staging user ID: ${id}`);
- try {
- yield (0, _fsExtraP().outputFile)(file, id);
- } catch (e) {
- _this9._logger.warn(`Couldn't write out staging user ID: ${e}`);
- }
- return id;
- })();
- }
- /** @internal */
- get isAddNoCacheQuery() {
- const headers = this.requestHeaders; // https://github.com/electron-userland/electron-builder/issues/3021
- if (headers == null) {
- return true;
- }
- for (const headerName of Object.keys(headers)) {
- const s = headerName.toLowerCase();
- if (s === "authorization" || s === "private-token") {
- return false;
- }
- }
- return true;
- }
- executeDownload(taskOptions) {
- var _this10 = this;
- return (0, _bluebirdLst().coroutine)(function* () {
- const fileInfo = taskOptions.fileInfo;
- const downloadOptions = {
- skipDirCreation: true,
- headers: taskOptions.downloadUpdateOptions.requestHeaders,
- cancellationToken: taskOptions.downloadUpdateOptions.cancellationToken,
- sha2: fileInfo.info.sha2,
- sha512: fileInfo.info.sha512
- };
- if (_this10.listenerCount(_main().DOWNLOAD_PROGRESS) > 0) {
- downloadOptions.onProgress = it => _this10.emit(_main().DOWNLOAD_PROGRESS, it);
- }
- const updateInfo = taskOptions.downloadUpdateOptions.updateInfo;
- const version = updateInfo.version;
- const packageInfo = fileInfo.packageInfo;
- function getCacheUpdateFileName() {
- // bloody NodeJS URL doesn't decode automatically
- const urlPath = decodeURIComponent(taskOptions.fileInfo.url.pathname);
- if (urlPath.endsWith(`.${taskOptions.fileExtension}`)) {
- return path.posix.basename(urlPath);
- } else {
- // url like /latest, generate name
- return `update.${taskOptions.fileExtension}`;
- }
- }
- const cacheDir = _this10.downloadedUpdateHelper.cacheDir;
- yield (0, _fsExtraP().ensureDir)(cacheDir);
- const updateFileName = getCacheUpdateFileName();
- let updateFile = path.join(cacheDir, updateFileName);
- const packageFile = packageInfo == null ? null : path.join(cacheDir, `package-${version}${path.extname(packageInfo.path) || ".7z"}`);
- const done = (() => {
- var _ref = (0, _bluebirdLst().coroutine)(function* (isSaveCache) {
- _this10.downloadedUpdateHelper.setDownloadedFile(updateFile, packageFile, updateInfo, fileInfo);
- if (isSaveCache) {
- yield _this10.downloadedUpdateHelper.cacheUpdateInfo(updateFileName);
- }
- _this10.emit(_main().UPDATE_DOWNLOADED, updateInfo);
- yield taskOptions.done(updateFile);
- return packageFile == null ? [updateFile] : [updateFile, packageFile];
- });
- return function done(_x) {
- return _ref.apply(this, arguments);
- };
- })();
- const log = _this10._logger;
- const cachedUpdateFile = yield _this10.downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
- if (cachedUpdateFile != null) {
- updateFile = cachedUpdateFile;
- return yield done(false);
- }
- const removeFileIfAny = (() => {
- var _ref2 = (0, _bluebirdLst().coroutine)(function* () {
- yield _this10.downloadedUpdateHelper.clear().catch(() => {// ignore
- });
- return yield (0, _fsExtraP().unlink)(updateFile).catch(() => {// ignore
- });
- });
- return function removeFileIfAny() {
- return _ref2.apply(this, arguments);
- };
- })(); // https://github.com/electron-userland/electron-builder/pull/2474#issuecomment-366481912
- let nameCounter = 0;
- let tempUpdateFile = path.join(cacheDir, `temp-${updateFileName}`);
- for (let i = 0; i < 3; i++) {
- try {
- yield (0, _fsExtraP().unlink)(tempUpdateFile);
- } catch (e) {
- if (e.code === "ENOENT") {
- break;
- }
- log.warn(`Error on remove temp update file: ${e}`);
- tempUpdateFile = path.join(cacheDir, `temp-${nameCounter++}-${updateFileName}`);
- }
- }
- try {
- yield taskOptions.task(tempUpdateFile, downloadOptions, packageFile, removeFileIfAny);
- yield (0, _fsExtraP().rename)(tempUpdateFile, updateFile);
- } catch (e) {
- yield removeFileIfAny();
- if (e instanceof _builderUtilRuntime().CancellationError) {
- log.info("Cancelled");
- _this10.emit("update-cancelled", updateInfo);
- }
- throw e;
- }
- log.info(`New version ${version} has been downloaded to ${updateFile}`);
- return yield done(true);
- })();
- }
- }
- exports.AppUpdater = AppUpdater;
- function hasPrereleaseComponents(version) {
- const versionPrereleaseComponent = (0, _semver().prerelease)(version);
- return versionPrereleaseComponent != null && versionPrereleaseComponent.length > 0;
- }
- /** @private */
- class NoOpLogger {
- info(message) {// ignore
- }
- warn(message) {// ignore
- }
- error(message) {// ignore
- }
- } exports.NoOpLogger = NoOpLogger;
- //# sourceMappingURL=AppUpdater.js.map
|