electron-incremental-update 1.1.0 → 1.2.0

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.
@@ -0,0 +1,236 @@
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
+
8
+ // src/utils/electron.ts
9
+ import { existsSync, mkdirSync, readFileSync } from "node:fs";
10
+ import { basename, dirname, join } from "node:path";
11
+ import { release } from "node:os";
12
+ import { app } from "electron";
13
+ var is = {
14
+ dev: !app.isPackaged,
15
+ win: process.platform === "win32",
16
+ mac: process.platform === "darwin",
17
+ linux: process.platform === "linux"
18
+ };
19
+ function getPathFromAppNameAsar(...path) {
20
+ return is.dev ? "DEV.asar" : join(dirname(app.getAppPath()), `${app.name}.asar`, ...path);
21
+ }
22
+ function getVersions() {
23
+ const platform = is.win ? "Windows" : is.mac ? "MacOS" : process.platform.toUpperCase();
24
+ return {
25
+ appVersion: is.dev ? app.getVersion() : readFileSync(getPathFromAppNameAsar("version"), "utf-8"),
26
+ entryVersion: app.getVersion(),
27
+ electronVersion: process.versions.electron,
28
+ nodeVersion: process.versions.node,
29
+ systemVersion: `${platform} ${release()}`
30
+ };
31
+ }
32
+ function loadNativeModuleFromEntry(devEntryDirPath = "../../dist-entry", entryDirPath = join(app.getAppPath(), basename(devEntryDirPath))) {
33
+ const path = is.dev ? devEntryDirPath : entryDirPath;
34
+ return (moduleName) => {
35
+ try {
36
+ return __require(join(path, moduleName));
37
+ } catch (error) {
38
+ console.error("fail to load module", error);
39
+ }
40
+ };
41
+ }
42
+ function restartApp() {
43
+ app.relaunch();
44
+ app.quit();
45
+ }
46
+ function setAppUserModelId(id) {
47
+ app.setAppUserModelId(is.dev ? process.execPath : id ?? `org.${app.name}`);
48
+ }
49
+ function disableHWAccForWin7() {
50
+ if (release().startsWith("6.1")) {
51
+ app.disableHardwareAcceleration();
52
+ }
53
+ }
54
+ function singleInstance(window) {
55
+ const result = app.requestSingleInstanceLock();
56
+ result ? app.on("second-instance", () => {
57
+ if (window) {
58
+ window.show();
59
+ if (window.isMinimized()) {
60
+ window.restore();
61
+ }
62
+ window.focus();
63
+ }
64
+ }) : app.quit();
65
+ return result;
66
+ }
67
+ function setPortableAppDataPath(dirName = "data") {
68
+ const portablePath = join(dirname(app.getPath("exe")), dirName);
69
+ if (!existsSync(portablePath)) {
70
+ mkdirSync(portablePath);
71
+ }
72
+ app.setPath("appData", portablePath);
73
+ }
74
+ function waitAppReady(timeout = 1e3) {
75
+ return app.isReady() ? Promise.resolve() : new Promise((resolve, reject) => {
76
+ const _ = setTimeout(() => {
77
+ reject(new Error("app is not ready"));
78
+ }, timeout);
79
+ app.whenReady().then(() => {
80
+ clearTimeout(_);
81
+ resolve();
82
+ });
83
+ });
84
+ }
85
+ function getPaths(entryDirName = "dist-entry") {
86
+ const root = join(__dirname, "..");
87
+ const mainDirPath = join(root, "main");
88
+ const preloadDirPath = join(root, "preload");
89
+ const rendererDirPath = join(root, "renderer");
90
+ const devServerURL = process.env.VITE_DEV_SERVER_URL;
91
+ const indexHTMLPath = join(rendererDirPath, "index.html");
92
+ const publicDirPath = devServerURL ? join(root, "../public") : rendererDirPath;
93
+ return {
94
+ /**
95
+ * @example
96
+ * ```ts
97
+ * devServerURL && win.loadURL(devServerURL)
98
+ * ```
99
+ */
100
+ devServerURL,
101
+ /**
102
+ * @example
103
+ * ```ts
104
+ * win.loadFile(indexHTMLPath)
105
+ * ```
106
+ */
107
+ indexHTMLPath,
108
+ /**
109
+ * get path inside entry asar
110
+ * @param paths joined path
111
+ */
112
+ getPathFromEntryAsar(...paths) {
113
+ return join(app.getAppPath(), entryDirName, ...paths);
114
+ },
115
+ /**
116
+ * get path inside `${electron.app.name}.asar/main`
117
+ * @param paths joined path
118
+ */
119
+ getPathFromMain(...paths) {
120
+ return join(mainDirPath, ...paths);
121
+ },
122
+ /**
123
+ * get path inside `${electron.app.name}.asar/preload`
124
+ * @param paths joined path
125
+ */
126
+ getPathFromPreload(...paths) {
127
+ return join(preloadDirPath, ...paths);
128
+ },
129
+ /**
130
+ * get path inside public dir
131
+ * @param paths joined path
132
+ */
133
+ getPathFromPublic(...paths) {
134
+ return join(publicDirPath, ...paths);
135
+ }
136
+ };
137
+ }
138
+
139
+ // src/utils/zip.ts
140
+ import { existsSync as existsSync2, readFileSync as readFileSync2, rmSync, writeFileSync } from "node:fs";
141
+ import { brotliCompress, brotliDecompress } from "node:zlib";
142
+ async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
143
+ if (!existsSync2(gzipPath)) {
144
+ throw new Error(`path to zipped file not exist: ${gzipPath}`);
145
+ }
146
+ const compressedBuffer = readFileSync2(gzipPath);
147
+ return new Promise((resolve, reject) => {
148
+ brotliDecompress(compressedBuffer, (err, buffer) => {
149
+ rmSync(gzipPath);
150
+ if (err) {
151
+ reject(err);
152
+ }
153
+ writeFileSync(targetFilePath, buffer);
154
+ resolve(null);
155
+ });
156
+ });
157
+ }
158
+ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
159
+ if (!existsSync2(filePath)) {
160
+ throw new Error(`path to be zipped not exist: ${filePath}`);
161
+ }
162
+ const buffer = readFileSync2(filePath);
163
+ return new Promise((resolve, reject) => {
164
+ brotliCompress(buffer, (err, buffer2) => {
165
+ if (err) {
166
+ reject(err);
167
+ }
168
+ writeFileSync(targetFilePath, buffer2);
169
+ resolve(null);
170
+ });
171
+ });
172
+ }
173
+
174
+ // src/utils/pure.ts
175
+ function parseGithubCdnURL(originRepoURL, cdnPrefix, relativeFilePath) {
176
+ if (!originRepoURL.startsWith("https://github.com/")) {
177
+ throw new Error("origin url must start with https://github.com/");
178
+ }
179
+ originRepoURL = originRepoURL.trim().replace(/\/?$/, "/").trim();
180
+ relativeFilePath = relativeFilePath.trim().replace(/^\/|\/?$/g, "").trim();
181
+ cdnPrefix = cdnPrefix.trim().replace(/^\/?|\/?$/g, "").trim();
182
+ return originRepoURL.replace("github.com", cdnPrefix) + relativeFilePath;
183
+ }
184
+ function handleUnexpectedErrors(callback) {
185
+ process.on("uncaughtException", callback);
186
+ process.on("unhandledRejection", callback);
187
+ }
188
+ function parseVersion(version) {
189
+ const semver = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?/i;
190
+ const match = semver.exec(version);
191
+ if (!match) {
192
+ throw new TypeError(`invalid version: ${version}`);
193
+ }
194
+ const [major, minor, patch] = match.slice(1, 4).map(Number);
195
+ const ret = {
196
+ major,
197
+ minor,
198
+ patch,
199
+ stage: "",
200
+ stageVersion: -1
201
+ };
202
+ if (match[4]) {
203
+ let [stage, _v] = match[4].split(".");
204
+ ret.stage = stage;
205
+ ret.stageVersion = Number(_v) || -1;
206
+ }
207
+ if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch) || Number.isNaN(ret.stageVersion)) {
208
+ throw new TypeError(`invalid version: ${version}`);
209
+ }
210
+ return ret;
211
+ }
212
+ function isUpdateJSON(json) {
213
+ const is2 = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
214
+ return is2(json) && is2(json?.beta);
215
+ }
216
+
217
+ export {
218
+ __require,
219
+ is,
220
+ getPathFromAppNameAsar,
221
+ getVersions,
222
+ loadNativeModuleFromEntry,
223
+ restartApp,
224
+ setAppUserModelId,
225
+ disableHWAccForWin7,
226
+ singleInstance,
227
+ setPortableAppDataPath,
228
+ waitAppReady,
229
+ getPaths,
230
+ unzipFile,
231
+ zipFile,
232
+ parseGithubCdnURL,
233
+ handleUnexpectedErrors,
234
+ parseVersion,
235
+ isUpdateJSON
236
+ };
package/dist/index.cjs CHANGED
@@ -35,7 +35,6 @@ var import_electron4 = require("electron");
35
35
 
36
36
  // src/updater/core.ts
37
37
  var import_node_fs3 = require("fs");
38
- var import_promises = require("fs/promises");
39
38
  var import_electron3 = require("electron");
40
39
 
41
40
  // src/utils/electron.ts
@@ -87,7 +86,7 @@ async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
87
86
  }
88
87
  const compressedBuffer = (0, import_node_fs2.readFileSync)(gzipPath);
89
88
  return new Promise((resolve2, reject) => {
90
- (0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
89
+ (0, import_node_zlib.brotliDecompress)(compressedBuffer, (err, buffer) => {
91
90
  (0, import_node_fs2.rmSync)(gzipPath);
92
91
  if (err) {
93
92
  reject(err);
@@ -275,6 +274,7 @@ var compareVersionDefault = (version1, version2) => {
275
274
 
276
275
  // src/updater/core.ts
277
276
  var Updater = class {
277
+ CERT = __SIGNATURE_CERT__;
278
278
  info;
279
279
  option;
280
280
  asarPath;
@@ -306,8 +306,11 @@ var Updater = class {
306
306
  * initialize incremental updater
307
307
  * @param option UpdaterOption
308
308
  */
309
- constructor(option) {
309
+ constructor(option = {}) {
310
310
  this.option = option;
311
+ if (option.SIGNATURE_CERT) {
312
+ this.CERT = option.SIGNATURE_CERT;
313
+ }
311
314
  this.asarPath = getPathFromAppNameAsar();
312
315
  this.gzipPath = `${this.asarPath}.gz`;
313
316
  this.tmpFilePath = `${this.asarPath}.tmp`;
@@ -324,11 +327,11 @@ var Updater = class {
324
327
  async parseData(format, data) {
325
328
  if ((0, import_node_fs3.existsSync)(this.tmpFilePath)) {
326
329
  this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
327
- await (0, import_promises.rm)(this.tmpFilePath);
330
+ (0, import_node_fs3.rmSync)(this.tmpFilePath);
328
331
  }
329
332
  if ((0, import_node_fs3.existsSync)(this.gzipPath)) {
330
333
  this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
331
- await (0, import_promises.rm)(this.gzipPath);
334
+ (0, import_node_fs3.rmSync)(this.gzipPath);
332
335
  }
333
336
  if (!["string", "object", "undefined"].includes(typeof data)) {
334
337
  throw new TypeError(`invalid type at format '${format}': ${data}`);
@@ -434,13 +437,13 @@ var Updater = class {
434
437
  const buffer = await this.parseData("buffer", data);
435
438
  this.logger?.info("verify start");
436
439
  const _verify = this.option.overrideFunctions?.verifySignaure ?? verify;
437
- const _ver = await _verify(buffer, _sig, this.option.SIGNATURE_CERT);
440
+ const _ver = await _verify(buffer, _sig, this.CERT);
438
441
  if (!_ver) {
439
- throw new VerifyFailedError(_sig, this.option.SIGNATURE_CERT);
442
+ throw new VerifyFailedError(_sig, this.CERT);
440
443
  }
441
444
  this.logger?.info("verify success");
442
445
  this.logger?.info(`write to ${this.gzipPath}`);
443
- await (0, import_promises.writeFile)(this.gzipPath, buffer);
446
+ (0, import_node_fs3.writeFileSync)(this.gzipPath, buffer);
444
447
  this.logger?.info(`extract to ${this.tmpFilePath}`);
445
448
  await unzipFile(this.gzipPath, this.tmpFilePath);
446
449
  this.logger?.info(`download success, version: ${_ver}`);
@@ -473,8 +476,9 @@ var defaultOnInstall = (install, _, __, logger) => {
473
476
  install();
474
477
  logger?.info(`update success!`);
475
478
  };
476
- function initApp(appOptions) {
479
+ async function initApp(appOptions = {}) {
477
480
  const {
481
+ updater,
478
482
  electronDevDistPath = "../dist-electron",
479
483
  mainPath = "main/index.js",
480
484
  hooks
@@ -484,43 +488,32 @@ function initApp(appOptions) {
484
488
  beforeStart,
485
489
  onStartError
486
490
  } = hooks || {};
487
- function handleError(err, logger) {
491
+ function handleError(err, logger2) {
488
492
  console.error(err);
489
- onStartError?.(err, logger);
493
+ onStartError?.(err, logger2);
490
494
  import_electron4.app.quit();
491
495
  }
492
- async function startup(updater) {
493
- const logger = updater.logger;
494
- try {
495
- const appNameAsarPath = getPathFromAppNameAsar();
496
- const tempAsarPath = `${appNameAsarPath}.tmp`;
497
- if ((0, import_node_fs4.existsSync)(tempAsarPath)) {
498
- logger?.info(`installing new asar: ${tempAsarPath}`);
499
- await onInstall(() => (0, import_node_fs4.renameSync)(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
500
- }
501
- const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
502
- const entry = (0, import_node_path2.resolve)(__dirname, mainDir, mainPath);
503
- await beforeStart?.(entry, logger);
504
- require(entry)(updater);
505
- } catch (error) {
506
- handleError(error, logger);
507
- }
496
+ let updaterInstance;
497
+ if (typeof updater === "object" || !updater) {
498
+ updaterInstance = createUpdater(updater);
499
+ } else {
500
+ updaterInstance = await updater();
508
501
  }
509
- let timer = setTimeout(() => {
510
- handleError("start app timeout, please start app with `initApp(options).startupWithUpdater(options)`");
511
- }, 3e3);
512
- return {
513
- async startupWithUpdater(updater) {
514
- clearTimeout(timer);
515
- if (typeof updater === "object") {
516
- await startup(createUpdater(updater));
517
- } else if (typeof updater === "function") {
518
- await startup(await updater());
519
- } else {
520
- handleError("invalid updater option or updater is not a function");
521
- }
502
+ const logger = updaterInstance.logger;
503
+ try {
504
+ const appNameAsarPath = getPathFromAppNameAsar();
505
+ const tempAsarPath = `${appNameAsarPath}.tmp`;
506
+ if ((0, import_node_fs4.existsSync)(tempAsarPath)) {
507
+ logger?.info(`installing new asar: ${tempAsarPath}`);
508
+ await onInstall(() => (0, import_node_fs4.renameSync)(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
522
509
  }
523
- };
510
+ const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
511
+ const entry = (0, import_node_path2.resolve)(__dirname, mainDir, mainPath);
512
+ await beforeStart?.(entry, logger);
513
+ require(entry)(updaterInstance);
514
+ } catch (error) {
515
+ handleError(error, logger);
516
+ }
524
517
  }
525
518
  // Annotate the CommonJS export names for ESM import in node:
526
519
  0 && (module.exports = {
package/dist/index.d.cts CHANGED
@@ -83,19 +83,10 @@ type UpdaterDownloadConfig = {
83
83
  };
84
84
  interface UpdaterOption {
85
85
  /**
86
- * public key of signature, which will be auto generated by plugin
87
- * @example
88
- * ```ts
89
- * // just empty here, auto filled by plugin
90
- * const SIGNATURE_CERT = ''
91
- *
92
- * const updater = createUpdater({
93
- * SIGNATURE_CERT,
94
- * ...
95
- * })
96
- * ```
86
+ * public key of signature, which will be auto generated by plugin,
87
+ * generate by `selfsigned` if not set
97
88
  */
98
- SIGNATURE_CERT: string;
89
+ SIGNATURE_CERT?: string;
99
90
  /**
100
91
  * repository url, e.g. `https://github.com/electron/electron`
101
92
  *
@@ -126,6 +117,7 @@ interface UpdaterOption {
126
117
  }
127
118
 
128
119
  declare class Updater {
120
+ private CERT;
129
121
  private info?;
130
122
  private option;
131
123
  private asarPath;
@@ -153,7 +145,7 @@ declare class Updater {
153
145
  * initialize incremental updater
154
146
  * @param option UpdaterOption
155
147
  */
156
- constructor(option: UpdaterOption);
148
+ constructor(option?: UpdaterOption);
157
149
  private needUpdate;
158
150
  /**
159
151
  * this function is used to parse download data.
@@ -200,11 +192,15 @@ declare class Updater {
200
192
  * @param option updater option
201
193
  * @returns updater
202
194
  */
203
- declare function createUpdater(option: UpdaterOption): Updater;
195
+ declare function createUpdater(option?: UpdaterOption): Updater;
204
196
 
205
197
  type Promisable<T> = T | Promise<T>;
206
198
  type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
207
199
  type AppOption = {
200
+ /**
201
+ * updater options
202
+ */
203
+ updater?: (() => Promisable<Updater>) | UpdaterOption;
208
204
  /**
209
205
  * path of electron output dist when in development
210
206
  * @default '../dist-electron'
@@ -252,13 +248,6 @@ type AppOption = {
252
248
  * })
253
249
  */
254
250
  declare function startupWithUpdater(fn: (updater: Updater) => Promisable<void>): (updater: Updater) => Promisable<void>;
255
- type StartupWithUpdater = {
256
- /**
257
- * starup app
258
- * @param updater updater option or create function
259
- */
260
- startupWithUpdater: (updater: (() => Promisable<Updater>) | UpdaterOption) => void;
261
- };
262
251
  /**
263
252
  * initialize app
264
253
  * @example
@@ -266,20 +255,22 @@ type StartupWithUpdater = {
266
255
  * import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
267
256
  * import { repository } from '../package.json'
268
257
  *
269
- * const SIGNATURE_CERT = '' // auto generate certificate when start app
270
258
  * const { cdnPrefix: asarPrefix } = getGithubReleaseCdnGroup()[0]
271
259
  * const { cdnPrefix: jsonPrefix } = getGithubFileCdnGroup()[0]
272
- * initApp({ onStart: console.log })
260
+ *
261
+ * initApp({
273
262
  * // can be updater option or function that return updater
274
- * .startupWithUpdater({
275
- * SIGNATURE_CERT,
263
+ * updater: {
264
+ * SIGNATURE_CERT: 'custom certificate',
276
265
  * repository,
277
266
  * updateJsonURL: parseGithubCdnURL(repository, jsonPrefix, 'version.json'),
278
267
  * releaseAsarURL: parseGithubCdnURL(repository, asarPrefix, `download/latest/${app.name}.asar.gz`),
279
268
  * receiveBeta: true,
280
- * })
269
+ * },
270
+ * onStart: console.log
271
+ * })
281
272
  * ```
282
273
  */
283
- declare function initApp(appOptions?: AppOption): StartupWithUpdater;
274
+ declare function initApp(appOptions?: AppOption): Promise<void>;
284
275
 
285
276
  export { type AppOption, type CheckResult, type CheckResultError, DownloadError, type DownloadResult, type DownloadResultError, type DownloadingInfo, type Logger, MinimumVersionError, Updater, type UpdaterDownloadConfig, type UpdaterOption, type UpdaterOverrideFunctions, VerifyFailedError, createUpdater, initApp, startupWithUpdater };
package/dist/index.d.ts CHANGED
@@ -83,19 +83,10 @@ type UpdaterDownloadConfig = {
83
83
  };
84
84
  interface UpdaterOption {
85
85
  /**
86
- * public key of signature, which will be auto generated by plugin
87
- * @example
88
- * ```ts
89
- * // just empty here, auto filled by plugin
90
- * const SIGNATURE_CERT = ''
91
- *
92
- * const updater = createUpdater({
93
- * SIGNATURE_CERT,
94
- * ...
95
- * })
96
- * ```
86
+ * public key of signature, which will be auto generated by plugin,
87
+ * generate by `selfsigned` if not set
97
88
  */
98
- SIGNATURE_CERT: string;
89
+ SIGNATURE_CERT?: string;
99
90
  /**
100
91
  * repository url, e.g. `https://github.com/electron/electron`
101
92
  *
@@ -126,6 +117,7 @@ interface UpdaterOption {
126
117
  }
127
118
 
128
119
  declare class Updater {
120
+ private CERT;
129
121
  private info?;
130
122
  private option;
131
123
  private asarPath;
@@ -153,7 +145,7 @@ declare class Updater {
153
145
  * initialize incremental updater
154
146
  * @param option UpdaterOption
155
147
  */
156
- constructor(option: UpdaterOption);
148
+ constructor(option?: UpdaterOption);
157
149
  private needUpdate;
158
150
  /**
159
151
  * this function is used to parse download data.
@@ -200,11 +192,15 @@ declare class Updater {
200
192
  * @param option updater option
201
193
  * @returns updater
202
194
  */
203
- declare function createUpdater(option: UpdaterOption): Updater;
195
+ declare function createUpdater(option?: UpdaterOption): Updater;
204
196
 
205
197
  type Promisable<T> = T | Promise<T>;
206
198
  type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
207
199
  type AppOption = {
200
+ /**
201
+ * updater options
202
+ */
203
+ updater?: (() => Promisable<Updater>) | UpdaterOption;
208
204
  /**
209
205
  * path of electron output dist when in development
210
206
  * @default '../dist-electron'
@@ -252,13 +248,6 @@ type AppOption = {
252
248
  * })
253
249
  */
254
250
  declare function startupWithUpdater(fn: (updater: Updater) => Promisable<void>): (updater: Updater) => Promisable<void>;
255
- type StartupWithUpdater = {
256
- /**
257
- * starup app
258
- * @param updater updater option or create function
259
- */
260
- startupWithUpdater: (updater: (() => Promisable<Updater>) | UpdaterOption) => void;
261
- };
262
251
  /**
263
252
  * initialize app
264
253
  * @example
@@ -266,20 +255,22 @@ type StartupWithUpdater = {
266
255
  * import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
267
256
  * import { repository } from '../package.json'
268
257
  *
269
- * const SIGNATURE_CERT = '' // auto generate certificate when start app
270
258
  * const { cdnPrefix: asarPrefix } = getGithubReleaseCdnGroup()[0]
271
259
  * const { cdnPrefix: jsonPrefix } = getGithubFileCdnGroup()[0]
272
- * initApp({ onStart: console.log })
260
+ *
261
+ * initApp({
273
262
  * // can be updater option or function that return updater
274
- * .startupWithUpdater({
275
- * SIGNATURE_CERT,
263
+ * updater: {
264
+ * SIGNATURE_CERT: 'custom certificate',
276
265
  * repository,
277
266
  * updateJsonURL: parseGithubCdnURL(repository, jsonPrefix, 'version.json'),
278
267
  * releaseAsarURL: parseGithubCdnURL(repository, asarPrefix, `download/latest/${app.name}.asar.gz`),
279
268
  * receiveBeta: true,
280
- * })
269
+ * },
270
+ * onStart: console.log
271
+ * })
281
272
  * ```
282
273
  */
283
- declare function initApp(appOptions?: AppOption): StartupWithUpdater;
274
+ declare function initApp(appOptions?: AppOption): Promise<void>;
284
275
 
285
276
  export { type AppOption, type CheckResult, type CheckResultError, DownloadError, type DownloadResult, type DownloadResultError, type DownloadingInfo, type Logger, MinimumVersionError, Updater, type UpdaterDownloadConfig, type UpdaterOption, type UpdaterOverrideFunctions, VerifyFailedError, createUpdater, initApp, startupWithUpdater };