electron-incremental-update 2.0.0-beta.2 → 2.0.0-beta.3

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.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- import { EventEmitter } from 'node:stream';
2
- import { U as UpdateJSON, a as UpdateInfo } from './version-CffZWDhZ.js';
3
- import { D as DownloadingInfo, U as URLHandler, I as IProvider } from './types-CPq1MrYZ.js';
1
+ import { EventEmitter } from 'node:events';
2
+ import { U as UpdateJSON, a as UpdateInfo } from './version-CemSHimT.js';
3
+ import { D as DownloadingInfo, I as IProvider, U as URLHandler } from './types-DxhNaNgR.js';
4
4
  import '@subframe7536/type-utils';
5
5
 
6
6
  declare const ErrorInfo: {
7
7
  readonly download: "Download failed";
8
8
  readonly validate: "Validate failed";
9
9
  readonly param: "Missing params";
10
+ readonly network: "Network error";
10
11
  };
11
12
  declare class UpdaterError extends Error {
12
13
  code: keyof typeof ErrorInfo;
@@ -60,9 +61,7 @@ declare class Updater extends EventEmitter<{
60
61
  }> {
61
62
  private CERT;
62
63
  private info?;
63
- private options;
64
64
  private asarPath;
65
- private gzipPath;
66
65
  private tmpFilePath;
67
66
  private provider;
68
67
  /**
@@ -70,18 +69,13 @@ declare class Updater extends EventEmitter<{
70
69
  */
71
70
  logger?: Logger;
72
71
  /**
73
- * URL handler hook
74
- *
75
- * for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDNs}
76
- * @param url source url
77
- * @param isDownloadAsar whether is download asar
72
+ * whether to receive beta update
78
73
  */
79
- handleURL?: URLHandler;
74
+ receiveBeta?: boolean;
80
75
  /**
81
- * whether receive beta version
76
+ * whether force update in DEV
82
77
  */
83
- get receiveBeta(): boolean;
84
- set receiveBeta(receiveBeta: boolean);
78
+ forceUpdate?: boolean;
85
79
  /**
86
80
  * initialize incremental updater
87
81
  * @param provider update provider
@@ -122,11 +116,22 @@ declare class Updater extends EventEmitter<{
122
116
  * @param data existing `asar.gz` buffer
123
117
  * @param sig signature
124
118
  */
125
- download(data: Uint8Array, sig: string): Promise<boolean>;
119
+ download(data: Uint8Array | Buffer, sig: string): Promise<boolean>;
126
120
  /**
127
121
  * quit App and install
128
122
  */
129
123
  quitAndInstall(): void;
124
+ /**
125
+ * setup provider URL handler
126
+ *
127
+ * @example
128
+ * updater.setURLHandler((url, isDownloadingAsar) => {
129
+ * if (isDownloadingAsar) {
130
+ * return url.replace('https://raw.githubusercontent.com', 'https://cdn.jsdelivr.net/gh')
131
+ * }
132
+ * })
133
+ */
134
+ setURLHandler(handler: URLHandler): void;
130
135
  }
131
136
 
132
137
  type Promisable<T> = T | Promise<T>;
@@ -138,7 +143,7 @@ type Promisable<T> = T | Promise<T>;
138
143
  * @param logger logger
139
144
  * @default install(); logger.info(`update success!`)
140
145
  */
141
- type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger: Logger) => Promisable<void>;
146
+ type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
142
147
  interface AppOption {
143
148
  /**
144
149
  * update provider
@@ -157,13 +162,13 @@ interface AppOption {
157
162
  * @param mainFilePath main file path of `${app.name}.asar`
158
163
  * @param logger logger
159
164
  */
160
- beforeStart?: (mainFilePath: string, logger: Logger) => Promisable<void>;
165
+ beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>;
161
166
  /**
162
167
  * hooks on app start up error
163
168
  * @param err installing or startup error
164
169
  * @param logger logger
165
170
  */
166
- onStartError?: (err: unknown, logger: Logger) => void;
171
+ onStartError?: (err: unknown, logger?: Logger) => void;
167
172
  }
168
173
  /**
169
174
  * utils for startuping with updater
package/dist/index.js CHANGED
@@ -1,29 +1,16 @@
1
- import {
2
- __require,
3
- getAppVersion,
4
- getEntryVersion,
5
- getPathFromAppNameAsar,
6
- isDev,
7
- isUpdateJSON,
8
- restartApp,
9
- unzipFile
10
- } from "./chunk-BG22XZAB.js";
11
-
12
- // src/entry.ts
13
- import { join } from "node:path";
14
- import { existsSync as existsSync2, renameSync } from "node:fs";
15
- import { app as app2 } from "electron";
16
-
17
- // src/updater/core.ts
18
- import { existsSync, rmSync, writeFileSync } from "node:fs";
19
- import { EventEmitter } from "node:stream";
20
- import { app } from "electron";
1
+ import { isDev, getPathFromAppNameAsar, getEntryVersion, getAppVersion, restartApp } from './chunk-PNYRQYFC.js';
2
+ import { isUpdateJSON, __require } from './chunk-BVFQWBLK.js';
3
+ import { join } from 'node:path';
4
+ import { existsSync, rmSync, renameSync } from 'node:fs';
5
+ import { app } from 'electron';
6
+ import { EventEmitter } from 'node:events';
21
7
 
22
8
  // src/updater/types.ts
23
9
  var ErrorInfo = {
24
10
  download: "Download failed",
25
11
  validate: "Validate failed",
26
- param: "Missing params"
12
+ param: "Missing params",
13
+ network: "Network error"
27
14
  };
28
15
  var UpdaterError = class extends Error {
29
16
  code;
@@ -37,9 +24,7 @@ var UpdaterError = class extends Error {
37
24
  var Updater = class extends EventEmitter {
38
25
  CERT = __EIU_SIGNATURE_CERT__;
39
26
  info;
40
- options;
41
27
  asarPath;
42
- gzipPath;
43
28
  tmpFilePath;
44
29
  provider;
45
30
  /**
@@ -47,22 +32,13 @@ var Updater = class extends EventEmitter {
47
32
  */
48
33
  logger;
49
34
  /**
50
- * URL handler hook
51
- *
52
- * for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDNs}
53
- * @param url source url
54
- * @param isDownloadAsar whether is download asar
35
+ * whether to receive beta update
55
36
  */
56
- handleURL;
37
+ receiveBeta;
57
38
  /**
58
- * whether receive beta version
39
+ * whether force update in DEV
59
40
  */
60
- get receiveBeta() {
61
- return !!this.options.receiveBeta;
62
- }
63
- set receiveBeta(receiveBeta) {
64
- this.options.receiveBeta = receiveBeta;
65
- }
41
+ forceUpdate;
66
42
  /**
67
43
  * initialize incremental updater
68
44
  * @param provider update provider
@@ -71,7 +47,7 @@ var Updater = class extends EventEmitter {
71
47
  constructor(provider, option = {}) {
72
48
  super();
73
49
  this.provider = provider;
74
- this.options = option;
50
+ this.receiveBeta = option.receiveBeta;
75
51
  if (option.SIGNATURE_CERT) {
76
52
  this.CERT = option.SIGNATURE_CERT;
77
53
  }
@@ -88,7 +64,6 @@ var Updater = class extends EventEmitter {
88
64
  this.logger.info("no logger set, enable dev-only logger");
89
65
  }
90
66
  this.asarPath = getPathFromAppNameAsar();
91
- this.gzipPath = `${this.asarPath}.gz`;
92
67
  this.tmpFilePath = `${this.asarPath}.tmp`;
93
68
  }
94
69
  async fetch(format, data) {
@@ -96,10 +71,6 @@ var Updater = class extends EventEmitter {
96
71
  this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
97
72
  rmSync(this.tmpFilePath);
98
73
  }
99
- if (existsSync(this.gzipPath)) {
100
- this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
101
- rmSync(this.gzipPath);
102
- }
103
74
  if (typeof data === "object") {
104
75
  if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
105
76
  return data;
@@ -114,7 +85,7 @@ var Updater = class extends EventEmitter {
114
85
  this.logger?.debug(`download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
115
86
  return result;
116
87
  } catch (e) {
117
- this.err(`download ${format} failed`, "download", `download ${format} failed: ${e}`);
88
+ this.err(`fetch ${format} failed`, "network", `download ${format} failed: ${e}`);
118
89
  }
119
90
  }
120
91
  /**
@@ -129,11 +100,11 @@ var Updater = class extends EventEmitter {
129
100
  const emitUnavailable = (msg) => {
130
101
  this.logger?.info(msg);
131
102
  this.emit("update-unavailable", msg);
103
+ return false;
132
104
  };
133
105
  const _data = await this.fetch("json", data);
134
106
  if (!_data) {
135
- emitUnavailable("failed to get update info");
136
- return false;
107
+ return emitUnavailable("failed to get update info");
137
108
  }
138
109
  let { signature, size, version, minimumVersion, beta } = _data;
139
110
  if (this.receiveBeta) {
@@ -143,21 +114,18 @@ var Updater = class extends EventEmitter {
143
114
  size = beta.size;
144
115
  }
145
116
  this.logger?.debug(`checked update, version: ${version}, size: ${size}, signature: ${signature}`);
146
- if (isDev) {
147
- emitUnavailable("in dev mode, skip check update");
148
- return false;
117
+ if (isDev && !this.forceUpdate && !data) {
118
+ return emitUnavailable("skip check update in dev mode, to force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON");
149
119
  }
150
120
  const isLowerVersion = this.provider.isLowerVersion;
151
121
  const entryVersion = getEntryVersion();
152
122
  const appVersion = getAppVersion();
153
123
  if (isLowerVersion(entryVersion, minimumVersion)) {
154
- emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
155
- return false;
124
+ return emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
156
125
  }
157
126
  this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
158
127
  if (!isLowerVersion(appVersion, version)) {
159
- emitUnavailable(`current version (${appVersion}) < new version (${version})`);
160
- return false;
128
+ return emitUnavailable(`current version (${appVersion}) < new version (${version})`);
161
129
  }
162
130
  this.logger?.info(`update available: ${version}`);
163
131
  this.info = { signature, minimumVersion, version, size };
@@ -165,11 +133,11 @@ var Updater = class extends EventEmitter {
165
133
  return true;
166
134
  }
167
135
  async download(data, sig) {
168
- if (!this.info) {
169
- this.err("download failed", "param", "no update info, call `checkUpdate` first");
136
+ const _sig = sig ?? this.info?.signature;
137
+ if (!_sig) {
138
+ this.err("download failed", "param", "no update signature, please call `checkUpdate` first");
170
139
  return false;
171
140
  }
172
- const _sig = sig ?? this.info.signature;
173
141
  const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
174
142
  if (!buffer) {
175
143
  this.err("download failed", "param", "no update asar file buffer");
@@ -178,21 +146,19 @@ var Updater = class extends EventEmitter {
178
146
  this.logger?.debug("verify start");
179
147
  const _ver = await this.provider.verifySignaure(buffer, _sig, this.CERT);
180
148
  if (!_ver) {
181
- this.err("verify failed", "validate", "invalid signature / certificate pair");
149
+ this.err("download failed", "validate", "invalid signature / certificate pair");
182
150
  return false;
183
151
  }
184
152
  this.logger?.debug("verify success");
185
153
  try {
186
- this.logger?.debug(`write to ${this.gzipPath}`);
187
- writeFileSync(this.gzipPath, buffer);
188
154
  this.logger?.debug(`extract to ${this.tmpFilePath}`);
189
- await unzipFile(this.gzipPath, this.tmpFilePath);
155
+ await this.provider.unzipFile(buffer, this.tmpFilePath);
190
156
  this.logger?.info(`download success, version: ${_ver}`);
191
157
  this.info = void 0;
192
158
  this.emit("update-downloaded");
193
159
  return true;
194
160
  } catch (error) {
195
- this.err("unwrap asar failed", "download", `fail to unwrap asar file, ${error}`);
161
+ this.err("download failed", "download", `fail to unwrap asar file, ${error}`);
196
162
  return false;
197
163
  }
198
164
  }
@@ -203,6 +169,19 @@ var Updater = class extends EventEmitter {
203
169
  this.logger?.info("quit and install");
204
170
  restartApp();
205
171
  }
172
+ /**
173
+ * setup provider URL handler
174
+ *
175
+ * @example
176
+ * updater.setURLHandler((url, isDownloadingAsar) => {
177
+ * if (isDownloadingAsar) {
178
+ * return url.replace('https://raw.githubusercontent.com', 'https://cdn.jsdelivr.net/gh')
179
+ * }
180
+ * })
181
+ */
182
+ setURLHandler(handler) {
183
+ this.provider.urlHandler = handler;
184
+ }
206
185
  };
207
186
 
208
187
  // src/entry.ts
@@ -211,7 +190,7 @@ function startupWithUpdater(fn) {
211
190
  }
212
191
  var defaultOnInstall = (install, _, __, logger) => {
213
192
  install();
214
- logger.info(`update success!`);
193
+ logger?.info(`update success!`);
215
194
  };
216
195
  async function initApp(appOptions) {
217
196
  const {
@@ -227,31 +206,34 @@ async function initApp(appOptions) {
227
206
  } else {
228
207
  updaterInstance = await updater();
229
208
  }
230
- const logger = updaterInstance.logger || console;
209
+ let logger = updaterInstance.logger;
210
+ if (isDev && !logger) {
211
+ logger = {
212
+ info: (...args) => console.log("[EIU-INFO ]", ...args),
213
+ debug: (...args) => console.log("[EIU-DEBUG]", ...args),
214
+ warn: (...args) => console.log("[EIU-WARN ]", ...args),
215
+ error: (...args) => console.error("[EIU-ERROR]", ...args)
216
+ };
217
+ }
231
218
  try {
232
219
  const appNameAsarPath = getPathFromAppNameAsar();
233
220
  const tempAsarPath = `${appNameAsarPath}.tmp`;
234
- if (existsSync2(tempAsarPath)) {
235
- logger.info(`installing new asar: ${tempAsarPath}`);
221
+ if (existsSync(tempAsarPath)) {
222
+ logger?.info(`installing new asar: ${tempAsarPath}`);
236
223
  await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
237
224
  }
238
225
  const mainFilePath = join(
239
- isDev ? join(app2.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
226
+ isDev ? join(app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
240
227
  "main",
241
228
  __EIU_MAIN_FILE__
242
229
  );
243
230
  await beforeStart?.(mainFilePath, logger);
244
231
  __require(mainFilePath)(updaterInstance);
245
232
  } catch (error) {
246
- logger.error("startup error", error);
233
+ logger?.error("startup error", error);
247
234
  onStartError?.(error, logger);
248
- app2.quit();
235
+ app.quit();
249
236
  }
250
237
  }
251
- export {
252
- ErrorInfo,
253
- Updater,
254
- UpdaterError,
255
- initApp,
256
- startupWithUpdater
257
- };
238
+
239
+ export { ErrorInfo, Updater, UpdaterError, initApp, startupWithUpdater };
package/dist/provider.cjs CHANGED
@@ -1,58 +1,11 @@
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);
1
+ 'use strict';
19
2
 
20
- // src/provider/index.ts
21
- var provider_exports = {};
22
- __export(provider_exports, {
23
- GitHubProvider: () => GitHubProvider,
24
- downloadAsarBufferDefault: () => downloadAsarBufferDefault,
25
- downloadUpdateJSONDefault: () => downloadUpdateJSONDefault
26
- });
27
- module.exports = __toCommonJS(provider_exports);
3
+ var electron = require('electron');
4
+ var crypto = require('crypto');
5
+ var fs = require('fs');
6
+ var zlib = require('zlib');
28
7
 
29
- // src/utils/electron.ts
30
- var import_node_fs = require("fs");
31
- var import_node_path = require("path");
32
- var import_electron = require("electron");
33
- var isDev = __EIU_IS_DEV__;
34
- var isWin = process.platform === "win32";
35
- var isMac = process.platform === "darwin";
36
- var isLinux = process.platform === "linux";
37
- function waitAppReady(timeout = 1e3) {
38
- return import_electron.app.isReady() ? Promise.resolve() : new Promise((resolve, reject) => {
39
- const _ = setTimeout(() => {
40
- reject(new Error("app is not ready"));
41
- }, timeout);
42
- import_electron.app.whenReady().then(() => {
43
- clearTimeout(_);
44
- resolve();
45
- });
46
- });
47
- }
48
-
49
- // src/utils/zip.ts
50
- var import_node_fs2 = require("fs");
51
- var import_node_zlib = require("zlib");
52
-
53
- // src/utils/unzip.ts
54
- var import_node_fs3 = require("fs");
55
- var import_node_zlib2 = require("zlib");
8
+ // src/provider/download.ts
56
9
 
57
10
  // src/utils/version.ts
58
11
  function parseVersion(version) {
@@ -78,7 +31,7 @@ function parseVersion(version) {
78
31
  }
79
32
  return ret;
80
33
  }
81
- function isLowerVersionDefault(oldVer, newVer) {
34
+ function defaultIsLowerVersion(oldVer, newVer) {
82
35
  const oldV = parseVersion(oldVer);
83
36
  const newV = parseVersion(newVer);
84
37
  function compareStrings(str1, str2) {
@@ -103,42 +56,11 @@ function isUpdateJSON(json) {
103
56
  return is(json) && is(json?.beta);
104
57
  }
105
58
 
106
- // src/utils/crypto/decrypt.ts
107
- var import_node_crypto2 = require("crypto");
108
-
109
- // src/utils/crypto/utils.ts
110
- var import_node_crypto = require("crypto");
111
- function hashString(data, length) {
112
- const hash = (0, import_node_crypto.createHash)("SHA256").update(data).digest("binary");
113
- return Buffer.from(hash).subarray(0, length);
114
- }
115
-
116
- // src/utils/crypto/decrypt.ts
117
- function decrypt(encryptedText, key, iv) {
118
- const decipher = (0, import_node_crypto2.createDecipheriv)("aes-256-cbc", key, iv);
119
- let decrypted = decipher.update(encryptedText, "base64url", "utf8");
120
- decrypted += decipher.final("utf8");
121
- return decrypted;
122
- }
123
- function verifySignatureDefault(buffer, signature, cert) {
124
- try {
125
- const [sig, version] = decrypt(signature, hashString(cert, 32), hashString(buffer, 16)).split("%");
126
- const result = (0, import_node_crypto2.createVerify)("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
127
- return result ? version : void 0;
128
- } catch {
129
- return void 0;
130
- }
131
- }
132
-
133
- // src/utils/crypto/encrypt.ts
134
- var import_node_crypto3 = require("crypto");
135
-
136
59
  // src/provider/download.ts
137
- var import_electron2 = require("electron");
138
- async function downlaodFn(url, headers, onResponse) {
139
- await waitAppReady();
60
+ async function downloadFn(url, headers, onResponse) {
61
+ await electron.app.whenReady();
140
62
  return new Promise((resolve, reject) => {
141
- const request = import_electron2.net.request({ url, method: "GET", redirect: "follow" });
63
+ const request = electron.net.request({ url, method: "GET", redirect: "follow" });
142
64
  Object.keys(headers).forEach((key) => request.setHeader(key, headers[key]));
143
65
  request.on("response", (resp) => {
144
66
  resp.on("aborted", () => reject(new Error("aborted")));
@@ -149,8 +71,8 @@ async function downlaodFn(url, headers, onResponse) {
149
71
  request.end();
150
72
  });
151
73
  }
152
- async function downloadUpdateJSONDefault(url, headers) {
153
- return await downlaodFn(url, headers, (resp, resolve, reject) => {
74
+ async function defaultDownloadUpdateJSON(url, headers) {
75
+ return await downloadFn(url, headers, (resp, resolve, reject) => {
154
76
  let data = "";
155
77
  resp.on("data", (chunk) => data += chunk);
156
78
  resp.on("end", () => {
@@ -167,10 +89,10 @@ async function downloadUpdateJSONDefault(url, headers) {
167
89
  });
168
90
  });
169
91
  }
170
- async function downloadAsarBufferDefault(url, headers, total, onDownloading) {
92
+ async function defaultDownloadAsar(url, headers, total, onDownloading) {
171
93
  let transferred = 0;
172
94
  let time = Date.now();
173
- return await downlaodFn(url, headers, (resp, resolve) => {
95
+ return await downloadFn(url, headers, (resp, resolve) => {
174
96
  let data = [];
175
97
  resp.on("data", (chunk) => {
176
98
  transferred += chunk.length;
@@ -188,49 +110,93 @@ async function downloadAsarBufferDefault(url, headers, total, onDownloading) {
188
110
  resp.on("end", () => resolve(Buffer.concat(data)));
189
111
  });
190
112
  }
113
+ function hashBuffer(data, length) {
114
+ const hash = crypto.createHash("SHA256").update(data).digest("binary");
115
+ return Buffer.from(hash).subarray(0, length);
116
+ }
117
+ function aesDecrypt(encryptedText, key, iv) {
118
+ const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
119
+ return decipher.update(encryptedText, "base64url", "utf8") + decipher.final("utf8");
120
+ }
121
+ function defaultVerify(buffer, signature, cert) {
122
+ try {
123
+ const [sig, version] = aesDecrypt(signature, hashBuffer(cert, 32), hashBuffer(buffer, 16)).split("%");
124
+ const result = crypto.createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
125
+ return result ? version : void 0;
126
+ } catch {
127
+ return void 0;
128
+ }
129
+ }
130
+ async function defaultUnzipFile(buffer, targetFilePath) {
131
+ return new Promise((resolve, reject) => {
132
+ zlib.brotliDecompress(buffer, (err, buffer2) => {
133
+ if (err) {
134
+ reject(err);
135
+ }
136
+ fs.writeFileSync(targetFilePath, buffer2);
137
+ resolve();
138
+ });
139
+ });
140
+ }
141
+
142
+ // src/provider/base.ts
143
+ var BaseProvider = class {
144
+ name = "BaseProvider";
145
+ isLowerVersion = defaultIsLowerVersion;
146
+ verifySignaure = defaultVerify;
147
+ unzipFile = defaultUnzipFile;
148
+ };
191
149
 
192
150
  // src/provider/github.ts
193
- var GitHubProvider = class {
151
+ var GitHubProvider = class extends BaseProvider {
194
152
  ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
195
153
  name = "GithubProvider";
196
154
  urlHandler;
197
155
  url;
198
156
  extraHeaders;
157
+ /**
158
+ * Update Provider for Github repo
159
+ * - download update json from `https://raw.githubusercontent.com/{user}/{repo}/HEAD/{versionPath}`
160
+ * - download update asar from `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
161
+ *
162
+ * you can setup `urlHandler` in {@link GitHubProviderOptions} or `Updater` to modify url before request
163
+ * @param options provider options
164
+ */
199
165
  constructor(options) {
200
- this.url = new URL(options.url);
166
+ super();
201
167
  this.extraHeaders = options.extraHeaders;
202
168
  this.urlHandler = options.urlHandler;
203
- if (this.url.host !== "github.com") {
169
+ if (!options.url.startsWith("https://github.com")) {
204
170
  throw new Error(`${this.name}: invalid github url: ${options.url}`);
205
171
  }
206
- if (!this.url.pathname.endsWith("/")) {
207
- this.url.pathname += "/";
172
+ this.url = options.url;
173
+ if (!this.url.endsWith("/")) {
174
+ this.url += "/";
208
175
  }
209
176
  }
210
- parseURL(isDownloadAsar, path) {
211
- const url = this.url.href + path;
212
- return this.urlHandler ? this.urlHandler(url, isDownloadAsar) : url;
177
+ async parseURL(isDownloadAsar, extraPath) {
178
+ const _url = new URL(this.url);
179
+ _url.hostname = isDownloadAsar ? "github.com" : "raw.githubusercontent.com";
180
+ _url.pathname += extraPath;
181
+ return (await this.urlHandler?.(_url, isDownloadAsar) || _url).toString();
213
182
  }
214
- isLowerVersion = isLowerVersionDefault;
215
- verifySignaure = verifySignatureDefault;
216
183
  async downloadJSON(versionPath) {
217
- return await downloadUpdateJSONDefault(
218
- this.parseURL(false, `HEAD/${versionPath}`),
184
+ return await defaultDownloadUpdateJSON(
185
+ await this.parseURL(false, `HEAD/${versionPath}`),
219
186
  { userAgent: this.ua, accept: "application/json", ...this.extraHeaders }
220
187
  );
221
188
  }
222
189
  async downloadAsar(name, { version, size }, onDownloading) {
223
- return await downloadAsarBufferDefault(
224
- this.parseURL(true, `releases/download/v${version}/${name}-${version}.asar.gz`),
190
+ return await defaultDownloadAsar(
191
+ await this.parseURL(true, `releases/download/v${version}/${name}-${version}.asar.gz`),
225
192
  { userAgent: this.ua, accept: "application/octet-stream", ...this.extraHeaders },
226
193
  size,
227
194
  onDownloading
228
195
  );
229
196
  }
230
197
  };
231
- // Annotate the CommonJS export names for ESM import in node:
232
- 0 && (module.exports = {
233
- GitHubProvider,
234
- downloadAsarBufferDefault,
235
- downloadUpdateJSONDefault
236
- });
198
+
199
+ exports.BaseProvider = BaseProvider;
200
+ exports.GitHubProvider = GitHubProvider;
201
+ exports.defaultDownloadAsar = defaultDownloadAsar;
202
+ exports.defaultDownloadUpdateJSON = defaultDownloadUpdateJSON;