electron-updater 4.3.8 → 4.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/out/AppAdapter.js +19 -28
- package/out/AppAdapter.js.map +1 -1
- package/out/AppImageUpdater.js +103 -195
- package/out/AppImageUpdater.js.map +1 -1
- package/out/AppUpdater.d.ts +1 -1
- package/out/AppUpdater.js +517 -771
- package/out/AppUpdater.js.map +1 -1
- package/out/BaseUpdater.js +79 -103
- package/out/BaseUpdater.js.map +1 -1
- package/out/DownloadedUpdateHelper.js +150 -223
- package/out/DownloadedUpdateHelper.js.map +1 -1
- package/out/ElectronAppAdapter.js +35 -63
- package/out/ElectronAppAdapter.js.map +1 -1
- package/out/MacUpdater.js +132 -201
- package/out/MacUpdater.js.map +1 -1
- package/out/NoOpLogger.d.ts +6 -0
- package/out/NoOpLogger.js +19 -0
- package/out/NoOpLogger.js.map +1 -0
- package/out/NsisUpdater.js +199 -345
- package/out/NsisUpdater.js.map +1 -1
- package/out/differentialDownloader/DataSplitter.js +180 -252
- package/out/differentialDownloader/DataSplitter.js.map +1 -1
- package/out/differentialDownloader/DifferentialDownloader.d.ts +1 -1
- package/out/differentialDownloader/DifferentialDownloader.js +242 -355
- package/out/differentialDownloader/DifferentialDownloader.js.map +1 -1
- package/out/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js +29 -65
- package/out/differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js.map +1 -1
- package/out/differentialDownloader/GenericDifferentialDownloader.js +7 -21
- package/out/differentialDownloader/GenericDifferentialDownloader.js.map +1 -1
- package/out/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js +79 -107
- package/out/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js.map +1 -1
- package/out/differentialDownloader/downloadPlanBuilder.js +99 -123
- package/out/differentialDownloader/downloadPlanBuilder.js.map +1 -1
- package/out/differentialDownloader/multipleRangeDownloader.js +99 -148
- package/out/differentialDownloader/multipleRangeDownloader.js.map +1 -1
- package/out/electronHttpExecutor.js +73 -106
- package/out/electronHttpExecutor.js.map +1 -1
- package/out/event.d.ts +35 -0
- package/out/event.js +39 -0
- package/out/event.js.map +1 -0
- package/out/log.d.ts +11 -0
- package/out/log.js +19 -0
- package/out/log.js.map +1 -0
- package/out/main.d.ts +1 -3
- package/out/main.js +60 -196
- package/out/main.js.map +1 -1
- package/out/providerFactory.js +49 -105
- package/out/providerFactory.js.map +1 -1
- package/out/providers/BintrayProvider.d.ts +2 -2
- package/out/providers/BintrayProvider.js +40 -95
- package/out/providers/BintrayProvider.js.map +1 -1
- package/out/providers/GenericProvider.d.ts +2 -2
- package/out/providers/GenericProvider.js +46 -80
- package/out/providers/GenericProvider.js.map +1 -1
- package/out/providers/GitHubProvider.d.ts +2 -2
- package/out/providers/GitHubProvider.js +122 -201
- package/out/providers/GitHubProvider.js.map +1 -1
- package/out/providers/PrivateGitHubProvider.js +87 -165
- package/out/providers/PrivateGitHubProvider.js.map +1 -1
- package/out/providers/Provider.js +122 -173
- package/out/providers/Provider.js.map +1 -1
- package/out/util.d.ts +5 -0
- package/out/util.js +42 -0
- package/out/util.js.map +1 -0
- package/out/windowsExecutableCodeSignatureVerifier.js +99 -139
- package/out/windowsExecutableCodeSignatureVerifier.js.map +1 -1
- package/package.json +33 -31
package/out/AppUpdater.js
CHANGED
|
@@ -1,797 +1,543 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.NoOpLogger = exports.AppUpdater = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const data = require("./ElectronAppAdapter");
|
|
102
|
-
|
|
103
|
-
_ElectronAppAdapter = function () {
|
|
104
|
-
return data;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
return data;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function _electronHttpExecutor() {
|
|
111
|
-
const data = require("./electronHttpExecutor");
|
|
112
|
-
|
|
113
|
-
_electronHttpExecutor = function () {
|
|
114
|
-
return data;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
return data;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function _GenericProvider() {
|
|
121
|
-
const data = require("./providers/GenericProvider");
|
|
122
|
-
|
|
123
|
-
_GenericProvider = function () {
|
|
124
|
-
return data;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
return data;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function _main() {
|
|
131
|
-
const data = require("./main");
|
|
132
|
-
|
|
133
|
-
_main = function () {
|
|
134
|
-
return data;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
return data;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function _providerFactory() {
|
|
141
|
-
const data = require("./providerFactory");
|
|
142
|
-
|
|
143
|
-
_providerFactory = function () {
|
|
144
|
-
return data;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
return data;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
|
151
|
-
|
|
152
|
-
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
153
|
-
|
|
154
|
-
class AppUpdater extends _events().EventEmitter {
|
|
155
|
-
constructor(options, app) {
|
|
156
|
-
super();
|
|
157
|
-
/**
|
|
158
|
-
* Whether to automatically download an update when it is found.
|
|
159
|
-
*/
|
|
160
|
-
|
|
161
|
-
this.autoDownload = true;
|
|
4
|
+
const builder_util_runtime_1 = require("builder-util-runtime");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const events_1 = require("events");
|
|
7
|
+
const fs_extra_1 = require("fs-extra");
|
|
8
|
+
const js_yaml_1 = require("js-yaml");
|
|
9
|
+
const lazy_val_1 = require("lazy-val");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
const semver_1 = require("semver");
|
|
12
|
+
const DownloadedUpdateHelper_1 = require("./DownloadedUpdateHelper");
|
|
13
|
+
const ElectronAppAdapter_1 = require("./ElectronAppAdapter");
|
|
14
|
+
const electronHttpExecutor_1 = require("./electronHttpExecutor");
|
|
15
|
+
const GenericProvider_1 = require("./providers/GenericProvider");
|
|
16
|
+
const main_1 = require("./main");
|
|
17
|
+
const providerFactory_1 = require("./providerFactory");
|
|
18
|
+
class AppUpdater extends events_1.EventEmitter {
|
|
19
|
+
constructor(options, app) {
|
|
20
|
+
super();
|
|
21
|
+
/**
|
|
22
|
+
* Whether to automatically download an update when it is found.
|
|
23
|
+
*/
|
|
24
|
+
this.autoDownload = true;
|
|
25
|
+
/**
|
|
26
|
+
* Whether to automatically install a downloaded update on app quit (if `quitAndInstall` was not called before).
|
|
27
|
+
*/
|
|
28
|
+
this.autoInstallOnAppQuit = true;
|
|
29
|
+
/**
|
|
30
|
+
* *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`.
|
|
31
|
+
*
|
|
32
|
+
* If `true`, downgrade will be allowed (`allowDowngrade` will be set to `true`).
|
|
33
|
+
*/
|
|
34
|
+
this.allowPrerelease = false;
|
|
35
|
+
/**
|
|
36
|
+
* *GitHub provider only.* Get all release notes (from current version to latest), not just the latest.
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
this.fullChangelog = false;
|
|
40
|
+
/**
|
|
41
|
+
* Whether to allow version downgrade (when a user from the beta channel wants to go back to the stable channel).
|
|
42
|
+
*
|
|
43
|
+
* Taken in account only if channel differs (pre-release version component in terms of semantic versioning).
|
|
44
|
+
*
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
this.allowDowngrade = false;
|
|
48
|
+
this._channel = null;
|
|
49
|
+
this.downloadedUpdateHelper = null;
|
|
50
|
+
/**
|
|
51
|
+
* The request headers.
|
|
52
|
+
*/
|
|
53
|
+
this.requestHeaders = null;
|
|
54
|
+
this._logger = console;
|
|
55
|
+
// noinspection JSUnusedGlobalSymbols
|
|
56
|
+
/**
|
|
57
|
+
* For type safety you can use signals, e.g. `autoUpdater.signals.updateDownloaded(() => {})` instead of `autoUpdater.on('update-available', () => {})`
|
|
58
|
+
*/
|
|
59
|
+
this.signals = new main_1.UpdaterSignal(this);
|
|
60
|
+
this._appUpdateConfigPath = null;
|
|
61
|
+
this.clientPromise = null;
|
|
62
|
+
this.stagingUserIdPromise = new lazy_val_1.Lazy(() => this.getOrCreateStagingUserId());
|
|
63
|
+
// public, allow to read old config for anyone
|
|
64
|
+
/** @internal */
|
|
65
|
+
this.configOnDisk = new lazy_val_1.Lazy(() => this.loadUpdateConfig());
|
|
66
|
+
this.checkForUpdatesPromise = null;
|
|
67
|
+
this.updateInfoAndProvider = null;
|
|
68
|
+
/**
|
|
69
|
+
* @private
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
this._testOnlyOptions = null;
|
|
73
|
+
this.on("error", (error) => {
|
|
74
|
+
this._logger.error(`Error: ${error.stack || error.message}`);
|
|
75
|
+
});
|
|
76
|
+
if (app == null) {
|
|
77
|
+
this.app = new ElectronAppAdapter_1.ElectronAppAdapter();
|
|
78
|
+
this.httpExecutor = new electronHttpExecutor_1.ElectronHttpExecutor((authInfo, callback) => this.emit("login", authInfo, callback));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.app = app;
|
|
82
|
+
this.httpExecutor = null;
|
|
83
|
+
}
|
|
84
|
+
const currentVersionString = this.app.version;
|
|
85
|
+
const currentVersion = semver_1.parse(currentVersionString);
|
|
86
|
+
if (currentVersion == null) {
|
|
87
|
+
throw builder_util_runtime_1.newError(`App version is not a valid semver version: "${currentVersionString}"`, "ERR_UPDATER_INVALID_VERSION");
|
|
88
|
+
}
|
|
89
|
+
this.currentVersion = currentVersion;
|
|
90
|
+
this.allowPrerelease = hasPrereleaseComponents(currentVersion);
|
|
91
|
+
if (options != null) {
|
|
92
|
+
this.setFeedURL(options);
|
|
93
|
+
if (typeof options !== "string" && options.requestHeaders) {
|
|
94
|
+
this.requestHeaders = options.requestHeaders;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
162
98
|
/**
|
|
163
|
-
*
|
|
99
|
+
* Get the update channel. Not applicable for GitHub. Doesn't return `channel` from the update configuration, only if was previously set.
|
|
164
100
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
101
|
+
get channel() {
|
|
102
|
+
return this._channel;
|
|
103
|
+
}
|
|
167
104
|
/**
|
|
168
|
-
*
|
|
105
|
+
* Set the update channel. Not applicable for GitHub. Overrides `channel` in the update configuration.
|
|
169
106
|
*
|
|
170
|
-
*
|
|
107
|
+
* `allowDowngrade` will be automatically set to `true`. If this behavior is not suitable for you, simple set `allowDowngrade` explicitly after.
|
|
171
108
|
*/
|
|
172
|
-
|
|
173
|
-
|
|
109
|
+
set channel(value) {
|
|
110
|
+
if (this._channel != null) {
|
|
111
|
+
// noinspection SuspiciousTypeOfGuard
|
|
112
|
+
if (typeof value !== "string") {
|
|
113
|
+
throw builder_util_runtime_1.newError(`Channel must be a string, but got: ${value}`, "ERR_UPDATER_INVALID_CHANNEL");
|
|
114
|
+
}
|
|
115
|
+
else if (value.length === 0) {
|
|
116
|
+
throw builder_util_runtime_1.newError(`Channel must be not an empty string`, "ERR_UPDATER_INVALID_CHANNEL");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this._channel = value;
|
|
120
|
+
this.allowDowngrade = true;
|
|
121
|
+
}
|
|
122
|
+
// noinspection JSMethodCanBeStatic,JSUnusedGlobalSymbols
|
|
123
|
+
get netSession() {
|
|
124
|
+
return electronHttpExecutor_1.getNetSession();
|
|
125
|
+
}
|
|
174
126
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
127
|
+
* 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() }`.
|
|
128
|
+
* Set it to `null` if you would like to disable a logging feature.
|
|
177
129
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
130
|
+
get logger() {
|
|
131
|
+
return this._logger;
|
|
132
|
+
}
|
|
133
|
+
set logger(value) {
|
|
134
|
+
this._logger = value == null ? new NoOpLogger() : value;
|
|
135
|
+
}
|
|
136
|
+
// noinspection JSUnusedGlobalSymbols
|
|
180
137
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* Taken in account only if channel differs (pre-release version component in terms of semantic versioning).
|
|
184
|
-
*
|
|
185
|
-
* @default false
|
|
138
|
+
* test only
|
|
139
|
+
* @private
|
|
186
140
|
*/
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
141
|
+
set updateConfigPath(value) {
|
|
142
|
+
this.clientPromise = null;
|
|
143
|
+
this._appUpdateConfigPath = value;
|
|
144
|
+
this.configOnDisk = new lazy_val_1.Lazy(() => this.loadUpdateConfig());
|
|
145
|
+
}
|
|
146
|
+
//noinspection JSMethodCanBeStatic,JSUnusedGlobalSymbols
|
|
147
|
+
getFeedURL() {
|
|
148
|
+
return "Deprecated. Do not use it.";
|
|
149
|
+
}
|
|
191
150
|
/**
|
|
192
|
-
*
|
|
151
|
+
* Configure update provider. If value is `string`, [GenericServerOptions](/configuration/publish#genericserveroptions) will be set with value as `url`.
|
|
152
|
+
* @param options If you want to override configuration in the `app-update.yml`.
|
|
193
153
|
*/
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
154
|
+
setFeedURL(options) {
|
|
155
|
+
const runtimeOptions = this.createProviderRuntimeOptions();
|
|
156
|
+
// https://github.com/electron-userland/electron-builder/issues/1105
|
|
157
|
+
let provider;
|
|
158
|
+
if (typeof options === "string") {
|
|
159
|
+
provider = new GenericProvider_1.GenericProvider({ provider: "generic", url: options }, this, {
|
|
160
|
+
...runtimeOptions,
|
|
161
|
+
isUseMultipleRangeRequest: providerFactory_1.isUrlProbablySupportMultiRangeRequests(options),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
provider = providerFactory_1.createClient(options, this, runtimeOptions);
|
|
166
|
+
}
|
|
167
|
+
this.clientPromise = Promise.resolve(provider);
|
|
168
|
+
}
|
|
198
169
|
/**
|
|
199
|
-
*
|
|
170
|
+
* Asks the server whether there is an update.
|
|
200
171
|
*/
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
172
|
+
checkForUpdates() {
|
|
173
|
+
let checkForUpdatesPromise = this.checkForUpdatesPromise;
|
|
174
|
+
if (checkForUpdatesPromise != null) {
|
|
175
|
+
this._logger.info("Checking for update (already in progress)");
|
|
176
|
+
return checkForUpdatesPromise;
|
|
177
|
+
}
|
|
178
|
+
const nullizePromise = () => (this.checkForUpdatesPromise = null);
|
|
179
|
+
this._logger.info("Checking for update");
|
|
180
|
+
checkForUpdatesPromise = this.doCheckForUpdates()
|
|
181
|
+
.then(it => {
|
|
182
|
+
nullizePromise();
|
|
183
|
+
return it;
|
|
184
|
+
})
|
|
185
|
+
.catch(e => {
|
|
186
|
+
nullizePromise();
|
|
187
|
+
this.emit("error", e, `Cannot check for updates: ${(e.stack || e).toString()}`);
|
|
188
|
+
throw e;
|
|
189
|
+
});
|
|
190
|
+
this.checkForUpdatesPromise = checkForUpdatesPromise;
|
|
191
|
+
return checkForUpdatesPromise;
|
|
192
|
+
}
|
|
193
|
+
isUpdaterActive() {
|
|
194
|
+
if (!this.app.isPackaged) {
|
|
195
|
+
this._logger.info("Skip checkForUpdatesAndNotify because application is not packed");
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
// noinspection JSUnusedGlobalSymbols
|
|
201
|
+
checkForUpdatesAndNotify(downloadNotification) {
|
|
202
|
+
if (!this.isUpdaterActive()) {
|
|
203
|
+
return Promise.resolve(null);
|
|
204
|
+
}
|
|
205
|
+
return this.checkForUpdates().then(it => {
|
|
206
|
+
const downloadPromise = it.downloadPromise;
|
|
207
|
+
if (downloadPromise == null) {
|
|
208
|
+
if (this._logger.debug != null) {
|
|
209
|
+
this._logger.debug("checkForUpdatesAndNotify called, downloadPromise is null");
|
|
210
|
+
}
|
|
211
|
+
return it;
|
|
212
|
+
}
|
|
213
|
+
void downloadPromise.then(() => {
|
|
214
|
+
const notificationContent = AppUpdater.formatDownloadNotification(it.updateInfo.version, this.app.name, downloadNotification);
|
|
215
|
+
new (require("electron").Notification)(notificationContent).show();
|
|
216
|
+
});
|
|
217
|
+
return it;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
static formatDownloadNotification(version, appName, downloadNotification) {
|
|
221
|
+
if (downloadNotification == null) {
|
|
222
|
+
downloadNotification = {
|
|
223
|
+
title: "A new update is ready to install",
|
|
224
|
+
body: `{appName} version {version} has been downloaded and will be automatically installed on exit`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
downloadNotification = {
|
|
228
|
+
title: downloadNotification.title.replace("{appName}", appName).replace("{version}", version),
|
|
229
|
+
body: downloadNotification.body.replace("{appName}", appName).replace("{version}", version),
|
|
230
|
+
};
|
|
231
|
+
return downloadNotification;
|
|
232
|
+
}
|
|
233
|
+
async isStagingMatch(updateInfo) {
|
|
234
|
+
const rawStagingPercentage = updateInfo.stagingPercentage;
|
|
235
|
+
let stagingPercentage = rawStagingPercentage;
|
|
236
|
+
if (stagingPercentage == null) {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
stagingPercentage = parseInt(stagingPercentage, 10);
|
|
240
|
+
if (isNaN(stagingPercentage)) {
|
|
241
|
+
this._logger.warn(`Staging percentage is NaN: ${rawStagingPercentage}`);
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
// convert from user 0-100 to internal 0-1
|
|
245
|
+
stagingPercentage = stagingPercentage / 100;
|
|
246
|
+
const stagingUserId = await this.stagingUserIdPromise.value;
|
|
247
|
+
const val = builder_util_runtime_1.UUID.parse(stagingUserId).readUInt32BE(12);
|
|
248
|
+
const percentage = val / 0xffffffff;
|
|
249
|
+
this._logger.info(`Staging percentage: ${stagingPercentage}, percentage: ${percentage}, user id: ${stagingUserId}`);
|
|
250
|
+
return percentage < stagingPercentage;
|
|
251
|
+
}
|
|
252
|
+
computeFinalHeaders(headers) {
|
|
253
|
+
if (this.requestHeaders != null) {
|
|
254
|
+
Object.assign(headers, this.requestHeaders);
|
|
255
|
+
}
|
|
256
|
+
return headers;
|
|
257
|
+
}
|
|
258
|
+
async isUpdateAvailable(updateInfo) {
|
|
259
|
+
const latestVersion = semver_1.parse(updateInfo.version);
|
|
260
|
+
if (latestVersion == null) {
|
|
261
|
+
throw builder_util_runtime_1.newError(`This file could not be downloaded, or the latest version (from update server) does not have a valid semver version: "${updateInfo.version}"`, "ERR_UPDATER_INVALID_VERSION");
|
|
262
|
+
}
|
|
263
|
+
const currentVersion = this.currentVersion;
|
|
264
|
+
if (semver_1.eq(latestVersion, currentVersion)) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
const isStagingMatch = await this.isStagingMatch(updateInfo);
|
|
268
|
+
if (!isStagingMatch) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
// https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405033227
|
|
272
|
+
// https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405030797
|
|
273
|
+
const isLatestVersionNewer = semver_1.gt(latestVersion, currentVersion);
|
|
274
|
+
const isLatestVersionOlder = semver_1.lt(latestVersion, currentVersion);
|
|
275
|
+
if (isLatestVersionNewer) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
return this.allowDowngrade && isLatestVersionOlder;
|
|
279
|
+
}
|
|
280
|
+
async getUpdateInfoAndProvider() {
|
|
281
|
+
await this.app.whenReady();
|
|
282
|
+
if (this.clientPromise == null) {
|
|
283
|
+
this.clientPromise = this.configOnDisk.value.then(it => providerFactory_1.createClient(it, this, this.createProviderRuntimeOptions()));
|
|
284
|
+
}
|
|
285
|
+
const client = await this.clientPromise;
|
|
286
|
+
const stagingUserId = await this.stagingUserIdPromise.value;
|
|
287
|
+
client.setRequestHeaders(this.computeFinalHeaders({ "x-user-staging-id": stagingUserId }));
|
|
288
|
+
return {
|
|
289
|
+
info: await client.getLatestVersion(),
|
|
290
|
+
provider: client,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
294
|
+
createProviderRuntimeOptions() {
|
|
295
|
+
return {
|
|
296
|
+
isUseMultipleRangeRequest: true,
|
|
297
|
+
platform: this._testOnlyOptions == null ? process.platform : this._testOnlyOptions.platform,
|
|
298
|
+
executor: this.httpExecutor,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
async doCheckForUpdates() {
|
|
302
|
+
this.emit("checking-for-update");
|
|
303
|
+
const result = await this.getUpdateInfoAndProvider();
|
|
304
|
+
const updateInfo = result.info;
|
|
305
|
+
if (!(await this.isUpdateAvailable(updateInfo))) {
|
|
306
|
+
this._logger.info(`Update for version ${this.currentVersion} is not available (latest version: ${updateInfo.version}, downgrade is ${this.allowDowngrade ? "allowed" : "disallowed"}).`);
|
|
307
|
+
this.emit("update-not-available", updateInfo);
|
|
308
|
+
return {
|
|
309
|
+
versionInfo: updateInfo,
|
|
310
|
+
updateInfo,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
this.updateInfoAndProvider = result;
|
|
314
|
+
this.onUpdateAvailable(updateInfo);
|
|
315
|
+
const cancellationToken = new builder_util_runtime_1.CancellationToken();
|
|
316
|
+
//noinspection ES6MissingAwait
|
|
317
|
+
return {
|
|
318
|
+
versionInfo: updateInfo,
|
|
319
|
+
updateInfo,
|
|
320
|
+
cancellationToken,
|
|
321
|
+
downloadPromise: this.autoDownload ? this.downloadUpdate(cancellationToken) : null,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
onUpdateAvailable(updateInfo) {
|
|
325
|
+
this._logger.info(`Found version ${updateInfo.version} (url: ${builder_util_runtime_1.asArray(updateInfo.files)
|
|
326
|
+
.map(it => it.url)
|
|
327
|
+
.join(", ")})`);
|
|
328
|
+
this.emit("update-available", updateInfo);
|
|
329
|
+
}
|
|
212
330
|
/**
|
|
213
|
-
*
|
|
214
|
-
* @
|
|
331
|
+
* Start downloading update manually. You can use this method if `autoDownload` option is set to `false`.
|
|
332
|
+
* @returns {Promise<string>} Path to downloaded file.
|
|
215
333
|
*/
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
get netSession() {
|
|
279
|
-
return (0, _electronHttpExecutor().getNetSession)();
|
|
280
|
-
}
|
|
281
|
-
/**
|
|
282
|
-
* 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() }`.
|
|
283
|
-
* Set it to `null` if you would like to disable a logging feature.
|
|
284
|
-
*/
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
get logger() {
|
|
288
|
-
return this._logger;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
set logger(value) {
|
|
292
|
-
this._logger = value == null ? new NoOpLogger() : value;
|
|
293
|
-
} // noinspection JSUnusedGlobalSymbols
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* test only
|
|
297
|
-
* @private
|
|
298
|
-
*/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
set updateConfigPath(value) {
|
|
302
|
-
this.clientPromise = null;
|
|
303
|
-
this._appUpdateConfigPath = value;
|
|
304
|
-
this.configOnDisk = new (_lazyVal().Lazy)(() => this.loadUpdateConfig());
|
|
305
|
-
} //noinspection JSMethodCanBeStatic,JSUnusedGlobalSymbols
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
getFeedURL() {
|
|
309
|
-
return "Deprecated. Do not use it.";
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Configure update provider. If value is `string`, [GenericServerOptions](/configuration/publish#genericserveroptions) will be set with value as `url`.
|
|
313
|
-
* @param options If you want to override configuration in the `app-update.yml`.
|
|
314
|
-
*/
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
setFeedURL(options) {
|
|
318
|
-
const runtimeOptions = this.createProviderRuntimeOptions(); // https://github.com/electron-userland/electron-builder/issues/1105
|
|
319
|
-
|
|
320
|
-
let provider;
|
|
321
|
-
|
|
322
|
-
if (typeof options === "string") {
|
|
323
|
-
provider = new (_GenericProvider().GenericProvider)({
|
|
324
|
-
provider: "generic",
|
|
325
|
-
url: options
|
|
326
|
-
}, this, { ...runtimeOptions,
|
|
327
|
-
isUseMultipleRangeRequest: (0, _providerFactory().isUrlProbablySupportMultiRangeRequests)(options)
|
|
328
|
-
});
|
|
329
|
-
} else {
|
|
330
|
-
provider = (0, _providerFactory().createClient)(options, this, runtimeOptions);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
this.clientPromise = Promise.resolve(provider);
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Asks the server whether there is an update.
|
|
337
|
-
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
checkForUpdates() {
|
|
341
|
-
let checkForUpdatesPromise = this.checkForUpdatesPromise;
|
|
342
|
-
|
|
343
|
-
if (checkForUpdatesPromise != null) {
|
|
344
|
-
this._logger.info("Checking for update (already in progress)");
|
|
345
|
-
|
|
346
|
-
return checkForUpdatesPromise;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
const nullizePromise = () => this.checkForUpdatesPromise = null;
|
|
350
|
-
|
|
351
|
-
this._logger.info("Checking for update");
|
|
352
|
-
|
|
353
|
-
checkForUpdatesPromise = this.doCheckForUpdates().then(it => {
|
|
354
|
-
nullizePromise();
|
|
355
|
-
return it;
|
|
356
|
-
}).catch(e => {
|
|
357
|
-
nullizePromise();
|
|
358
|
-
this.emit("error", e, `Cannot check for updates: ${(e.stack || e).toString()}`);
|
|
359
|
-
throw e;
|
|
360
|
-
});
|
|
361
|
-
this.checkForUpdatesPromise = checkForUpdatesPromise;
|
|
362
|
-
return checkForUpdatesPromise;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
isUpdaterActive() {
|
|
366
|
-
if (!this.app.isPackaged) {
|
|
367
|
-
this._logger.info("Skip checkForUpdatesAndNotify because application is not packed");
|
|
368
|
-
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return true;
|
|
373
|
-
} // noinspection JSUnusedGlobalSymbols
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
checkForUpdatesAndNotify(downloadNotification) {
|
|
377
|
-
if (!this.isUpdaterActive()) {
|
|
378
|
-
return Promise.resolve(null);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return this.checkForUpdates().then(it => {
|
|
382
|
-
const downloadPromise = it.downloadPromise;
|
|
383
|
-
|
|
384
|
-
if (downloadPromise == null) {
|
|
385
|
-
const debug = this._logger.debug;
|
|
386
|
-
|
|
387
|
-
if (debug != null) {
|
|
388
|
-
debug("checkForUpdatesAndNotify called, downloadPromise is null");
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return it;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
downloadPromise.then(() => {
|
|
395
|
-
const notificationContent = this.formatDownloadNotification(it.updateInfo.version, this.app.name, downloadNotification);
|
|
396
|
-
new (_electron().Notification)(notificationContent).show();
|
|
397
|
-
});
|
|
398
|
-
return it;
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
formatDownloadNotification(version, appName, downloadNotification) {
|
|
403
|
-
if (downloadNotification == null) {
|
|
404
|
-
downloadNotification = {
|
|
405
|
-
title: "A new update is ready to install",
|
|
406
|
-
body: `{appName} version {version} has been downloaded and will be automatically installed on exit`
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
downloadNotification = {
|
|
411
|
-
title: downloadNotification.title.replace("{appName}", appName).replace("{version}", version),
|
|
412
|
-
body: downloadNotification.body.replace("{appName}", appName).replace("{version}", version)
|
|
413
|
-
};
|
|
414
|
-
return downloadNotification;
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
async isStagingMatch(updateInfo) {
|
|
418
|
-
const rawStagingPercentage = updateInfo.stagingPercentage;
|
|
419
|
-
let stagingPercentage = rawStagingPercentage;
|
|
420
|
-
|
|
421
|
-
if (stagingPercentage == null) {
|
|
422
|
-
return true;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
stagingPercentage = parseInt(stagingPercentage, 10);
|
|
426
|
-
|
|
427
|
-
if (isNaN(stagingPercentage)) {
|
|
428
|
-
this._logger.warn(`Staging percentage is NaN: ${rawStagingPercentage}`);
|
|
429
|
-
|
|
430
|
-
return true;
|
|
431
|
-
} // convert from user 0-100 to internal 0-1
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
stagingPercentage = stagingPercentage / 100;
|
|
435
|
-
const stagingUserId = await this.stagingUserIdPromise.value;
|
|
436
|
-
|
|
437
|
-
const val = _builderUtilRuntime().UUID.parse(stagingUserId).readUInt32BE(12);
|
|
438
|
-
|
|
439
|
-
const percentage = val / 0xFFFFFFFF;
|
|
440
|
-
|
|
441
|
-
this._logger.info(`Staging percentage: ${stagingPercentage}, percentage: ${percentage}, user id: ${stagingUserId}`);
|
|
442
|
-
|
|
443
|
-
return percentage < stagingPercentage;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
computeFinalHeaders(headers) {
|
|
447
|
-
if (this.requestHeaders != null) {
|
|
448
|
-
Object.assign(headers, this.requestHeaders);
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
return headers;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
async isUpdateAvailable(updateInfo) {
|
|
455
|
-
const latestVersion = (0, _semver().parse)(updateInfo.version);
|
|
456
|
-
|
|
457
|
-
if (latestVersion == null) {
|
|
458
|
-
throw (0, _builderUtilRuntime().newError)(`This file could not be downloaded, or the latest version (from update server) does not have a valid semver version: "${updateInfo.version}"`, "ERR_UPDATER_INVALID_VERSION");
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const currentVersion = this.currentVersion;
|
|
462
|
-
|
|
463
|
-
if ((0, _semver().eq)(latestVersion, currentVersion)) {
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
const isStagingMatch = await this.isStagingMatch(updateInfo);
|
|
468
|
-
|
|
469
|
-
if (!isStagingMatch) {
|
|
470
|
-
return false;
|
|
471
|
-
} // https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405033227
|
|
472
|
-
// https://github.com/electron-userland/electron-builder/pull/3111#issuecomment-405030797
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const isLatestVersionNewer = (0, _semver().gt)(latestVersion, currentVersion);
|
|
476
|
-
const isLatestVersionOlder = (0, _semver().lt)(latestVersion, currentVersion);
|
|
477
|
-
|
|
478
|
-
if (isLatestVersionNewer) {
|
|
479
|
-
return true;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
return this.allowDowngrade && isLatestVersionOlder;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
async getUpdateInfoAndProvider() {
|
|
486
|
-
await this.app.whenReady();
|
|
487
|
-
|
|
488
|
-
if (this.clientPromise == null) {
|
|
489
|
-
this.clientPromise = this.configOnDisk.value.then(it => (0, _providerFactory().createClient)(it, this, this.createProviderRuntimeOptions()));
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
const client = await this.clientPromise;
|
|
493
|
-
const stagingUserId = await this.stagingUserIdPromise.value;
|
|
494
|
-
client.setRequestHeaders(this.computeFinalHeaders({
|
|
495
|
-
"x-user-staging-id": stagingUserId
|
|
496
|
-
}));
|
|
497
|
-
return {
|
|
498
|
-
info: await client.getLatestVersion(),
|
|
499
|
-
provider: client
|
|
500
|
-
};
|
|
501
|
-
} // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
createProviderRuntimeOptions() {
|
|
505
|
-
return {
|
|
506
|
-
isUseMultipleRangeRequest: true,
|
|
507
|
-
platform: this._testOnlyOptions == null ? process.platform : this._testOnlyOptions.platform,
|
|
508
|
-
executor: this.httpExecutor
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
async doCheckForUpdates() {
|
|
513
|
-
this.emit("checking-for-update");
|
|
514
|
-
const result = await this.getUpdateInfoAndProvider();
|
|
515
|
-
const updateInfo = result.info;
|
|
516
|
-
|
|
517
|
-
if (!(await this.isUpdateAvailable(updateInfo))) {
|
|
518
|
-
this._logger.info(`Update for version ${this.currentVersion} is not available (latest version: ${updateInfo.version}, downgrade is ${this.allowDowngrade ? "allowed" : "disallowed"}).`);
|
|
519
|
-
|
|
520
|
-
this.emit("update-not-available", updateInfo);
|
|
521
|
-
return {
|
|
522
|
-
versionInfo: updateInfo,
|
|
523
|
-
updateInfo
|
|
524
|
-
};
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
this.updateInfoAndProvider = result;
|
|
528
|
-
this.onUpdateAvailable(updateInfo);
|
|
529
|
-
const cancellationToken = new (_builderUtilRuntime().CancellationToken)(); //noinspection ES6MissingAwait
|
|
530
|
-
|
|
531
|
-
return {
|
|
532
|
-
versionInfo: updateInfo,
|
|
533
|
-
updateInfo,
|
|
534
|
-
cancellationToken,
|
|
535
|
-
downloadPromise: this.autoDownload ? this.downloadUpdate(cancellationToken) : null
|
|
536
|
-
};
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
onUpdateAvailable(updateInfo) {
|
|
540
|
-
this._logger.info(`Found version ${updateInfo.version} (url: ${(0, _builderUtilRuntime().asArray)(updateInfo.files).map(it => it.url).join(", ")})`);
|
|
541
|
-
|
|
542
|
-
this.emit("update-available", updateInfo);
|
|
543
|
-
}
|
|
544
|
-
/**
|
|
545
|
-
* Start downloading update manually. You can use this method if `autoDownload` option is set to `false`.
|
|
546
|
-
* @returns {Promise<string>} Path to downloaded file.
|
|
547
|
-
*/
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
downloadUpdate(cancellationToken = new (_builderUtilRuntime().CancellationToken)()) {
|
|
551
|
-
const updateInfoAndProvider = this.updateInfoAndProvider;
|
|
552
|
-
|
|
553
|
-
if (updateInfoAndProvider == null) {
|
|
554
|
-
const error = new Error("Please check update first");
|
|
555
|
-
this.dispatchError(error);
|
|
556
|
-
return Promise.reject(error);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
this._logger.info(`Downloading update from ${(0, _builderUtilRuntime().asArray)(updateInfoAndProvider.info.files).map(it => it.url).join(", ")}`);
|
|
560
|
-
|
|
561
|
-
const errorHandler = e => {
|
|
562
|
-
// https://github.com/electron-userland/electron-builder/issues/1150#issuecomment-436891159
|
|
563
|
-
if (!(e instanceof _builderUtilRuntime().CancellationError)) {
|
|
334
|
+
downloadUpdate(cancellationToken = new builder_util_runtime_1.CancellationToken()) {
|
|
335
|
+
const updateInfoAndProvider = this.updateInfoAndProvider;
|
|
336
|
+
if (updateInfoAndProvider == null) {
|
|
337
|
+
const error = new Error("Please check update first");
|
|
338
|
+
this.dispatchError(error);
|
|
339
|
+
return Promise.reject(error);
|
|
340
|
+
}
|
|
341
|
+
this._logger.info(`Downloading update from ${builder_util_runtime_1.asArray(updateInfoAndProvider.info.files)
|
|
342
|
+
.map(it => it.url)
|
|
343
|
+
.join(", ")}`);
|
|
344
|
+
const errorHandler = (e) => {
|
|
345
|
+
// https://github.com/electron-userland/electron-builder/issues/1150#issuecomment-436891159
|
|
346
|
+
if (!(e instanceof builder_util_runtime_1.CancellationError)) {
|
|
347
|
+
try {
|
|
348
|
+
this.dispatchError(e);
|
|
349
|
+
}
|
|
350
|
+
catch (nestedError) {
|
|
351
|
+
this._logger.warn(`Cannot dispatch error event: ${nestedError.stack || nestedError}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return e;
|
|
355
|
+
};
|
|
356
|
+
try {
|
|
357
|
+
return this.doDownloadUpdate({
|
|
358
|
+
updateInfoAndProvider,
|
|
359
|
+
requestHeaders: this.computeRequestHeaders(updateInfoAndProvider.provider),
|
|
360
|
+
cancellationToken,
|
|
361
|
+
}).catch(e => {
|
|
362
|
+
throw errorHandler(e);
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
catch (e) {
|
|
366
|
+
return Promise.reject(errorHandler(e));
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
dispatchError(e) {
|
|
370
|
+
this.emit("error", e, (e.stack || e).toString());
|
|
371
|
+
}
|
|
372
|
+
dispatchUpdateDownloaded(event) {
|
|
373
|
+
this.emit(main_1.UPDATE_DOWNLOADED, event);
|
|
374
|
+
}
|
|
375
|
+
async loadUpdateConfig() {
|
|
376
|
+
if (this._appUpdateConfigPath == null) {
|
|
377
|
+
this._appUpdateConfigPath = this.app.appUpdateConfigPath;
|
|
378
|
+
}
|
|
379
|
+
return js_yaml_1.load(await fs_extra_1.readFile(this._appUpdateConfigPath, "utf-8"));
|
|
380
|
+
}
|
|
381
|
+
computeRequestHeaders(provider) {
|
|
382
|
+
const fileExtraDownloadHeaders = provider.fileExtraDownloadHeaders;
|
|
383
|
+
if (fileExtraDownloadHeaders != null) {
|
|
384
|
+
const requestHeaders = this.requestHeaders;
|
|
385
|
+
return requestHeaders == null
|
|
386
|
+
? fileExtraDownloadHeaders
|
|
387
|
+
: {
|
|
388
|
+
...fileExtraDownloadHeaders,
|
|
389
|
+
...requestHeaders,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
return this.computeFinalHeaders({ accept: "*/*" });
|
|
393
|
+
}
|
|
394
|
+
async getOrCreateStagingUserId() {
|
|
395
|
+
const file = path.join(this.app.userDataPath, ".updaterId");
|
|
564
396
|
try {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
dispatchError(e) {
|
|
588
|
-
this.emit("error", e, (e.stack || e).toString());
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
dispatchUpdateDownloaded(event) {
|
|
592
|
-
this.emit(_main().UPDATE_DOWNLOADED, event);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
async loadUpdateConfig() {
|
|
596
|
-
if (this._appUpdateConfigPath == null) {
|
|
597
|
-
this._appUpdateConfigPath = this.app.appUpdateConfigPath;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
return (0, _jsYaml().load)(await (0, _fsExtra().readFile)(this._appUpdateConfigPath, "utf-8"));
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
computeRequestHeaders(provider) {
|
|
604
|
-
const fileExtraDownloadHeaders = provider.fileExtraDownloadHeaders;
|
|
605
|
-
|
|
606
|
-
if (fileExtraDownloadHeaders != null) {
|
|
607
|
-
const requestHeaders = this.requestHeaders;
|
|
608
|
-
return requestHeaders == null ? fileExtraDownloadHeaders : { ...fileExtraDownloadHeaders,
|
|
609
|
-
...requestHeaders
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
return this.computeFinalHeaders({
|
|
614
|
-
accept: "*/*"
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
async getOrCreateStagingUserId() {
|
|
619
|
-
const file = path.join(this.app.userDataPath, ".updaterId");
|
|
620
|
-
|
|
621
|
-
try {
|
|
622
|
-
const id = await (0, _fsExtra().readFile)(file, "utf-8");
|
|
623
|
-
|
|
624
|
-
if (_builderUtilRuntime().UUID.check(id)) {
|
|
397
|
+
const id = await fs_extra_1.readFile(file, "utf-8");
|
|
398
|
+
if (builder_util_runtime_1.UUID.check(id)) {
|
|
399
|
+
return id;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
this._logger.warn(`Staging user id file exists, but content was invalid: ${id}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch (e) {
|
|
406
|
+
if (e.code !== "ENOENT") {
|
|
407
|
+
this._logger.warn(`Couldn't read staging user ID, creating a blank one: ${e}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const id = builder_util_runtime_1.UUID.v5(crypto_1.randomBytes(4096), builder_util_runtime_1.UUID.OID);
|
|
411
|
+
this._logger.info(`Generated new staging user ID: ${id}`);
|
|
412
|
+
try {
|
|
413
|
+
await fs_extra_1.outputFile(file, id);
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
this._logger.warn(`Couldn't write out staging user ID: ${e}`);
|
|
417
|
+
}
|
|
625
418
|
return id;
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
const done = async isSaveCache => {
|
|
729
|
-
await downloadedUpdateHelper.setDownloadedFile(updateFile, packageFile, updateInfo, fileInfo, updateFileName, isSaveCache);
|
|
730
|
-
await taskOptions.done({ ...updateInfo,
|
|
731
|
-
downloadedFile: updateFile
|
|
732
|
-
});
|
|
733
|
-
return packageFile == null ? [updateFile] : [updateFile, packageFile];
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
const log = this._logger;
|
|
737
|
-
const cachedUpdateFile = await downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
|
|
738
|
-
|
|
739
|
-
if (cachedUpdateFile != null) {
|
|
740
|
-
updateFile = cachedUpdateFile;
|
|
741
|
-
return await done(false);
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
const removeFileIfAny = async () => {
|
|
745
|
-
await downloadedUpdateHelper.clear().catch(() => {// ignore
|
|
746
|
-
});
|
|
747
|
-
return await (0, _fsExtra().unlink)(updateFile).catch(() => {// ignore
|
|
748
|
-
});
|
|
749
|
-
};
|
|
750
|
-
|
|
751
|
-
const tempUpdateFile = await (0, _DownloadedUpdateHelper().createTempUpdateFile)(`temp-${updateFileName}`, cacheDir, log);
|
|
752
|
-
|
|
753
|
-
try {
|
|
754
|
-
await taskOptions.task(tempUpdateFile, downloadOptions, packageFile, removeFileIfAny);
|
|
755
|
-
await (0, _fsExtra().rename)(tempUpdateFile, updateFile);
|
|
756
|
-
} catch (e) {
|
|
757
|
-
await removeFileIfAny();
|
|
758
|
-
|
|
759
|
-
if (e instanceof _builderUtilRuntime().CancellationError) {
|
|
760
|
-
log.info("cancelled");
|
|
761
|
-
this.emit("update-cancelled", updateInfo);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
throw e;
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
log.info(`New version ${version} has been downloaded to ${updateFile}`);
|
|
768
|
-
return await done(true);
|
|
769
|
-
}
|
|
770
|
-
|
|
419
|
+
}
|
|
420
|
+
/** @internal */
|
|
421
|
+
get isAddNoCacheQuery() {
|
|
422
|
+
const headers = this.requestHeaders;
|
|
423
|
+
// https://github.com/electron-userland/electron-builder/issues/3021
|
|
424
|
+
if (headers == null) {
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
for (const headerName of Object.keys(headers)) {
|
|
428
|
+
const s = headerName.toLowerCase();
|
|
429
|
+
if (s === "authorization" || s === "private-token") {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
async getOrCreateDownloadHelper() {
|
|
436
|
+
let result = this.downloadedUpdateHelper;
|
|
437
|
+
if (result == null) {
|
|
438
|
+
const dirName = (await this.configOnDisk.value).updaterCacheDirName;
|
|
439
|
+
const logger = this._logger;
|
|
440
|
+
if (dirName == null) {
|
|
441
|
+
logger.error("updaterCacheDirName is not specified in app-update.yml Was app build using at least electron-builder 20.34.0?");
|
|
442
|
+
}
|
|
443
|
+
const cacheDir = path.join(this.app.baseCachePath, dirName || this.app.name);
|
|
444
|
+
if (logger.debug != null) {
|
|
445
|
+
logger.debug(`updater cache dir: ${cacheDir}`);
|
|
446
|
+
}
|
|
447
|
+
result = new DownloadedUpdateHelper_1.DownloadedUpdateHelper(cacheDir);
|
|
448
|
+
this.downloadedUpdateHelper = result;
|
|
449
|
+
}
|
|
450
|
+
return result;
|
|
451
|
+
}
|
|
452
|
+
async executeDownload(taskOptions) {
|
|
453
|
+
const fileInfo = taskOptions.fileInfo;
|
|
454
|
+
const downloadOptions = {
|
|
455
|
+
headers: taskOptions.downloadUpdateOptions.requestHeaders,
|
|
456
|
+
cancellationToken: taskOptions.downloadUpdateOptions.cancellationToken,
|
|
457
|
+
sha2: fileInfo.info.sha2,
|
|
458
|
+
sha512: fileInfo.info.sha512,
|
|
459
|
+
};
|
|
460
|
+
if (this.listenerCount(main_1.DOWNLOAD_PROGRESS) > 0) {
|
|
461
|
+
downloadOptions.onProgress = it => this.emit(main_1.DOWNLOAD_PROGRESS, it);
|
|
462
|
+
}
|
|
463
|
+
const updateInfo = taskOptions.downloadUpdateOptions.updateInfoAndProvider.info;
|
|
464
|
+
const version = updateInfo.version;
|
|
465
|
+
const packageInfo = fileInfo.packageInfo;
|
|
466
|
+
function getCacheUpdateFileName() {
|
|
467
|
+
// NodeJS URL doesn't decode automatically
|
|
468
|
+
const urlPath = decodeURIComponent(taskOptions.fileInfo.url.pathname);
|
|
469
|
+
if (urlPath.endsWith(`.${taskOptions.fileExtension}`)) {
|
|
470
|
+
return path.posix.basename(urlPath);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// url like /latest, generate name
|
|
474
|
+
return `update.${taskOptions.fileExtension}`;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const downloadedUpdateHelper = await this.getOrCreateDownloadHelper();
|
|
478
|
+
const cacheDir = downloadedUpdateHelper.cacheDirForPendingUpdate;
|
|
479
|
+
await fs_extra_1.ensureDir(cacheDir);
|
|
480
|
+
const updateFileName = getCacheUpdateFileName();
|
|
481
|
+
let updateFile = path.join(cacheDir, updateFileName);
|
|
482
|
+
const packageFile = packageInfo == null ? null : path.join(cacheDir, `package-${version}${path.extname(packageInfo.path) || ".7z"}`);
|
|
483
|
+
const done = async (isSaveCache) => {
|
|
484
|
+
await downloadedUpdateHelper.setDownloadedFile(updateFile, packageFile, updateInfo, fileInfo, updateFileName, isSaveCache);
|
|
485
|
+
await taskOptions.done({
|
|
486
|
+
...updateInfo,
|
|
487
|
+
downloadedFile: updateFile,
|
|
488
|
+
});
|
|
489
|
+
return packageFile == null ? [updateFile] : [updateFile, packageFile];
|
|
490
|
+
};
|
|
491
|
+
const log = this._logger;
|
|
492
|
+
const cachedUpdateFile = await downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
|
|
493
|
+
if (cachedUpdateFile != null) {
|
|
494
|
+
updateFile = cachedUpdateFile;
|
|
495
|
+
return await done(false);
|
|
496
|
+
}
|
|
497
|
+
const removeFileIfAny = async () => {
|
|
498
|
+
await downloadedUpdateHelper.clear().catch(() => {
|
|
499
|
+
// ignore
|
|
500
|
+
});
|
|
501
|
+
return await fs_extra_1.unlink(updateFile).catch(() => {
|
|
502
|
+
// ignore
|
|
503
|
+
});
|
|
504
|
+
};
|
|
505
|
+
const tempUpdateFile = await DownloadedUpdateHelper_1.createTempUpdateFile(`temp-${updateFileName}`, cacheDir, log);
|
|
506
|
+
try {
|
|
507
|
+
await taskOptions.task(tempUpdateFile, downloadOptions, packageFile, removeFileIfAny);
|
|
508
|
+
await fs_extra_1.rename(tempUpdateFile, updateFile);
|
|
509
|
+
}
|
|
510
|
+
catch (e) {
|
|
511
|
+
await removeFileIfAny();
|
|
512
|
+
if (e instanceof builder_util_runtime_1.CancellationError) {
|
|
513
|
+
log.info("cancelled");
|
|
514
|
+
this.emit("update-cancelled", updateInfo);
|
|
515
|
+
}
|
|
516
|
+
throw e;
|
|
517
|
+
}
|
|
518
|
+
log.info(`New version ${version} has been downloaded to ${updateFile}`);
|
|
519
|
+
return await done(true);
|
|
520
|
+
}
|
|
771
521
|
}
|
|
772
|
-
|
|
773
522
|
exports.AppUpdater = AppUpdater;
|
|
774
|
-
|
|
775
523
|
function hasPrereleaseComponents(version) {
|
|
776
|
-
|
|
777
|
-
|
|
524
|
+
const versionPrereleaseComponent = semver_1.prerelease(version);
|
|
525
|
+
return versionPrereleaseComponent != null && versionPrereleaseComponent.length > 0;
|
|
778
526
|
}
|
|
779
527
|
/** @private */
|
|
780
|
-
|
|
781
|
-
|
|
782
528
|
class NoOpLogger {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
}
|
|
796
|
-
|
|
529
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
530
|
+
info(message) {
|
|
531
|
+
// ignore
|
|
532
|
+
}
|
|
533
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
534
|
+
warn(message) {
|
|
535
|
+
// ignore
|
|
536
|
+
}
|
|
537
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
538
|
+
error(message) {
|
|
539
|
+
// ignore
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
exports.NoOpLogger = NoOpLogger;
|
|
797
543
|
//# sourceMappingURL=AppUpdater.js.map
|