electron-incremental-update 2.0.0-beta.6 → 2.0.0-beta.8

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.
@@ -1,23 +1,23 @@
1
1
  import { __require } from './chunk-72ZAJ7AF.js';
2
- import { readFileSync, existsSync, mkdirSync } from 'node:fs';
3
- import { join, dirname } from 'node:path';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
4
  import { app } from 'electron';
5
5
 
6
6
  var isDev = __EIU_IS_DEV__;
7
7
  var isWin = process.platform === "win32";
8
8
  var isMac = process.platform === "darwin";
9
9
  var isLinux = process.platform === "linux";
10
- function getPathFromAppNameAsar(...path) {
11
- return isDev ? "DEV.asar" : join(dirname(app.getAppPath()), `${app.name}.asar`, ...path);
10
+ function getPathFromAppNameAsar(...paths) {
11
+ return isDev ? "DEV.asar" : path.join(path.dirname(app.getAppPath()), `${app.name}.asar`, ...paths);
12
12
  }
13
13
  function getAppVersion() {
14
- return isDev ? getEntryVersion() : readFileSync(getPathFromAppNameAsar("version"), "utf-8");
14
+ return isDev ? getEntryVersion() : fs.readFileSync(getPathFromAppNameAsar("version"), "utf-8");
15
15
  }
16
16
  function getEntryVersion() {
17
17
  return app.getVersion();
18
18
  }
19
19
  function requireNative(moduleName) {
20
- return __require(join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, moduleName));
20
+ return __require(path.join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, moduleName));
21
21
  }
22
22
  function restartApp() {
23
23
  app.relaunch();
@@ -51,9 +51,9 @@ function singleInstance(window) {
51
51
  return result;
52
52
  }
53
53
  function setPortableAppDataPath(dirName = "data") {
54
- const portablePath = join(dirname(app.getPath("exe")), dirName);
55
- if (!existsSync(portablePath)) {
56
- mkdirSync(portablePath);
54
+ const portablePath = path.join(path.dirname(app.getPath("exe")), dirName);
55
+ if (!fs.existsSync(portablePath)) {
56
+ fs.mkdirSync(portablePath);
57
57
  }
58
58
  app.setPath("appData", portablePath);
59
59
  }
@@ -65,13 +65,13 @@ function loadPage(win, htmlFilePath = "index.html") {
65
65
  }
66
66
  }
67
67
  function getPathFromPreload(...paths) {
68
- return isDev ? join(app.getAppPath(), __EIU_ELECTRON_DIST_PATH__, "preload", ...paths) : getPathFromAppNameAsar("preload", ...paths);
68
+ return isDev ? path.join(app.getAppPath(), __EIU_ELECTRON_DIST_PATH__, "preload", ...paths) : getPathFromAppNameAsar("preload", ...paths);
69
69
  }
70
70
  function getPathFromPublic(...paths) {
71
- return isDev ? join(app.getAppPath(), "public", ...paths) : getPathFromAppNameAsar("renderer", ...paths);
71
+ return isDev ? path.join(app.getAppPath(), "public", ...paths) : getPathFromAppNameAsar("renderer", ...paths);
72
72
  }
73
73
  function getPathFromEntryAsar(...paths) {
74
- return join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, ...paths);
74
+ return path.join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, ...paths);
75
75
  }
76
76
  function handleUnexpectedErrors(callback) {
77
77
  process.on("uncaughtException", callback);
@@ -1,10 +1,10 @@
1
- import { brotliCompress, brotliDecompress } from 'node:zlib';
2
- import { createHash, createCipheriv, createSign, createPrivateKey, createDecipheriv, createVerify } from 'node:crypto';
1
+ import zlib from 'node:zlib';
2
+ import crypto from 'node:crypto';
3
3
 
4
4
  // src/utils/zip.ts
5
5
  async function defaultZipFile(buffer) {
6
6
  return new Promise((resolve, reject) => {
7
- brotliCompress(buffer, (err, buffer2) => {
7
+ zlib.brotliCompress(buffer, (err, buffer2) => {
8
8
  if (err) {
9
9
  reject(err);
10
10
  } else {
@@ -15,7 +15,7 @@ async function defaultZipFile(buffer) {
15
15
  }
16
16
  async function defaultUnzipFile(buffer) {
17
17
  return new Promise((resolve, reject) => {
18
- brotliDecompress(buffer, (err, buffer2) => {
18
+ zlib.brotliDecompress(buffer, (err, buffer2) => {
19
19
  if (err) {
20
20
  reject(err);
21
21
  } else {
@@ -25,19 +25,19 @@ async function defaultUnzipFile(buffer) {
25
25
  });
26
26
  }
27
27
  function hashBuffer(data, length) {
28
- const hash = createHash("SHA256").update(data).digest("binary");
28
+ const hash = crypto.createHash("SHA256").update(data).digest("binary");
29
29
  return Buffer.from(hash).subarray(0, length);
30
30
  }
31
31
  function aesEncrypt(plainText, key, iv) {
32
- const cipher = createCipheriv("aes-256-cbc", key, iv);
32
+ const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
33
33
  return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
34
34
  }
35
35
  function defaultSignature(buffer, privateKey, cert, version) {
36
- const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
36
+ const sig = crypto.createSign("RSA-SHA256").update(buffer).sign(crypto.createPrivateKey(privateKey), "base64");
37
37
  return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
38
38
  }
39
39
  function aesDecrypt(encryptedText, key, iv) {
40
- const decipher = createDecipheriv("aes-256-cbc", key, iv);
40
+ const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
41
41
  return decipher.update(encryptedText, "base64url", "utf8") + decipher.final("utf8");
42
42
  }
43
43
  function defaultVerifySignature(buffer, version, signature, cert) {
@@ -46,7 +46,7 @@ function defaultVerifySignature(buffer, version, signature, cert) {
46
46
  if (ver !== version) {
47
47
  return false;
48
48
  }
49
- return createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
49
+ return crypto.createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
50
50
  } catch {
51
51
  return false;
52
52
  }
@@ -0,0 +1,134 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { a as UpdateJSON, U as UpdateInfo, D as DownloadingInfo, I as IProvider, c as URLHandler } from './types-CItP6bL-.js';
3
+
4
+ declare const ErrorInfo: {
5
+ readonly download: "Download failed";
6
+ readonly validate: "Validate failed";
7
+ readonly param: "Missing params";
8
+ readonly network: "Network error";
9
+ };
10
+ declare class UpdaterError extends Error {
11
+ code: keyof typeof ErrorInfo;
12
+ constructor(msg: keyof typeof ErrorInfo, info: string);
13
+ }
14
+ type CheckResult<T extends UpdateJSON> = {
15
+ success: true;
16
+ data: Omit<T, 'beta'>;
17
+ } | {
18
+ success: false;
19
+ /**
20
+ * minimal version that can update
21
+ */
22
+ data: string;
23
+ } | {
24
+ success: false;
25
+ data: UpdaterError;
26
+ };
27
+ type DownloadResult = {
28
+ success: true;
29
+ } | {
30
+ success: false;
31
+ data: UpdaterError;
32
+ };
33
+ interface Logger {
34
+ info: (msg: string) => void;
35
+ debug: (msg: string) => void;
36
+ warn: (msg: string) => void;
37
+ error: (msg: string, e?: unknown) => void;
38
+ }
39
+ interface UpdaterOption {
40
+ /**
41
+ * public key of signature, which will be auto generated by plugin,
42
+ * generate by `selfsigned` if not set
43
+ */
44
+ SIGNATURE_CERT?: string;
45
+ /**
46
+ * whether to receive beta update
47
+ */
48
+ receiveBeta?: boolean;
49
+ logger?: Logger;
50
+ }
51
+
52
+ declare class Updater extends EventEmitter<{
53
+ 'checking': any;
54
+ 'update-available': [data: UpdateInfo];
55
+ 'update-unavailable': [reason: string];
56
+ 'error': [error: UpdaterError];
57
+ 'download-progress': [info: DownloadingInfo];
58
+ 'update-downloaded': any;
59
+ }> {
60
+ private CERT;
61
+ private info?;
62
+ private provider;
63
+ /**
64
+ * updater logger
65
+ */
66
+ logger?: Logger;
67
+ /**
68
+ * whether to receive beta update
69
+ */
70
+ receiveBeta?: boolean;
71
+ /**
72
+ * whether force update in DEV
73
+ */
74
+ forceUpdate?: boolean;
75
+ /**
76
+ * initialize incremental updater
77
+ * @param provider update provider
78
+ * @param option UpdaterOption
79
+ */
80
+ constructor(provider: IProvider, option?: UpdaterOption);
81
+ /**
82
+ * this function is used to parse download data.
83
+ * - if format is `'json'`
84
+ * - if data is `UpdateJSON`, return it
85
+ * - if data is string or absent, download URL data and return it
86
+ * - if format is `'buffer'`
87
+ * - if data is `Buffer`, return it
88
+ * - if data is string or absent, download URL data and return it
89
+ * @param format 'json' or 'buffer'
90
+ * @param data download URL or update json or buffer
91
+ */
92
+ private fetch;
93
+ /**
94
+ * handle error message and emit error event
95
+ */
96
+ private err;
97
+ /**
98
+ * check update info using default options
99
+ */
100
+ checkUpdate(): Promise<boolean>;
101
+ /**
102
+ * check update info using existing update json
103
+ * @param data existing update json
104
+ */
105
+ checkUpdate(data: UpdateJSON): Promise<boolean>;
106
+ /**
107
+ * download update using default options
108
+ */
109
+ downloadUpdate(): Promise<boolean>;
110
+ /**
111
+ * download update using existing `asar.gz` buffer and signature
112
+ * @param data existing `asar.gz` buffer
113
+ * @param info update info
114
+ */
115
+ downloadUpdate(data: Uint8Array, info: Omit<UpdateInfo, 'minimumVersion'>): Promise<boolean>;
116
+ /**
117
+ * quit App and install
118
+ */
119
+ quitAndInstall(): void;
120
+ /**
121
+ * setup provider URL handler
122
+ *
123
+ * @example
124
+ * updater.setURLHandler((url, isDownloadingAsar) => {
125
+ * if (isDownloadingAsar) {
126
+ * url.hostname = 'https://cdn.jsdelivr.net/gh'
127
+ * return url
128
+ * }
129
+ * })
130
+ */
131
+ setURLHandler(handler: URLHandler): void;
132
+ }
133
+
134
+ export { type CheckResult as C, type DownloadResult as D, ErrorInfo as E, type Logger as L, Updater as U, type UpdaterOption as a, UpdaterError as b };
@@ -0,0 +1,134 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { a as UpdateJSON, U as UpdateInfo, D as DownloadingInfo, I as IProvider, c as URLHandler } from './types-CItP6bL-.cjs';
3
+
4
+ declare const ErrorInfo: {
5
+ readonly download: "Download failed";
6
+ readonly validate: "Validate failed";
7
+ readonly param: "Missing params";
8
+ readonly network: "Network error";
9
+ };
10
+ declare class UpdaterError extends Error {
11
+ code: keyof typeof ErrorInfo;
12
+ constructor(msg: keyof typeof ErrorInfo, info: string);
13
+ }
14
+ type CheckResult<T extends UpdateJSON> = {
15
+ success: true;
16
+ data: Omit<T, 'beta'>;
17
+ } | {
18
+ success: false;
19
+ /**
20
+ * minimal version that can update
21
+ */
22
+ data: string;
23
+ } | {
24
+ success: false;
25
+ data: UpdaterError;
26
+ };
27
+ type DownloadResult = {
28
+ success: true;
29
+ } | {
30
+ success: false;
31
+ data: UpdaterError;
32
+ };
33
+ interface Logger {
34
+ info: (msg: string) => void;
35
+ debug: (msg: string) => void;
36
+ warn: (msg: string) => void;
37
+ error: (msg: string, e?: unknown) => void;
38
+ }
39
+ interface UpdaterOption {
40
+ /**
41
+ * public key of signature, which will be auto generated by plugin,
42
+ * generate by `selfsigned` if not set
43
+ */
44
+ SIGNATURE_CERT?: string;
45
+ /**
46
+ * whether to receive beta update
47
+ */
48
+ receiveBeta?: boolean;
49
+ logger?: Logger;
50
+ }
51
+
52
+ declare class Updater extends EventEmitter<{
53
+ 'checking': any;
54
+ 'update-available': [data: UpdateInfo];
55
+ 'update-unavailable': [reason: string];
56
+ 'error': [error: UpdaterError];
57
+ 'download-progress': [info: DownloadingInfo];
58
+ 'update-downloaded': any;
59
+ }> {
60
+ private CERT;
61
+ private info?;
62
+ private provider;
63
+ /**
64
+ * updater logger
65
+ */
66
+ logger?: Logger;
67
+ /**
68
+ * whether to receive beta update
69
+ */
70
+ receiveBeta?: boolean;
71
+ /**
72
+ * whether force update in DEV
73
+ */
74
+ forceUpdate?: boolean;
75
+ /**
76
+ * initialize incremental updater
77
+ * @param provider update provider
78
+ * @param option UpdaterOption
79
+ */
80
+ constructor(provider: IProvider, option?: UpdaterOption);
81
+ /**
82
+ * this function is used to parse download data.
83
+ * - if format is `'json'`
84
+ * - if data is `UpdateJSON`, return it
85
+ * - if data is string or absent, download URL data and return it
86
+ * - if format is `'buffer'`
87
+ * - if data is `Buffer`, return it
88
+ * - if data is string or absent, download URL data and return it
89
+ * @param format 'json' or 'buffer'
90
+ * @param data download URL or update json or buffer
91
+ */
92
+ private fetch;
93
+ /**
94
+ * handle error message and emit error event
95
+ */
96
+ private err;
97
+ /**
98
+ * check update info using default options
99
+ */
100
+ checkUpdate(): Promise<boolean>;
101
+ /**
102
+ * check update info using existing update json
103
+ * @param data existing update json
104
+ */
105
+ checkUpdate(data: UpdateJSON): Promise<boolean>;
106
+ /**
107
+ * download update using default options
108
+ */
109
+ downloadUpdate(): Promise<boolean>;
110
+ /**
111
+ * download update using existing `asar.gz` buffer and signature
112
+ * @param data existing `asar.gz` buffer
113
+ * @param info update info
114
+ */
115
+ downloadUpdate(data: Uint8Array, info: Omit<UpdateInfo, 'minimumVersion'>): Promise<boolean>;
116
+ /**
117
+ * quit App and install
118
+ */
119
+ quitAndInstall(): void;
120
+ /**
121
+ * setup provider URL handler
122
+ *
123
+ * @example
124
+ * updater.setURLHandler((url, isDownloadingAsar) => {
125
+ * if (isDownloadingAsar) {
126
+ * url.hostname = 'https://cdn.jsdelivr.net/gh'
127
+ * return url
128
+ * }
129
+ * })
130
+ */
131
+ setURLHandler(handler: URLHandler): void;
132
+ }
133
+
134
+ export { type CheckResult as C, type DownloadResult as D, ErrorInfo as E, type Logger as L, Updater as U, type UpdaterOption as a, UpdaterError as b };
package/dist/index.cjs CHANGED
@@ -1,10 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  var path = require('path');
4
- var fs = require('fs');
4
+ var fs3 = require('fs');
5
5
  var electron = require('electron');
6
6
  var events = require('events');
7
7
 
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var path__default = /*#__PURE__*/_interopDefault(path);
11
+ var fs3__default = /*#__PURE__*/_interopDefault(fs3);
12
+
8
13
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
14
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
15
  }) : x)(function(x) {
@@ -21,11 +26,11 @@ var isDev = __EIU_IS_DEV__;
21
26
  process.platform === "win32";
22
27
  process.platform === "darwin";
23
28
  process.platform === "linux";
24
- function getPathFromAppNameAsar(...path$1) {
25
- return isDev ? "DEV.asar" : path.join(path.dirname(electron.app.getAppPath()), `${electron.app.name}.asar`, ...path$1);
29
+ function getPathFromAppNameAsar(...paths) {
30
+ return isDev ? "DEV.asar" : path__default.default.join(path__default.default.dirname(electron.app.getAppPath()), `${electron.app.name}.asar`, ...paths);
26
31
  }
27
32
  function getAppVersion() {
28
- return isDev ? getEntryVersion() : fs.readFileSync(getPathFromAppNameAsar("version"), "utf-8");
33
+ return isDev ? getEntryVersion() : fs3__default.default.readFileSync(getPathFromAppNameAsar("version"), "utf-8");
29
34
  }
30
35
  function getEntryVersion() {
31
36
  return electron.app.getVersion();
@@ -167,14 +172,14 @@ var Updater = class extends events.EventEmitter {
167
172
  }
168
173
  this.logger?.debug("verify start");
169
174
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
170
- this.err("download failed", "validate", "invalid signature / certificate pair");
175
+ this.err("download failed", "validate", "invalid update asar file");
171
176
  return false;
172
177
  }
173
178
  this.logger?.debug("verify success");
174
179
  try {
175
180
  const tmpFilePath = getPathFromAppNameAsar() + ".tmp";
176
181
  this.logger?.debug(`install to ${tmpFilePath}`);
177
- fs.writeFileSync(tmpFilePath, await this.provider.unzipFile(buffer));
182
+ fs3__default.default.writeFileSync(tmpFilePath, await this.provider.unzipFile(buffer));
178
183
  this.logger?.info(`download success, version: ${_version}`);
179
184
  this.info = void 0;
180
185
  this.emit("update-downloaded");
@@ -241,12 +246,12 @@ async function initApp(appOptions) {
241
246
  try {
242
247
  const appNameAsarPath = getPathFromAppNameAsar();
243
248
  const tempAsarPath = `${appNameAsarPath}.tmp`;
244
- if (fs.existsSync(tempAsarPath)) {
249
+ if (fs3__default.default.existsSync(tempAsarPath)) {
245
250
  logger?.info(`installing new asar: ${tempAsarPath}`);
246
- await onInstall(() => fs.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
251
+ await onInstall(() => fs3__default.default.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
247
252
  }
248
- const mainFilePath = path.join(
249
- isDev ? path.join(electron.app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
253
+ const mainFilePath = path__default.default.join(
254
+ isDev ? path__default.default.join(electron.app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
250
255
  "main",
251
256
  __EIU_MAIN_FILE__
252
257
  );
@@ -0,0 +1,78 @@
1
+ import { U as Updater, a as UpdaterOption, L as Logger } from './core-ZUlLHadf.cjs';
2
+ export { C as CheckResult, D as DownloadResult, E as ErrorInfo, b as UpdaterError } from './core-ZUlLHadf.cjs';
3
+ import { I as IProvider } from './types-CItP6bL-.cjs';
4
+ import 'node:events';
5
+ import '@subframe7536/type-utils';
6
+
7
+ type Promisable<T> = T | Promise<T>;
8
+ /**
9
+ * hooks on rename temp asar path to `${app.name}.asar`
10
+ * @param install `() => renameSync(tempAsarPath, appNameAsarPath)`
11
+ * @param tempAsarPath temp(updated) asar path
12
+ * @param appNameAsarPath `${app.name}.asar` path
13
+ * @param logger logger
14
+ * @default install(); logger.info(`update success!`)
15
+ */
16
+ type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
17
+ interface AppOption {
18
+ /**
19
+ * update provider
20
+ */
21
+ provider: IProvider;
22
+ /**
23
+ * updater options
24
+ */
25
+ updater?: (() => Promisable<Updater>) | UpdaterOption;
26
+ /**
27
+ * hooks on rename temp asar path to `${app.name}.asar`
28
+ */
29
+ onInstall?: OnInstallFunction;
30
+ /**
31
+ * hooks before app start up
32
+ * @param mainFilePath main file path of `${app.name}.asar`
33
+ * @param logger logger
34
+ */
35
+ beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>;
36
+ /**
37
+ * hooks on app start up error
38
+ * @param err installing or startup error
39
+ * @param logger logger
40
+ */
41
+ onStartError?: (err: unknown, logger?: Logger) => void;
42
+ }
43
+ /**
44
+ * utils for startuping with updater
45
+ * @param fn startup function
46
+ * @example
47
+ * // in electron/main/index.ts
48
+ * export default startupWithUpdater((updater) => {
49
+ * updater.checkUpdate()
50
+ * })
51
+ */
52
+ declare function startupWithUpdater(fn: (updater: Updater) => Promisable<void>): (updater: Updater) => Promisable<void>;
53
+ /**
54
+ * initialize app
55
+ * @example
56
+ * ```ts
57
+ * import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
58
+ * import { repository } from '../package.json'
59
+ *
60
+ * const { cdnPrefix: asarPrefix } = getGithubReleaseCdnGroup()[0]
61
+ * const { cdnPrefix: jsonPrefix } = getGithubFileCdnGroup()[0]
62
+ *
63
+ * initApp({
64
+ * // can be updater option or function that return updater
65
+ * updater: {
66
+ * SIGNATURE_CERT: 'custom certificate',
67
+ * repository,
68
+ * updateJsonURL: parseGithubCdnURL(repository, jsonPrefix, 'version.json'),
69
+ * releaseAsarURL: parseGithubCdnURL(repository, asarPrefix, `download/latest/${app.name}.asar.gz`),
70
+ * receiveBeta: true,
71
+ * },
72
+ * onStart: console.log
73
+ * })
74
+ * ```
75
+ */
76
+ declare function initApp(appOptions: AppOption): Promise<void>;
77
+
78
+ export { type AppOption, Logger, Updater, UpdaterOption, initApp, startupWithUpdater };
@@ -0,0 +1,78 @@
1
+ import { U as Updater, a as UpdaterOption, L as Logger } from './core-DJdvtwvU.js';
2
+ export { C as CheckResult, D as DownloadResult, E as ErrorInfo, b as UpdaterError } from './core-DJdvtwvU.js';
3
+ import { I as IProvider } from './types-CItP6bL-.js';
4
+ import 'node:events';
5
+ import '@subframe7536/type-utils';
6
+
7
+ type Promisable<T> = T | Promise<T>;
8
+ /**
9
+ * hooks on rename temp asar path to `${app.name}.asar`
10
+ * @param install `() => renameSync(tempAsarPath, appNameAsarPath)`
11
+ * @param tempAsarPath temp(updated) asar path
12
+ * @param appNameAsarPath `${app.name}.asar` path
13
+ * @param logger logger
14
+ * @default install(); logger.info(`update success!`)
15
+ */
16
+ type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
17
+ interface AppOption {
18
+ /**
19
+ * update provider
20
+ */
21
+ provider: IProvider;
22
+ /**
23
+ * updater options
24
+ */
25
+ updater?: (() => Promisable<Updater>) | UpdaterOption;
26
+ /**
27
+ * hooks on rename temp asar path to `${app.name}.asar`
28
+ */
29
+ onInstall?: OnInstallFunction;
30
+ /**
31
+ * hooks before app start up
32
+ * @param mainFilePath main file path of `${app.name}.asar`
33
+ * @param logger logger
34
+ */
35
+ beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>;
36
+ /**
37
+ * hooks on app start up error
38
+ * @param err installing or startup error
39
+ * @param logger logger
40
+ */
41
+ onStartError?: (err: unknown, logger?: Logger) => void;
42
+ }
43
+ /**
44
+ * utils for startuping with updater
45
+ * @param fn startup function
46
+ * @example
47
+ * // in electron/main/index.ts
48
+ * export default startupWithUpdater((updater) => {
49
+ * updater.checkUpdate()
50
+ * })
51
+ */
52
+ declare function startupWithUpdater(fn: (updater: Updater) => Promisable<void>): (updater: Updater) => Promisable<void>;
53
+ /**
54
+ * initialize app
55
+ * @example
56
+ * ```ts
57
+ * import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
58
+ * import { repository } from '../package.json'
59
+ *
60
+ * const { cdnPrefix: asarPrefix } = getGithubReleaseCdnGroup()[0]
61
+ * const { cdnPrefix: jsonPrefix } = getGithubFileCdnGroup()[0]
62
+ *
63
+ * initApp({
64
+ * // can be updater option or function that return updater
65
+ * updater: {
66
+ * SIGNATURE_CERT: 'custom certificate',
67
+ * repository,
68
+ * updateJsonURL: parseGithubCdnURL(repository, jsonPrefix, 'version.json'),
69
+ * releaseAsarURL: parseGithubCdnURL(repository, asarPrefix, `download/latest/${app.name}.asar.gz`),
70
+ * receiveBeta: true,
71
+ * },
72
+ * onStart: console.log
73
+ * })
74
+ * ```
75
+ */
76
+ declare function initApp(appOptions: AppOption): Promise<void>;
77
+
78
+ export { type AppOption, Logger, Updater, UpdaterOption, initApp, startupWithUpdater };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { isDev, getEntryVersion, getAppVersion, getPathFromAppNameAsar, restartApp } from './chunk-DFNDKSE6.js';
1
+ import { isDev, getEntryVersion, getAppVersion, getPathFromAppNameAsar, restartApp } from './chunk-4MH6ZXCY.js';
2
2
  import { isUpdateJSON, __require } from './chunk-72ZAJ7AF.js';
3
- import { join } from 'node:path';
4
- import { writeFileSync, existsSync, renameSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import fs2 from 'node:fs';
5
5
  import { app } from 'electron';
6
6
  import { EventEmitter } from 'node:events';
7
7
 
@@ -137,14 +137,14 @@ var Updater = class extends EventEmitter {
137
137
  }
138
138
  this.logger?.debug("verify start");
139
139
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
140
- this.err("download failed", "validate", "invalid signature / certificate pair");
140
+ this.err("download failed", "validate", "invalid update asar file");
141
141
  return false;
142
142
  }
143
143
  this.logger?.debug("verify success");
144
144
  try {
145
145
  const tmpFilePath = getPathFromAppNameAsar() + ".tmp";
146
146
  this.logger?.debug(`install to ${tmpFilePath}`);
147
- writeFileSync(tmpFilePath, await this.provider.unzipFile(buffer));
147
+ fs2.writeFileSync(tmpFilePath, await this.provider.unzipFile(buffer));
148
148
  this.logger?.info(`download success, version: ${_version}`);
149
149
  this.info = void 0;
150
150
  this.emit("update-downloaded");
@@ -211,12 +211,12 @@ async function initApp(appOptions) {
211
211
  try {
212
212
  const appNameAsarPath = getPathFromAppNameAsar();
213
213
  const tempAsarPath = `${appNameAsarPath}.tmp`;
214
- if (existsSync(tempAsarPath)) {
214
+ if (fs2.existsSync(tempAsarPath)) {
215
215
  logger?.info(`installing new asar: ${tempAsarPath}`);
216
- await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
216
+ await onInstall(() => fs2.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
217
217
  }
218
- const mainFilePath = join(
219
- isDev ? join(app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
218
+ const mainFilePath = path.join(
219
+ isDev ? path.join(app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
220
220
  "main",
221
221
  __EIU_MAIN_FILE__
222
222
  );