@todesktop/runtime
Advanced tools
Comparing version 0.1.0-rc.3 to 0.1.0-rc.r
@@ -1,4 +0,4 @@ | ||
import * as electronUpdater from "electron-updater"; | ||
import { EventEmitter2 } from "eventemitter2"; | ||
export declare type ConstructorOptions = { | ||
import { UpdateInfo } from "./updaterAgents"; | ||
export declare type AutoUpdaterConstructorOptions = { | ||
readonly shouldAutoCheckOnLaunch?: boolean; | ||
@@ -14,6 +14,2 @@ readonly autoCheckInterval?: number; | ||
export declare type Source = BuiltInSources | string; | ||
export declare type UpdateInfo = { | ||
readonly releaseDate: electronUpdater.UpdateInfo["releaseDate"]; | ||
readonly version: electronUpdater.UpdateInfo["version"]; | ||
}; | ||
export declare type UpdateAvailableEventPayload = { | ||
@@ -26,6 +22,7 @@ readonly sources: Source[]; | ||
}; | ||
export { UpdateInfo } from "./updaterAgents"; | ||
export default class AutoUpdater extends EventEmitter2 { | ||
#private; | ||
constructor({ autoCheckInterval, // 10 min | ||
shouldAutoCheckOnLaunch, shouldNotify, }?: ConstructorOptions); | ||
shouldAutoCheckOnLaunch, shouldNotify, }?: AutoUpdaterConstructorOptions); | ||
checkForUpdates({ source, }?: { | ||
@@ -39,6 +36,5 @@ source?: Source; | ||
private _check; | ||
private _initializeInternalAutoUpdater; | ||
private _initializeUpdaterAgent; | ||
private _log; | ||
private _setTimeout; | ||
private _subscribeToElectronEvents; | ||
} |
@@ -15,3 +15,3 @@ "use strict"; | ||
}; | ||
var _autoUpdater, _createdAt, _hasAppFinishedLaunching, _hasNotified, _hasUpdateReadyToInstall, _isActive, _pendingCheckSources, _pendingUpdateCheckPromise, _shouldNotify; | ||
var _createdAt, _hasAppFinishedLaunching, _hasNotified, _hasUpdateReadyToInstall, _isActive, _pendingCheckSources, _pendingUpdateCheckPromise, _shouldNotify, _updaterAgent; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -21,7 +21,10 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-ignore | ||
const electron = require("electron"); | ||
const electronUpdater = require("electron-updater"); | ||
const eventemitter2_1 = require("eventemitter2"); | ||
const fs = require("fs"); | ||
const once = require("lodash.once"); | ||
const semver = require("semver"); | ||
const path = require("path"); | ||
const getConfig_1 = require("./getConfig"); | ||
const logger_1 = require("./logger"); | ||
const setTimeout_1 = require("./setTimeout"); | ||
const updaterAgents_1 = require("./updaterAgents"); | ||
var BuiltInSources; | ||
@@ -37,3 +40,2 @@ (function (BuiltInSources) { | ||
super(); | ||
_autoUpdater.set(this, void 0); | ||
_createdAt.set(this, Date.now()); | ||
@@ -47,5 +49,6 @@ _hasAppFinishedLaunching.set(this, false); | ||
_shouldNotify.set(this, void 0); | ||
_updaterAgent.set(this, void 0); | ||
__classPrivateFieldSet(this, _shouldNotify, shouldNotify); | ||
if (__classPrivateFieldGet(this, _isActive)) { | ||
this._initializeInternalAutoUpdater(); | ||
this._initializeUpdaterAgent(); | ||
} | ||
@@ -78,11 +81,3 @@ else { | ||
} | ||
try { | ||
return await this._check({ source }); | ||
} | ||
catch (e) { | ||
if (e.name === "CancellationError") { | ||
throw new Error("Update check cancelled"); | ||
} | ||
throw e; | ||
} | ||
return await this._check({ source }); | ||
} | ||
@@ -93,10 +88,9 @@ restartAndInstall() { | ||
} | ||
__classPrivateFieldGet(this, _autoUpdater).quitAndInstall(); | ||
__classPrivateFieldGet(this, _updaterAgent).restartAndInstall(); | ||
} | ||
async _actuallyPerformCheck() { | ||
this._log("_actuallyPerformCheck called"); | ||
let updateCheckResult; | ||
let updateInfo; | ||
try { | ||
// This auto-downloads the update too | ||
updateCheckResult = await __classPrivateFieldGet(this, _autoUpdater).checkForUpdates(); | ||
updateInfo = await __classPrivateFieldGet(this, _updaterAgent).checkAndDownload(); | ||
} | ||
@@ -114,27 +108,11 @@ catch (e) { | ||
__classPrivateFieldSet(this, _pendingCheckSources, []); | ||
let isThereAnUpdate = false; | ||
if (updateCheckResult && updateCheckResult.updateInfo) { | ||
// We need to make sure the version is actually newer | ||
const currentVersion = electron.app.getVersion(); | ||
const newVersion = updateCheckResult.updateInfo.version; | ||
this._log("Analysing autoUpdater.checkForUpdates result", { | ||
currentVersion, | ||
newVersion, | ||
updateInfo: updateCheckResult.updateInfo, | ||
}); | ||
isThereAnUpdate = semver.gt(newVersion, currentVersion); | ||
} | ||
// No update available; exit early | ||
if (!isThereAnUpdate) { | ||
if (!updateInfo) { | ||
// To be safe | ||
__classPrivateFieldSet(this, _hasUpdateReadyToInstall, false); | ||
return { | ||
updateInfo: null, | ||
updateInfo, | ||
}; | ||
} | ||
__classPrivateFieldSet(this, _hasUpdateReadyToInstall, true); | ||
const updateInfo = { | ||
releaseDate: updateCheckResult.updateInfo.releaseDate, | ||
version: updateCheckResult.updateInfo.version, | ||
}; | ||
// Emit the event | ||
@@ -145,3 +123,3 @@ const eventPayload = { | ||
}; | ||
const emitPromise = this.emitAsync("update-available", eventPayload); | ||
const emitPromise = this.emitAsync("update-downloaded", eventPayload); | ||
/* | ||
@@ -168,3 +146,3 @@ If they haven't disabled the default behaviour or they've already been notified of an update | ||
title: "A new update is ready to install", | ||
body: `${electron.app.name} version ${updateCheckResult.updateInfo.version} has been downloaded and will be automatically installed on exit`, | ||
body: `${electron.app.name} version ${updateInfo.version} has been downloaded and will be automatically installed on exit`, | ||
}); | ||
@@ -174,3 +152,3 @@ notification.show(); | ||
// They have a time-limited window to respond. Try to notify when it ends | ||
this._setTimeout(() => { | ||
setTimeout_1.default(() => { | ||
this._log("before notify call in setTimeout"); | ||
@@ -211,3 +189,3 @@ notify(); | ||
this._log("checkAfterTimeout"); | ||
this._setTimeout(async () => { | ||
setTimeout_1.default(async () => { | ||
try { | ||
@@ -239,3 +217,3 @@ await this._check({ | ||
/* | ||
We collect the sources and emit them with the update-available event. | ||
We collect the sources and emit them with the update-downloaded event. | ||
Other noteworthy bits: | ||
@@ -269,4 +247,31 @@ - The update check promise is reused by electron-updater. | ||
} | ||
_initializeInternalAutoUpdater() { | ||
__classPrivateFieldSet(this, _autoUpdater, electronUpdater.autoUpdater); | ||
/* | ||
Why are thgere UpdaterAgent classes? | ||
To transition apps to us, specifically Squirrel.Windows apps, we need | ||
to use electron-updater. They put runtime in their app, built with | ||
their existing tooling/infrastructure, then runtime will point to | ||
a Squirrel.Windows on our server which will actually use an NSIS | ||
installer and transition them. | ||
For Mac apps not built by us, we can use electron-updater but we need | ||
to make sure we point to our server. | ||
*/ | ||
_initializeUpdaterAgent() { | ||
if (process.platform === "win32" && | ||
!getConfig_1.default().wasBuiltByUs && | ||
// This is the official way to detect Squirrel.Windows | ||
fs.existsSync(path.join(electron.app.getAppPath(), "../Update.exe"))) { | ||
__classPrivateFieldSet(this, _updaterAgent, new updaterAgents_1.SquirrelWindowsUpdaterAgent({ | ||
log: (...args) => { | ||
this._log("UpdaterAgent:", ...args); | ||
}, | ||
})); | ||
return; | ||
} | ||
__classPrivateFieldSet(this, _updaterAgent, new updaterAgents_1.UpdaterAgent({ | ||
log: (...args) => { | ||
this._log("SquirrelWindowsUpdaterAgent:", ...args); | ||
}, | ||
})); | ||
} | ||
@@ -288,12 +293,2 @@ _log(...args) { | ||
} | ||
_setTimeout(callback, interval) { | ||
if (process.env.AVA_PATH && typeof setTimeout === "undefined") { | ||
/* | ||
setTimeout doesn't exist. Ignoring because it's during a test. | ||
This happens sometimes after a test ends. Probably related to using fake timers that overwrite setTimeout | ||
*/ | ||
return; | ||
} | ||
return setTimeout(callback, interval); | ||
} | ||
_subscribeToElectronEvents() { | ||
@@ -306,2 +301,2 @@ electron.autoUpdater.on("before-quit-for-update", (...args) => { | ||
exports.default = AutoUpdater; | ||
_autoUpdater = new WeakMap(), _createdAt = new WeakMap(), _hasAppFinishedLaunching = new WeakMap(), _hasNotified = new WeakMap(), _hasUpdateReadyToInstall = new WeakMap(), _isActive = new WeakMap(), _pendingCheckSources = new WeakMap(), _pendingUpdateCheckPromise = new WeakMap(), _shouldNotify = new WeakMap(); | ||
_createdAt = new WeakMap(), _hasAppFinishedLaunching = new WeakMap(), _hasNotified = new WeakMap(), _hasUpdateReadyToInstall = new WeakMap(), _isActive = new WeakMap(), _pendingCheckSources = new WeakMap(), _pendingUpdateCheckPromise = new WeakMap(), _shouldNotify = new WeakMap(), _updaterAgent = new WeakMap(); |
{ | ||
"private": false, | ||
"name": "@todesktop/runtime", | ||
"version": "0.1.0-rc.3", | ||
"version": "0.1.0-rc.r", | ||
"license": "MIT", | ||
@@ -39,2 +39,3 @@ "author": "Adam Lynch <contact@adamlynch.com> (http://adamlynch.com/)", | ||
"@babel/register": "^7.9.0", | ||
"@types/node": "^13.13.4", | ||
"@typescript-eslint/eslint-plugin": "^2.29.0", | ||
@@ -41,0 +42,0 @@ "@typescript-eslint/parser": "^2.29.0", |
@@ -66,3 +66,3 @@ # @todesktop/runtime | ||
What happens when an update is found can be disabled using the [`update-available` event](#events) (learn more below). | ||
What happens when an update is found can be disabled using the [`update-downloaded` event](#events) (learn more below). | ||
@@ -135,3 +135,3 @@ Everything (the notification, the auto-checks on launch and on interval) can be disabled by passing `autoUpdater: false` to the [`.init` method](#initoptions) (learn more below). | ||
The source/trigger of the update check. The `update-available` event passes this back to you so you can identify the source(s) of the update check. | ||
The source/trigger of the update check. The `update-downloaded` event passes this back to you so you can identify the source(s) of the update check. | ||
@@ -175,3 +175,3 @@ #### Example | ||
NOTE: this method will close all application windows first and only emit `before-quit` event on app after that. This is different from the normal quit event sequence. | ||
NOTE: this method will close all application windows first and only emit `before-quit` event on app after that. This is different from the normal quit event sequence. However, this is not the case if the method is called from a Squirrel.Windows application. | ||
@@ -185,5 +185,5 @@ | ||
### `update-available` | ||
### `update-downloaded` | ||
Emitted when there is an available update. The update has already been downloaded. | ||
Emitted when there is an update available and downloaded. The update has already been downloaded. | ||
@@ -211,3 +211,3 @@ Your callback is called with an object like this: | ||
```javascript | ||
todesktop.autoUpdater.on("update-available", (event) => { | ||
todesktop.autoUpdater.on("update-downloaded", (event) => { | ||
console.log("Update found:", event.updateInfo.version); | ||
@@ -214,0 +214,0 @@ if(event.sources.includes("my-custom-source")) { |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
36785
17
649
27
7