electron-incremental-update 3.0.0-beta.4 → 3.0.0-beta.6

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.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { a as getPathFromAppNameAsar, f as isDev, i as getEntryVersion, r as getAppVersion, y as restartApp } from "./electron-BJCk7uxG.mjs";
2
- import { r as isUpdateJSON } from "./version--eVB2A7n.mjs";
3
- import { BrowserWindow, app } from "electron";
1
+ import { u as isUpdateJSON } from "./zip-DUK3opmV.mjs";
2
+ import { t as LocalDevProvider } from "./local-s1cw_vwb.mjs";
3
+ import { a as getPathFromAppNameAsar, f as isDev, i as getEntryVersion, r as getAppVersion, y as restartApp } from "./electron-BInvFJ-W.mjs";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
6
+ import { BrowserWindow, app } from "electron";
6
7
  import { EventEmitter } from "node:events";
7
-
8
8
  //#region src/entry/types.ts
9
9
  var UpdaterError = class extends Error {
10
10
  code;
@@ -13,12 +13,12 @@ var UpdaterError = class extends Error {
13
13
  this.code = code;
14
14
  }
15
15
  };
16
-
17
16
  //#endregion
18
17
  //#region src/entry/updater.ts
19
18
  var Updater = class extends EventEmitter {
20
19
  CERT;
21
20
  controller;
21
+ getCurrentAppVersion;
22
22
  info;
23
23
  tmpFilePath;
24
24
  processing = false;
@@ -45,6 +45,7 @@ var Updater = class extends EventEmitter {
45
45
  this.receiveBeta = options.receiveBeta;
46
46
  this.CERT = options.SIGNATURE_CERT || __EIU_SIGNATURE_CERT__;
47
47
  this.logger = options.logger;
48
+ this.getCurrentAppVersion = options.getAppVersion ?? getAppVersion;
48
49
  this.controller = new AbortController();
49
50
  if (isDev && !this.logger) {
50
51
  this.logger = {
@@ -55,7 +56,6 @@ var Updater = class extends EventEmitter {
55
56
  };
56
57
  this.logger.info("No logger set, enable dev-only logger");
57
58
  }
58
- if (!this.provider) this.logger?.debug("WARN: No update provider");
59
59
  }
60
60
  async fetch(format, data) {
61
61
  if (typeof data === "object") if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) return data;
@@ -88,9 +88,12 @@ var Updater = class extends EventEmitter {
88
88
  const err = new UpdaterError(code, errorInfo);
89
89
  this.logger?.error(`[${code}] ${msg}`, err);
90
90
  this.cleanup();
91
- this.emit("error", err);
91
+ if (this.listenerCount("error") > 0) this.emit("error", err);
92
92
  }
93
- async checkForUpdates(data) {
93
+ /**
94
+ * Check update info using default options
95
+ */
96
+ async checkForUpdates() {
94
97
  const emitUnavailable = (msg, code, info) => {
95
98
  this.logger?.info(`[${code}] ${msg}`);
96
99
  this.logger?.debug("Check update end");
@@ -98,18 +101,18 @@ var Updater = class extends EventEmitter {
98
101
  this.emit("update-not-available", code, msg, info);
99
102
  return false;
100
103
  };
104
+ if (!this.provider) {
105
+ const msg = "No update json or provider";
106
+ this.err("Check update failed", "ERR_PARAM", msg);
107
+ return emitUnavailable(msg, "UNAVAILABLE_ERROR");
108
+ }
101
109
  if (this.processing) {
102
110
  this.logger?.info("Updater is already processing, skip check update");
103
111
  return false;
104
112
  }
105
113
  this.processing = true;
106
114
  this.logger?.debug("Check update start");
107
- if (!data && !this.provider) {
108
- const msg = "No update json or provider";
109
- this.err("Check update failed", "ERR_PARAM", msg);
110
- return emitUnavailable(msg, "UNAVAILABLE_ERROR");
111
- }
112
- const _data = await this.fetch("json", data);
115
+ const _data = await this.fetch("json");
113
116
  if (!_data) return emitUnavailable("Failed to get update info", "UNAVAILABLE_ERROR");
114
117
  const { signature, version, minimumVersion, url, ...rest } = this.receiveBeta ? _data.beta : _data;
115
118
  const info = {
@@ -122,12 +125,12 @@ var Updater = class extends EventEmitter {
122
125
  signature,
123
126
  minimumVersion,
124
127
  version,
125
- appVersion: getAppVersion(),
128
+ appVersion: this.getCurrentAppVersion(),
126
129
  entryVersion: getEntryVersion(),
127
130
  ...rest
128
131
  };
129
132
  this.logger?.debug(`Checked update, version: ${version}, signature: ${signature}`);
130
- if (isDev && !this.forceUpdate && !data) return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON", "UNAVAILABLE_DEV");
133
+ if (isDev && !this.forceUpdate) return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to `true`", "UNAVAILABLE_DEV");
131
134
  const isLowerVersion = this.provider.isLowerVersion;
132
135
  try {
133
136
  if (isLowerVersion(extraVersionInfo.entryVersion, minimumVersion)) return emitUnavailable(`Entry Version (${extraVersionInfo.entryVersion}) < MinimumVersion (${minimumVersion})`, "UNAVAILABLE_VERSION", extraVersionInfo);
@@ -145,25 +148,32 @@ var Updater = class extends EventEmitter {
145
148
  return emitUnavailable(msg, "UNAVAILABLE_ERROR", extraVersionInfo);
146
149
  }
147
150
  }
148
- async downloadUpdate(data, info) {
151
+ /**
152
+ * Download update using default options
153
+ */
154
+ async downloadUpdate() {
149
155
  const emitError = (code, errorInfo) => {
150
156
  this.err(`Download update failed`, code, errorInfo);
151
157
  this.logger?.debug("Download update end");
152
158
  this.processing = false;
153
159
  return false;
154
160
  };
161
+ if (!this.provider) return emitError("ERR_PARAM", "No update asar buffer and provider");
155
162
  if (this.processing) {
156
163
  this.logger?.info("Updater is already processing, skip download update");
157
164
  return false;
158
165
  }
159
166
  this.processing = true;
160
167
  this.logger?.debug("Download update start");
161
- const _sig = info?.signature ?? this.info?.signature;
162
- const _version = info?.version ?? this.info?.version;
163
- if (!_sig || !_version) return emitError("ERR_PARAM", "No update signature, please call `checkUpdate` first or manually setup params");
164
- if (!data && !this.provider) return emitError("ERR_PARAM", "No update asar buffer and provider");
165
- const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
166
- if (!buffer) return emitError("ERR_PARAM", "No update asar file buffer");
168
+ const _sig = this.info?.signature;
169
+ const _version = this.info?.version;
170
+ if (!_sig || !_version) return emitError("ERR_PARAM", "No update signature, please call `checkUpdate` first");
171
+ const buffer = await this.fetch("buffer");
172
+ if (!buffer) {
173
+ this.logger?.debug("Download update end");
174
+ this.processing = false;
175
+ return false;
176
+ }
167
177
  this.logger?.debug("Validation start");
168
178
  if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) return emitError("ERR_VALIDATE", "Invalid update asar file");
169
179
  this.logger?.debug("Validation end");
@@ -204,7 +214,6 @@ var Updater = class extends EventEmitter {
204
214
  async function autoUpdate(updater) {
205
215
  if (await updater.checkForUpdates() && await updater.downloadUpdate()) updater.quitAndInstall();
206
216
  }
207
-
208
217
  //#endregion
209
218
  //#region src/entry/core.ts
210
219
  /**
@@ -229,6 +238,25 @@ const defaultOnInstall = (install, _, __, logger) => {
229
238
  install();
230
239
  logger?.info(`update success!`);
231
240
  };
241
+ function readDevAsarVersion() {
242
+ try {
243
+ return fs.readFileSync(getPathFromAppNameAsar("version"), "utf-8").trim();
244
+ } catch {
245
+ return app.getVersion();
246
+ }
247
+ }
248
+ function resolveUpdaterOption(updater) {
249
+ if (!isDev || !__EIU_LOCAL_DEV_UPDATE__ || updater?.provider) return updater;
250
+ return {
251
+ ...updater,
252
+ provider: new LocalDevProvider({
253
+ baseDir: __EIU_LOCAL_DEV_UPDATE_DIR__,
254
+ chunkDelay: __EIU_LOCAL_DEV_UPDATE_CHUNK_DELAY__,
255
+ chunkSize: __EIU_LOCAL_DEV_UPDATE_CHUNK_SIZE__
256
+ }),
257
+ getAppVersion: updater?.getAppVersion ?? readDevAsarVersion
258
+ };
259
+ }
232
260
  /**
233
261
  * Initialize Electron with updater
234
262
  * @example
@@ -247,7 +275,9 @@ const defaultOnInstall = (install, _, __, logger) => {
247
275
  async function createElectronApp(appOptions = {}) {
248
276
  const appNameAsarPath = getPathFromAppNameAsar();
249
277
  const { mainPath = isDev ? path.join(app.getAppPath(), __EIU_ELECTRON_DIST_PATH__, "main", __EIU_MAIN_FILE__) : path.join(path.dirname(app.getAppPath()), __EIU_ASAR_BASE_NAME__, "main", __EIU_MAIN_FILE__), updater, onInstall = defaultOnInstall, beforeStart, onStartError } = appOptions;
250
- const updaterInstance = typeof updater === "object" || !updater ? new Updater(updater) : await updater();
278
+ const useAutoLocalDevProvider = isDev && __EIU_LOCAL_DEV_UPDATE__ && typeof updater !== "function";
279
+ const updaterInstance = typeof updater === "object" || !updater ? new Updater(resolveUpdaterOption(updater)) : await updater();
280
+ if (useAutoLocalDevProvider && updaterInstance.provider?.name === "LocalDevProvider") updaterInstance.forceUpdate = true;
251
281
  const logger = updaterInstance.logger;
252
282
  try {
253
283
  const tempAsarPath = `${appNameAsarPath}.tmp`;
@@ -256,8 +286,10 @@ async function createElectronApp(appOptions = {}) {
256
286
  await onInstall(() => fs.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
257
287
  }
258
288
  await beforeStart?.(mainPath, logger);
259
- if (__EIU_IS_ESM__) runWithDefaultExport(await import(`file://${mainPath}`), updaterInstance);
260
- else runWithDefaultExport(require(mainPath), updaterInstance);
289
+ if (__EIU_IS_ESM__) {
290
+ const { pathToFileURL } = await import("node:url");
291
+ runWithDefaultExport(await import(pathToFileURL(mainPath).href), updaterInstance);
292
+ } else runWithDefaultExport(require(mainPath), updaterInstance);
261
293
  } catch (error) {
262
294
  logger?.error("Fail to startup", error);
263
295
  onStartError?.(error, logger);
@@ -268,6 +300,5 @@ async function createElectronApp(appOptions = {}) {
268
300
  * @deprecated Use {@link createElectronApp} instead
269
301
  */
270
302
  const initApp = createElectronApp;
271
-
272
303
  //#endregion
273
- export { Updater, UpdaterError, autoUpdate, createElectronApp, initApp, startupWithUpdater };
304
+ export { Updater, UpdaterError, autoUpdate, createElectronApp, initApp, startupWithUpdater };
@@ -0,0 +1,118 @@
1
+ const require_zip = require("./zip-D1dbBzw4.cjs");
2
+ let node_path = require("node:path");
3
+ node_path = require_zip.__toESM(node_path, 1);
4
+ let node_fs_promises = require("node:fs/promises");
5
+ node_fs_promises = require_zip.__toESM(node_fs_promises, 1);
6
+ //#region src/provider/base.ts
7
+ var BaseProvider = class {
8
+ name = "BaseProvider";
9
+ /**
10
+ * @inheritdoc
11
+ */
12
+ isLowerVersion = require_zip.defaultIsLowerVersion;
13
+ /**
14
+ * @inheritdoc
15
+ */
16
+ verifySignaure = require_zip.defaultVerifySignature;
17
+ /**
18
+ * @inheritdoc
19
+ */
20
+ unzipFile = require_zip.defaultUnzipFile;
21
+ };
22
+ //#endregion
23
+ //#region src/provider/local.ts
24
+ /**
25
+ * Update Provider for local development
26
+ * - download update json from `{baseDir}/{versionPath}`
27
+ * - download update asar from `{baseDir}/{name}-{version}.asar.gz`
28
+ *
29
+ * This provider is useful for testing updates during development without
30
+ * needing to deploy to a remote server.
31
+ * @param options provider options
32
+ */
33
+ var LocalDevProvider = class extends BaseProvider {
34
+ name = "LocalDevProvider";
35
+ verifySignaure;
36
+ options;
37
+ constructor(options) {
38
+ super();
39
+ const resolvedOptions = {
40
+ chunkSize: 64 * 1024,
41
+ chunkDelay: 30,
42
+ ...options
43
+ };
44
+ if (resolvedOptions.chunkSize <= 0) throw new Error("localDevUpdate.chunkSize must be greater than 0");
45
+ if (resolvedOptions.chunkDelay < 0) throw new Error("localDevUpdate.chunkDelay must be greater than or equal to 0");
46
+ this.options = resolvedOptions;
47
+ this.verifySignaure = async function verifySignaure() {
48
+ return true;
49
+ };
50
+ }
51
+ /**
52
+ * @inheritdoc
53
+ */
54
+ async downloadJSON(name, versionPath, signal) {
55
+ signal.throwIfAborted();
56
+ const { beta, version, ...info } = await this.readJSON(versionPath);
57
+ const getURL = (ver) => node_path.default.join(this.options.baseDir, `${name}-${ver}.asar.gz`);
58
+ return {
59
+ ...info,
60
+ version,
61
+ url: getURL(version),
62
+ beta: {
63
+ ...beta,
64
+ url: getURL(beta.version)
65
+ }
66
+ };
67
+ }
68
+ /**
69
+ * @inheritdoc
70
+ */
71
+ async downloadAsar(info, signal, onDownloading) {
72
+ signal.throwIfAborted();
73
+ const fileBuffer = await node_fs_promises.default.readFile(info.url);
74
+ await this.emitProgress(fileBuffer, signal, onDownloading);
75
+ return fileBuffer;
76
+ }
77
+ async readJSON(versionPath) {
78
+ const fullPath = node_path.default.join(this.options.baseDir, versionPath);
79
+ const content = await node_fs_promises.default.readFile(fullPath, "utf-8");
80
+ const json = JSON.parse(content);
81
+ if (!require_zip.isUpdateJSON(json)) throw new Error(`Invalid update json: ${content}`);
82
+ return json;
83
+ }
84
+ async emitProgress(fileBuffer, signal, onDownloading) {
85
+ if (!onDownloading) return;
86
+ const total = fileBuffer.length;
87
+ let transferred = 0;
88
+ let lastTime = Date.now();
89
+ while (transferred < total) {
90
+ signal.throwIfAborted();
91
+ const currentTime = Date.now();
92
+ const delta = Math.min(this.options.chunkSize, total - transferred);
93
+ transferred += delta;
94
+ onDownloading({
95
+ delta,
96
+ percent: Math.round(transferred / total * 100),
97
+ total,
98
+ transferred,
99
+ bps: Math.round(delta / Math.max(currentTime - lastTime, 1) * 1e3)
100
+ });
101
+ lastTime = currentTime;
102
+ if (transferred < total && this.options.chunkDelay > 0) await new Promise((resolve) => setTimeout(resolve, this.options.chunkDelay));
103
+ }
104
+ }
105
+ };
106
+ //#endregion
107
+ Object.defineProperty(exports, "BaseProvider", {
108
+ enumerable: true,
109
+ get: function() {
110
+ return BaseProvider;
111
+ }
112
+ });
113
+ Object.defineProperty(exports, "LocalDevProvider", {
114
+ enumerable: true,
115
+ get: function() {
116
+ return LocalDevProvider;
117
+ }
118
+ });
@@ -0,0 +1,105 @@
1
+ import { c as defaultIsLowerVersion, o as defaultVerifySignature, t as defaultUnzipFile, u as isUpdateJSON } from "./zip-DUK3opmV.mjs";
2
+ import path from "node:path";
3
+ import fs from "node:fs/promises";
4
+ //#region src/provider/base.ts
5
+ var BaseProvider = class {
6
+ name = "BaseProvider";
7
+ /**
8
+ * @inheritdoc
9
+ */
10
+ isLowerVersion = defaultIsLowerVersion;
11
+ /**
12
+ * @inheritdoc
13
+ */
14
+ verifySignaure = defaultVerifySignature;
15
+ /**
16
+ * @inheritdoc
17
+ */
18
+ unzipFile = defaultUnzipFile;
19
+ };
20
+ //#endregion
21
+ //#region src/provider/local.ts
22
+ /**
23
+ * Update Provider for local development
24
+ * - download update json from `{baseDir}/{versionPath}`
25
+ * - download update asar from `{baseDir}/{name}-{version}.asar.gz`
26
+ *
27
+ * This provider is useful for testing updates during development without
28
+ * needing to deploy to a remote server.
29
+ * @param options provider options
30
+ */
31
+ var LocalDevProvider = class extends BaseProvider {
32
+ name = "LocalDevProvider";
33
+ verifySignaure;
34
+ options;
35
+ constructor(options) {
36
+ super();
37
+ const resolvedOptions = {
38
+ chunkSize: 64 * 1024,
39
+ chunkDelay: 30,
40
+ ...options
41
+ };
42
+ if (resolvedOptions.chunkSize <= 0) throw new Error("localDevUpdate.chunkSize must be greater than 0");
43
+ if (resolvedOptions.chunkDelay < 0) throw new Error("localDevUpdate.chunkDelay must be greater than or equal to 0");
44
+ this.options = resolvedOptions;
45
+ this.verifySignaure = async function verifySignaure() {
46
+ return true;
47
+ };
48
+ }
49
+ /**
50
+ * @inheritdoc
51
+ */
52
+ async downloadJSON(name, versionPath, signal) {
53
+ signal.throwIfAborted();
54
+ const { beta, version, ...info } = await this.readJSON(versionPath);
55
+ const getURL = (ver) => path.join(this.options.baseDir, `${name}-${ver}.asar.gz`);
56
+ return {
57
+ ...info,
58
+ version,
59
+ url: getURL(version),
60
+ beta: {
61
+ ...beta,
62
+ url: getURL(beta.version)
63
+ }
64
+ };
65
+ }
66
+ /**
67
+ * @inheritdoc
68
+ */
69
+ async downloadAsar(info, signal, onDownloading) {
70
+ signal.throwIfAborted();
71
+ const fileBuffer = await fs.readFile(info.url);
72
+ await this.emitProgress(fileBuffer, signal, onDownloading);
73
+ return fileBuffer;
74
+ }
75
+ async readJSON(versionPath) {
76
+ const fullPath = path.join(this.options.baseDir, versionPath);
77
+ const content = await fs.readFile(fullPath, "utf-8");
78
+ const json = JSON.parse(content);
79
+ if (!isUpdateJSON(json)) throw new Error(`Invalid update json: ${content}`);
80
+ return json;
81
+ }
82
+ async emitProgress(fileBuffer, signal, onDownloading) {
83
+ if (!onDownloading) return;
84
+ const total = fileBuffer.length;
85
+ let transferred = 0;
86
+ let lastTime = Date.now();
87
+ while (transferred < total) {
88
+ signal.throwIfAborted();
89
+ const currentTime = Date.now();
90
+ const delta = Math.min(this.options.chunkSize, total - transferred);
91
+ transferred += delta;
92
+ onDownloading({
93
+ delta,
94
+ percent: Math.round(transferred / total * 100),
95
+ total,
96
+ transferred,
97
+ bps: Math.round(delta / Math.max(currentTime - lastTime, 1) * 1e3)
98
+ });
99
+ lastTime = currentTime;
100
+ if (transferred < total && this.options.chunkDelay > 0) await new Promise((resolve) => setTimeout(resolve, this.options.chunkDelay));
101
+ }
102
+ }
103
+ };
104
+ //#endregion
105
+ export { BaseProvider as n, LocalDevProvider as t };
package/dist/provider.cjs CHANGED
@@ -1,27 +1,10 @@
1
- const require_version = require('./version-aPrLuz_-.cjs');
2
- const require_zip = require('./zip-BCC7FAQ_.cjs');
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_local = require("./local-Daf8naRn.cjs");
3
+ const require_download = require("./download-BYnkme_X.cjs");
3
4
  let node_url = require("node:url");
4
-
5
- //#region src/provider/base.ts
6
- var BaseProvider = class {
7
- name = "BaseProvider";
8
- /**
9
- * @inheritdoc
10
- */
11
- isLowerVersion = require_version.defaultIsLowerVersion;
12
- /**
13
- * @inheritdoc
14
- */
15
- verifySignaure = require_zip.defaultVerifySignature;
16
- /**
17
- * @inheritdoc
18
- */
19
- unzipFile = require_zip.defaultUnzipFile;
20
- };
21
-
22
- //#endregion
23
5
  //#region src/provider/github/base.ts
24
- var BaseGitHubProvider = class extends BaseProvider {
6
+ var BaseGitHubProvider = class extends require_local.BaseProvider {
7
+ options;
25
8
  constructor(options) {
26
9
  super();
27
10
  this.options = options;
@@ -32,12 +15,12 @@ var BaseGitHubProvider = class extends BaseProvider {
32
15
  set urlHandler(handler) {
33
16
  this.options.urlHandler = handler;
34
17
  }
35
- async parseURL(extraPath) {
36
- const url = new node_url.URL(`/${this.options.user}/${this.options.repo}/${extraPath}`, "https://github.com");
18
+ async parseURL(pathOrURL) {
19
+ const url = node_url.URL.canParse(pathOrURL) ? new node_url.URL(pathOrURL) : new node_url.URL(`/${this.options.user}/${this.options.repo}/${pathOrURL}`, "https://github.com");
37
20
  return (await this.urlHandler?.(url) || url).toString();
38
21
  }
39
22
  async downloadJSON(name, versionPath, signal) {
40
- const { beta, version, ...info } = await require_zip.defaultDownloadUpdateJSON(await this.parseURL(await this.getVersionURL(versionPath, signal)), this.getHeaders("json"), signal);
23
+ const { beta, version, ...info } = await require_download.defaultDownloadUpdateJSON(await this.parseURL(await this.getVersionURL(versionPath, signal)), this.getHeaders("json"), signal);
41
24
  const getURL = (ver) => this.parseURL(`releases/download/v${ver}/${name}-${ver}.asar.gz`);
42
25
  return {
43
26
  ...info,
@@ -53,10 +36,9 @@ var BaseGitHubProvider = class extends BaseProvider {
53
36
  * @inheritdoc
54
37
  */
55
38
  async downloadAsar(info, signal, onDownloading) {
56
- return await require_zip.defaultDownloadAsar(info.url, this.getHeaders("octet-stream"), signal, onDownloading);
39
+ return await require_download.defaultDownloadAsar(info.url, this.getHeaders("octet-stream"), signal, onDownloading);
57
40
  }
58
41
  };
59
-
60
42
  //#endregion
61
43
  //#region src/provider/github/api.ts
62
44
  const ERROR_MSG = "Cannot find UpdateJSON in latest release";
@@ -83,13 +65,12 @@ var GitHubApiProvider = class extends BaseGitHubProvider {
83
65
  */
84
66
  async getVersionURL(versionPath, signal) {
85
67
  const basename = versionPath.slice(versionPath.lastIndexOf("/") + 1);
86
- const data = await require_zip.defaultDownloadText(await this.parseURL(`https://api.github.com/repos/${this.options.user}/${this.options.repo}/releases?per_page=1`), this.getHeaders("vnd.github.v3+json"), signal, require_zip.resolveJson);
68
+ const data = await require_download.defaultDownloadText(await this.parseURL(`https://api.github.com/repos/${this.options.user}/${this.options.repo}/releases?per_page=1`), this.getHeaders("vnd.github.v3+json"), signal, require_download.resolveJson);
87
69
  const versionAssets = data[0]?.assets.find((asset) => asset.name === basename);
88
70
  if (!versionAssets) throw new Error(`${ERROR_MSG}, ${"message" in data ? data.message : "please check the release assets"}`);
89
71
  return versionAssets.browser_download_url;
90
72
  }
91
73
  };
92
-
93
74
  //#endregion
94
75
  //#region src/provider/github/atom.ts
95
76
  /**
@@ -113,14 +94,14 @@ var GitHubAtomProvider = class extends BaseGitHubProvider {
113
94
  * @inheritdoc
114
95
  */
115
96
  async getVersionURL(versionPath, signal) {
116
- return `releases/download/v${await require_zip.defaultDownloadText(await this.parseURL(`releases.atom`), this.getHeaders("xml"), signal, (data, resolve, reject) => {
97
+ const tag = await require_download.defaultDownloadText(await this.parseURL(`releases.atom`), this.getHeaders("xml"), signal, (data, resolve, reject) => {
117
98
  const result = data.match(/<entry>\s*<id>([^<]*\/)?([^/<]+)<\/id>/)?.[2];
118
99
  if (result) resolve(result);
119
100
  else reject("No tag matched");
120
- })}/${versionPath}`;
101
+ });
102
+ return `releases/download/v${tag.startsWith("v") ? tag.slice(1) : tag}/${versionPath}`;
121
103
  }
122
104
  };
123
-
124
105
  //#endregion
125
106
  //#region src/provider/github/file.ts
126
107
  /**
@@ -147,16 +128,16 @@ var GitHubProvider = class extends BaseGitHubProvider {
147
128
  return `raw/${this.options.branch}/${versionPath}`;
148
129
  }
149
130
  };
150
-
151
131
  //#endregion
152
132
  exports.BaseGitHubProvider = BaseGitHubProvider;
153
- exports.BaseProvider = BaseProvider;
133
+ exports.BaseProvider = require_local.BaseProvider;
154
134
  exports.GitHubApiProvider = GitHubApiProvider;
155
135
  exports.GitHubAtomProvider = GitHubAtomProvider;
156
136
  exports.GitHubProvider = GitHubProvider;
157
- exports.defaultDownloadAsar = require_zip.defaultDownloadAsar;
158
- exports.defaultDownloadText = require_zip.defaultDownloadText;
159
- exports.defaultDownloadUpdateJSON = require_zip.defaultDownloadUpdateJSON;
160
- exports.downloadUtil = require_zip.downloadUtil;
161
- exports.getHeader = require_zip.getHeader;
162
- exports.resolveJson = require_zip.resolveJson;
137
+ exports.LocalDevProvider = require_local.LocalDevProvider;
138
+ exports.defaultDownloadAsar = require_download.defaultDownloadAsar;
139
+ exports.defaultDownloadText = require_download.defaultDownloadText;
140
+ exports.defaultDownloadUpdateJSON = require_download.defaultDownloadUpdateJSON;
141
+ exports.downloadUtil = require_download.downloadUtil;
142
+ exports.getHeader = require_download.getHeader;
143
+ exports.resolveJson = require_download.resolveJson;
@@ -1,5 +1,6 @@
1
- import { a as UpdateJSONWithURL, i as UpdateInfoWithURL, m as Promisable, n as IProvider, r as URLHandler, t as DownloadingInfo } from "./types-BM9Jfu7q.cjs";
2
- import { a as getHeader, i as downloadUtil, n as defaultDownloadText, o as resolveJson, r as defaultDownloadUpdateJSON, t as defaultDownloadAsar } from "./download-DO7iuxEJ.cjs";
1
+ import { a as VersionJSON, i as UpdateInfoWithURL, m as Promisable, n as IProvider, r as URLHandler, t as DownloadingInfo } from "./types-BOqQ_r5Q.cjs";
2
+ import { a as getHeader, i as downloadUtil, n as defaultDownloadText, o as resolveJson, r as defaultDownloadUpdateJSON, t as defaultDownloadAsar } from "./download-BjWmHHAu.cjs";
3
+ import { Buffer as Buffer$1 } from "node:buffer";
3
4
 
4
5
  //#region src/provider/base.d.ts
5
6
  declare abstract class BaseProvider implements IProvider {
@@ -19,7 +20,7 @@ declare abstract class BaseProvider implements IProvider {
19
20
  /**
20
21
  * @inheritdoc
21
22
  */
22
- abstract downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<UpdateJSONWithURL>;
23
+ abstract downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<VersionJSON>;
23
24
  /**
24
25
  * @inheritdoc
25
26
  */
@@ -56,10 +57,10 @@ declare abstract class BaseGitHubProvider<T extends BaseGitHubProviderOptions =
56
57
  constructor(options: T);
57
58
  get urlHandler(): URLHandler | undefined;
58
59
  set urlHandler(handler: URLHandler);
59
- protected parseURL(extraPath: string): Promise<string>;
60
+ protected parseURL(pathOrURL: string): Promise<string>;
60
61
  protected abstract getHeaders(accept: string): Record<string, string>;
61
62
  protected abstract getVersionURL(versionPath: string, signal: AbortSignal): Promisable<string>;
62
- downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<UpdateJSONWithURL>;
63
+ downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<VersionJSON>;
63
64
  /**
64
65
  * @inheritdoc
65
66
  */
@@ -80,7 +81,7 @@ interface GitHubApiProviderOptions extends BaseGitHubProviderOptions {
80
81
  * @param options provider options
81
82
  */
82
83
  declare class GitHubApiProvider extends BaseGitHubProvider<GitHubApiProviderOptions> {
83
- name: string;
84
+ override name: string;
84
85
  protected getHeaders(accept: string): Record<string, string>;
85
86
  /**
86
87
  * @inheritdoc
@@ -99,7 +100,7 @@ declare class GitHubApiProvider extends BaseGitHubProvider<GitHubApiProviderOpti
99
100
  * @param options provider options
100
101
  */
101
102
  declare class GitHubAtomProvider extends BaseGitHubProvider {
102
- name: string;
103
+ override name: string;
103
104
  protected getHeaders(accept: string): Record<string, string>;
104
105
  /**
105
106
  * @inheritdoc
@@ -124,10 +125,53 @@ interface GitHubProviderOptions extends BaseGitHubProviderOptions {
124
125
  * @param options provider options
125
126
  */
126
127
  declare class GitHubProvider extends BaseGitHubProvider<GitHubProviderOptions> {
127
- name: string;
128
+ override name: string;
128
129
  constructor(options: GitHubProviderOptions);
129
130
  protected getHeaders(accept: string): Record<string, string>;
130
131
  protected getVersionURL(versionPath: string): string;
131
132
  }
132
133
  //#endregion
133
- export { BaseGitHubProvider, BaseGitHubProviderOptions, BaseProvider, DownloadingInfo, GitHubApiProvider, GitHubApiProviderOptions, GitHubAtomProvider, GitHubProvider, GitHubProviderOptions, IProvider, URLHandler, UpdateInfoWithURL, UpdateJSONWithURL, defaultDownloadAsar, defaultDownloadText, defaultDownloadUpdateJSON, downloadUtil, getHeader, resolveJson };
134
+ //#region src/provider/local.d.ts
135
+ interface LocalDevProviderOptions {
136
+ /**
137
+ * Base directory for update files
138
+ */
139
+ baseDir: string;
140
+ /**
141
+ * Local read chunk size for simulated download progress
142
+ * @default 64 * 1024
143
+ */
144
+ chunkSize?: number;
145
+ /**
146
+ * Delay between chunks in milliseconds
147
+ * @default 30
148
+ */
149
+ chunkDelay?: number;
150
+ }
151
+ /**
152
+ * Update Provider for local development
153
+ * - download update json from `{baseDir}/{versionPath}`
154
+ * - download update asar from `{baseDir}/{name}-{version}.asar.gz`
155
+ *
156
+ * This provider is useful for testing updates during development without
157
+ * needing to deploy to a remote server.
158
+ * @param options provider options
159
+ */
160
+ declare class LocalDevProvider extends BaseProvider {
161
+ override name: string;
162
+ override verifySignaure: IProvider["verifySignaure"];
163
+ private readonly options;
164
+ constructor(options: LocalDevProviderOptions);
165
+ /**
166
+ * @inheritdoc
167
+ */
168
+ downloadJSON(name: string, versionPath: string, signal: AbortSignal): Promise<VersionJSON>;
169
+ /**
170
+ * @inheritdoc
171
+ */
172
+ downloadAsar(info: UpdateInfoWithURL, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer$1>;
173
+ private readJSON;
174
+ private emitProgress;
175
+ }
176
+ //#endregion
177
+ export { BaseGitHubProvider, BaseGitHubProviderOptions, BaseProvider, DownloadingInfo, GitHubApiProvider, GitHubApiProviderOptions, GitHubAtomProvider, GitHubProvider, GitHubProviderOptions, IProvider, LocalDevProvider, LocalDevProviderOptions, URLHandler, UpdateInfoWithURL, VersionJSON, defaultDownloadAsar, defaultDownloadText, defaultDownloadUpdateJSON, downloadUtil, getHeader, resolveJson };