electron-updater 4.3.7 → 4.3.8

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.
@@ -2,6 +2,7 @@
2
2
  import { BlockMapDataHolder, HttpExecutor } from "builder-util-runtime";
3
3
  import { BlockMap } from "builder-util-runtime/out/blockMapApi";
4
4
  import { OutgoingHttpHeaders, RequestOptions } from "http";
5
+ import { ProgressInfo, CancellationToken } from "builder-util-runtime";
5
6
  import { Logger } from "../main";
6
7
  import { URL } from "url";
7
8
  export interface DifferentialDownloaderOptions {
@@ -11,6 +12,8 @@ export interface DifferentialDownloaderOptions {
11
12
  readonly newFile: string;
12
13
  readonly requestHeaders: OutgoingHttpHeaders | null;
13
14
  readonly isUseMultipleRangeRequest?: boolean;
15
+ readonly cancellationToken: CancellationToken;
16
+ onProgress?(progress: ProgressInfo): void;
14
17
  }
15
18
  export declare abstract class DifferentialDownloader {
16
19
  protected readonly blockAwareFileInfo: BlockMapDataHolder;
@@ -67,6 +67,16 @@ function _multipleRangeDownloader() {
67
67
  return data;
68
68
  }
69
69
 
70
+ function _ProgressDifferentialDownloadCallbackTransform() {
71
+ const data = require("./ProgressDifferentialDownloadCallbackTransform");
72
+
73
+ _ProgressDifferentialDownloadCallbackTransform = function () {
74
+ return data;
75
+ };
76
+
77
+ return data;
78
+ }
79
+
70
80
  class DifferentialDownloader {
71
81
  // noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected
72
82
  constructor(blockAwareFileInfo, httpExecutor, options) {
@@ -171,7 +181,30 @@ class DifferentialDownloader {
171
181
  fd: newFileFd
172
182
  });
173
183
  await new Promise((resolve, reject) => {
174
- const streams = [];
184
+ const streams = []; // Create our download info transformer if we have one
185
+
186
+ let downloadInfoTransform = undefined;
187
+
188
+ if (!this.options.isUseMultipleRangeRequest && this.options.onProgress) {
189
+ // TODO: Does not support multiple ranges (someone feel free to PR this!)
190
+ const expectedByteCounts = [];
191
+ let grandTotalBytes = 0;
192
+
193
+ for (const task of tasks) {
194
+ if (task.kind === _downloadPlanBuilder().OperationKind.DOWNLOAD) {
195
+ expectedByteCounts.push(task.end - task.start);
196
+ grandTotalBytes += task.end - task.start;
197
+ }
198
+ }
199
+
200
+ const progressDifferentialDownloadInfo = {
201
+ expectedByteCounts: expectedByteCounts,
202
+ grandTotal: grandTotalBytes
203
+ };
204
+ downloadInfoTransform = new (_ProgressDifferentialDownloadCallbackTransform().ProgressDifferentialDownloadCallbackTransform)(progressDifferentialDownloadInfo, this.options.cancellationToken, this.options.onProgress);
205
+ streams.push(downloadInfoTransform);
206
+ }
207
+
175
208
  const digestTransform = new (_builderUtilRuntime().DigestTransform)(this.blockAwareFileInfo.sha512); // to simply debug, do manual validation to allow file to be fully written
176
209
 
177
210
  digestTransform.isValidateOnEnd = false;
@@ -233,6 +266,11 @@ class DifferentialDownloader {
233
266
  const operation = tasks[index++];
234
267
 
235
268
  if (operation.kind === _downloadPlanBuilder().OperationKind.COPY) {
269
+ // We are copying, let's not send status updates to the UI
270
+ if (downloadInfoTransform) {
271
+ downloadInfoTransform.beginFileCopy();
272
+ }
273
+
236
274
  (0, _DataSplitter().copyData)(operation, firstStream, oldFileFd, reject, () => w(index));
237
275
  return;
238
276
  }
@@ -243,6 +281,11 @@ class DifferentialDownloader {
243
281
 
244
282
  if (debug != null) {
245
283
  debug(`download range: ${range}`);
284
+ } // We are starting to download
285
+
286
+
287
+ if (downloadInfoTransform) {
288
+ downloadInfoTransform.beginRangeDownload();
246
289
  }
247
290
 
248
291
  const request = this.httpExecutor.createRequest(requestOptions, response => {
@@ -255,6 +298,11 @@ class DifferentialDownloader {
255
298
  end: false
256
299
  });
257
300
  response.once("end", () => {
301
+ // Pass on that we are downloading a segment
302
+ if (downloadInfoTransform) {
303
+ downloadInfoTransform.endRangeDownload();
304
+ }
305
+
258
306
  if (++downloadOperationCount === 100) {
259
307
  downloadOperationCount = 0;
260
308
  setTimeout(() => w(index), 1000);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/differentialDownloader/DifferentialDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockMapDataHolder, createHttpError, DigestTransform, HttpExecutor, configureRequestUrl, configureRequestOptions } from \"builder-util-runtime\"\nimport { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { close, open } from \"fs-extra\"\nimport { createWriteStream } from \"fs\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { Logger } from \"../main\"\nimport { copyData } from \"./DataSplitter\"\nimport { URL } from \"url\"\nimport { computeOperations, Operation, OperationKind } from \"./downloadPlanBuilder\"\nimport { checkIsRangesSupported, executeTasksUsingMultipleRangeRequests } from \"./multipleRangeDownloader\"\n\nexport interface DifferentialDownloaderOptions {\n readonly oldFile: string\n readonly newUrl: URL\n readonly logger: Logger\n readonly newFile: string\n\n readonly requestHeaders: OutgoingHttpHeaders | null\n\n readonly isUseMultipleRangeRequest?: boolean\n}\n\nexport abstract class DifferentialDownloader {\n fileMetadataBuffer: Buffer | null = null\n\n private readonly logger: Logger\n\n // noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected\n constructor(protected readonly blockAwareFileInfo: BlockMapDataHolder, readonly httpExecutor: HttpExecutor<any>, readonly options: DifferentialDownloaderOptions) {\n this.logger = options.logger\n }\n\n createRequestOptions(): RequestOptions {\n const result = {\n headers: {\n ...this.options.requestHeaders,\n accept: \"*/*\",\n },\n }\n configureRequestUrl(this.options.newUrl, result)\n // user-agent, cache-control and other common options\n configureRequestOptions(result)\n return result\n }\n\n protected doDownload(oldBlockMap: BlockMap, newBlockMap: BlockMap): Promise<any> {\n // we don't check other metadata like compressionMethod - generic check that it is make sense to differentially update is suitable for it\n if (oldBlockMap.version !== newBlockMap.version) {\n throw new Error(`version is different (${oldBlockMap.version} - ${newBlockMap.version}), full download is required`)\n }\n\n const logger = this.logger\n const operations = computeOperations(oldBlockMap, newBlockMap, logger)\n if (logger.debug != null) {\n logger.debug(JSON.stringify(operations, null, 2))\n }\n\n let downloadSize = 0\n let copySize = 0\n for (const operation of operations) {\n const length = operation.end - operation.start\n if (operation.kind === OperationKind.DOWNLOAD) {\n downloadSize += length\n }\n else {\n copySize += length\n }\n }\n\n const newSize = this.blockAwareFileInfo.size\n if ((downloadSize + copySize + (this.fileMetadataBuffer == null ? 0 : this.fileMetadataBuffer.length)) !== newSize) {\n throw new Error(`Internal error, size mismatch: downloadSize: ${downloadSize}, copySize: ${copySize}, newSize: ${newSize}`)\n }\n\n logger.info(`Full: ${formatBytes(newSize)}, To download: ${formatBytes(downloadSize)} (${Math.round(downloadSize / (newSize / 100))}%)`)\n\n return this.downloadFile(operations)\n }\n\n private downloadFile(tasks: Array<Operation>): Promise<any> {\n const fdList: Array<OpenedFile> = []\n const closeFiles = (): Promise<Array<void>> => {\n return Promise.all(fdList.map(openedFile => {\n return close(openedFile.descriptor)\n .catch(e => {\n this.logger.error(`cannot close file \"${openedFile.path}\": ${e}`)\n })\n }))\n }\n return this.doDownloadFile(tasks, fdList)\n .then(closeFiles)\n .catch(e => {\n // then must be after catch here (since then always throws error)\n return closeFiles()\n .catch(closeFilesError => {\n // closeFiles never throw error, but just to be sure\n try {\n this.logger.error(`cannot close files: ${closeFilesError}`)\n }\n catch (errorOnLog) {\n try {\n console.error(errorOnLog)\n }\n catch (ignored) {\n // ok, give up and ignore error\n }\n }\n throw e\n })\n .then(() => {\n throw e\n })\n })\n }\n\n private async doDownloadFile(tasks: Array<Operation>, fdList: Array<OpenedFile>): Promise<any> {\n const oldFileFd = await open(this.options.oldFile, \"r\")\n fdList.push({descriptor: oldFileFd, path: this.options.oldFile})\n const newFileFd = await open(this.options.newFile, \"w\")\n fdList.push({descriptor: newFileFd, path: this.options.newFile})\n const fileOut = createWriteStream(this.options.newFile, {fd: newFileFd})\n await new Promise((resolve, reject) => {\n const streams: Array<any> = []\n const digestTransform = new DigestTransform(this.blockAwareFileInfo.sha512)\n // to simply debug, do manual validation to allow file to be fully written\n digestTransform.isValidateOnEnd = false\n streams.push(digestTransform)\n\n // noinspection JSArrowFunctionCanBeReplacedWithShorthand\n fileOut.on(\"finish\", () => {\n (fileOut.close as any)(() => {\n // remove from fd list because closed successfully\n fdList.splice(1, 1)\n try {\n digestTransform.validate()\n }\n catch (e) {\n reject(e)\n return\n }\n\n resolve(undefined)\n })\n })\n\n streams.push(fileOut)\n\n let lastStream = null\n for (const stream of streams) {\n stream.on(\"error\", reject)\n if (lastStream == null) {\n lastStream = stream\n }\n else {\n lastStream = lastStream.pipe(stream)\n }\n }\n\n const firstStream = streams[0]\n\n let w: any\n if (this.options.isUseMultipleRangeRequest) {\n w = executeTasksUsingMultipleRangeRequests(this, tasks, firstStream, oldFileFd, reject)\n w(0)\n return\n }\n\n let downloadOperationCount = 0\n let actualUrl: string | null = null\n this.logger.info(`Differential download: ${this.options.newUrl}`)\n\n const requestOptions = this.createRequestOptions();\n (requestOptions as any).redirect = \"manual\"\n\n w = (index: number): void => {\n if (index >= tasks.length) {\n if (this.fileMetadataBuffer != null) {\n firstStream.write(this.fileMetadataBuffer)\n }\n firstStream.end()\n return\n }\n\n const operation = tasks[index++]\n if (operation.kind === OperationKind.COPY) {\n copyData(operation, firstStream, oldFileFd, reject, () => w(index))\n return\n }\n\n const range = `bytes=${operation.start}-${operation.end - 1}`\n requestOptions.headers!!.range = range\n\n const debug = this.logger.debug\n if (debug != null) {\n debug(`download range: ${range}`)\n }\n\n const request = this.httpExecutor.createRequest(requestOptions, response => {\n // Electron net handles redirects automatically, our NodeJS test server doesn't use redirects - so, we don't check 3xx codes.\n if (response.statusCode >= 400) {\n reject(createHttpError(response))\n }\n\n response.pipe(firstStream, {\n end: false\n })\n response.once(\"end\", () => {\n if (++downloadOperationCount === 100) {\n downloadOperationCount = 0\n setTimeout(() => w(index), 1000)\n }\n else {\n w(index)\n }\n })\n })\n request.on(\"redirect\", (statusCode: number, method: string, redirectUrl: string) => {\n this.logger.info(`Redirect to ${removeQuery(redirectUrl)}`)\n actualUrl = redirectUrl\n configureRequestUrl(new URL(actualUrl), requestOptions)\n request.followRedirect()\n })\n this.httpExecutor.addErrorAndTimeoutHandlers(request, reject)\n request.end()\n }\n\n w(0)\n })\n }\n\n protected async readRemoteBytes(start: number, endInclusive: number): Promise<Buffer> {\n const buffer = Buffer.allocUnsafe((endInclusive + 1) - start)\n const requestOptions = this.createRequestOptions()\n requestOptions.headers!!.range = `bytes=${start}-${endInclusive}`\n let position = 0\n await this.request(requestOptions, chunk => {\n chunk.copy(buffer, position)\n position += chunk.length\n })\n\n if (position !== buffer.length) {\n throw new Error(`Received data length ${position} is not equal to expected ${buffer.length}`)\n }\n return buffer\n }\n\n private request(requestOptions: RequestOptions, dataHandler: (chunk: Buffer) => void): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = this.httpExecutor.createRequest(requestOptions, response => {\n if (!checkIsRangesSupported(response, reject)) {\n return\n }\n\n response.on(\"data\", dataHandler)\n response.on(\"end\", () => resolve())\n })\n this.httpExecutor.addErrorAndTimeoutHandlers(request, reject)\n request.end()\n })\n }\n}\n\nfunction formatBytes(value: number, symbol = \" KB\"): string {\n return new Intl.NumberFormat(\"en\").format((value / 1024).toFixed(2) as any) + symbol\n}\n\n// safety\nfunction removeQuery(url: string): string {\n const index = url.indexOf(\"?\")\n return index < 0 ? url : url.substring(0, index)\n}\n\ninterface OpenedFile {\n readonly descriptor: number\n readonly path: string\n}"],"sourceRoot":""}
1
+ {"version":3,"sources":["../../src/differentialDownloader/DifferentialDownloader.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockMapDataHolder, createHttpError, DigestTransform, HttpExecutor, configureRequestUrl, configureRequestOptions } from \"builder-util-runtime\"\nimport { BlockMap } from \"builder-util-runtime/out/blockMapApi\"\nimport { close, open } from \"fs-extra\"\nimport { createWriteStream } from \"fs\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { ProgressInfo, CancellationToken } from \"builder-util-runtime\"\nimport { Logger } from \"../main\"\nimport { copyData } from \"./DataSplitter\"\nimport { URL } from \"url\"\nimport { computeOperations, Operation, OperationKind } from \"./downloadPlanBuilder\"\nimport { checkIsRangesSupported, executeTasksUsingMultipleRangeRequests } from \"./multipleRangeDownloader\"\nimport { ProgressDifferentialDownloadCallbackTransform, ProgressDifferentialDownloadInfo } from \"./ProgressDifferentialDownloadCallbackTransform\"\n\nexport interface DifferentialDownloaderOptions {\n readonly oldFile: string\n readonly newUrl: URL\n readonly logger: Logger\n readonly newFile: string\n\n readonly requestHeaders: OutgoingHttpHeaders | null\n\n readonly isUseMultipleRangeRequest?: boolean\n\n readonly cancellationToken: CancellationToken\n onProgress?(progress: ProgressInfo): void\n}\n\nexport abstract class DifferentialDownloader {\n fileMetadataBuffer: Buffer | null = null\n\n private readonly logger: Logger\n\n // noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected\n constructor(protected readonly blockAwareFileInfo: BlockMapDataHolder, readonly httpExecutor: HttpExecutor<any>, readonly options: DifferentialDownloaderOptions) {\n this.logger = options.logger\n }\n\n createRequestOptions(): RequestOptions {\n const result = {\n headers: {\n ...this.options.requestHeaders,\n accept: \"*/*\",\n },\n }\n configureRequestUrl(this.options.newUrl, result)\n // user-agent, cache-control and other common options\n configureRequestOptions(result)\n return result\n }\n\n protected doDownload(oldBlockMap: BlockMap, newBlockMap: BlockMap): Promise<any> {\n // we don't check other metadata like compressionMethod - generic check that it is make sense to differentially update is suitable for it\n if (oldBlockMap.version !== newBlockMap.version) {\n throw new Error(`version is different (${oldBlockMap.version} - ${newBlockMap.version}), full download is required`)\n }\n\n const logger = this.logger\n const operations = computeOperations(oldBlockMap, newBlockMap, logger)\n if (logger.debug != null) {\n logger.debug(JSON.stringify(operations, null, 2))\n }\n\n let downloadSize = 0\n let copySize = 0\n for (const operation of operations) {\n const length = operation.end - operation.start\n if (operation.kind === OperationKind.DOWNLOAD) {\n downloadSize += length\n }\n else {\n copySize += length\n }\n }\n\n const newSize = this.blockAwareFileInfo.size\n if ((downloadSize + copySize + (this.fileMetadataBuffer == null ? 0 : this.fileMetadataBuffer.length)) !== newSize) {\n throw new Error(`Internal error, size mismatch: downloadSize: ${downloadSize}, copySize: ${copySize}, newSize: ${newSize}`)\n }\n\n logger.info(`Full: ${formatBytes(newSize)}, To download: ${formatBytes(downloadSize)} (${Math.round(downloadSize / (newSize / 100))}%)`)\n\n return this.downloadFile(operations)\n }\n\n private downloadFile(tasks: Array<Operation>): Promise<any> {\n const fdList: Array<OpenedFile> = []\n const closeFiles = (): Promise<Array<void>> => {\n return Promise.all(fdList.map(openedFile => {\n return close(openedFile.descriptor)\n .catch(e => {\n this.logger.error(`cannot close file \"${openedFile.path}\": ${e}`)\n })\n }))\n }\n return this.doDownloadFile(tasks, fdList)\n .then(closeFiles)\n .catch(e => {\n // then must be after catch here (since then always throws error)\n return closeFiles()\n .catch(closeFilesError => {\n // closeFiles never throw error, but just to be sure\n try {\n this.logger.error(`cannot close files: ${closeFilesError}`)\n }\n catch (errorOnLog) {\n try {\n console.error(errorOnLog)\n }\n catch (ignored) {\n // ok, give up and ignore error\n }\n }\n throw e\n })\n .then(() => {\n throw e\n })\n })\n }\n\n private async doDownloadFile(tasks: Array<Operation>, fdList: Array<OpenedFile>): Promise<any> {\n const oldFileFd = await open(this.options.oldFile, \"r\")\n fdList.push({descriptor: oldFileFd, path: this.options.oldFile})\n const newFileFd = await open(this.options.newFile, \"w\")\n fdList.push({descriptor: newFileFd, path: this.options.newFile})\n const fileOut = createWriteStream(this.options.newFile, {fd: newFileFd})\n await new Promise((resolve, reject) => {\n const streams: Array<any> = []\n\n // Create our download info transformer if we have one\n let downloadInfoTransform: ProgressDifferentialDownloadCallbackTransform | undefined = undefined\n if (!this.options.isUseMultipleRangeRequest && this.options.onProgress) { // TODO: Does not support multiple ranges (someone feel free to PR this!)\n const expectedByteCounts: Array<number> = []\n let grandTotalBytes = 0\n\n for (const task of tasks) {\n if (task.kind === OperationKind.DOWNLOAD) {\n expectedByteCounts.push(task.end - task.start)\n grandTotalBytes += task.end - task.start\n }\n }\n\n const progressDifferentialDownloadInfo: ProgressDifferentialDownloadInfo = {\n expectedByteCounts: expectedByteCounts,\n grandTotal: grandTotalBytes\n }\n\n downloadInfoTransform = new ProgressDifferentialDownloadCallbackTransform(progressDifferentialDownloadInfo, this.options.cancellationToken, this.options.onProgress)\n streams.push(downloadInfoTransform)\n }\n\n const digestTransform = new DigestTransform(this.blockAwareFileInfo.sha512)\n // to simply debug, do manual validation to allow file to be fully written\n digestTransform.isValidateOnEnd = false\n streams.push(digestTransform)\n\n // noinspection JSArrowFunctionCanBeReplacedWithShorthand\n fileOut.on(\"finish\", () => {\n (fileOut.close as any)(() => {\n // remove from fd list because closed successfully\n fdList.splice(1, 1)\n try {\n digestTransform.validate()\n }\n catch (e) {\n reject(e)\n return\n }\n\n resolve(undefined)\n })\n })\n\n streams.push(fileOut)\n\n let lastStream = null\n for (const stream of streams) {\n stream.on(\"error\", reject)\n if (lastStream == null) {\n lastStream = stream\n }\n else {\n lastStream = lastStream.pipe(stream)\n }\n }\n\n const firstStream = streams[0]\n\n let w: any\n if (this.options.isUseMultipleRangeRequest) {\n w = executeTasksUsingMultipleRangeRequests(this, tasks, firstStream, oldFileFd, reject)\n w(0)\n return\n }\n\n let downloadOperationCount = 0\n let actualUrl: string | null = null\n this.logger.info(`Differential download: ${this.options.newUrl}`)\n\n const requestOptions = this.createRequestOptions();\n (requestOptions as any).redirect = \"manual\"\n\n w = (index: number): void => {\n if (index >= tasks.length) {\n if (this.fileMetadataBuffer != null) {\n firstStream.write(this.fileMetadataBuffer)\n }\n firstStream.end()\n return\n }\n\n const operation = tasks[index++]\n if (operation.kind === OperationKind.COPY) {\n // We are copying, let's not send status updates to the UI\n if (downloadInfoTransform) {\n downloadInfoTransform.beginFileCopy()\n }\n\n copyData(operation, firstStream, oldFileFd, reject, () => w(index))\n return\n }\n\n const range = `bytes=${operation.start}-${operation.end - 1}`\n requestOptions.headers!!.range = range\n\n const debug = this.logger.debug\n if (debug != null) {\n debug(`download range: ${range}`)\n }\n\n // We are starting to download\n if (downloadInfoTransform) {\n downloadInfoTransform.beginRangeDownload()\n }\n\n const request = this.httpExecutor.createRequest(requestOptions, response => {\n // Electron net handles redirects automatically, our NodeJS test server doesn't use redirects - so, we don't check 3xx codes.\n if (response.statusCode >= 400) {\n reject(createHttpError(response))\n }\n\n response.pipe(firstStream, {\n end: false\n })\n response.once(\"end\", () => {\n // Pass on that we are downloading a segment\n if (downloadInfoTransform) {\n downloadInfoTransform.endRangeDownload()\n }\n\n if (++downloadOperationCount === 100) {\n downloadOperationCount = 0\n setTimeout(() => w(index), 1000)\n }\n else {\n w(index)\n }\n })\n })\n request.on(\"redirect\", (statusCode: number, method: string, redirectUrl: string) => {\n this.logger.info(`Redirect to ${removeQuery(redirectUrl)}`)\n actualUrl = redirectUrl\n configureRequestUrl(new URL(actualUrl), requestOptions)\n request.followRedirect()\n })\n this.httpExecutor.addErrorAndTimeoutHandlers(request, reject)\n request.end()\n }\n\n w(0)\n })\n }\n\n protected async readRemoteBytes(start: number, endInclusive: number): Promise<Buffer> {\n const buffer = Buffer.allocUnsafe((endInclusive + 1) - start)\n const requestOptions = this.createRequestOptions()\n requestOptions.headers!!.range = `bytes=${start}-${endInclusive}`\n let position = 0\n await this.request(requestOptions, chunk => {\n chunk.copy(buffer, position)\n position += chunk.length\n })\n\n if (position !== buffer.length) {\n throw new Error(`Received data length ${position} is not equal to expected ${buffer.length}`)\n }\n return buffer\n }\n\n private request(requestOptions: RequestOptions, dataHandler: (chunk: Buffer) => void): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = this.httpExecutor.createRequest(requestOptions, response => {\n if (!checkIsRangesSupported(response, reject)) {\n return\n }\n\n response.on(\"data\", dataHandler)\n response.on(\"end\", () => resolve())\n })\n this.httpExecutor.addErrorAndTimeoutHandlers(request, reject)\n request.end()\n })\n }\n}\n\nfunction formatBytes(value: number, symbol = \" KB\"): string {\n return new Intl.NumberFormat(\"en\").format((value / 1024).toFixed(2) as any) + symbol\n}\n\n// safety\nfunction removeQuery(url: string): string {\n const index = url.indexOf(\"?\")\n return index < 0 ? url : url.substring(0, index)\n}\n\ninterface OpenedFile {\n readonly descriptor: number\n readonly path: string\n}\n"],"sourceRoot":""}
@@ -0,0 +1,32 @@
1
+ /// <reference types="node" />
2
+ import { Transform } from "stream";
3
+ import { CancellationToken } from "builder-util-runtime";
4
+ export interface ProgressInfo {
5
+ total: number;
6
+ delta: number;
7
+ transferred: number;
8
+ percent: number;
9
+ bytesPerSecond: number;
10
+ }
11
+ export interface ProgressDifferentialDownloadInfo {
12
+ expectedByteCounts: Array<number>;
13
+ grandTotal: number;
14
+ }
15
+ export declare class ProgressDifferentialDownloadCallbackTransform extends Transform {
16
+ private readonly progressDifferentialDownloadInfo;
17
+ private readonly cancellationToken;
18
+ private readonly onProgress;
19
+ private start;
20
+ private transferred;
21
+ private delta;
22
+ private expectedBytes;
23
+ private index;
24
+ private operationType;
25
+ private nextUpdate;
26
+ constructor(progressDifferentialDownloadInfo: ProgressDifferentialDownloadInfo, cancellationToken: CancellationToken, onProgress: (info: ProgressInfo) => any);
27
+ _transform(chunk: any, encoding: string, callback: any): void;
28
+ beginFileCopy(): void;
29
+ beginRangeDownload(): void;
30
+ endRangeDownload(): void;
31
+ _flush(callback: any): void;
32
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ProgressDifferentialDownloadCallbackTransform = void 0;
7
+
8
+ function _stream() {
9
+ const data = require("stream");
10
+
11
+ _stream = function () {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
17
+
18
+ var OperationKind;
19
+
20
+ (function (OperationKind) {
21
+ OperationKind[OperationKind["COPY"] = 0] = "COPY";
22
+ OperationKind[OperationKind["DOWNLOAD"] = 1] = "DOWNLOAD";
23
+ })(OperationKind || (OperationKind = {}));
24
+
25
+ class ProgressDifferentialDownloadCallbackTransform extends _stream().Transform {
26
+ constructor(progressDifferentialDownloadInfo, cancellationToken, onProgress) {
27
+ super();
28
+ this.progressDifferentialDownloadInfo = progressDifferentialDownloadInfo;
29
+ this.cancellationToken = cancellationToken;
30
+ this.onProgress = onProgress;
31
+ this.start = Date.now();
32
+ this.transferred = 0;
33
+ this.delta = 0;
34
+ this.expectedBytes = 0;
35
+ this.index = 0;
36
+ this.operationType = OperationKind.COPY;
37
+ this.nextUpdate = this.start + 1000;
38
+ }
39
+
40
+ _transform(chunk, encoding, callback) {
41
+ if (this.cancellationToken.cancelled) {
42
+ callback(new Error("cancelled"), null);
43
+ return;
44
+ } // Don't send progress update when copying from disk
45
+
46
+
47
+ if (this.operationType == OperationKind.COPY) {
48
+ callback(null, chunk);
49
+ return;
50
+ }
51
+
52
+ this.transferred += chunk.length;
53
+ this.delta += chunk.length;
54
+ const now = Date.now();
55
+
56
+ if (now >= this.nextUpdate && this.transferred !== this.expectedBytes
57
+ /* will be emitted by endRangeDownload() */
58
+ && this.transferred !== this.progressDifferentialDownloadInfo.grandTotal
59
+ /* will be emitted on _flush */
60
+ ) {
61
+ this.nextUpdate = now + 1000;
62
+ this.onProgress({
63
+ total: this.progressDifferentialDownloadInfo.grandTotal,
64
+ delta: this.delta,
65
+ transferred: this.transferred,
66
+ percent: this.transferred / this.progressDifferentialDownloadInfo.grandTotal * 100,
67
+ bytesPerSecond: Math.round(this.transferred / ((now - this.start) / 1000))
68
+ });
69
+ this.delta = 0;
70
+ }
71
+
72
+ callback(null, chunk);
73
+ }
74
+
75
+ beginFileCopy() {
76
+ this.operationType = OperationKind.COPY;
77
+ }
78
+
79
+ beginRangeDownload() {
80
+ this.operationType = OperationKind.DOWNLOAD;
81
+ this.expectedBytes += this.progressDifferentialDownloadInfo.expectedByteCounts[this.index++];
82
+ }
83
+
84
+ endRangeDownload() {
85
+ // _flush() will doour final 100%
86
+ if (this.transferred !== this.progressDifferentialDownloadInfo.grandTotal) {
87
+ this.onProgress({
88
+ total: this.progressDifferentialDownloadInfo.grandTotal,
89
+ delta: this.delta,
90
+ transferred: this.transferred,
91
+ percent: this.transferred / this.progressDifferentialDownloadInfo.grandTotal * 100,
92
+ bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000))
93
+ });
94
+ }
95
+ } // Called when we are 100% done with the connection/download
96
+
97
+
98
+ _flush(callback) {
99
+ if (this.cancellationToken.cancelled) {
100
+ callback(new Error("cancelled"));
101
+ return;
102
+ }
103
+
104
+ this.onProgress({
105
+ total: this.progressDifferentialDownloadInfo.grandTotal,
106
+ delta: this.delta,
107
+ transferred: this.transferred,
108
+ percent: 100,
109
+ bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000))
110
+ });
111
+ this.delta = 0;
112
+ this.transferred = 0;
113
+ callback(null);
114
+ }
115
+
116
+ } exports.ProgressDifferentialDownloadCallbackTransform = ProgressDifferentialDownloadCallbackTransform;
117
+ // __ts-babel@6.0.4
118
+ //# sourceMappingURL=ProgressDifferentialDownloadCallbackTransform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.ts"],"names":[],"mappings":"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","sourcesContent":["import { Transform } from \"stream\"\nimport { CancellationToken } from \"builder-util-runtime\"\n\nenum OperationKind {\n COPY, DOWNLOAD\n}\n\nexport interface ProgressInfo {\n total: number\n delta: number\n transferred: number\n percent: number\n bytesPerSecond: number\n}\n\nexport interface ProgressDifferentialDownloadInfo {\n expectedByteCounts: Array<number>\n grandTotal: number\n}\n\nexport class ProgressDifferentialDownloadCallbackTransform extends Transform {\n private start = Date.now()\n private transferred = 0\n private delta = 0\n private expectedBytes = 0\n private index = 0\n private operationType = OperationKind.COPY\n\n private nextUpdate = this.start + 1000\n\n constructor(private readonly progressDifferentialDownloadInfo: ProgressDifferentialDownloadInfo, private readonly cancellationToken: CancellationToken, private readonly onProgress: (info: ProgressInfo) => any) {\n super()\n }\n\n _transform(chunk: any, encoding: string, callback: any) {\n if (this.cancellationToken.cancelled) {\n callback(new Error(\"cancelled\"), null)\n return\n }\n\n // Don't send progress update when copying from disk\n if (this.operationType == OperationKind.COPY) {\n callback(null, chunk)\n return\n }\n\n this.transferred += chunk.length\n this.delta += chunk.length\n\n const now = Date.now()\n if (now >= this.nextUpdate\n && this.transferred !== this.expectedBytes /* will be emitted by endRangeDownload() */\n && this.transferred !== this.progressDifferentialDownloadInfo.grandTotal /* will be emitted on _flush */) {\n this.nextUpdate = now + 1000\n\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,\n bytesPerSecond: Math.round(this.transferred / ((now - this.start) / 1000))\n })\n this.delta = 0\n }\n\n callback(null, chunk)\n }\n\n beginFileCopy(): void {\n this.operationType = OperationKind.COPY\n }\n\n beginRangeDownload(): void {\n this.operationType = OperationKind.DOWNLOAD\n\n this.expectedBytes += this.progressDifferentialDownloadInfo.expectedByteCounts[this.index++]\n }\n\n endRangeDownload(): void {\n // _flush() will doour final 100%\n if (this.transferred !== this.progressDifferentialDownloadInfo.grandTotal) {\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: (this.transferred / this.progressDifferentialDownloadInfo.grandTotal) * 100,\n bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000))\n })\n }\n }\n\n // Called when we are 100% done with the connection/download\n _flush(callback: any): void {\n if (this.cancellationToken.cancelled) {\n callback(new Error(\"cancelled\"))\n return\n }\n\n this.onProgress({\n total: this.progressDifferentialDownloadInfo.grandTotal,\n delta: this.delta,\n transferred: this.transferred,\n percent: 100,\n bytesPerSecond: Math.round(this.transferred / ((Date.now() - this.start) / 1000))\n })\n this.delta = 0\n this.transferred = 0\n\n\n callback(null)\n }\n}\n"],"sourceRoot":""}
@@ -102,7 +102,6 @@ function buildChecksumMap(file, fileOffset, logger) {
102
102
  const checksumToOffset = new Map();
103
103
  const checksumToSize = new Map();
104
104
  let offset = fileOffset;
105
- const debugLog = logger.debug;
106
105
 
107
106
  for (let i = 0; i < file.checksums.length; i++) {
108
107
  const checksum = file.checksums[i];
@@ -112,9 +111,9 @@ function buildChecksumMap(file, fileOffset, logger) {
112
111
  if (existing === undefined) {
113
112
  checksumToOffset.set(checksum, offset);
114
113
  checksumToSize.set(checksum, size);
115
- } else if (debugLog != null) {
114
+ } else if (logger.debug != null) {
116
115
  const sizeExplanation = existing === size ? "(same size)" : `(size: ${existing}, this size: ${size})`;
117
- debugLog(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`);
116
+ logger.debug(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`);
118
117
  }
119
118
 
120
119
  offset += size;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/differentialDownloader/downloadPlanBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockMap, BlockMapFile } from \"builder-util-runtime/out/blockMapApi\"\nimport { Logger } from \"../main\"\n\nexport enum OperationKind {\n COPY, DOWNLOAD\n}\n\nexport interface Operation {\n kind: OperationKind\n\n // inclusive\n start: number\n // exclusive\n end: number\n\n // debug only\n // oldBlocks: Array<string> | null\n}\n\nexport function computeOperations(oldBlockMap: BlockMap, newBlockMap: BlockMap, logger: Logger): Array<Operation> {\n const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files)\n const nameToNewBlocks = buildBlockFileMap(newBlockMap.files)\n\n let lastOperation: Operation | null = null\n\n // for now only one file is supported in block map\n const blockMapFile = newBlockMap.files[0]\n const operations: Array<Operation> = []\n const name = blockMapFile.name\n const oldEntry = nameToOldBlocks.get(name)\n if (oldEntry == null) {\n // new file (unrealistic case for now, because in any case both blockmap contain the only file named as \"file\")\n throw new Error(`no file ${name} in old blockmap`)\n }\n\n const newFile = nameToNewBlocks.get(name)!!\n let changedBlockCount = 0\n\n const {checksumToOffset: checksumToOldOffset, checksumToOldSize} = buildChecksumMap(nameToOldBlocks.get(name)!!, oldEntry.offset, logger)\n\n let newOffset = blockMapFile.offset\n for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {\n const blockSize = newFile.sizes[i]\n const checksum = newFile.checksums[i]\n let oldOffset = checksumToOldOffset.get(checksum)\n if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {\n logger.warn(`Checksum (\"${checksum}\") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`)\n oldOffset = undefined\n }\n\n if (oldOffset === undefined) {\n // download data from new file\n changedBlockCount++\n\n if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {\n lastOperation.end += blockSize\n }\n else {\n lastOperation = {\n kind: OperationKind.DOWNLOAD,\n start: newOffset,\n end: newOffset + blockSize,\n // oldBlocks: null,\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n else {\n // reuse data from old file\n if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {\n lastOperation.end += blockSize\n // lastOperation.oldBlocks!!.push(checksum)\n }\n else {\n lastOperation = {\n kind: OperationKind.COPY,\n start: oldOffset,\n end: oldOffset + blockSize,\n // oldBlocks: [checksum]\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n }\n\n if (changedBlockCount > 0) {\n logger.info(`File${blockMapFile.name === \"file\" ? \"\" : (\" \" + blockMapFile.name)} has ${changedBlockCount} changed blocks`)\n }\n return operations\n}\n\nconst isValidateOperationRange = process.env.DIFFERENTIAL_DOWNLOAD_PLAN_BUILDER_VALIDATE_RANGES === \"true\"\n\nfunction validateAndAdd(operation: Operation, operations: Array<Operation>, checksum: string, index: number): void {\n if (isValidateOperationRange && operations.length !== 0) {\n const lastOperation = operations[operations.length - 1]\n if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {\n const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => p < v ? p : v)\n throw new Error(`operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\\n` +\n `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\\n` +\n `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`\n )\n }\n }\n operations.push(operation)\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction buildChecksumMap(file: BlockMapFile, fileOffset: number, logger: Logger) {\n const checksumToOffset = new Map<string, number>()\n const checksumToSize = new Map<string, number>()\n let offset = fileOffset\n const debugLog = logger.debug\n for (let i = 0; i < file.checksums.length; i++) {\n const checksum = file.checksums[i]\n const size = file.sizes[i]\n\n const existing = checksumToSize.get(checksum)\n if (existing === undefined) {\n checksumToOffset.set(checksum, offset)\n checksumToSize.set(checksum, size)\n }\n else if (debugLog != null) {\n const sizeExplanation = existing === size ? \"(same size)\" : `(size: ${existing}, this size: ${size})`\n debugLog(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`)\n }\n offset += size\n }\n return {checksumToOffset, checksumToOldSize: checksumToSize}\n}\n\nfunction buildBlockFileMap(list: Array<BlockMapFile>): Map<string, BlockMapFile> {\n const result = new Map<string, BlockMapFile>()\n for (const item of list) {\n result.set(item.name, item)\n }\n return result\n}\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["../../src/differentialDownloader/downloadPlanBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import { BlockMap, BlockMapFile } from \"builder-util-runtime/out/blockMapApi\"\nimport { Logger } from \"../main\"\n\nexport enum OperationKind {\n COPY, DOWNLOAD\n}\n\nexport interface Operation {\n kind: OperationKind\n\n // inclusive\n start: number\n // exclusive\n end: number\n\n // debug only\n // oldBlocks: Array<string> | null\n}\n\nexport function computeOperations(oldBlockMap: BlockMap, newBlockMap: BlockMap, logger: Logger): Array<Operation> {\n const nameToOldBlocks = buildBlockFileMap(oldBlockMap.files)\n const nameToNewBlocks = buildBlockFileMap(newBlockMap.files)\n\n let lastOperation: Operation | null = null\n\n // for now only one file is supported in block map\n const blockMapFile = newBlockMap.files[0]\n const operations: Array<Operation> = []\n const name = blockMapFile.name\n const oldEntry = nameToOldBlocks.get(name)\n if (oldEntry == null) {\n // new file (unrealistic case for now, because in any case both blockmap contain the only file named as \"file\")\n throw new Error(`no file ${name} in old blockmap`)\n }\n\n const newFile = nameToNewBlocks.get(name)!!\n let changedBlockCount = 0\n\n const {checksumToOffset: checksumToOldOffset, checksumToOldSize} = buildChecksumMap(nameToOldBlocks.get(name)!!, oldEntry.offset, logger)\n\n let newOffset = blockMapFile.offset\n for (let i = 0; i < newFile.checksums.length; newOffset += newFile.sizes[i], i++) {\n const blockSize = newFile.sizes[i]\n const checksum = newFile.checksums[i]\n let oldOffset = checksumToOldOffset.get(checksum)\n if (oldOffset != null && checksumToOldSize.get(checksum) !== blockSize) {\n logger.warn(`Checksum (\"${checksum}\") matches, but size differs (old: ${checksumToOldSize.get(checksum)}, new: ${blockSize})`)\n oldOffset = undefined\n }\n\n if (oldOffset === undefined) {\n // download data from new file\n changedBlockCount++\n\n if (lastOperation != null && lastOperation.kind === OperationKind.DOWNLOAD && lastOperation.end === newOffset) {\n lastOperation.end += blockSize\n }\n else {\n lastOperation = {\n kind: OperationKind.DOWNLOAD,\n start: newOffset,\n end: newOffset + blockSize,\n // oldBlocks: null,\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n else {\n // reuse data from old file\n if (lastOperation != null && lastOperation.kind === OperationKind.COPY && lastOperation.end === oldOffset) {\n lastOperation.end += blockSize\n // lastOperation.oldBlocks!!.push(checksum)\n }\n else {\n lastOperation = {\n kind: OperationKind.COPY,\n start: oldOffset,\n end: oldOffset + blockSize,\n // oldBlocks: [checksum]\n }\n validateAndAdd(lastOperation, operations, checksum, i)\n }\n }\n }\n\n if (changedBlockCount > 0) {\n logger.info(`File${blockMapFile.name === \"file\" ? \"\" : (\" \" + blockMapFile.name)} has ${changedBlockCount} changed blocks`)\n }\n return operations\n}\n\nconst isValidateOperationRange = process.env.DIFFERENTIAL_DOWNLOAD_PLAN_BUILDER_VALIDATE_RANGES === \"true\"\n\nfunction validateAndAdd(operation: Operation, operations: Array<Operation>, checksum: string, index: number): void {\n if (isValidateOperationRange && operations.length !== 0) {\n const lastOperation = operations[operations.length - 1]\n if (lastOperation.kind === operation.kind && operation.start < lastOperation.end && operation.start > lastOperation.start) {\n const min = [lastOperation.start, lastOperation.end, operation.start, operation.end].reduce((p, v) => p < v ? p : v)\n throw new Error(`operation (block index: ${index}, checksum: ${checksum}, kind: ${OperationKind[operation.kind]}) overlaps previous operation (checksum: ${checksum}):\\n` +\n `abs: ${lastOperation.start} until ${lastOperation.end} and ${operation.start} until ${operation.end}\\n` +\n `rel: ${lastOperation.start - min} until ${lastOperation.end - min} and ${operation.start - min} until ${operation.end - min}`\n )\n }\n }\n operations.push(operation)\n}\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nfunction buildChecksumMap(file: BlockMapFile, fileOffset: number, logger: Logger) {\n const checksumToOffset = new Map<string, number>()\n const checksumToSize = new Map<string, number>()\n let offset = fileOffset\n for (let i = 0; i < file.checksums.length; i++) {\n const checksum = file.checksums[i]\n const size = file.sizes[i]\n\n const existing = checksumToSize.get(checksum)\n if (existing === undefined) {\n checksumToOffset.set(checksum, offset)\n checksumToSize.set(checksum, size)\n }\n else if (logger.debug != null) {\n const sizeExplanation = existing === size ? \"(same size)\" : `(size: ${existing}, this size: ${size})`\n logger.debug(`${checksum} duplicated in blockmap ${sizeExplanation}, it doesn't lead to broken differential downloader, just corresponding block will be skipped)`)\n }\n offset += size\n }\n return {checksumToOffset, checksumToOldSize: checksumToSize}\n}\n\nfunction buildBlockFileMap(list: Array<BlockMapFile>): Map<string, BlockMapFile> {\n const result = new Map<string, BlockMapFile>()\n for (const item of list) {\n result.set(item.name, item)\n }\n return result\n}\n"],"sourceRoot":""}
package/out/main.d.ts CHANGED
@@ -6,7 +6,6 @@ import { AppUpdater } from "./AppUpdater";
6
6
  import { LoginCallback } from "./electronHttpExecutor";
7
7
  export { AppUpdater, NoOpLogger } from "./AppUpdater";
8
8
  export { UpdateInfo };
9
- export { CancellationToken } from "builder-util-runtime";
10
9
  export { Provider } from "./providers/Provider";
11
10
  export { AppImageUpdater } from "./AppImageUpdater";
12
11
  export { MacUpdater } from "./MacUpdater";
package/out/main.js CHANGED
@@ -18,12 +18,6 @@ Object.defineProperty(exports, "NoOpLogger", {
18
18
  return _AppUpdater().NoOpLogger;
19
19
  }
20
20
  });
21
- Object.defineProperty(exports, "CancellationToken", {
22
- enumerable: true,
23
- get: function () {
24
- return _builderUtilRuntime().CancellationToken;
25
- }
26
- });
27
21
  Object.defineProperty(exports, "Provider", {
28
22
  enumerable: true,
29
23
  get: function () {
@@ -70,16 +64,6 @@ function _AppUpdater() {
70
64
  return data;
71
65
  }
72
66
 
73
- function _builderUtilRuntime() {
74
- const data = require("builder-util-runtime");
75
-
76
- _builderUtilRuntime = function () {
77
- return data;
78
- };
79
-
80
- return data;
81
- }
82
-
83
67
  function _Provider() {
84
68
  const data = require("./providers/Provider");
85
69
 
package/out/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, PackageFileInfo, ProgressInfo, UpdateFileInfo, UpdateInfo } from \"builder-util-runtime\"\nimport { EventEmitter } from \"events\"\nimport { URL } from \"url\"\nimport { AppUpdater } from \"./AppUpdater\"\nimport { LoginCallback } from \"./electronHttpExecutor\"\n\nexport { AppUpdater, NoOpLogger } from \"./AppUpdater\"\nexport { UpdateInfo }\nexport { CancellationToken } from \"builder-util-runtime\"\nexport { Provider } from \"./providers/Provider\"\nexport { AppImageUpdater } from \"./AppImageUpdater\"\nexport { MacUpdater } from \"./MacUpdater\"\nexport { NsisUpdater } from \"./NsisUpdater\"\n\n// autoUpdater to mimic electron bundled autoUpdater\nlet _autoUpdater: any\n\n// required for jsdoc\nexport declare const autoUpdater: AppUpdater\n\nfunction doLoadAutoUpdater(): AppUpdater {\n // tslint:disable:prefer-conditional-expression\n if (process.platform === \"win32\") {\n _autoUpdater = new (require(\"./NsisUpdater\").NsisUpdater)()\n }\n else if (process.platform === \"darwin\") {\n _autoUpdater = new (require(\"./MacUpdater\").MacUpdater)()\n }\n else {\n _autoUpdater = new (require(\"./AppImageUpdater\").AppImageUpdater)()\n }\n return _autoUpdater\n}\n\nObject.defineProperty(exports, \"autoUpdater\", {\n enumerable: true,\n get: () => {\n return _autoUpdater || doLoadAutoUpdater()\n }\n})\n\nexport interface ResolvedUpdateFileInfo {\n readonly url: URL\n readonly info: UpdateFileInfo\n\n packageInfo?: PackageFileInfo\n}\n\nexport function getChannelFilename(channel: string): string {\n return `${channel}.yml`\n}\n\nexport interface UpdateCheckResult {\n readonly updateInfo: UpdateInfo\n\n readonly downloadPromise?: Promise<Array<string>> | null\n\n readonly cancellationToken?: CancellationToken\n\n /** @deprecated */\n readonly versionInfo: UpdateInfo\n}\n\nexport type UpdaterEvents = \"login\" | \"checking-for-update\" | \"update-available\" | \"update-cancelled\" | \"download-progress\" | \"update-downloaded\" | \"error\"\n\nexport const DOWNLOAD_PROGRESS: UpdaterEvents = \"download-progress\"\nexport const UPDATE_DOWNLOADED: UpdaterEvents = \"update-downloaded\"\n\nexport type LoginHandler = (authInfo: any, callback: LoginCallback) => void\n\nexport class UpdaterSignal {\n constructor(private emitter: EventEmitter) {\n }\n\n /**\n * Emitted when an authenticating proxy is [asking for user credentials](https://github.com/electron/electron/blob/master/docs/api/client-request.md#event-login).\n */\n login(handler: LoginHandler): void {\n addHandler(this.emitter, \"login\", handler)\n }\n\n progress(handler: (info: ProgressInfo) => void): void {\n addHandler(this.emitter, DOWNLOAD_PROGRESS, handler)\n }\n\n updateDownloaded(handler: (info: UpdateDownloadedEvent) => void): void {\n addHandler(this.emitter, UPDATE_DOWNLOADED, handler)\n }\n\n updateCancelled(handler: (info: UpdateInfo) => void): void {\n addHandler(this.emitter, \"update-cancelled\", handler)\n }\n}\n\nexport interface UpdateDownloadedEvent extends UpdateInfo {\n downloadedFile: string\n}\n\nconst isLogEvent = false\n\nfunction addHandler(emitter: EventEmitter, event: UpdaterEvents, handler: (...args: Array<any>) => void): void {\n if (isLogEvent) {\n emitter.on(event, (...args: Array<any>) => {\n console.log(\"%s %s\", event, args)\n handler(...args)\n })\n }\n else {\n emitter.on(event, handler)\n }\n}\n\nexport interface Logger {\n info(message?: any): void\n\n warn(message?: any): void\n\n error(message?: any): void\n\n debug?(message: string): void\n}\n\n// if baseUrl path doesn't ends with /, this path will be not prepended to passed pathname for new URL(input, base)\n/** @internal */\nexport function newBaseUrl(url: string): URL {\n const result = new URL(url)\n if (!result.pathname.endsWith(\"/\")) {\n result.pathname += \"/\"\n }\n return result\n}\n\n// addRandomQueryToAvoidCaching is false by default because in most cases URL already contains version number,\n// so, it makes sense only for Generic Provider for channel files\nexport function newUrlFromBase(pathname: string, baseUrl: URL, addRandomQueryToAvoidCaching = false): URL {\n const result = new URL(pathname, baseUrl)\n // search is not propagated (search is an empty string if not specified)\n const search = baseUrl.search\n if (search != null && search.length !== 0) {\n result.search = search\n }\n else if (addRandomQueryToAvoidCaching) {\n result.search = `noCache=${Date.now().toString(32)}`\n }\n return result\n}"],"sourceRoot":""}
1
+ {"version":3,"sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, PackageFileInfo, ProgressInfo, UpdateFileInfo, UpdateInfo } from \"builder-util-runtime\"\nimport { EventEmitter } from \"events\"\nimport { URL } from \"url\"\nimport { AppUpdater } from \"./AppUpdater\"\nimport { LoginCallback } from \"./electronHttpExecutor\"\n\nexport { AppUpdater, NoOpLogger } from \"./AppUpdater\"\nexport { UpdateInfo }\nexport { Provider } from \"./providers/Provider\"\nexport { AppImageUpdater } from \"./AppImageUpdater\"\nexport { MacUpdater } from \"./MacUpdater\"\nexport { NsisUpdater } from \"./NsisUpdater\"\n\n// autoUpdater to mimic electron bundled autoUpdater\nlet _autoUpdater: any\n\n// required for jsdoc\nexport declare const autoUpdater: AppUpdater\n\nfunction doLoadAutoUpdater(): AppUpdater {\n // tslint:disable:prefer-conditional-expression\n if (process.platform === \"win32\") {\n _autoUpdater = new (require(\"./NsisUpdater\").NsisUpdater)()\n }\n else if (process.platform === \"darwin\") {\n _autoUpdater = new (require(\"./MacUpdater\").MacUpdater)()\n }\n else {\n _autoUpdater = new (require(\"./AppImageUpdater\").AppImageUpdater)()\n }\n return _autoUpdater\n}\n\nObject.defineProperty(exports, \"autoUpdater\", {\n enumerable: true,\n get: () => {\n return _autoUpdater || doLoadAutoUpdater()\n }\n})\n\nexport interface ResolvedUpdateFileInfo {\n readonly url: URL\n readonly info: UpdateFileInfo\n\n packageInfo?: PackageFileInfo\n}\n\nexport function getChannelFilename(channel: string): string {\n return `${channel}.yml`\n}\n\nexport interface UpdateCheckResult {\n readonly updateInfo: UpdateInfo\n\n readonly downloadPromise?: Promise<Array<string>> | null\n\n readonly cancellationToken?: CancellationToken\n\n /** @deprecated */\n readonly versionInfo: UpdateInfo\n}\n\nexport type UpdaterEvents = \"login\" | \"checking-for-update\" | \"update-available\" | \"update-cancelled\" | \"download-progress\" | \"update-downloaded\" | \"error\"\n\nexport const DOWNLOAD_PROGRESS: UpdaterEvents = \"download-progress\"\nexport const UPDATE_DOWNLOADED: UpdaterEvents = \"update-downloaded\"\n\nexport type LoginHandler = (authInfo: any, callback: LoginCallback) => void\n\nexport class UpdaterSignal {\n constructor(private emitter: EventEmitter) {\n }\n\n /**\n * Emitted when an authenticating proxy is [asking for user credentials](https://github.com/electron/electron/blob/master/docs/api/client-request.md#event-login).\n */\n login(handler: LoginHandler): void {\n addHandler(this.emitter, \"login\", handler)\n }\n\n progress(handler: (info: ProgressInfo) => void): void {\n addHandler(this.emitter, DOWNLOAD_PROGRESS, handler)\n }\n\n updateDownloaded(handler: (info: UpdateDownloadedEvent) => void): void {\n addHandler(this.emitter, UPDATE_DOWNLOADED, handler)\n }\n\n updateCancelled(handler: (info: UpdateInfo) => void): void {\n addHandler(this.emitter, \"update-cancelled\", handler)\n }\n}\n\nexport interface UpdateDownloadedEvent extends UpdateInfo {\n downloadedFile: string\n}\n\nconst isLogEvent = false\n\nfunction addHandler(emitter: EventEmitter, event: UpdaterEvents, handler: (...args: Array<any>) => void): void {\n if (isLogEvent) {\n emitter.on(event, (...args: Array<any>) => {\n console.log(\"%s %s\", event, args)\n handler(...args)\n })\n }\n else {\n emitter.on(event, handler)\n }\n}\n\nexport interface Logger {\n info(message?: any): void\n\n warn(message?: any): void\n\n error(message?: any): void\n\n debug?(message: string): void\n}\n\n// if baseUrl path doesn't ends with /, this path will be not prepended to passed pathname for new URL(input, base)\n/** @internal */\nexport function newBaseUrl(url: string): URL {\n const result = new URL(url)\n if (!result.pathname.endsWith(\"/\")) {\n result.pathname += \"/\"\n }\n return result\n}\n\n// addRandomQueryToAvoidCaching is false by default because in most cases URL already contains version number,\n// so, it makes sense only for Generic Provider for channel files\nexport function newUrlFromBase(pathname: string, baseUrl: URL, addRandomQueryToAvoidCaching = false): URL {\n const result = new URL(pathname, baseUrl)\n // search is not propagated (search is an empty string if not specified)\n const search = baseUrl.search\n if (search != null && search.length !== 0) {\n result.search = search\n }\n else if (addRandomQueryToAvoidCaching) {\n result.search = `noCache=${Date.now().toString(32)}`\n }\n return result\n}\n"],"sourceRoot":""}
@@ -99,7 +99,7 @@ class PrivateGitHubProvider extends _GitHubProvider().BaseGitHubProvider {
99
99
  let result;
100
100
 
101
101
  try {
102
- result = (0, _jsYaml().safeLoad)(await this.httpRequest(url, this.configureHeaders("application/octet-stream"), cancellationToken));
102
+ result = (0, _jsYaml().load)(await this.httpRequest(url, this.configureHeaders("application/octet-stream"), cancellationToken));
103
103
  } catch (e) {
104
104
  if (e instanceof _builderUtilRuntime().HttpError && e.statusCode === 404) {
105
105
  throw (0, _builderUtilRuntime().newError)(`Cannot find ${channelFile} in the latest release artifacts (${url}): ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/PrivateGitHubProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, GithubOptions, HttpError, newError, UpdateInfo } from \"builder-util-runtime\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { safeLoad } from \"js-yaml\"\nimport * as path from \"path\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { URL } from \"url\"\nimport { BaseGitHubProvider } from \"./GitHubProvider\"\nimport { getChannelFilename, newUrlFromBase, ResolvedUpdateFileInfo } from \"../main\"\nimport { getFileList, ProviderRuntimeOptions } from \"./Provider\"\n\nexport interface PrivateGitHubUpdateInfo extends UpdateInfo {\n assets: Array<Asset>\n}\n\nexport class PrivateGitHubProvider extends BaseGitHubProvider<PrivateGitHubUpdateInfo> {\n constructor(options: GithubOptions, private readonly updater: AppUpdater, private readonly token: string, runtimeOptions: ProviderRuntimeOptions) {\n super(options, \"api.github.com\", runtimeOptions)\n }\n\n protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions {\n const result = super.createRequestOptions(url, headers);\n (result as any).redirect = \"manual\"\n return result\n }\n\n async getLatestVersion(): Promise<PrivateGitHubUpdateInfo> {\n const cancellationToken = new CancellationToken()\n const channelFile = getChannelFilename(this.getDefaultChannelName())\n\n const releaseInfo = await this.getLatestVersionInfo(cancellationToken)\n const asset = releaseInfo.assets.find(it => it.name === channelFile)\n if (asset == null) {\n // html_url must be always, but just to be sure\n throw newError(`Cannot find ${channelFile} in the release ${releaseInfo.html_url || releaseInfo.name}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n\n const url = new URL(asset.url)\n let result: any\n try {\n result = safeLoad((await this.httpRequest(url, this.configureHeaders(\"application/octet-stream\"), cancellationToken))!!)\n }\n catch (e) {\n if (e instanceof HttpError && e.statusCode === 404) {\n throw newError(`Cannot find ${channelFile} in the latest release artifacts (${url}): ${e.stack || e.message}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n throw e\n }\n\n (result as PrivateGitHubUpdateInfo).assets = releaseInfo.assets\n return result\n }\n\n get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null {\n return this.configureHeaders(\"application/octet-stream\")\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n private configureHeaders(accept: string) {\n return {\n accept,\n authorization: `token ${this.token}`,\n }\n }\n\n private async getLatestVersionInfo(cancellationToken: CancellationToken): Promise<ReleaseInfo> {\n const allowPrerelease = this.updater.allowPrerelease\n let basePath = this.basePath\n if (!allowPrerelease) {\n basePath = `${basePath}/latest`\n }\n\n const url = newUrlFromBase(basePath, this.baseUrl)\n try {\n const version = (JSON.parse((await this.httpRequest(url, this.configureHeaders(\"application/vnd.github.v3+json\"), cancellationToken))!!))\n if (allowPrerelease) {\n return version.find((v: any) => v.prerelease) || version[0]\n }\n else {\n return version\n }\n }\n catch (e) {\n throw newError(`Unable to find latest version on GitHub (${url}), please ensure a production release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n private get basePath(): string {\n return this.computeGithubBasePath(`/repos/${this.options.owner}/${this.options.repo}/releases`)\n }\n\n resolveFiles(updateInfo: PrivateGitHubUpdateInfo): Array<ResolvedUpdateFileInfo> {\n return getFileList(updateInfo).map(it => {\n const name = path.posix.basename(it.url).replace(/ /g, \"-\")\n const asset = updateInfo.assets.find(it => it != null && it.name === name)\n if (asset == null) {\n throw newError(`Cannot find asset \"${name}\" in: ${JSON.stringify(updateInfo.assets, null, 2)}`, \"ERR_UPDATER_ASSET_NOT_FOUND\")\n }\n\n return {\n url: new URL(asset.url),\n info: it,\n }\n })\n }\n}\n\ninterface ReleaseInfo {\n name: string\n html_url: string\n assets: Array<Asset>\n}\n\nexport interface Asset {\n name: string\n url: string\n}"],"sourceRoot":""}
1
+ {"version":3,"sources":["../../src/providers/PrivateGitHubProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, GithubOptions, HttpError, newError, UpdateInfo } from \"builder-util-runtime\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { load } from \"js-yaml\"\nimport * as path from \"path\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { URL } from \"url\"\nimport { BaseGitHubProvider } from \"./GitHubProvider\"\nimport { getChannelFilename, newUrlFromBase, ResolvedUpdateFileInfo } from \"../main\"\nimport { getFileList, ProviderRuntimeOptions } from \"./Provider\"\n\nexport interface PrivateGitHubUpdateInfo extends UpdateInfo {\n assets: Array<Asset>\n}\n\nexport class PrivateGitHubProvider extends BaseGitHubProvider<PrivateGitHubUpdateInfo> {\n constructor(options: GithubOptions, private readonly updater: AppUpdater, private readonly token: string, runtimeOptions: ProviderRuntimeOptions) {\n super(options, \"api.github.com\", runtimeOptions)\n }\n\n protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions {\n const result = super.createRequestOptions(url, headers);\n (result as any).redirect = \"manual\"\n return result\n }\n\n async getLatestVersion(): Promise<PrivateGitHubUpdateInfo> {\n const cancellationToken = new CancellationToken()\n const channelFile = getChannelFilename(this.getDefaultChannelName())\n\n const releaseInfo = await this.getLatestVersionInfo(cancellationToken)\n const asset = releaseInfo.assets.find(it => it.name === channelFile)\n if (asset == null) {\n // html_url must be always, but just to be sure\n throw newError(`Cannot find ${channelFile} in the release ${releaseInfo.html_url || releaseInfo.name}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n\n const url = new URL(asset.url)\n let result: any\n try {\n result = load((await this.httpRequest(url, this.configureHeaders(\"application/octet-stream\"), cancellationToken))!!)\n }\n catch (e) {\n if (e instanceof HttpError && e.statusCode === 404) {\n throw newError(`Cannot find ${channelFile} in the latest release artifacts (${url}): ${e.stack || e.message}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n throw e\n }\n\n (result as PrivateGitHubUpdateInfo).assets = releaseInfo.assets\n return result\n }\n\n get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null {\n return this.configureHeaders(\"application/octet-stream\")\n }\n\n // eslint-disable-next-line @typescript-eslint/explicit-function-return-type\n private configureHeaders(accept: string) {\n return {\n accept,\n authorization: `token ${this.token}`,\n }\n }\n\n private async getLatestVersionInfo(cancellationToken: CancellationToken): Promise<ReleaseInfo> {\n const allowPrerelease = this.updater.allowPrerelease\n let basePath = this.basePath\n if (!allowPrerelease) {\n basePath = `${basePath}/latest`\n }\n\n const url = newUrlFromBase(basePath, this.baseUrl)\n try {\n const version = (JSON.parse((await this.httpRequest(url, this.configureHeaders(\"application/vnd.github.v3+json\"), cancellationToken))!!))\n if (allowPrerelease) {\n return version.find((v: any) => v.prerelease) || version[0]\n }\n else {\n return version\n }\n }\n catch (e) {\n throw newError(`Unable to find latest version on GitHub (${url}), please ensure a production release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n private get basePath(): string {\n return this.computeGithubBasePath(`/repos/${this.options.owner}/${this.options.repo}/releases`)\n }\n\n resolveFiles(updateInfo: PrivateGitHubUpdateInfo): Array<ResolvedUpdateFileInfo> {\n return getFileList(updateInfo).map(it => {\n const name = path.posix.basename(it.url).replace(/ /g, \"-\")\n const asset = updateInfo.assets.find(it => it != null && it.name === name)\n if (asset == null) {\n throw newError(`Cannot find asset \"${name}\" in: ${JSON.stringify(updateInfo.assets, null, 2)}`, \"ERR_UPDATER_ASSET_NOT_FOUND\")\n }\n\n return {\n url: new URL(asset.url),\n info: it,\n }\n })\n }\n}\n\ninterface ReleaseInfo {\n name: string\n html_url: string\n assets: Array<Asset>\n}\n\nexport interface Asset {\n name: string\n url: string\n}"],"sourceRoot":""}
@@ -130,7 +130,7 @@ function parseUpdateInfo(rawData, channelFile, channelFileUrl) {
130
130
  let result;
131
131
 
132
132
  try {
133
- result = (0, _jsYaml().safeLoad)(rawData);
133
+ result = (0, _jsYaml().load)(rawData);
134
134
  } catch (e) {
135
135
  throw (0, _builderUtilRuntime().newError)(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}, rawData: ${rawData}`, "ERR_UPDATER_INVALID_UPDATE_INFO");
136
136
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/Provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, HttpExecutor, newError, safeStringifyJson, UpdateFileInfo, UpdateInfo, WindowsUpdateInfo, configureRequestUrl } from \"builder-util-runtime\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { safeLoad } from \"js-yaml\"\nimport { URL } from \"url\"\nimport { newUrlFromBase, ResolvedUpdateFileInfo } from \"../main\"\n\nexport type ProviderPlatform = \"darwin\" | \"linux\" | \"win32\"\n\nexport interface ProviderRuntimeOptions {\n isUseMultipleRangeRequest: boolean\n platform: ProviderPlatform\n\n executor: HttpExecutor<any>\n}\n\nexport abstract class Provider<T extends UpdateInfo> {\n private requestHeaders: OutgoingHttpHeaders | null = null\n protected readonly executor: HttpExecutor<any>\n\n protected constructor(private readonly runtimeOptions: ProviderRuntimeOptions) {\n this.executor = runtimeOptions.executor\n }\n\n get isUseMultipleRangeRequest(): boolean {\n return this.runtimeOptions.isUseMultipleRangeRequest !== false\n }\n\n private getChannelFilePrefix(): string {\n if (this.runtimeOptions.platform === \"linux\") {\n const arch = process.env.TEST_UPDATER_ARCH || process.arch\n const archSuffix = arch === \"x64\" ? \"\" : `-${arch}`\n return \"-linux\" + archSuffix\n }\n else {\n return this.runtimeOptions.platform === \"darwin\" ? \"-mac\" : \"\"\n }\n }\n\n // due to historical reasons for windows we use channel name without platform specifier\n protected getDefaultChannelName(): string {\n return this.getCustomChannelName(\"latest\")\n }\n\n protected getCustomChannelName(channel: string): string {\n return `${channel}${this.getChannelFilePrefix()}`\n }\n\n get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null {\n return null\n }\n\n setRequestHeaders(value: OutgoingHttpHeaders | null): void {\n this.requestHeaders = value\n }\n\n abstract getLatestVersion(): Promise<T>\n\n abstract resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo>\n\n /**\n * Method to perform API request only to resolve update info, but not to download update.\n */\n protected httpRequest(url: URL, headers?: OutgoingHttpHeaders | null, cancellationToken?: CancellationToken): Promise<string | null> {\n return this.executor.request(this.createRequestOptions(url, headers), cancellationToken)\n }\n\n protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions {\n const result: RequestOptions = {}\n if (this.requestHeaders == null) {\n if (headers != null) {\n result.headers = headers\n }\n }\n else {\n result.headers = headers == null ? this.requestHeaders : {...this.requestHeaders, ...headers}\n }\n\n configureRequestUrl(url, result)\n return result\n }\n}\n\nexport function findFile(files: Array<ResolvedUpdateFileInfo>, extension: string, not?: Array<string>): ResolvedUpdateFileInfo | null | undefined {\n if (files.length === 0) {\n throw newError(\"No files provided\", \"ERR_UPDATER_NO_FILES_PROVIDED\")\n }\n\n const result = files.find(it => it.url.pathname.toLowerCase().endsWith(`.${extension}`))\n if (result != null) {\n return result\n }\n else if (not == null) {\n return files[0]\n }\n else {\n return files.find(fileInfo => !not.some(ext => fileInfo.url.pathname.toLowerCase().endsWith(`.${ext}`)))\n }\n}\n\nexport function parseUpdateInfo(rawData: string | null, channelFile: string, channelFileUrl: URL): UpdateInfo {\n if (rawData == null) {\n throw newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): rawData: null`, \"ERR_UPDATER_INVALID_UPDATE_INFO\")\n }\n\n let result: UpdateInfo\n try {\n result = safeLoad(rawData) as UpdateInfo\n }\n catch (e) {\n throw newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}, rawData: ${rawData}`, \"ERR_UPDATER_INVALID_UPDATE_INFO\")\n }\n return result\n}\n\nexport function getFileList(updateInfo: UpdateInfo): Array<UpdateFileInfo> {\n const files = updateInfo.files\n if (files != null && files.length > 0) {\n return files\n }\n\n // noinspection JSDeprecatedSymbols\n if (updateInfo.path != null) {\n // noinspection JSDeprecatedSymbols\n return [\n {\n url: updateInfo.path,\n sha2: (updateInfo as any).sha2,\n sha512: updateInfo.sha512,\n } as any,\n ]\n }\n else {\n throw newError(`No files provided: ${safeStringifyJson(updateInfo)}`, \"ERR_UPDATER_NO_FILES_PROVIDED\")\n }\n}\n\nexport function resolveFiles(updateInfo: UpdateInfo, baseUrl: URL, pathTransformer: (p: string) => string = (p: string): string => p): Array<ResolvedUpdateFileInfo> {\n const files = getFileList(updateInfo)\n const result: Array<ResolvedUpdateFileInfo> = files.map(fileInfo => {\n if ((fileInfo as any).sha2 == null && fileInfo.sha512 == null) {\n throw newError(`Update info doesn't contain nor sha256 neither sha512 checksum: ${safeStringifyJson(fileInfo)}`, \"ERR_UPDATER_NO_CHECKSUM\")\n }\n return {\n url: newUrlFromBase(pathTransformer(fileInfo.url), baseUrl),\n info: fileInfo,\n }\n })\n\n const packages = (updateInfo as WindowsUpdateInfo).packages\n const packageInfo = packages == null ? null : (packages[process.arch] || packages.ia32)\n if (packageInfo != null) {\n (result[0] as any).packageInfo = {\n ...packageInfo,\n path: newUrlFromBase(pathTransformer(packageInfo.path), baseUrl).href,\n }\n }\n return result\n}"],"sourceRoot":""}
1
+ {"version":3,"sources":["../../src/providers/Provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, HttpExecutor, newError, safeStringifyJson, UpdateFileInfo, UpdateInfo, WindowsUpdateInfo, configureRequestUrl } from \"builder-util-runtime\"\nimport { OutgoingHttpHeaders, RequestOptions } from \"http\"\nimport { load } from \"js-yaml\"\nimport { URL } from \"url\"\nimport { newUrlFromBase, ResolvedUpdateFileInfo } from \"../main\"\n\nexport type ProviderPlatform = \"darwin\" | \"linux\" | \"win32\"\n\nexport interface ProviderRuntimeOptions {\n isUseMultipleRangeRequest: boolean\n platform: ProviderPlatform\n\n executor: HttpExecutor<any>\n}\n\nexport abstract class Provider<T extends UpdateInfo> {\n private requestHeaders: OutgoingHttpHeaders | null = null\n protected readonly executor: HttpExecutor<any>\n\n protected constructor(private readonly runtimeOptions: ProviderRuntimeOptions) {\n this.executor = runtimeOptions.executor\n }\n\n get isUseMultipleRangeRequest(): boolean {\n return this.runtimeOptions.isUseMultipleRangeRequest !== false\n }\n\n private getChannelFilePrefix(): string {\n if (this.runtimeOptions.platform === \"linux\") {\n const arch = process.env.TEST_UPDATER_ARCH || process.arch\n const archSuffix = arch === \"x64\" ? \"\" : `-${arch}`\n return \"-linux\" + archSuffix\n }\n else {\n return this.runtimeOptions.platform === \"darwin\" ? \"-mac\" : \"\"\n }\n }\n\n // due to historical reasons for windows we use channel name without platform specifier\n protected getDefaultChannelName(): string {\n return this.getCustomChannelName(\"latest\")\n }\n\n protected getCustomChannelName(channel: string): string {\n return `${channel}${this.getChannelFilePrefix()}`\n }\n\n get fileExtraDownloadHeaders(): OutgoingHttpHeaders | null {\n return null\n }\n\n setRequestHeaders(value: OutgoingHttpHeaders | null): void {\n this.requestHeaders = value\n }\n\n abstract getLatestVersion(): Promise<T>\n\n abstract resolveFiles(updateInfo: UpdateInfo): Array<ResolvedUpdateFileInfo>\n\n /**\n * Method to perform API request only to resolve update info, but not to download update.\n */\n protected httpRequest(url: URL, headers?: OutgoingHttpHeaders | null, cancellationToken?: CancellationToken): Promise<string | null> {\n return this.executor.request(this.createRequestOptions(url, headers), cancellationToken)\n }\n\n protected createRequestOptions(url: URL, headers?: OutgoingHttpHeaders | null): RequestOptions {\n const result: RequestOptions = {}\n if (this.requestHeaders == null) {\n if (headers != null) {\n result.headers = headers\n }\n }\n else {\n result.headers = headers == null ? this.requestHeaders : {...this.requestHeaders, ...headers}\n }\n\n configureRequestUrl(url, result)\n return result\n }\n}\n\nexport function findFile(files: Array<ResolvedUpdateFileInfo>, extension: string, not?: Array<string>): ResolvedUpdateFileInfo | null | undefined {\n if (files.length === 0) {\n throw newError(\"No files provided\", \"ERR_UPDATER_NO_FILES_PROVIDED\")\n }\n\n const result = files.find(it => it.url.pathname.toLowerCase().endsWith(`.${extension}`))\n if (result != null) {\n return result\n }\n else if (not == null) {\n return files[0]\n }\n else {\n return files.find(fileInfo => !not.some(ext => fileInfo.url.pathname.toLowerCase().endsWith(`.${ext}`)))\n }\n}\n\nexport function parseUpdateInfo(rawData: string | null, channelFile: string, channelFileUrl: URL): UpdateInfo {\n if (rawData == null) {\n throw newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): rawData: null`, \"ERR_UPDATER_INVALID_UPDATE_INFO\")\n }\n\n let result: UpdateInfo\n try {\n result = load(rawData) as UpdateInfo\n }\n catch (e) {\n throw newError(`Cannot parse update info from ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}, rawData: ${rawData}`, \"ERR_UPDATER_INVALID_UPDATE_INFO\")\n }\n return result\n}\n\nexport function getFileList(updateInfo: UpdateInfo): Array<UpdateFileInfo> {\n const files = updateInfo.files\n if (files != null && files.length > 0) {\n return files\n }\n\n // noinspection JSDeprecatedSymbols\n if (updateInfo.path != null) {\n // noinspection JSDeprecatedSymbols\n return [\n {\n url: updateInfo.path,\n sha2: (updateInfo as any).sha2,\n sha512: updateInfo.sha512,\n } as any,\n ]\n }\n else {\n throw newError(`No files provided: ${safeStringifyJson(updateInfo)}`, \"ERR_UPDATER_NO_FILES_PROVIDED\")\n }\n}\n\nexport function resolveFiles(updateInfo: UpdateInfo, baseUrl: URL, pathTransformer: (p: string) => string = (p: string): string => p): Array<ResolvedUpdateFileInfo> {\n const files = getFileList(updateInfo)\n const result: Array<ResolvedUpdateFileInfo> = files.map(fileInfo => {\n if ((fileInfo as any).sha2 == null && fileInfo.sha512 == null) {\n throw newError(`Update info doesn't contain nor sha256 neither sha512 checksum: ${safeStringifyJson(fileInfo)}`, \"ERR_UPDATER_NO_CHECKSUM\")\n }\n return {\n url: newUrlFromBase(pathTransformer(fileInfo.url), baseUrl),\n info: fileInfo,\n }\n })\n\n const packages = (updateInfo as WindowsUpdateInfo).packages\n const packageInfo = packages == null ? null : (packages[process.arch] || packages.ia32)\n if (packageInfo != null) {\n (result[0] as any).packageInfo = {\n ...packageInfo,\n path: newUrlFromBase(pathTransformer(packageInfo.path), baseUrl).href,\n }\n }\n return result\n}"],"sourceRoot":""}