electron-updater-for-render 1.1.3 → 2.0.0-beta.1
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/dist/bin/cli.cjs +4 -2
- package/dist/bin/cli.js +4 -2
- package/dist/builder/index.cjs +4 -2
- package/dist/builder/index.js +4 -2
- package/dist/main/index.cjs +80 -9
- package/dist/main/index.d.ts +4 -0
- package/dist/main/index.js +85 -8
- package/dist/preload/index.cjs +47 -0
- package/dist/preload/index.d.ts +13 -0
- package/dist/preload/index.js +22 -0
- package/dist/renderer/index.cjs +39 -0
- package/dist/renderer/index.d.ts +23 -0
- package/dist/renderer/index.js +14 -0
- package/dist/types.cjs +18 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.js +0 -0
- package/package.json +21 -1
package/dist/bin/cli.cjs
CHANGED
|
@@ -50,7 +50,8 @@ async function createUpdatePackage(options) {
|
|
|
50
50
|
packageJsonPath,
|
|
51
51
|
privateKeyPath,
|
|
52
52
|
releaseNotesPath,
|
|
53
|
-
forceUpdate
|
|
53
|
+
forceUpdate,
|
|
54
|
+
rolloutRule
|
|
54
55
|
} = options;
|
|
55
56
|
if (!import_fs.default.existsSync(outDir)) {
|
|
56
57
|
throw new Error(`Output directory not found at ${outDir}`);
|
|
@@ -100,7 +101,8 @@ async function createUpdatePackage(options) {
|
|
|
100
101
|
...signature ? { signature } : {},
|
|
101
102
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
102
103
|
releaseNotes: releaseNotesContent,
|
|
103
|
-
...forceUpdate ? { forceUpdate } : {}
|
|
104
|
+
...forceUpdate ? { forceUpdate } : {},
|
|
105
|
+
...rolloutRule ? { rolloutRule } : {}
|
|
104
106
|
};
|
|
105
107
|
const jsonPath = import_path.default.join(updatesDir, "latest.json");
|
|
106
108
|
import_fs.default.writeFileSync(jsonPath, JSON.stringify(updateInfo, null, 2));
|
package/dist/bin/cli.js
CHANGED
|
@@ -23,7 +23,8 @@ async function createUpdatePackage(options) {
|
|
|
23
23
|
packageJsonPath,
|
|
24
24
|
privateKeyPath,
|
|
25
25
|
releaseNotesPath,
|
|
26
|
-
forceUpdate
|
|
26
|
+
forceUpdate,
|
|
27
|
+
rolloutRule
|
|
27
28
|
} = options;
|
|
28
29
|
if (!fs.existsSync(outDir)) {
|
|
29
30
|
throw new Error(`Output directory not found at ${outDir}`);
|
|
@@ -73,7 +74,8 @@ async function createUpdatePackage(options) {
|
|
|
73
74
|
...signature ? { signature } : {},
|
|
74
75
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
75
76
|
releaseNotes: releaseNotesContent,
|
|
76
|
-
...forceUpdate ? { forceUpdate } : {}
|
|
77
|
+
...forceUpdate ? { forceUpdate } : {},
|
|
78
|
+
...rolloutRule ? { rolloutRule } : {}
|
|
77
79
|
};
|
|
78
80
|
const jsonPath = path.join(updatesDir, "latest.json");
|
|
79
81
|
fs.writeFileSync(jsonPath, JSON.stringify(updateInfo, null, 2));
|
package/dist/builder/index.cjs
CHANGED
|
@@ -52,7 +52,8 @@ async function createUpdatePackage(options) {
|
|
|
52
52
|
packageJsonPath,
|
|
53
53
|
privateKeyPath,
|
|
54
54
|
releaseNotesPath,
|
|
55
|
-
forceUpdate
|
|
55
|
+
forceUpdate,
|
|
56
|
+
rolloutRule
|
|
56
57
|
} = options;
|
|
57
58
|
if (!import_fs.default.existsSync(outDir)) {
|
|
58
59
|
throw new Error(`Output directory not found at ${outDir}`);
|
|
@@ -102,7 +103,8 @@ async function createUpdatePackage(options) {
|
|
|
102
103
|
...signature ? { signature } : {},
|
|
103
104
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
104
105
|
releaseNotes: releaseNotesContent,
|
|
105
|
-
...forceUpdate ? { forceUpdate } : {}
|
|
106
|
+
...forceUpdate ? { forceUpdate } : {},
|
|
107
|
+
...rolloutRule ? { rolloutRule } : {}
|
|
106
108
|
};
|
|
107
109
|
const jsonPath = import_path.default.join(updatesDir, "latest.json");
|
|
108
110
|
import_fs.default.writeFileSync(jsonPath, JSON.stringify(updateInfo, null, 2));
|
package/dist/builder/index.js
CHANGED
|
@@ -17,7 +17,8 @@ async function createUpdatePackage(options) {
|
|
|
17
17
|
packageJsonPath,
|
|
18
18
|
privateKeyPath,
|
|
19
19
|
releaseNotesPath,
|
|
20
|
-
forceUpdate
|
|
20
|
+
forceUpdate,
|
|
21
|
+
rolloutRule
|
|
21
22
|
} = options;
|
|
22
23
|
if (!fs.existsSync(outDir)) {
|
|
23
24
|
throw new Error(`Output directory not found at ${outDir}`);
|
|
@@ -67,7 +68,8 @@ async function createUpdatePackage(options) {
|
|
|
67
68
|
...signature ? { signature } : {},
|
|
68
69
|
date: (/* @__PURE__ */ new Date()).toISOString(),
|
|
69
70
|
releaseNotes: releaseNotesContent,
|
|
70
|
-
...forceUpdate ? { forceUpdate } : {}
|
|
71
|
+
...forceUpdate ? { forceUpdate } : {},
|
|
72
|
+
...rolloutRule ? { rolloutRule } : {}
|
|
71
73
|
};
|
|
72
74
|
const jsonPath = path.join(updatesDir, "latest.json");
|
|
73
75
|
fs.writeFileSync(jsonPath, JSON.stringify(updateInfo, null, 2));
|
package/dist/main/index.cjs
CHANGED
|
@@ -30,7 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/main/index.ts
|
|
31
31
|
var main_exports = {};
|
|
32
32
|
__export(main_exports, {
|
|
33
|
-
RenderUpdater: () => RenderUpdater
|
|
33
|
+
RenderUpdater: () => RenderUpdater,
|
|
34
|
+
setupUpdaterIPC: () => setupUpdaterIPC
|
|
34
35
|
});
|
|
35
36
|
module.exports = __toCommonJS(main_exports);
|
|
36
37
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -195,6 +196,7 @@ function verifyFileStream(filePath, info, publicKey) {
|
|
|
195
196
|
}
|
|
196
197
|
|
|
197
198
|
// src/main/index.ts
|
|
199
|
+
var import_electron3 = require("electron");
|
|
198
200
|
var fsPromises = import_original_fs.default.promises;
|
|
199
201
|
var RenderUpdater = class {
|
|
200
202
|
versionsDir;
|
|
@@ -217,6 +219,9 @@ var RenderUpdater = class {
|
|
|
217
219
|
onStatusChanged;
|
|
218
220
|
onError;
|
|
219
221
|
onBeforeRestart;
|
|
222
|
+
identity;
|
|
223
|
+
allowPrerelease;
|
|
224
|
+
requestOptions;
|
|
220
225
|
constructor(options) {
|
|
221
226
|
console.log("[RenderUpdater] Initializing with versionsDir:", options.versionsDir);
|
|
222
227
|
this.versionsDir = options.versionsDir;
|
|
@@ -234,6 +239,9 @@ var RenderUpdater = class {
|
|
|
234
239
|
this.onBeforeRestart = options.onBeforeRestart;
|
|
235
240
|
this.routerMode = options.routerMode ?? "hash";
|
|
236
241
|
this.protocolName = options.protocol ?? "app";
|
|
242
|
+
this.identity = options.identity;
|
|
243
|
+
this.allowPrerelease = options.allowPrerelease ?? false;
|
|
244
|
+
this.requestOptions = options.requestOptions;
|
|
237
245
|
this.download = this.download.bind(this);
|
|
238
246
|
this.check = this.check.bind(this);
|
|
239
247
|
this.checkForUpdatesAndNotify = this.checkForUpdatesAndNotify.bind(this);
|
|
@@ -333,7 +341,18 @@ var RenderUpdater = class {
|
|
|
333
341
|
async check() {
|
|
334
342
|
let remoteInfo = null;
|
|
335
343
|
try {
|
|
336
|
-
const
|
|
344
|
+
const fetchUrl = new URL(`${this.baseUrl}/latest.json`);
|
|
345
|
+
fetchUrl.searchParams.append("t", Date.now().toString());
|
|
346
|
+
if (this.requestOptions?.query) {
|
|
347
|
+
for (const [k, v] of Object.entries(this.requestOptions.query)) {
|
|
348
|
+
fetchUrl.searchParams.append(k, v);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
const fetchOpts = {};
|
|
352
|
+
if (this.requestOptions?.headers) {
|
|
353
|
+
fetchOpts.headers = this.requestOptions.headers;
|
|
354
|
+
}
|
|
355
|
+
const response = await fetch(fetchUrl.toString(), fetchOpts);
|
|
337
356
|
if (response.ok) {
|
|
338
357
|
remoteInfo = await response.json();
|
|
339
358
|
}
|
|
@@ -343,7 +362,16 @@ var RenderUpdater = class {
|
|
|
343
362
|
const runningVersion = this._activeVersion || "0.0.0";
|
|
344
363
|
const pendingVersion = this._diskVersion || "0.0.0";
|
|
345
364
|
if (remoteInfo && remoteInfo.version && import_semver.default.valid(remoteInfo.version)) {
|
|
346
|
-
|
|
365
|
+
let allowUpdate = true;
|
|
366
|
+
if (remoteInfo.rolloutRule?.deviceIds) {
|
|
367
|
+
if (!this.identity?.deviceId || !remoteInfo.rolloutRule.deviceIds.includes(this.identity.deviceId)) {
|
|
368
|
+
allowUpdate = false;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (allowUpdate && !this.allowPrerelease && import_semver.default.prerelease(remoteInfo.version)) {
|
|
372
|
+
allowUpdate = false;
|
|
373
|
+
}
|
|
374
|
+
if (allowUpdate && import_semver.default.gt(remoteInfo.version, pendingVersion, { includePrerelease: this.allowPrerelease })) {
|
|
347
375
|
return { updateAvailable: true, version: remoteInfo.version, info: remoteInfo, status: "available" };
|
|
348
376
|
}
|
|
349
377
|
}
|
|
@@ -368,7 +396,24 @@ var RenderUpdater = class {
|
|
|
368
396
|
this.isDownloading = true;
|
|
369
397
|
try {
|
|
370
398
|
console.log("[RenderUpdater] download() entry. current this.versionsDir:", this.versionsDir);
|
|
371
|
-
|
|
399
|
+
let infoToUse;
|
|
400
|
+
if (providedInfo) {
|
|
401
|
+
infoToUse = providedInfo;
|
|
402
|
+
} else {
|
|
403
|
+
const fetchUrl = new URL(`${this.baseUrl}/latest.json`);
|
|
404
|
+
fetchUrl.searchParams.append("t", Date.now().toString());
|
|
405
|
+
if (this.requestOptions?.query) {
|
|
406
|
+
for (const [k, v] of Object.entries(this.requestOptions.query)) {
|
|
407
|
+
fetchUrl.searchParams.append(k, v);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const fetchOpts = {};
|
|
411
|
+
if (this.requestOptions?.headers) {
|
|
412
|
+
fetchOpts.headers = this.requestOptions.headers;
|
|
413
|
+
}
|
|
414
|
+
const res = await fetch(fetchUrl.toString(), fetchOpts);
|
|
415
|
+
infoToUse = await res.json();
|
|
416
|
+
}
|
|
372
417
|
if (!this.versionsDir) throw new Error("[RenderUpdater] CRITICAL: this.versionsDir lost in download.");
|
|
373
418
|
if (!infoToUse || !infoToUse.version) throw new Error(`[RenderUpdater] CRITICAL: infoToUse or version missing. info: ${JSON.stringify(infoToUse)}`);
|
|
374
419
|
const versionDir = import_path2.default.join(this.versionsDir, infoToUse.version);
|
|
@@ -385,11 +430,12 @@ var RenderUpdater = class {
|
|
|
385
430
|
const stats = await fsPromises.stat(tmpAsarPath);
|
|
386
431
|
downloadedBytes = stats.size;
|
|
387
432
|
}
|
|
388
|
-
const fetchOptions = {};
|
|
433
|
+
const fetchOptions = { headers: {} };
|
|
434
|
+
if (this.requestOptions?.headers) {
|
|
435
|
+
Object.assign(fetchOptions.headers, this.requestOptions.headers);
|
|
436
|
+
}
|
|
389
437
|
if (downloadedBytes > 0) {
|
|
390
|
-
fetchOptions.headers = {
|
|
391
|
-
Range: `bytes=${downloadedBytes}-`
|
|
392
|
-
};
|
|
438
|
+
fetchOptions.headers["Range"] = `bytes=${downloadedBytes}-`;
|
|
393
439
|
}
|
|
394
440
|
const downloadUrl = infoToUse.path ? `${this.baseUrl.replace(/\/$/, "")}/${infoToUse.path}` : infoToUse.url;
|
|
395
441
|
if (!downloadUrl) throw new Error("[RenderUpdater] Cannot determine download URL: info.path and info.url are both missing.");
|
|
@@ -580,7 +626,32 @@ ${info.releaseNotes || "\u65E0\u8BE6\u7EC6\u8BB0\u5F55\u3002"}`,
|
|
|
580
626
|
return 0;
|
|
581
627
|
}
|
|
582
628
|
};
|
|
629
|
+
function setupUpdaterIPC(updater) {
|
|
630
|
+
import_electron3.ipcMain.handle("updater:check", () => updater.check());
|
|
631
|
+
import_electron3.ipcMain.handle("updater:download", () => updater.download());
|
|
632
|
+
import_electron3.ipcMain.handle("updater:installAndRestart", () => updater.installAndRestart());
|
|
633
|
+
import_electron3.ipcMain.on("updater:useVersion", (_, version) => updater.useVersion(version));
|
|
634
|
+
updater.onDownloadProgress = (percent) => {
|
|
635
|
+
const { webContents } = require("electron");
|
|
636
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
637
|
+
wc.send("updater:onDownloadProgress", percent);
|
|
638
|
+
});
|
|
639
|
+
};
|
|
640
|
+
updater.onStatusChanged = (status) => {
|
|
641
|
+
const { webContents } = require("electron");
|
|
642
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
643
|
+
wc.send("updater:onStatusChanged", status);
|
|
644
|
+
});
|
|
645
|
+
};
|
|
646
|
+
updater.onBeforeRestart = () => {
|
|
647
|
+
const { webContents } = require("electron");
|
|
648
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
649
|
+
wc.send("updater:onBeforeRestart");
|
|
650
|
+
});
|
|
651
|
+
};
|
|
652
|
+
}
|
|
583
653
|
// Annotate the CommonJS export names for ESM import in node:
|
|
584
654
|
0 && (module.exports = {
|
|
585
|
-
RenderUpdater
|
|
655
|
+
RenderUpdater,
|
|
656
|
+
setupUpdaterIPC
|
|
586
657
|
});
|
package/dist/main/index.d.ts
CHANGED
|
@@ -21,6 +21,9 @@ export declare class RenderUpdater {
|
|
|
21
21
|
}) => void;
|
|
22
22
|
onError?: (error: Error) => void;
|
|
23
23
|
onBeforeRestart?: () => void | Promise<void>;
|
|
24
|
+
private identity?;
|
|
25
|
+
private allowPrerelease;
|
|
26
|
+
private requestOptions?;
|
|
24
27
|
constructor(options: UpdaterOptions);
|
|
25
28
|
private readCurrentVersionFromFileSync;
|
|
26
29
|
private cleanOldVersions;
|
|
@@ -49,3 +52,4 @@ export declare class RenderUpdater {
|
|
|
49
52
|
private showNewUpdateDialog;
|
|
50
53
|
private showDownloadCompleteDialog;
|
|
51
54
|
}
|
|
55
|
+
export declare function setupUpdaterIPC(updater: RenderUpdater): void;
|
package/dist/main/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
1
8
|
// src/main/index.ts
|
|
2
9
|
import path2 from "path";
|
|
3
10
|
import fs2 from "original-fs";
|
|
@@ -161,6 +168,7 @@ function verifyFileStream(filePath, info, publicKey) {
|
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// src/main/index.ts
|
|
171
|
+
import { ipcMain } from "electron";
|
|
164
172
|
var fsPromises = fs2.promises;
|
|
165
173
|
var RenderUpdater = class {
|
|
166
174
|
versionsDir;
|
|
@@ -183,6 +191,9 @@ var RenderUpdater = class {
|
|
|
183
191
|
onStatusChanged;
|
|
184
192
|
onError;
|
|
185
193
|
onBeforeRestart;
|
|
194
|
+
identity;
|
|
195
|
+
allowPrerelease;
|
|
196
|
+
requestOptions;
|
|
186
197
|
constructor(options) {
|
|
187
198
|
console.log("[RenderUpdater] Initializing with versionsDir:", options.versionsDir);
|
|
188
199
|
this.versionsDir = options.versionsDir;
|
|
@@ -200,6 +211,9 @@ var RenderUpdater = class {
|
|
|
200
211
|
this.onBeforeRestart = options.onBeforeRestart;
|
|
201
212
|
this.routerMode = options.routerMode ?? "hash";
|
|
202
213
|
this.protocolName = options.protocol ?? "app";
|
|
214
|
+
this.identity = options.identity;
|
|
215
|
+
this.allowPrerelease = options.allowPrerelease ?? false;
|
|
216
|
+
this.requestOptions = options.requestOptions;
|
|
203
217
|
this.download = this.download.bind(this);
|
|
204
218
|
this.check = this.check.bind(this);
|
|
205
219
|
this.checkForUpdatesAndNotify = this.checkForUpdatesAndNotify.bind(this);
|
|
@@ -299,7 +313,18 @@ var RenderUpdater = class {
|
|
|
299
313
|
async check() {
|
|
300
314
|
let remoteInfo = null;
|
|
301
315
|
try {
|
|
302
|
-
const
|
|
316
|
+
const fetchUrl = new URL(`${this.baseUrl}/latest.json`);
|
|
317
|
+
fetchUrl.searchParams.append("t", Date.now().toString());
|
|
318
|
+
if (this.requestOptions?.query) {
|
|
319
|
+
for (const [k, v] of Object.entries(this.requestOptions.query)) {
|
|
320
|
+
fetchUrl.searchParams.append(k, v);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const fetchOpts = {};
|
|
324
|
+
if (this.requestOptions?.headers) {
|
|
325
|
+
fetchOpts.headers = this.requestOptions.headers;
|
|
326
|
+
}
|
|
327
|
+
const response = await fetch(fetchUrl.toString(), fetchOpts);
|
|
303
328
|
if (response.ok) {
|
|
304
329
|
remoteInfo = await response.json();
|
|
305
330
|
}
|
|
@@ -309,7 +334,16 @@ var RenderUpdater = class {
|
|
|
309
334
|
const runningVersion = this._activeVersion || "0.0.0";
|
|
310
335
|
const pendingVersion = this._diskVersion || "0.0.0";
|
|
311
336
|
if (remoteInfo && remoteInfo.version && semver.valid(remoteInfo.version)) {
|
|
312
|
-
|
|
337
|
+
let allowUpdate = true;
|
|
338
|
+
if (remoteInfo.rolloutRule?.deviceIds) {
|
|
339
|
+
if (!this.identity?.deviceId || !remoteInfo.rolloutRule.deviceIds.includes(this.identity.deviceId)) {
|
|
340
|
+
allowUpdate = false;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (allowUpdate && !this.allowPrerelease && semver.prerelease(remoteInfo.version)) {
|
|
344
|
+
allowUpdate = false;
|
|
345
|
+
}
|
|
346
|
+
if (allowUpdate && semver.gt(remoteInfo.version, pendingVersion, { includePrerelease: this.allowPrerelease })) {
|
|
313
347
|
return { updateAvailable: true, version: remoteInfo.version, info: remoteInfo, status: "available" };
|
|
314
348
|
}
|
|
315
349
|
}
|
|
@@ -334,7 +368,24 @@ var RenderUpdater = class {
|
|
|
334
368
|
this.isDownloading = true;
|
|
335
369
|
try {
|
|
336
370
|
console.log("[RenderUpdater] download() entry. current this.versionsDir:", this.versionsDir);
|
|
337
|
-
|
|
371
|
+
let infoToUse;
|
|
372
|
+
if (providedInfo) {
|
|
373
|
+
infoToUse = providedInfo;
|
|
374
|
+
} else {
|
|
375
|
+
const fetchUrl = new URL(`${this.baseUrl}/latest.json`);
|
|
376
|
+
fetchUrl.searchParams.append("t", Date.now().toString());
|
|
377
|
+
if (this.requestOptions?.query) {
|
|
378
|
+
for (const [k, v] of Object.entries(this.requestOptions.query)) {
|
|
379
|
+
fetchUrl.searchParams.append(k, v);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const fetchOpts = {};
|
|
383
|
+
if (this.requestOptions?.headers) {
|
|
384
|
+
fetchOpts.headers = this.requestOptions.headers;
|
|
385
|
+
}
|
|
386
|
+
const res = await fetch(fetchUrl.toString(), fetchOpts);
|
|
387
|
+
infoToUse = await res.json();
|
|
388
|
+
}
|
|
338
389
|
if (!this.versionsDir) throw new Error("[RenderUpdater] CRITICAL: this.versionsDir lost in download.");
|
|
339
390
|
if (!infoToUse || !infoToUse.version) throw new Error(`[RenderUpdater] CRITICAL: infoToUse or version missing. info: ${JSON.stringify(infoToUse)}`);
|
|
340
391
|
const versionDir = path2.join(this.versionsDir, infoToUse.version);
|
|
@@ -351,11 +402,12 @@ var RenderUpdater = class {
|
|
|
351
402
|
const stats = await fsPromises.stat(tmpAsarPath);
|
|
352
403
|
downloadedBytes = stats.size;
|
|
353
404
|
}
|
|
354
|
-
const fetchOptions = {};
|
|
405
|
+
const fetchOptions = { headers: {} };
|
|
406
|
+
if (this.requestOptions?.headers) {
|
|
407
|
+
Object.assign(fetchOptions.headers, this.requestOptions.headers);
|
|
408
|
+
}
|
|
355
409
|
if (downloadedBytes > 0) {
|
|
356
|
-
fetchOptions.headers = {
|
|
357
|
-
Range: `bytes=${downloadedBytes}-`
|
|
358
|
-
};
|
|
410
|
+
fetchOptions.headers["Range"] = `bytes=${downloadedBytes}-`;
|
|
359
411
|
}
|
|
360
412
|
const downloadUrl = infoToUse.path ? `${this.baseUrl.replace(/\/$/, "")}/${infoToUse.path}` : infoToUse.url;
|
|
361
413
|
if (!downloadUrl) throw new Error("[RenderUpdater] Cannot determine download URL: info.path and info.url are both missing.");
|
|
@@ -546,6 +598,31 @@ ${info.releaseNotes || "\u65E0\u8BE6\u7EC6\u8BB0\u5F55\u3002"}`,
|
|
|
546
598
|
return 0;
|
|
547
599
|
}
|
|
548
600
|
};
|
|
601
|
+
function setupUpdaterIPC(updater) {
|
|
602
|
+
ipcMain.handle("updater:check", () => updater.check());
|
|
603
|
+
ipcMain.handle("updater:download", () => updater.download());
|
|
604
|
+
ipcMain.handle("updater:installAndRestart", () => updater.installAndRestart());
|
|
605
|
+
ipcMain.on("updater:useVersion", (_, version) => updater.useVersion(version));
|
|
606
|
+
updater.onDownloadProgress = (percent) => {
|
|
607
|
+
const { webContents } = __require("electron");
|
|
608
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
609
|
+
wc.send("updater:onDownloadProgress", percent);
|
|
610
|
+
});
|
|
611
|
+
};
|
|
612
|
+
updater.onStatusChanged = (status) => {
|
|
613
|
+
const { webContents } = __require("electron");
|
|
614
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
615
|
+
wc.send("updater:onStatusChanged", status);
|
|
616
|
+
});
|
|
617
|
+
};
|
|
618
|
+
updater.onBeforeRestart = () => {
|
|
619
|
+
const { webContents } = __require("electron");
|
|
620
|
+
webContents.getAllWebContents().forEach((wc) => {
|
|
621
|
+
wc.send("updater:onBeforeRestart");
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
}
|
|
549
625
|
export {
|
|
550
|
-
RenderUpdater
|
|
626
|
+
RenderUpdater,
|
|
627
|
+
setupUpdaterIPC
|
|
551
628
|
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/preload/index.ts
|
|
21
|
+
var preload_exports = {};
|
|
22
|
+
__export(preload_exports, {
|
|
23
|
+
exposeUpdaterPreload: () => exposeUpdaterPreload
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(preload_exports);
|
|
26
|
+
function exposeUpdaterPreload(ipcRenderer) {
|
|
27
|
+
return {
|
|
28
|
+
check: () => ipcRenderer.invoke("updater:check"),
|
|
29
|
+
download: () => ipcRenderer.invoke("updater:download"),
|
|
30
|
+
installAndRestart: () => ipcRenderer.invoke("updater:installAndRestart"),
|
|
31
|
+
useVersion: (version) => ipcRenderer.send("updater:useVersion", version),
|
|
32
|
+
// 监听事件
|
|
33
|
+
onDownloadProgress: (callback) => {
|
|
34
|
+
ipcRenderer.on("updater:onDownloadProgress", (_, percent) => callback(percent));
|
|
35
|
+
},
|
|
36
|
+
onStatusChanged: (callback) => {
|
|
37
|
+
ipcRenderer.on("updater:onStatusChanged", (_, data) => callback(data));
|
|
38
|
+
},
|
|
39
|
+
onBeforeRestart: (callback) => {
|
|
40
|
+
ipcRenderer.on("updater:onBeforeRestart", () => callback());
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
exposeUpdaterPreload
|
|
47
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IpcRenderer } from 'electron';
|
|
2
|
+
export declare function exposeUpdaterPreload(ipcRenderer: IpcRenderer): {
|
|
3
|
+
check: () => Promise<any>;
|
|
4
|
+
download: () => Promise<any>;
|
|
5
|
+
installAndRestart: () => Promise<any>;
|
|
6
|
+
useVersion: (version: string) => void;
|
|
7
|
+
onDownloadProgress: (callback: (percent: number) => void) => void;
|
|
8
|
+
onStatusChanged: (callback: (data: {
|
|
9
|
+
status: "ready" | "available" | "idle";
|
|
10
|
+
version: string;
|
|
11
|
+
}) => void) => void;
|
|
12
|
+
onBeforeRestart: (callback: () => void) => void;
|
|
13
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/preload/index.ts
|
|
2
|
+
function exposeUpdaterPreload(ipcRenderer) {
|
|
3
|
+
return {
|
|
4
|
+
check: () => ipcRenderer.invoke("updater:check"),
|
|
5
|
+
download: () => ipcRenderer.invoke("updater:download"),
|
|
6
|
+
installAndRestart: () => ipcRenderer.invoke("updater:installAndRestart"),
|
|
7
|
+
useVersion: (version) => ipcRenderer.send("updater:useVersion", version),
|
|
8
|
+
// 监听事件
|
|
9
|
+
onDownloadProgress: (callback) => {
|
|
10
|
+
ipcRenderer.on("updater:onDownloadProgress", (_, percent) => callback(percent));
|
|
11
|
+
},
|
|
12
|
+
onStatusChanged: (callback) => {
|
|
13
|
+
ipcRenderer.on("updater:onStatusChanged", (_, data) => callback(data));
|
|
14
|
+
},
|
|
15
|
+
onBeforeRestart: (callback) => {
|
|
16
|
+
ipcRenderer.on("updater:onBeforeRestart", () => callback());
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
exposeUpdaterPreload
|
|
22
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/renderer/index.ts
|
|
21
|
+
var renderer_exports = {};
|
|
22
|
+
__export(renderer_exports, {
|
|
23
|
+
getUpdater: () => getUpdater
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(renderer_exports);
|
|
26
|
+
function getUpdater(namespace = "updaterAPI") {
|
|
27
|
+
if (typeof window === "undefined") {
|
|
28
|
+
throw new Error("[RenderUpdater] getUpdater() can only be called in a Browser/Renderer context.");
|
|
29
|
+
}
|
|
30
|
+
const api = window[namespace];
|
|
31
|
+
if (!api) {
|
|
32
|
+
throw new Error(`[RenderUpdater] Cannot find window.${namespace}. Did you forget to call exposeUpdaterPreload in your preload script?`);
|
|
33
|
+
}
|
|
34
|
+
return api;
|
|
35
|
+
}
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
getUpdater
|
|
39
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { UpdateInfo } from '../types';
|
|
2
|
+
export interface UpdaterClientAPI {
|
|
3
|
+
check(): Promise<{
|
|
4
|
+
updateAvailable: boolean;
|
|
5
|
+
version?: string;
|
|
6
|
+
info?: UpdateInfo;
|
|
7
|
+
status: 'idle' | 'available' | 'ready';
|
|
8
|
+
}>;
|
|
9
|
+
download(): Promise<void>;
|
|
10
|
+
installAndRestart(): Promise<void>;
|
|
11
|
+
useVersion(version: string): void;
|
|
12
|
+
onDownloadProgress(callback: (percent: number) => void): void;
|
|
13
|
+
onStatusChanged(callback: (data: {
|
|
14
|
+
status: 'ready' | 'available' | 'idle';
|
|
15
|
+
version: string;
|
|
16
|
+
}) => void): void;
|
|
17
|
+
onBeforeRestart(callback: () => void): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Ensures the updater preload API is accessible and typed.
|
|
21
|
+
* This should only be used in the renderer process (e.g. standard Vue/React contexts).
|
|
22
|
+
*/
|
|
23
|
+
export declare function getUpdater(namespace?: string): UpdaterClientAPI;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/renderer/index.ts
|
|
2
|
+
function getUpdater(namespace = "updaterAPI") {
|
|
3
|
+
if (typeof window === "undefined") {
|
|
4
|
+
throw new Error("[RenderUpdater] getUpdater() can only be called in a Browser/Renderer context.");
|
|
5
|
+
}
|
|
6
|
+
const api = window[namespace];
|
|
7
|
+
if (!api) {
|
|
8
|
+
throw new Error(`[RenderUpdater] Cannot find window.${namespace}. Did you forget to call exposeUpdaterPreload in your preload script?`);
|
|
9
|
+
}
|
|
10
|
+
return api;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
getUpdater
|
|
14
|
+
};
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/types.ts
|
|
17
|
+
var types_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(types_exports);
|
package/dist/types.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export interface UpdateInfo {
|
|
|
12
12
|
* 'silent' - downloads and restarts invisibly on the background.
|
|
13
13
|
*/
|
|
14
14
|
forceUpdate?: 'prompt' | 'silent';
|
|
15
|
+
/**
|
|
16
|
+
* Defines targeted rollout rules.
|
|
17
|
+
* If not empty, only clients matching the rules will be allowed to update.
|
|
18
|
+
*/
|
|
19
|
+
rolloutRule?: {
|
|
20
|
+
deviceIds?: string[];
|
|
21
|
+
};
|
|
15
22
|
}
|
|
16
23
|
export interface UpdaterOptions {
|
|
17
24
|
/**
|
|
@@ -23,6 +30,24 @@ export interface UpdaterOptions {
|
|
|
23
30
|
* (e.g. app.getPath('userData') + '/versions')
|
|
24
31
|
*/
|
|
25
32
|
versionsDir: string;
|
|
33
|
+
/**
|
|
34
|
+
* Client identity details for targeted rollouts (e.g. gray release).
|
|
35
|
+
*/
|
|
36
|
+
identity?: {
|
|
37
|
+
deviceId?: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* If true, will allow semver engine to pull prerelease versions (like beta or rc).
|
|
41
|
+
* Default: false
|
|
42
|
+
*/
|
|
43
|
+
allowPrerelease?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Custom HTTP headers and query params for the check & download requests (useful for auth).
|
|
46
|
+
*/
|
|
47
|
+
requestOptions?: {
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
query?: Record<string, string>;
|
|
50
|
+
};
|
|
26
51
|
/**
|
|
27
52
|
* Public key string (PEM format) to verify the RSA signature
|
|
28
53
|
*/
|
|
@@ -122,4 +147,10 @@ export interface BuilderOptions {
|
|
|
122
147
|
* 'silent': Stealthily apply it in the background.
|
|
123
148
|
*/
|
|
124
149
|
forceUpdate?: 'prompt' | 'silent';
|
|
150
|
+
/**
|
|
151
|
+
* Rollout whitelist rule for precise targeting during build packing.
|
|
152
|
+
*/
|
|
153
|
+
rolloutRule?: {
|
|
154
|
+
deviceIds?: string[];
|
|
155
|
+
};
|
|
125
156
|
}
|
package/dist/types.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electron-updater-for-render",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"description": "A lightweight incremental updater for Electron renderer processes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,26 @@
|
|
|
15
15
|
"import": "./dist/main/index.js",
|
|
16
16
|
"require": "./dist/main/index.cjs"
|
|
17
17
|
},
|
|
18
|
+
"./main": {
|
|
19
|
+
"types": "./dist/main/index.d.ts",
|
|
20
|
+
"import": "./dist/main/index.js",
|
|
21
|
+
"require": "./dist/main/index.cjs"
|
|
22
|
+
},
|
|
23
|
+
"./preload": {
|
|
24
|
+
"types": "./dist/preload/index.d.ts",
|
|
25
|
+
"import": "./dist/preload/index.js",
|
|
26
|
+
"require": "./dist/preload/index.cjs"
|
|
27
|
+
},
|
|
28
|
+
"./renderer": {
|
|
29
|
+
"types": "./dist/renderer/index.d.ts",
|
|
30
|
+
"import": "./dist/renderer/index.js",
|
|
31
|
+
"require": "./dist/renderer/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./types": {
|
|
34
|
+
"types": "./dist/types.d.ts",
|
|
35
|
+
"import": "./dist/types.js",
|
|
36
|
+
"require": "./dist/types.cjs"
|
|
37
|
+
},
|
|
18
38
|
"./builder": {
|
|
19
39
|
"types": "./dist/builder/index.d.ts",
|
|
20
40
|
"import": "./dist/builder/index.js",
|