electron-incremental-update 2.0.0-beta.1 → 2.0.0-beta.11

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/provider.cjs CHANGED
@@ -1,58 +1,17 @@
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 url = require('url');
4
+ var electron = require('electron');
5
+ var crypto = require('crypto');
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
- }
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
48
9
 
49
- // src/utils/zip.ts
50
- var import_node_fs2 = require("fs");
51
- var import_node_zlib = require("zlib");
10
+ var electron__default = /*#__PURE__*/_interopDefault(electron);
11
+ var crypto__default = /*#__PURE__*/_interopDefault(crypto);
12
+ var zlib__default = /*#__PURE__*/_interopDefault(zlib);
52
13
 
53
- // src/utils/unzip.ts
54
- var import_node_fs3 = require("fs");
55
- var import_node_zlib2 = require("zlib");
14
+ // src/provider/github.ts
56
15
 
57
16
  // src/utils/version.ts
58
17
  function parseVersion(version) {
@@ -74,11 +33,11 @@ function parseVersion(version) {
74
33
  ret.stageVersion = Number(_v) || -1;
75
34
  }
76
35
  if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch) || Number.isNaN(ret.stageVersion)) {
77
- throw new TypeError(`invalid version: ${version}`);
36
+ throw new TypeError(`Invalid version: ${version}`);
78
37
  }
79
38
  return ret;
80
39
  }
81
- function isLowerVersionDefault(oldVer, newVer) {
40
+ function defaultIsLowerVersion(oldVer, newVer) {
82
41
  const oldV = parseVersion(oldVer);
83
42
  const newV = parseVersion(newVer);
84
43
  function compareStrings(str1, str2) {
@@ -99,47 +58,24 @@ function isLowerVersionDefault(oldVer, newVer) {
99
58
  return false;
100
59
  }
101
60
  function isUpdateJSON(json) {
102
- const is = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
61
+ const is = (j) => !!(j && j.minimumVersion && j.signature && j.version);
103
62
  return is(json) && is(json?.beta);
104
63
  }
105
64
 
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 (error) {
129
- return void 0;
65
+ // src/provider/download.ts
66
+ function getHeader(headers, key) {
67
+ const value = headers[key];
68
+ if (Array.isArray(value)) {
69
+ return value.length === 0 ? null : value[value.length - 1];
70
+ } else {
71
+ return value;
130
72
  }
131
73
  }
132
-
133
- // src/utils/crypto/encrypt.ts
134
- var import_node_crypto3 = require("crypto");
135
-
136
- // src/provider/download.ts
137
- var import_electron2 = require("electron");
138
- async function downlaodFn(url, headers, onResponse) {
139
- await waitAppReady();
74
+ async function downloadFn(url, headers, signal, onResponse) {
75
+ await electron__default.default.app.whenReady();
140
76
  return new Promise((resolve, reject) => {
141
- const request = import_electron2.net.request({ url, method: "GET", redirect: "follow" });
142
- Object.keys(headers).forEach((key) => request.setHeader(key, headers[key]));
77
+ const request = electron__default.default.net.request({ url, method: "GET", redirect: "follow", headers, cache: "no-cache" });
78
+ signal.addEventListener("abort", () => request.abort(), { once: true });
143
79
  request.on("response", (resp) => {
144
80
  resp.on("aborted", () => reject(new Error("aborted")));
145
81
  resp.on("error", () => reject(new Error("download error")));
@@ -149,79 +85,162 @@ async function downlaodFn(url, headers, onResponse) {
149
85
  request.end();
150
86
  });
151
87
  }
152
- async function downloadUpdateJSONDefault(url, headers) {
153
- return await downlaodFn(url, headers, (resp, resolve, reject) => {
154
- let data = "";
155
- resp.on("data", (chunk) => data += chunk);
156
- resp.on("end", () => {
157
- try {
158
- const json = JSON.parse(data);
159
- if (isUpdateJSON(json)) {
160
- resolve(json);
161
- } else {
162
- throw Error;
88
+ async function defaultDownloadUpdateJSON(url, headers, signal) {
89
+ return await downloadFn(
90
+ url,
91
+ headers,
92
+ signal,
93
+ (resp, resolve, reject) => {
94
+ let data = "";
95
+ 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));
163
106
  }
164
- } catch (ignore) {
165
- reject(new Error("invalid update json"));
166
- }
167
- });
168
- });
107
+ });
108
+ }
109
+ );
110
+ }
111
+ async function defaultDownloadAsar(url, headers, signal, onDownloading) {
112
+ let transferred = 0;
113
+ let time = Date.now();
114
+ return await downloadFn(
115
+ url,
116
+ headers,
117
+ signal,
118
+ (resp, resolve) => {
119
+ const total = +getHeader(resp.headers, "content-length") || -1;
120
+ let data = [];
121
+ resp.on("data", (chunk) => {
122
+ const delta = chunk.length;
123
+ transferred += delta;
124
+ const current = Date.now();
125
+ onDownloading?.({
126
+ percent: total ? +(transferred / total).toFixed(2) * 100 : -1,
127
+ total,
128
+ transferred,
129
+ delta,
130
+ bps: delta / ((current - time) * 1e3)
131
+ });
132
+ time = current;
133
+ data.push(chunk);
134
+ });
135
+ resp.on("end", () => resolve(Buffer.concat(data)));
136
+ }
137
+ );
138
+ }
139
+ function hashBuffer(data, length) {
140
+ const hash = crypto__default.default.createHash("SHA256").update(data).digest("binary");
141
+ return Buffer.from(hash).subarray(0, length);
142
+ }
143
+ function aesDecrypt(encryptedText, key, iv) {
144
+ const decipher = crypto__default.default.createDecipheriv("aes-256-cbc", key, iv);
145
+ return decipher.update(encryptedText, "base64url", "utf8") + decipher.final("utf8");
146
+ }
147
+ function defaultVerifySignature(buffer, version, signature, cert) {
148
+ try {
149
+ const [sig, ver] = aesDecrypt(signature, hashBuffer(cert, 32), hashBuffer(buffer, 16)).split("%");
150
+ if (ver !== version) {
151
+ return false;
152
+ }
153
+ return crypto__default.default.createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
154
+ } catch {
155
+ return false;
156
+ }
169
157
  }
170
- async function downloadAsarBufferDefault(url, headers, total, onDownloading) {
171
- let current = 0;
172
- return await downlaodFn(url, headers, (resp, resolve) => {
173
- let data = [];
174
- resp.on("data", (chunk) => {
175
- current += chunk.length;
176
- onDownloading?.({ percent: `${+(current / total).toFixed(2) * 100}%`, total, current });
177
- data.push(chunk);
158
+ async function defaultUnzipFile(buffer) {
159
+ return new Promise((resolve, reject) => {
160
+ zlib__default.default.brotliDecompress(buffer, (err, buffer2) => {
161
+ if (err) {
162
+ reject(err);
163
+ } else {
164
+ resolve(buffer2);
165
+ }
178
166
  });
179
- resp.on("end", () => resolve(Buffer.concat(data)));
180
167
  });
181
168
  }
182
169
 
170
+ // src/provider/base.ts
171
+ var BaseProvider = class {
172
+ name = "BaseProvider";
173
+ /**
174
+ * @inheritdoc
175
+ */
176
+ isLowerVersion = defaultIsLowerVersion;
177
+ /**
178
+ * @inheritdoc
179
+ */
180
+ verifySignaure = defaultVerifySignature;
181
+ /**
182
+ * @inheritdoc
183
+ */
184
+ unzipFile = defaultUnzipFile;
185
+ };
186
+
183
187
  // src/provider/github.ts
184
- var GitHubProvider = class {
185
- ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
188
+ var GitHubProvider = class extends BaseProvider {
186
189
  name = "GithubProvider";
187
- urlHandler;
188
- url;
189
- extraHeaders;
190
+ options;
191
+ /**
192
+ * Update Provider for Github repo
193
+ * - download update json from `https://raw.githubusercontent.com/{user}/{repo}/HEAD/{versionPath}`
194
+ * - download update asar from `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
195
+ *
196
+ * you can setup `urlHandler` in {@link GitHubProviderOptions} to modify url before request
197
+ * @param options provider options
198
+ */
190
199
  constructor(options) {
191
- this.url = new URL(options.url);
192
- this.extraHeaders = options.extraHeaders;
193
- this.urlHandler = options.urlHandler;
194
- if (this.url.host !== "github.com") {
195
- throw new Error(`${this.name}: invalid github url: ${options.url}`);
196
- }
197
- if (!this.url.pathname.endsWith("/")) {
198
- this.url.pathname += "/";
200
+ super();
201
+ this.options = options;
202
+ if (!options.branch) {
203
+ this.options.branch = "HEAD";
199
204
  }
200
205
  }
201
- parseURL(isDownloadAsar, path) {
202
- const url = this.url.href + path;
203
- return this.urlHandler ? this.urlHandler(url, isDownloadAsar) : url;
206
+ get urlHandler() {
207
+ return this.options.urlHandler;
208
+ }
209
+ set urlHandler(handler) {
210
+ this.options.urlHandler = handler;
204
211
  }
205
- isLowerVersion = isLowerVersionDefault;
206
- verifySignaure = verifySignatureDefault;
207
- async downloadJSON(versionPath) {
208
- return await downloadUpdateJSONDefault(
209
- this.parseURL(false, `HEAD/${versionPath}`),
210
- { userAgent: this.ua, accept: "application/json", ...this.extraHeaders }
212
+ async parseURL(isDownloadAsar, extraPath) {
213
+ const url$1 = new url.URL(
214
+ `/${this.options.user}/${this.options.repo}/${extraPath}`,
215
+ "https://" + (isDownloadAsar ? "github.com" : "raw.githubusercontent.com")
211
216
  );
217
+ return (await this.urlHandler?.(url$1, isDownloadAsar) || url$1).toString();
212
218
  }
213
- async downloadBuffer(name, { version, size }, onDownloading) {
214
- return await downloadAsarBufferDefault(
215
- this.parseURL(true, `releases/download/v${version}/${name}-${version}.asar.gz`),
216
- { userAgent: this.ua, accept: "application/octet-stream", ...this.extraHeaders },
217
- size,
219
+ /**
220
+ * @inheritdoc
221
+ */
222
+ async downloadJSON(versionPath, signal) {
223
+ return await defaultDownloadUpdateJSON(
224
+ await this.parseURL(false, `${this.options.branch}/${versionPath}`),
225
+ { Accept: "application/json", ...this.options.extraHeaders },
226
+ signal
227
+ );
228
+ }
229
+ /**
230
+ * @inheritdoc
231
+ */
232
+ async downloadAsar(name, info, signal, onDownloading) {
233
+ return await defaultDownloadAsar(
234
+ await this.parseURL(true, `releases/download/v${info.version}/${name}-${info.version}.asar.gz`),
235
+ { Accept: "application/octet-stream", ...this.options.extraHeaders },
236
+ signal,
218
237
  onDownloading
219
238
  );
220
239
  }
221
240
  };
222
- // Annotate the CommonJS export names for ESM import in node:
223
- 0 && (module.exports = {
224
- GitHubProvider,
225
- downloadAsarBufferDefault,
226
- downloadUpdateJSONDefault
227
- });
241
+
242
+ exports.BaseProvider = BaseProvider;
243
+ exports.GitHubProvider = GitHubProvider;
244
+ exports.defaultDownloadAsar = defaultDownloadAsar;
245
+ exports.defaultDownloadUpdateJSON = defaultDownloadUpdateJSON;
246
+ exports.getHeader = getHeader;
@@ -1,37 +1,109 @@
1
- import { i as isLowerVersionDefault, U as UpdateJSON, a as UpdateInfo } from './version-CffZWDhZ.cjs';
2
- import { v as verifySignatureDefault } from './decrypt-BNBcodiO.cjs';
3
- import { U as URLHandler, I as IProvider, D as DownloadingInfo, O as OnDownloading } from './types-DxPmQmaq.cjs';
4
- import '@subframe7536/type-utils';
1
+ import { d as defaultIsLowerVersion, a as UpdateJSON, U as UpdateInfo } from './version-BYVQ367i.cjs';
2
+ import { I as IProvider, D as DownloadingInfo, U as URLHandler, O as OnDownloading } from './types-CGSkHX4Y.cjs';
3
+ import { f as defaultVerifySignature, a as defaultUnzipFile } from './zip-rm9ED9nU.cjs';
4
+ import { Arrayable } from '@subframe7536/type-utils';
5
+
6
+ declare abstract class BaseProvider implements IProvider {
7
+ name: string;
8
+ /**
9
+ * @inheritdoc
10
+ */
11
+ isLowerVersion: typeof defaultIsLowerVersion;
12
+ /**
13
+ * @inheritdoc
14
+ */
15
+ verifySignaure: typeof defaultVerifySignature;
16
+ /**
17
+ * @inheritdoc
18
+ */
19
+ unzipFile: typeof defaultUnzipFile;
20
+ /**
21
+ * @inheritdoc
22
+ */
23
+ abstract downloadJSON(versionPath: string, signal: AbortSignal): Promise<UpdateJSON>;
24
+ /**
25
+ * @inheritdoc
26
+ */
27
+ abstract downloadAsar(name: string, info: UpdateInfo, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
28
+ }
5
29
 
6
30
  interface GitHubProviderOptions {
7
31
  /**
8
- * github repo root url
9
- * @example 'https://github.com/electron/electron'
32
+ * Github user name
33
+ */
34
+ user: string;
35
+ /**
36
+ * Github repo name
37
+ */
38
+ repo: string;
39
+ /**
40
+ * Github branch name that fetch version
41
+ * @default 'HEAD'
42
+ */
43
+ branch?: string;
44
+ /**
45
+ * Extra headers
10
46
  */
11
- url: string;
12
47
  extraHeaders?: Record<string, string>;
13
48
  /**
14
- * custom url handler
15
- *
16
- * for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDN links}
49
+ * Custom url handler ({@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L40 some public CDN links})
50
+ * @example
51
+ * (url, isDownloadAsar) => {
52
+ * if (isDownloadAsar) {
53
+ * url.hostname = 'mirror.ghproxy.com'
54
+ * url.pathname = 'https://github.com' + url.pathname
55
+ * return url
56
+ * }
57
+ * }
17
58
  */
18
59
  urlHandler?: URLHandler;
19
60
  }
20
- declare class GitHubProvider implements IProvider {
21
- private ua;
61
+ declare class GitHubProvider extends BaseProvider {
22
62
  name: string;
23
- urlHandler?: URLHandler;
24
- private url;
25
- private extraHeaders?;
63
+ private options;
64
+ /**
65
+ * Update Provider for Github repo
66
+ * - download update json from `https://raw.githubusercontent.com/{user}/{repo}/HEAD/{versionPath}`
67
+ * - download update asar from `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
68
+ *
69
+ * you can setup `urlHandler` in {@link GitHubProviderOptions} to modify url before request
70
+ * @param options provider options
71
+ */
26
72
  constructor(options: GitHubProviderOptions);
73
+ get urlHandler(): URLHandler | undefined;
74
+ set urlHandler(handler: URLHandler);
27
75
  private parseURL;
28
- isLowerVersion: typeof isLowerVersionDefault;
29
- verifySignaure: typeof verifySignatureDefault;
30
- downloadJSON(versionPath: string): Promise<UpdateJSON>;
31
- downloadBuffer(name: string, { version, size }: UpdateInfo, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
76
+ /**
77
+ * @inheritdoc
78
+ */
79
+ downloadJSON(versionPath: string, signal: AbortSignal): Promise<UpdateJSON>;
80
+ /**
81
+ * @inheritdoc
82
+ */
83
+ downloadAsar(name: string, info: UpdateInfo, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
32
84
  }
33
85
 
34
- declare function downloadUpdateJSONDefault(url: string, headers: Record<string, any>): Promise<UpdateJSON>;
35
- declare function downloadAsarBufferDefault(url: string, headers: Record<string, any>, total: number, onDownloading?: OnDownloading): Promise<Buffer>;
86
+ /**
87
+ * Safe get value from header
88
+ * @param headers response header
89
+ * @param key target header key
90
+ */
91
+ declare function getHeader(headers: Record<string, Arrayable<string>>, key: any): any;
92
+ /**
93
+ * Default function to download json and parse to UpdateJson
94
+ * @param url target url
95
+ * @param headers extra headers
96
+ * @param signal abort signal
97
+ */
98
+ declare function defaultDownloadUpdateJSON(url: string, headers: Record<string, any>, signal: AbortSignal): Promise<UpdateJSON>;
99
+ /**
100
+ * Default function to download asar buffer,
101
+ * get total size from `Content-Length` header
102
+ * @param url target url
103
+ * @param headers extra headers
104
+ * @param signal abort signal
105
+ * @param onDownloading on downloading callback
106
+ */
107
+ declare function defaultDownloadAsar(url: string, headers: Record<string, any>, signal: AbortSignal, onDownloading?: OnDownloading): Promise<Buffer>;
36
108
 
37
- export { DownloadingInfo, GitHubProvider, type GitHubProviderOptions, IProvider, OnDownloading, URLHandler, downloadAsarBufferDefault, downloadUpdateJSONDefault };
109
+ export { BaseProvider, DownloadingInfo, GitHubProvider, type GitHubProviderOptions, IProvider, OnDownloading, URLHandler, defaultDownloadAsar, defaultDownloadUpdateJSON, getHeader };
@@ -1,37 +1,109 @@
1
- import { i as isLowerVersionDefault, U as UpdateJSON, a as UpdateInfo } from './version-CffZWDhZ.js';
2
- import { v as verifySignatureDefault } from './decrypt-BNBcodiO.js';
3
- import { U as URLHandler, I as IProvider, D as DownloadingInfo, O as OnDownloading } from './types-seJf3Wbc.js';
4
- import '@subframe7536/type-utils';
1
+ import { d as defaultIsLowerVersion, a as UpdateJSON, U as UpdateInfo } from './version-BYVQ367i.js';
2
+ import { I as IProvider, D as DownloadingInfo, U as URLHandler, O as OnDownloading } from './types-C8JhnJjU.js';
3
+ import { f as defaultVerifySignature, a as defaultUnzipFile } from './zip-rm9ED9nU.js';
4
+ import { Arrayable } from '@subframe7536/type-utils';
5
+
6
+ declare abstract class BaseProvider implements IProvider {
7
+ name: string;
8
+ /**
9
+ * @inheritdoc
10
+ */
11
+ isLowerVersion: typeof defaultIsLowerVersion;
12
+ /**
13
+ * @inheritdoc
14
+ */
15
+ verifySignaure: typeof defaultVerifySignature;
16
+ /**
17
+ * @inheritdoc
18
+ */
19
+ unzipFile: typeof defaultUnzipFile;
20
+ /**
21
+ * @inheritdoc
22
+ */
23
+ abstract downloadJSON(versionPath: string, signal: AbortSignal): Promise<UpdateJSON>;
24
+ /**
25
+ * @inheritdoc
26
+ */
27
+ abstract downloadAsar(name: string, info: UpdateInfo, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
28
+ }
5
29
 
6
30
  interface GitHubProviderOptions {
7
31
  /**
8
- * github repo root url
9
- * @example 'https://github.com/electron/electron'
32
+ * Github user name
33
+ */
34
+ user: string;
35
+ /**
36
+ * Github repo name
37
+ */
38
+ repo: string;
39
+ /**
40
+ * Github branch name that fetch version
41
+ * @default 'HEAD'
42
+ */
43
+ branch?: string;
44
+ /**
45
+ * Extra headers
10
46
  */
11
- url: string;
12
47
  extraHeaders?: Record<string, string>;
13
48
  /**
14
- * custom url handler
15
- *
16
- * for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDN links}
49
+ * Custom url handler ({@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L40 some public CDN links})
50
+ * @example
51
+ * (url, isDownloadAsar) => {
52
+ * if (isDownloadAsar) {
53
+ * url.hostname = 'mirror.ghproxy.com'
54
+ * url.pathname = 'https://github.com' + url.pathname
55
+ * return url
56
+ * }
57
+ * }
17
58
  */
18
59
  urlHandler?: URLHandler;
19
60
  }
20
- declare class GitHubProvider implements IProvider {
21
- private ua;
61
+ declare class GitHubProvider extends BaseProvider {
22
62
  name: string;
23
- urlHandler?: URLHandler;
24
- private url;
25
- private extraHeaders?;
63
+ private options;
64
+ /**
65
+ * Update Provider for Github repo
66
+ * - download update json from `https://raw.githubusercontent.com/{user}/{repo}/HEAD/{versionPath}`
67
+ * - download update asar from `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
68
+ *
69
+ * you can setup `urlHandler` in {@link GitHubProviderOptions} to modify url before request
70
+ * @param options provider options
71
+ */
26
72
  constructor(options: GitHubProviderOptions);
73
+ get urlHandler(): URLHandler | undefined;
74
+ set urlHandler(handler: URLHandler);
27
75
  private parseURL;
28
- isLowerVersion: typeof isLowerVersionDefault;
29
- verifySignaure: typeof verifySignatureDefault;
30
- downloadJSON(versionPath: string): Promise<UpdateJSON>;
31
- downloadBuffer(name: string, { version, size }: UpdateInfo, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
76
+ /**
77
+ * @inheritdoc
78
+ */
79
+ downloadJSON(versionPath: string, signal: AbortSignal): Promise<UpdateJSON>;
80
+ /**
81
+ * @inheritdoc
82
+ */
83
+ downloadAsar(name: string, info: UpdateInfo, signal: AbortSignal, onDownloading?: (info: DownloadingInfo) => void): Promise<Buffer>;
32
84
  }
33
85
 
34
- declare function downloadUpdateJSONDefault(url: string, headers: Record<string, any>): Promise<UpdateJSON>;
35
- declare function downloadAsarBufferDefault(url: string, headers: Record<string, any>, total: number, onDownloading?: OnDownloading): Promise<Buffer>;
86
+ /**
87
+ * Safe get value from header
88
+ * @param headers response header
89
+ * @param key target header key
90
+ */
91
+ declare function getHeader(headers: Record<string, Arrayable<string>>, key: any): any;
92
+ /**
93
+ * Default function to download json and parse to UpdateJson
94
+ * @param url target url
95
+ * @param headers extra headers
96
+ * @param signal abort signal
97
+ */
98
+ declare function defaultDownloadUpdateJSON(url: string, headers: Record<string, any>, signal: AbortSignal): Promise<UpdateJSON>;
99
+ /**
100
+ * Default function to download asar buffer,
101
+ * get total size from `Content-Length` header
102
+ * @param url target url
103
+ * @param headers extra headers
104
+ * @param signal abort signal
105
+ * @param onDownloading on downloading callback
106
+ */
107
+ declare function defaultDownloadAsar(url: string, headers: Record<string, any>, signal: AbortSignal, onDownloading?: OnDownloading): Promise<Buffer>;
36
108
 
37
- export { DownloadingInfo, GitHubProvider, type GitHubProviderOptions, IProvider, OnDownloading, URLHandler, downloadAsarBufferDefault, downloadUpdateJSONDefault };
109
+ export { BaseProvider, DownloadingInfo, GitHubProvider, type GitHubProviderOptions, IProvider, OnDownloading, URLHandler, defaultDownloadAsar, defaultDownloadUpdateJSON, getHeader };