electron-incremental-update 2.0.1 → 2.1.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/index.cjs CHANGED
@@ -42,17 +42,11 @@ function restartApp() {
42
42
  }
43
43
 
44
44
  // src/entry/types.ts
45
- var ErrorInfo = {
46
- download: "Download Failed",
47
- validate: "Validate Failed",
48
- param: "Missing Params",
49
- network: "Network Error"
50
- };
51
45
  var UpdaterError = class extends Error {
52
46
  code;
53
- constructor(msg, info) {
54
- super(`[${ErrorInfo[msg]}] ${info}`);
55
- this.code = msg;
47
+ constructor(code, info) {
48
+ super(`[${code}] ${info}`);
49
+ this.code = code;
56
50
  }
57
51
  };
58
52
 
@@ -103,17 +97,17 @@ var Updater = class extends events.EventEmitter {
103
97
  if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
104
98
  return data;
105
99
  } else {
106
- this.err("Invalid type", "param", `Invalid type at format '${format}': ${JSON.stringify(data)}`);
100
+ this.err("Invalid type", "ERR_PARAM", `Invalid type at format '${format}': ${JSON.stringify(data)}`);
107
101
  return;
108
102
  }
109
103
  }
110
104
  this.logger?.debug(`Download from \`${this.provider.name}\``);
111
105
  try {
112
- const result = format === "json" ? await this.provider.downloadJSON(__EIU_VERSION_PATH__, this.controller.signal) : await this.provider.downloadAsar(electron.app.name, this.info, this.controller.signal, (info) => this.emit("download-progress", info));
106
+ const result = format === "json" ? await this.provider.downloadJSON(electron.app.name, __EIU_VERSION_PATH__, this.controller.signal) : await this.provider.downloadAsar(this.info, this.controller.signal, (info) => this.emit("download-progress", info));
113
107
  this.logger?.debug(`Download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
114
108
  return result;
115
109
  } catch (e) {
116
- this.err(`Fetch ${format} failed`, "network", e instanceof Error ? e.message : e.toString());
110
+ this.err(`Fetch ${format} failed`, "ERR_NETWORK", e instanceof Error ? e.message : e.toString());
117
111
  }
118
112
  }
119
113
  /**
@@ -121,68 +115,75 @@ var Updater = class extends events.EventEmitter {
121
115
  */
122
116
  err(msg, code, errorInfo) {
123
117
  const err = new UpdaterError(code, errorInfo);
124
- this.logger?.error(msg, err);
118
+ this.logger?.error(`[${code}] ${msg}`, err);
125
119
  this.emit("error", err);
126
120
  }
127
121
  async checkForUpdates(data) {
128
- const emitUnavailable = (msg, info2) => {
129
- this.logger?.info(msg);
130
- this.emit("update-not-available", msg, info2);
122
+ const emitUnavailable = (msg, code, info2) => {
123
+ this.logger?.info(`[${code}] ${msg}`);
124
+ this.emit("update-not-available", code, msg, info2);
131
125
  return false;
132
126
  };
133
127
  if (!data && !this.provider) {
134
- this.err("Check update failed", "param", "No update json or provider");
135
- return false;
128
+ const msg = "No update json or provider";
129
+ this.err("Check update failed", "ERR_PARAM", msg);
130
+ return emitUnavailable(msg, "UNAVAILABLE_ERROR");
136
131
  }
137
132
  const _data = await this.fetch("json", data);
138
133
  if (!_data) {
139
- return emitUnavailable("Failed to get update info");
134
+ return emitUnavailable("Failed to get update info", "UNAVAILABLE_ERROR");
140
135
  }
141
- const { signature, version, minimumVersion } = this.receiveBeta ? _data.beta : _data;
142
- const info = { signature, minimumVersion, version };
136
+ const { signature, version, minimumVersion, url = "" } = this.receiveBeta ? _data.beta : _data;
137
+ const info = { signature, minimumVersion, version, url };
138
+ const extraVersionInfo = {
139
+ signature,
140
+ minimumVersion,
141
+ version,
142
+ appVersion: getAppVersion(),
143
+ entryVersion: getEntryVersion()
144
+ };
143
145
  this.logger?.debug(`Checked update, version: ${version}, signature: ${signature}`);
144
146
  if (isDev && !this.forceUpdate && !data) {
145
- return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON", info);
147
+ return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON", "UNAVAILABLE_DEV", extraVersionInfo);
146
148
  }
147
149
  const isLowerVersion = this.provider.isLowerVersion;
148
- const entryVersion = getEntryVersion();
149
- const appVersion = getAppVersion();
150
150
  try {
151
- if (isLowerVersion(entryVersion, minimumVersion)) {
152
- return emitUnavailable(`Entry Version (${entryVersion}) < MinimumVersion (${minimumVersion})`, info);
151
+ if (isLowerVersion(extraVersionInfo.entryVersion, minimumVersion)) {
152
+ return emitUnavailable(`Entry Version (${extraVersionInfo.entryVersion}) < MinimumVersion (${minimumVersion})`, "UNAVAILABLE_VERSION", extraVersionInfo);
153
153
  }
154
- this.logger?.info(`Check update: current version is ${appVersion}, new version is ${version}`);
155
- if (!isLowerVersion(appVersion, version)) {
156
- return emitUnavailable(`Current version (${appVersion}) < New version (${version})`, info);
154
+ this.logger?.info(`Current version is ${extraVersionInfo.appVersion}, new version is ${version}`);
155
+ if (!isLowerVersion(extraVersionInfo.appVersion, version)) {
156
+ return emitUnavailable(`Current version (${extraVersionInfo.appVersion}) > New version (${version})`, "UNAVAILABLE_VERSION", extraVersionInfo);
157
157
  }
158
158
  this.logger?.info(`Update available: ${version}`);
159
- this.emit("update-available", info);
159
+ this.emit("update-available", extraVersionInfo);
160
160
  this.info = info;
161
161
  return true;
162
162
  } catch {
163
- this.err("Fail to parse version", "validate", "Fail to parse version string");
164
- return false;
163
+ const msg = "Fail to parse version string";
164
+ this.err("Check update failed", "ERR_VALIDATE", msg);
165
+ return emitUnavailable(msg, "UNAVAILABLE_ERROR", extraVersionInfo);
165
166
  }
166
167
  }
167
168
  async downloadUpdate(data, info) {
168
169
  const _sig = info?.signature ?? this.info?.signature;
169
170
  const _version = info?.version ?? this.info?.version;
170
171
  if (!_sig || !_version) {
171
- this.err("Download failed", "param", "No update signature, please call `checkUpdate` first or manually setup params");
172
+ this.err("Download failed", "ERR_PARAM", "No update signature, please call `checkUpdate` first or manually setup params");
172
173
  return false;
173
174
  }
174
175
  if (!data && !this.provider) {
175
- this.err("Download failed", "param", "No update asar buffer and provider");
176
+ this.err("Download failed", "ERR_PARAM", "No update asar buffer and provider");
176
177
  return false;
177
178
  }
178
179
  const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
179
180
  if (!buffer) {
180
- this.err("Download failed", "param", "No update asar file buffer");
181
+ this.err("Download failed", "ERR_PARAM", "No update asar file buffer");
181
182
  return false;
182
183
  }
183
184
  this.logger?.debug("verify start");
184
185
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
185
- this.err("Download failed", "validate", "Invalid update asar file");
186
+ this.err("Download failed", "ERR_VALIDATE", "Invalid update asar file");
186
187
  return false;
187
188
  }
188
189
  this.logger?.debug("Verify success");
@@ -195,7 +196,7 @@ var Updater = class extends events.EventEmitter {
195
196
  this.emit("update-downloaded");
196
197
  return true;
197
198
  } catch (error) {
198
- this.err("Download failed", "download", `Fail to unwrap asar file, ${error}`);
199
+ this.err("Download failed", "ERR_DOWNLOAD", `Fail to unwrap asar file, ${error}`);
199
200
  return false;
200
201
  }
201
202
  }
@@ -268,7 +269,6 @@ async function createElectronApp(appOptions = {}) {
268
269
  }
269
270
  var initApp = createElectronApp;
270
271
 
271
- exports.ErrorInfo = ErrorInfo;
272
272
  exports.Updater = Updater;
273
273
  exports.UpdaterError = UpdaterError;
274
274
  exports.autoUpdate = autoUpdate;
package/dist/index.d.cts CHANGED
@@ -1,50 +1,13 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { U as UpdateInfo, a as UpdateJSON } from './version-BYVQ367i.cjs';
3
- import { I as IProvider, D as DownloadingInfo } from './types-DkCn03M3.cjs';
2
+ import { U as UpdateJSON, a as UpdateInfo } from './version-DcFMG3pT.cjs';
3
+ import { U as UpdateInfoWithExtraVersion, a as UnavailableCode, b as UpdaterError, D as DownloadingInfo, I as IProvider, L as Logger, c as UpdaterOption, d as UpdateJSONWithURL } from './types-DADYYy6C.cjs';
4
+ export { E as ErrorCode, e as UpdateInfoWithURL } from './types-DADYYy6C.cjs';
4
5
  import { Promisable } from '@subframe7536/type-utils';
5
6
 
6
- declare const ErrorInfo: {
7
- readonly download: "Download Failed";
8
- readonly validate: "Validate Failed";
9
- readonly param: "Missing Params";
10
- readonly network: "Network Error";
11
- };
12
- declare class UpdaterError extends Error {
13
- code: keyof typeof ErrorInfo;
14
- constructor(msg: keyof typeof ErrorInfo, info: string);
15
- }
16
- interface Logger {
17
- info: (msg: string) => void;
18
- debug: (msg: string) => void;
19
- warn: (msg: string) => void;
20
- error: (msg: string, e?: unknown) => void;
21
- }
22
- interface UpdaterOption {
23
- /**
24
- * Update provider
25
- *
26
- * If you will not setup `UpdateJSON` or `Buffer` in params when checking update or download, this option is **required**
27
- */
28
- provider?: IProvider;
29
- /**
30
- * Certifaction key of signature, which will be auto generated by plugin,
31
- * generate by `selfsigned` if not set
32
- */
33
- SIGNATURE_CERT?: string;
34
- /**
35
- * Whether to receive beta update
36
- */
37
- receiveBeta?: boolean;
38
- /**
39
- * Updater logger
40
- */
41
- logger?: Logger;
42
- }
43
-
44
7
  declare class Updater extends EventEmitter<{
45
8
  'checking': any;
46
- 'update-available': [data: UpdateInfo];
47
- 'update-not-available': [reason: string, data?: UpdateInfo];
9
+ 'update-available': [data: UpdateInfoWithExtraVersion];
10
+ 'update-not-available': [code: UnavailableCode, msg: string, info?: UpdateInfoWithExtraVersion];
48
11
  'error': [error: UpdaterError];
49
12
  'download-progress': [info: DownloadingInfo];
50
13
  'update-downloaded': any;
@@ -90,7 +53,7 @@ declare class Updater extends EventEmitter<{
90
53
  * Check update info using existing update json
91
54
  * @param data existing update json
92
55
  */
93
- checkForUpdates(data: UpdateJSON): Promise<boolean>;
56
+ checkForUpdates(data: UpdateJSON | UpdateJSONWithURL): Promise<boolean>;
94
57
  /**
95
58
  * Download update using default options
96
59
  */
@@ -180,4 +143,4 @@ declare function createElectronApp(appOptions?: AppOption): Promise<void>;
180
143
  */
181
144
  declare const initApp: typeof createElectronApp;
182
145
 
183
- export { type AppOption, ErrorInfo, type Logger, Updater, UpdaterError, type UpdaterOption, autoUpdate, createElectronApp, initApp, startupWithUpdater };
146
+ export { type AppOption, Logger, UnavailableCode, UpdateInfoWithExtraVersion, Updater, UpdaterError, UpdaterOption, autoUpdate, createElectronApp, initApp, startupWithUpdater };
package/dist/index.d.ts CHANGED
@@ -1,50 +1,13 @@
1
1
  import { EventEmitter } from 'node:events';
2
- import { U as UpdateInfo, a as UpdateJSON } from './version-BYVQ367i.js';
3
- import { I as IProvider, D as DownloadingInfo } from './types-BLdN9rkY.js';
2
+ import { U as UpdateJSON, a as UpdateInfo } from './version-DcFMG3pT.js';
3
+ import { U as UpdateInfoWithExtraVersion, a as UnavailableCode, b as UpdaterError, D as DownloadingInfo, I as IProvider, L as Logger, c as UpdaterOption, d as UpdateJSONWithURL } from './types-BVcfNRXE.js';
4
+ export { E as ErrorCode, e as UpdateInfoWithURL } from './types-BVcfNRXE.js';
4
5
  import { Promisable } from '@subframe7536/type-utils';
5
6
 
6
- declare const ErrorInfo: {
7
- readonly download: "Download Failed";
8
- readonly validate: "Validate Failed";
9
- readonly param: "Missing Params";
10
- readonly network: "Network Error";
11
- };
12
- declare class UpdaterError extends Error {
13
- code: keyof typeof ErrorInfo;
14
- constructor(msg: keyof typeof ErrorInfo, info: string);
15
- }
16
- interface Logger {
17
- info: (msg: string) => void;
18
- debug: (msg: string) => void;
19
- warn: (msg: string) => void;
20
- error: (msg: string, e?: unknown) => void;
21
- }
22
- interface UpdaterOption {
23
- /**
24
- * Update provider
25
- *
26
- * If you will not setup `UpdateJSON` or `Buffer` in params when checking update or download, this option is **required**
27
- */
28
- provider?: IProvider;
29
- /**
30
- * Certifaction key of signature, which will be auto generated by plugin,
31
- * generate by `selfsigned` if not set
32
- */
33
- SIGNATURE_CERT?: string;
34
- /**
35
- * Whether to receive beta update
36
- */
37
- receiveBeta?: boolean;
38
- /**
39
- * Updater logger
40
- */
41
- logger?: Logger;
42
- }
43
-
44
7
  declare class Updater extends EventEmitter<{
45
8
  'checking': any;
46
- 'update-available': [data: UpdateInfo];
47
- 'update-not-available': [reason: string, data?: UpdateInfo];
9
+ 'update-available': [data: UpdateInfoWithExtraVersion];
10
+ 'update-not-available': [code: UnavailableCode, msg: string, info?: UpdateInfoWithExtraVersion];
48
11
  'error': [error: UpdaterError];
49
12
  'download-progress': [info: DownloadingInfo];
50
13
  'update-downloaded': any;
@@ -90,7 +53,7 @@ declare class Updater extends EventEmitter<{
90
53
  * Check update info using existing update json
91
54
  * @param data existing update json
92
55
  */
93
- checkForUpdates(data: UpdateJSON): Promise<boolean>;
56
+ checkForUpdates(data: UpdateJSON | UpdateJSONWithURL): Promise<boolean>;
94
57
  /**
95
58
  * Download update using default options
96
59
  */
@@ -180,4 +143,4 @@ declare function createElectronApp(appOptions?: AppOption): Promise<void>;
180
143
  */
181
144
  declare const initApp: typeof createElectronApp;
182
145
 
183
- export { type AppOption, ErrorInfo, type Logger, Updater, UpdaterError, type UpdaterOption, autoUpdate, createElectronApp, initApp, startupWithUpdater };
146
+ export { type AppOption, Logger, UnavailableCode, UpdateInfoWithExtraVersion, Updater, UpdaterError, UpdaterOption, autoUpdate, createElectronApp, initApp, startupWithUpdater };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isDev, getEntryVersion, getAppVersion, getPathFromAppNameAsar, restartApp } from './chunk-GTDMND3I.js';
1
+ import { isDev, getAppVersion, getEntryVersion, getPathFromAppNameAsar, restartApp } from './chunk-ZM5CIZ4L.js';
2
2
  import { isUpdateJSON, __require } from './chunk-RCRKUKFX.js';
3
3
  import fs2 from 'node:fs';
4
4
  import { EventEmitter } from 'node:events';
@@ -6,17 +6,11 @@ import { app } from 'electron';
6
6
  import path from 'node:path';
7
7
 
8
8
  // src/entry/types.ts
9
- var ErrorInfo = {
10
- download: "Download Failed",
11
- validate: "Validate Failed",
12
- param: "Missing Params",
13
- network: "Network Error"
14
- };
15
9
  var UpdaterError = class extends Error {
16
10
  code;
17
- constructor(msg, info) {
18
- super(`[${ErrorInfo[msg]}] ${info}`);
19
- this.code = msg;
11
+ constructor(code, info) {
12
+ super(`[${code}] ${info}`);
13
+ this.code = code;
20
14
  }
21
15
  };
22
16
 
@@ -67,17 +61,17 @@ var Updater = class extends EventEmitter {
67
61
  if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
68
62
  return data;
69
63
  } else {
70
- this.err("Invalid type", "param", `Invalid type at format '${format}': ${JSON.stringify(data)}`);
64
+ this.err("Invalid type", "ERR_PARAM", `Invalid type at format '${format}': ${JSON.stringify(data)}`);
71
65
  return;
72
66
  }
73
67
  }
74
68
  this.logger?.debug(`Download from \`${this.provider.name}\``);
75
69
  try {
76
- const result = format === "json" ? await this.provider.downloadJSON(__EIU_VERSION_PATH__, this.controller.signal) : await this.provider.downloadAsar(app.name, this.info, this.controller.signal, (info) => this.emit("download-progress", info));
70
+ const result = format === "json" ? await this.provider.downloadJSON(app.name, __EIU_VERSION_PATH__, this.controller.signal) : await this.provider.downloadAsar(this.info, this.controller.signal, (info) => this.emit("download-progress", info));
77
71
  this.logger?.debug(`Download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
78
72
  return result;
79
73
  } catch (e) {
80
- this.err(`Fetch ${format} failed`, "network", e instanceof Error ? e.message : e.toString());
74
+ this.err(`Fetch ${format} failed`, "ERR_NETWORK", e instanceof Error ? e.message : e.toString());
81
75
  }
82
76
  }
83
77
  /**
@@ -85,68 +79,75 @@ var Updater = class extends EventEmitter {
85
79
  */
86
80
  err(msg, code, errorInfo) {
87
81
  const err = new UpdaterError(code, errorInfo);
88
- this.logger?.error(msg, err);
82
+ this.logger?.error(`[${code}] ${msg}`, err);
89
83
  this.emit("error", err);
90
84
  }
91
85
  async checkForUpdates(data) {
92
- const emitUnavailable = (msg, info2) => {
93
- this.logger?.info(msg);
94
- this.emit("update-not-available", msg, info2);
86
+ const emitUnavailable = (msg, code, info2) => {
87
+ this.logger?.info(`[${code}] ${msg}`);
88
+ this.emit("update-not-available", code, msg, info2);
95
89
  return false;
96
90
  };
97
91
  if (!data && !this.provider) {
98
- this.err("Check update failed", "param", "No update json or provider");
99
- return false;
92
+ const msg = "No update json or provider";
93
+ this.err("Check update failed", "ERR_PARAM", msg);
94
+ return emitUnavailable(msg, "UNAVAILABLE_ERROR");
100
95
  }
101
96
  const _data = await this.fetch("json", data);
102
97
  if (!_data) {
103
- return emitUnavailable("Failed to get update info");
104
- }
105
- const { signature, version, minimumVersion } = this.receiveBeta ? _data.beta : _data;
106
- const info = { signature, minimumVersion, version };
98
+ return emitUnavailable("Failed to get update info", "UNAVAILABLE_ERROR");
99
+ }
100
+ const { signature, version, minimumVersion, url = "" } = this.receiveBeta ? _data.beta : _data;
101
+ const info = { signature, minimumVersion, version, url };
102
+ const extraVersionInfo = {
103
+ signature,
104
+ minimumVersion,
105
+ version,
106
+ appVersion: getAppVersion(),
107
+ entryVersion: getEntryVersion()
108
+ };
107
109
  this.logger?.debug(`Checked update, version: ${version}, signature: ${signature}`);
108
110
  if (isDev && !this.forceUpdate && !data) {
109
- return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON", info);
111
+ return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON", "UNAVAILABLE_DEV", extraVersionInfo);
110
112
  }
111
113
  const isLowerVersion = this.provider.isLowerVersion;
112
- const entryVersion = getEntryVersion();
113
- const appVersion = getAppVersion();
114
114
  try {
115
- if (isLowerVersion(entryVersion, minimumVersion)) {
116
- return emitUnavailable(`Entry Version (${entryVersion}) < MinimumVersion (${minimumVersion})`, info);
115
+ if (isLowerVersion(extraVersionInfo.entryVersion, minimumVersion)) {
116
+ return emitUnavailable(`Entry Version (${extraVersionInfo.entryVersion}) < MinimumVersion (${minimumVersion})`, "UNAVAILABLE_VERSION", extraVersionInfo);
117
117
  }
118
- this.logger?.info(`Check update: current version is ${appVersion}, new version is ${version}`);
119
- if (!isLowerVersion(appVersion, version)) {
120
- return emitUnavailable(`Current version (${appVersion}) < New version (${version})`, info);
118
+ this.logger?.info(`Current version is ${extraVersionInfo.appVersion}, new version is ${version}`);
119
+ if (!isLowerVersion(extraVersionInfo.appVersion, version)) {
120
+ return emitUnavailable(`Current version (${extraVersionInfo.appVersion}) > New version (${version})`, "UNAVAILABLE_VERSION", extraVersionInfo);
121
121
  }
122
122
  this.logger?.info(`Update available: ${version}`);
123
- this.emit("update-available", info);
123
+ this.emit("update-available", extraVersionInfo);
124
124
  this.info = info;
125
125
  return true;
126
126
  } catch {
127
- this.err("Fail to parse version", "validate", "Fail to parse version string");
128
- return false;
127
+ const msg = "Fail to parse version string";
128
+ this.err("Check update failed", "ERR_VALIDATE", msg);
129
+ return emitUnavailable(msg, "UNAVAILABLE_ERROR", extraVersionInfo);
129
130
  }
130
131
  }
131
132
  async downloadUpdate(data, info) {
132
133
  const _sig = info?.signature ?? this.info?.signature;
133
134
  const _version = info?.version ?? this.info?.version;
134
135
  if (!_sig || !_version) {
135
- this.err("Download failed", "param", "No update signature, please call `checkUpdate` first or manually setup params");
136
+ this.err("Download failed", "ERR_PARAM", "No update signature, please call `checkUpdate` first or manually setup params");
136
137
  return false;
137
138
  }
138
139
  if (!data && !this.provider) {
139
- this.err("Download failed", "param", "No update asar buffer and provider");
140
+ this.err("Download failed", "ERR_PARAM", "No update asar buffer and provider");
140
141
  return false;
141
142
  }
142
143
  const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
143
144
  if (!buffer) {
144
- this.err("Download failed", "param", "No update asar file buffer");
145
+ this.err("Download failed", "ERR_PARAM", "No update asar file buffer");
145
146
  return false;
146
147
  }
147
148
  this.logger?.debug("verify start");
148
149
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
149
- this.err("Download failed", "validate", "Invalid update asar file");
150
+ this.err("Download failed", "ERR_VALIDATE", "Invalid update asar file");
150
151
  return false;
151
152
  }
152
153
  this.logger?.debug("Verify success");
@@ -159,7 +160,7 @@ var Updater = class extends EventEmitter {
159
160
  this.emit("update-downloaded");
160
161
  return true;
161
162
  } catch (error) {
162
- this.err("Download failed", "download", `Fail to unwrap asar file, ${error}`);
163
+ this.err("Download failed", "ERR_DOWNLOAD", `Fail to unwrap asar file, ${error}`);
163
164
  return false;
164
165
  }
165
166
  }
@@ -232,4 +233,4 @@ async function createElectronApp(appOptions = {}) {
232
233
  }
233
234
  var initApp = createElectronApp;
234
235
 
235
- export { ErrorInfo, Updater, UpdaterError, autoUpdate, createElectronApp, initApp, startupWithUpdater };
236
+ export { Updater, UpdaterError, autoUpdate, createElectronApp, initApp, startupWithUpdater };
package/dist/provider.cjs CHANGED
@@ -85,7 +85,17 @@ async function downloadFn(url, headers, signal, onResponse) {
85
85
  request.end();
86
86
  });
87
87
  }
88
- async function defaultDownloadUpdateJSON(url, headers, signal) {
88
+ function trimData(data) {
89
+ return data.trim().slice(0, 5e3).replace(/\s+/g, " ");
90
+ }
91
+ var defaultResolveDataFn = (data, resolve, reject) => {
92
+ try {
93
+ resolve(JSON.parse(data));
94
+ } catch {
95
+ reject(new Error(`Invalid json, "${trimData(data)}"`));
96
+ }
97
+ };
98
+ async function defaultDownloadJSON(url, headers, signal, resolveData = defaultResolveDataFn) {
89
99
  return await downloadFn(
90
100
  url,
91
101
  headers,
@@ -93,18 +103,26 @@ async function defaultDownloadUpdateJSON(url, headers, signal) {
93
103
  (resp, resolve, reject) => {
94
104
  let data = "";
95
105
  resp.on("data", (chunk) => data += chunk);
96
- resp.on("end", () => {
97
- try {
98
- const json = JSON.parse(data);
99
- if (isUpdateJSON(json)) {
100
- resolve(json);
101
- } else {
102
- throw Error;
103
- }
104
- } catch {
105
- reject(new Error(`Invalid update json, "${data}"`));
106
+ resp.on("end", () => resolveData(data, resolve, reject));
107
+ }
108
+ );
109
+ }
110
+ async function defaultDownloadUpdateJSON(url, headers, signal) {
111
+ return await defaultDownloadJSON(
112
+ url,
113
+ headers,
114
+ signal,
115
+ (data, resolve, reject) => {
116
+ try {
117
+ const json = JSON.parse(data);
118
+ if (isUpdateJSON(json)) {
119
+ resolve(json);
120
+ } else {
121
+ throw Error;
106
122
  }
107
- });
123
+ } catch {
124
+ reject(new Error(`Invalid update json, "${trimData(data)}"`));
125
+ }
108
126
  }
109
127
  );
110
128
  }
@@ -216,23 +234,125 @@ var GitHubProvider = class extends BaseProvider {
216
234
  );
217
235
  return (await this.urlHandler?.(url$1) || url$1).toString();
218
236
  }
237
+ getHeaders(accept) {
238
+ return { Accept: `application/${accept}`, ...this.options.extraHeaders };
239
+ }
219
240
  /**
220
241
  * @inheritdoc
221
242
  */
222
- async downloadJSON(versionPath, signal) {
223
- return await defaultDownloadUpdateJSON(
243
+ async downloadJSON(name, versionPath, signal) {
244
+ const { beta, version, ...info } = await defaultDownloadUpdateJSON(
224
245
  await this.parseURL(`raw/${this.options.branch}/${versionPath}`),
225
- { Accept: "application/json", ...this.options.extraHeaders },
246
+ this.getHeaders("json"),
247
+ signal
248
+ );
249
+ const getURL = (ver) => this.parseURL(`releases/download/v${ver}/${name}-${ver}.asar.gz`);
250
+ return {
251
+ ...info,
252
+ version,
253
+ url: await getURL(version),
254
+ beta: {
255
+ ...beta,
256
+ url: await getURL(beta.version)
257
+ }
258
+ };
259
+ }
260
+ /**
261
+ * @inheritdoc
262
+ */
263
+ async downloadAsar(info, signal, onDownloading) {
264
+ return await defaultDownloadAsar(
265
+ info.url,
266
+ this.getHeaders("octet-stream"),
267
+ signal,
268
+ onDownloading
269
+ );
270
+ }
271
+ };
272
+ var ERROR_MSG = "Cannot find UpdateJSON in latest release";
273
+ var GitHubApiProvider = class extends BaseProvider {
274
+ name = "GithubApiProvider";
275
+ options;
276
+ /**
277
+ * Update Provider for Github API, you need to upload `version.json` to release as well
278
+ * - check update from `https://api.github.com/repos/{user}/{repo}/releases?per_page=1`
279
+ * - download update json and get version and download url
280
+ * - download update asar from update info
281
+ *
282
+ * you can setup `urlHandler` in {@link GitHubApiProviderOptions} to modify url before request
283
+ * @param options provider options
284
+ */
285
+ constructor(options) {
286
+ super();
287
+ this.options = options;
288
+ }
289
+ get urlHandler() {
290
+ return this.options.urlHandler;
291
+ }
292
+ set urlHandler(handler) {
293
+ this.options.urlHandler = handler;
294
+ }
295
+ async parseURL(url$1) {
296
+ const _url = new url.URL(url$1);
297
+ return (await this.urlHandler?.(_url) || _url).toString();
298
+ }
299
+ getHeaders(accept) {
300
+ return {
301
+ Accept: `application/${accept}`,
302
+ ...this.options.token ? { Authorization: `token ${this.options.token}` } : {},
303
+ ...this.options.extraHeaders
304
+ };
305
+ }
306
+ /**
307
+ * @inheritdoc
308
+ */
309
+ async downloadJSON(name, versionPath, signal) {
310
+ const basename = versionPath.slice(versionPath.lastIndexOf("/") + 1);
311
+ const data = await defaultDownloadJSON(
312
+ await this.parseURL(`https://api.github.com/repos/${this.options.user}/${this.options.repo}/releases?per_page=1`),
313
+ this.getHeaders("vnd.github.v3+json"),
226
314
  signal
227
315
  );
316
+ const versionAssets = data[0]?.assets.find((asset) => asset.name === basename);
317
+ if (!versionAssets) {
318
+ throw new Error(`${ERROR_MSG}, ${"message" in data ? data.message : "please check the release assets"}`);
319
+ }
320
+ const { beta, version, ...info } = await defaultDownloadUpdateJSON(
321
+ versionAssets.browser_download_url,
322
+ this.getHeaders("json"),
323
+ signal
324
+ );
325
+ const getURL = (ver) => {
326
+ const _ver = data.find((r) => r.tag_name === ver);
327
+ if (!_ver) {
328
+ throw new Error(ERROR_MSG);
329
+ }
330
+ const asset = _ver.assets.find((a) => a.name === `${name}-${ver}.asar.gz`);
331
+ if (!asset) {
332
+ throw new Error(ERROR_MSG);
333
+ }
334
+ return this.parseURL(asset.browser_download_url);
335
+ };
336
+ return {
337
+ ...info,
338
+ version,
339
+ url: await getURL(version),
340
+ beta: {
341
+ ...beta,
342
+ url: await getURL(beta.version)
343
+ }
344
+ };
228
345
  }
229
346
  /**
230
347
  * @inheritdoc
231
348
  */
232
- async downloadAsar(name, info, signal, onDownloading) {
349
+ async downloadAsar(info, signal, onDownloading) {
350
+ if (!info.url) {
351
+ throw new Error("Cannot download asar without url");
352
+ }
233
353
  return await defaultDownloadAsar(
234
- await this.parseURL(`releases/download/v${info.version}/${name}-${info.version}.asar.gz`),
235
- { Accept: "application/octet-stream", ...this.options.extraHeaders },
354
+ info.url,
355
+ this.getHeaders("octet-stream"),
236
356
  signal,
237
357
  onDownloading
238
358
  );
@@ -240,7 +360,9 @@ var GitHubProvider = class extends BaseProvider {
240
360
  };
241
361
 
242
362
  exports.BaseProvider = BaseProvider;
363
+ exports.GitHubApiProvider = GitHubApiProvider;
243
364
  exports.GitHubProvider = GitHubProvider;
244
365
  exports.defaultDownloadAsar = defaultDownloadAsar;
366
+ exports.defaultDownloadJSON = defaultDownloadJSON;
245
367
  exports.defaultDownloadUpdateJSON = defaultDownloadUpdateJSON;
246
368
  exports.getHeader = getHeader;