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.
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  restartApp,
9
9
  unzipFile,
10
10
  waitAppReady
11
- } from "./chunk-CXHA5TF7.js";
11
+ } from "./chunk-RQCTJY4L.js";
12
12
 
13
13
  // src/index.ts
14
14
  import { resolve } from "node:path";
@@ -16,8 +16,7 @@ import { existsSync as existsSync2, renameSync } from "node:fs";
16
16
  import { app as app2 } from "electron";
17
17
 
18
18
  // src/updater/core.ts
19
- import { existsSync } from "node:fs";
20
- import { rm, writeFile } from "node:fs/promises";
19
+ import { existsSync, rmSync, writeFileSync } from "node:fs";
21
20
  import { app } from "electron";
22
21
 
23
22
  // src/crypto/dec.ts
@@ -164,6 +163,7 @@ var compareVersionDefault = (version1, version2) => {
164
163
 
165
164
  // src/updater/core.ts
166
165
  var Updater = class {
166
+ CERT = __SIGNATURE_CERT__;
167
167
  info;
168
168
  option;
169
169
  asarPath;
@@ -195,8 +195,11 @@ var Updater = class {
195
195
  * initialize incremental updater
196
196
  * @param option UpdaterOption
197
197
  */
198
- constructor(option) {
198
+ constructor(option = {}) {
199
199
  this.option = option;
200
+ if (option.SIGNATURE_CERT) {
201
+ this.CERT = option.SIGNATURE_CERT;
202
+ }
200
203
  this.asarPath = getPathFromAppNameAsar();
201
204
  this.gzipPath = `${this.asarPath}.gz`;
202
205
  this.tmpFilePath = `${this.asarPath}.tmp`;
@@ -213,11 +216,11 @@ var Updater = class {
213
216
  async parseData(format, data) {
214
217
  if (existsSync(this.tmpFilePath)) {
215
218
  this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
216
- await rm(this.tmpFilePath);
219
+ rmSync(this.tmpFilePath);
217
220
  }
218
221
  if (existsSync(this.gzipPath)) {
219
222
  this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
220
- await rm(this.gzipPath);
223
+ rmSync(this.gzipPath);
221
224
  }
222
225
  if (!["string", "object", "undefined"].includes(typeof data)) {
223
226
  throw new TypeError(`invalid type at format '${format}': ${data}`);
@@ -323,13 +326,13 @@ var Updater = class {
323
326
  const buffer = await this.parseData("buffer", data);
324
327
  this.logger?.info("verify start");
325
328
  const _verify = this.option.overrideFunctions?.verifySignaure ?? verify;
326
- const _ver = await _verify(buffer, _sig, this.option.SIGNATURE_CERT);
329
+ const _ver = await _verify(buffer, _sig, this.CERT);
327
330
  if (!_ver) {
328
- throw new VerifyFailedError(_sig, this.option.SIGNATURE_CERT);
331
+ throw new VerifyFailedError(_sig, this.CERT);
329
332
  }
330
333
  this.logger?.info("verify success");
331
334
  this.logger?.info(`write to ${this.gzipPath}`);
332
- await writeFile(this.gzipPath, buffer);
335
+ writeFileSync(this.gzipPath, buffer);
333
336
  this.logger?.info(`extract to ${this.tmpFilePath}`);
334
337
  await unzipFile(this.gzipPath, this.tmpFilePath);
335
338
  this.logger?.info(`download success, version: ${_ver}`);
@@ -362,8 +365,9 @@ var defaultOnInstall = (install, _, __, logger) => {
362
365
  install();
363
366
  logger?.info(`update success!`);
364
367
  };
365
- function initApp(appOptions) {
368
+ async function initApp(appOptions = {}) {
366
369
  const {
370
+ updater,
367
371
  electronDevDistPath = "../dist-electron",
368
372
  mainPath = "main/index.js",
369
373
  hooks
@@ -373,43 +377,32 @@ function initApp(appOptions) {
373
377
  beforeStart,
374
378
  onStartError
375
379
  } = hooks || {};
376
- function handleError(err, logger) {
380
+ function handleError(err, logger2) {
377
381
  console.error(err);
378
- onStartError?.(err, logger);
382
+ onStartError?.(err, logger2);
379
383
  app2.quit();
380
384
  }
381
- async function startup(updater) {
382
- const logger = updater.logger;
383
- try {
384
- const appNameAsarPath = getPathFromAppNameAsar();
385
- const tempAsarPath = `${appNameAsarPath}.tmp`;
386
- if (existsSync2(tempAsarPath)) {
387
- logger?.info(`installing new asar: ${tempAsarPath}`);
388
- await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
389
- }
390
- const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
391
- const entry = resolve(__dirname, mainDir, mainPath);
392
- await beforeStart?.(entry, logger);
393
- __require(entry)(updater);
394
- } catch (error) {
395
- handleError(error, logger);
396
- }
385
+ let updaterInstance;
386
+ if (typeof updater === "object" || !updater) {
387
+ updaterInstance = createUpdater(updater);
388
+ } else {
389
+ updaterInstance = await updater();
397
390
  }
398
- let timer = setTimeout(() => {
399
- handleError("start app timeout, please start app with `initApp(options).startupWithUpdater(options)`");
400
- }, 3e3);
401
- return {
402
- async startupWithUpdater(updater) {
403
- clearTimeout(timer);
404
- if (typeof updater === "object") {
405
- await startup(createUpdater(updater));
406
- } else if (typeof updater === "function") {
407
- await startup(await updater());
408
- } else {
409
- handleError("invalid updater option or updater is not a function");
410
- }
391
+ const logger = updaterInstance.logger;
392
+ try {
393
+ const appNameAsarPath = getPathFromAppNameAsar();
394
+ const tempAsarPath = `${appNameAsarPath}.tmp`;
395
+ if (existsSync2(tempAsarPath)) {
396
+ logger?.info(`installing new asar: ${tempAsarPath}`);
397
+ await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
411
398
  }
412
- };
399
+ const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
400
+ const entry = resolve(__dirname, mainDir, mainPath);
401
+ await beforeStart?.(entry, logger);
402
+ __require(entry)(updaterInstance);
403
+ } catch (error) {
404
+ handleError(error, logger);
405
+ }
413
406
  }
414
407
  export {
415
408
  DownloadError,
package/dist/utils.cjs CHANGED
@@ -148,14 +148,14 @@ function getPaths(entryDirName = "dist-entry") {
148
148
  return (0, import_node_path.join)(import_electron.app.getAppPath(), entryDirName, ...paths);
149
149
  },
150
150
  /**
151
- * get path inside `${app.name}.asar/main`
151
+ * get path inside `${electron.app.name}.asar/main`
152
152
  * @param paths joined path
153
153
  */
154
154
  getPathFromMain(...paths) {
155
155
  return (0, import_node_path.join)(mainDirPath, ...paths);
156
156
  },
157
157
  /**
158
- * get path inside `${app.name}.asar/preload`
158
+ * get path inside `${electron.app.name}.asar/preload`
159
159
  * @param paths joined path
160
160
  */
161
161
  getPathFromPreload(...paths) {
@@ -180,7 +180,7 @@ async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
180
180
  }
181
181
  const compressedBuffer = (0, import_node_fs2.readFileSync)(gzipPath);
182
182
  return new Promise((resolve, reject) => {
183
- (0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
183
+ (0, import_node_zlib.brotliDecompress)(compressedBuffer, (err, buffer) => {
184
184
  (0, import_node_fs2.rmSync)(gzipPath);
185
185
  if (err) {
186
186
  reject(err);
@@ -196,7 +196,7 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
196
196
  }
197
197
  const buffer = (0, import_node_fs2.readFileSync)(filePath);
198
198
  return new Promise((resolve, reject) => {
199
- (0, import_node_zlib.gzip)(buffer, (err, buffer2) => {
199
+ (0, import_node_zlib.brotliCompress)(buffer, (err, buffer2) => {
200
200
  if (err) {
201
201
  reject(err);
202
202
  }
package/dist/utils.d.cts CHANGED
@@ -19,7 +19,7 @@ declare function getPathFromAppNameAsar(...path: string[]): string;
19
19
  /**
20
20
  * get versions of App, Entry, Electron, Node and System
21
21
  *
22
- * App version is read from `version` file in `${app.name}.asar`
22
+ * App version is read from `version` file in `${electron.app.name}.asar`
23
23
  *
24
24
  * Entry version is read from `package.json`
25
25
  *
@@ -54,7 +54,7 @@ declare function loadNativeModuleFromEntry(devEntryDirPath?: string, entryDirPat
54
54
  declare function restartApp(): void;
55
55
  /**
56
56
  * fix app use model id, only for Windows
57
- * @param id app id @default `org.${app.name}`
57
+ * @param id app id @default `org.${electron.app.name}`
58
58
  */
59
59
  declare function setAppUserModelId(id?: string): void;
60
60
  /**
@@ -104,12 +104,12 @@ declare function getPaths(entryDirName?: string): {
104
104
  */
105
105
  getPathFromEntryAsar(...paths: string[]): string;
106
106
  /**
107
- * get path inside `${app.name}.asar/main`
107
+ * get path inside `${electron.app.name}.asar/main`
108
108
  * @param paths joined path
109
109
  */
110
110
  getPathFromMain(...paths: string[]): string;
111
111
  /**
112
- * get path inside `${app.name}.asar/preload`
112
+ * get path inside `${electron.app.name}.asar/preload`
113
113
  * @param paths joined path
114
114
  */
115
115
  getPathFromPreload(...paths: string[]): string;
package/dist/utils.d.ts CHANGED
@@ -19,7 +19,7 @@ declare function getPathFromAppNameAsar(...path: string[]): string;
19
19
  /**
20
20
  * get versions of App, Entry, Electron, Node and System
21
21
  *
22
- * App version is read from `version` file in `${app.name}.asar`
22
+ * App version is read from `version` file in `${electron.app.name}.asar`
23
23
  *
24
24
  * Entry version is read from `package.json`
25
25
  *
@@ -54,7 +54,7 @@ declare function loadNativeModuleFromEntry(devEntryDirPath?: string, entryDirPat
54
54
  declare function restartApp(): void;
55
55
  /**
56
56
  * fix app use model id, only for Windows
57
- * @param id app id @default `org.${app.name}`
57
+ * @param id app id @default `org.${electron.app.name}`
58
58
  */
59
59
  declare function setAppUserModelId(id?: string): void;
60
60
  /**
@@ -104,12 +104,12 @@ declare function getPaths(entryDirName?: string): {
104
104
  */
105
105
  getPathFromEntryAsar(...paths: string[]): string;
106
106
  /**
107
- * get path inside `${app.name}.asar/main`
107
+ * get path inside `${electron.app.name}.asar/main`
108
108
  * @param paths joined path
109
109
  */
110
110
  getPathFromMain(...paths: string[]): string;
111
111
  /**
112
- * get path inside `${app.name}.asar/preload`
112
+ * get path inside `${electron.app.name}.asar/preload`
113
113
  * @param paths joined path
114
114
  */
115
115
  getPathFromPreload(...paths: string[]): string;
package/dist/utils.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  unzipFile,
17
17
  waitAppReady,
18
18
  zipFile
19
- } from "./chunk-CXHA5TF7.js";
19
+ } from "./chunk-RQCTJY4L.js";
20
20
  export {
21
21
  disableHWAccForWin7,
22
22
  getPathFromAppNameAsar,
package/dist/vite.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as vite from 'vite';
2
1
  import { Plugin } from 'vite';
3
2
  import { ElectronSimpleOptions } from 'vite-plugin-electron/simple';
4
3
  import { Promisable } from '@subframe7536/type-utils';
@@ -81,6 +80,9 @@ type BuildEntryOption = {
81
80
  * loader: {
82
81
  * '.node': 'empty',
83
82
  * },
83
+ * define: {
84
+ * __SIGNATURE_CERT__: JSON.stringify(cert),
85
+ * },
84
86
  * }
85
87
  * ```
86
88
  */
@@ -220,6 +222,17 @@ type ElectronUpdaterOptions = {
220
222
  };
221
223
  };
222
224
 
225
+ type BytecodeOptions = {
226
+ /**
227
+ * strings that should be transformed
228
+ */
229
+ protectedStrings?: string[];
230
+ /**
231
+ * Remember to set `sandbox: false` when creating window
232
+ */
233
+ enablePreload?: boolean;
234
+ };
235
+
223
236
  type MakeRequired<T, K extends keyof T> = Exclude<T, undefined> & {
224
237
  [P in K]-?: T[P];
225
238
  };
@@ -254,7 +267,7 @@ type ElectronWithUpdaterOptions = {
254
267
  */
255
268
  isBuild: boolean;
256
269
  /**
257
- * manullay setup package.json, read name, version and main
270
+ * manually setup package.json, read name, version and main
258
271
  * ```ts
259
272
  * import pkg from './package.json'
260
273
  * ```
@@ -262,12 +275,22 @@ type ElectronWithUpdaterOptions = {
262
275
  pkg?: PKG;
263
276
  /**
264
277
  * whether to generate sourcemap
278
+ * @default !isBuild
265
279
  */
266
280
  sourcemap?: boolean;
267
281
  /**
268
282
  * whether to minify the code
283
+ * @default isBuild
269
284
  */
270
285
  minify?: boolean;
286
+ /**
287
+ * whether to generate bytecode
288
+ *
289
+ * **only support commonjs**
290
+ *
291
+ * only main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
292
+ */
293
+ bytecode?: boolean | BytecodeOptions;
271
294
  /**
272
295
  * use NotBundle() plugin in main
273
296
  * @default true
@@ -275,8 +298,12 @@ type ElectronWithUpdaterOptions = {
275
298
  useNotBundle?: boolean;
276
299
  /**
277
300
  * Whether to log parsed options
301
+ *
302
+ * to show certificate and private keys, set `logParsedOptions: { showKeys: true }`
278
303
  */
279
- logParsedOptions?: boolean;
304
+ logParsedOptions?: boolean | {
305
+ showKeys: boolean;
306
+ };
280
307
  /**
281
308
  * main options
282
309
  */
@@ -290,7 +317,6 @@ type ElectronWithUpdaterOptions = {
290
317
  */
291
318
  updater?: ElectronUpdaterOptions;
292
319
  };
293
- declare const log: vite.Logger;
294
320
  /**
295
321
  * build options for `vite-plugin-electron/simple`
296
322
  * - integrate with updater
@@ -341,6 +367,6 @@ declare const log: vite.Logger;
341
367
  * }
342
368
  * })
343
369
  */
344
- declare function electronWithUpdater(options: ElectronWithUpdaterOptions): (Plugin<any> | Promise<Plugin<any>[]> | undefined)[] | null;
370
+ declare function electronWithUpdater(options: ElectronWithUpdaterOptions): Promise<(Plugin<any> | Promise<Plugin<any>[]> | undefined)[] | null>;
345
371
 
346
- export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater, log };
372
+ export { type ElectronWithUpdaterOptions, debugStartup, electronWithUpdater };