Initial Typescripting for Element Desktop

This commit is contained in:
Michael Telatynski 2021-06-25 14:35:58 +01:00
parent 6e76d658b1
commit 53e7100033
14 changed files with 543 additions and 238 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
/dist /dist
/lib
/webapp /webapp
/webapp.asar /webapp.asar
/packages /packages

View file

@ -1,7 +1,7 @@
{ {
"name": "element-desktop", "name": "element-desktop",
"productName": "Element", "productName": "Element",
"main": "src/electron-main.js", "main": "lib/electron-main.js",
"version": "1.7.31", "version": "1.7.31",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "Element", "author": "Element",
@ -18,12 +18,13 @@
"mkdirs": "mkdirp packages deploys", "mkdirs": "mkdirp packages deploys",
"fetch": "yarn run mkdirs && node scripts/fetch-package.js", "fetch": "yarn run mkdirs && node scripts/fetch-package.js",
"asar-webapp": "asar p webapp webapp.asar", "asar-webapp": "asar p webapp webapp.asar",
"start": "electron .", "start": "yarn run tsbuild && electron .",
"lint": "eslint src/ scripts/ hak/", "lint": "eslint src/ scripts/ hak/",
"build:native": "yarn run hak", "build:native": "yarn run hak",
"build32": "electron-builder --ia32", "build32": "electron-builder --ia32",
"build64": "electron-builder --x64", "build64": "electron-builder --x64",
"build": "electron-builder", "build": "yarn run tsbuild && electron-builder",
"tsbuild": "tsc",
"docker:setup": "docker build -t element-desktop-dockerbuild dockerbuild", "docker:setup": "docker build -t element-desktop-dockerbuild dockerbuild",
"docker:build:native": "scripts/in-docker.sh yarn run hak", "docker:build:native": "scripts/in-docker.sh yarn run hak",
"docker:build": "scripts/in-docker.sh yarn run build", "docker:build": "scripts/in-docker.sh yarn run build",
@ -42,7 +43,10 @@
"request": "^2.88.2" "request": "^2.88.2"
}, },
"devDependencies": { "devDependencies": {
"@types/auto-launch": "^5.0.1",
"@types/counterpart": "^0.18.1",
"asar": "^2.0.1", "asar": "^2.0.1",
"electron": "12.0.11",
"electron-builder": "22.11.4", "electron-builder": "22.11.4",
"electron-builder-squirrel-windows": "22.11.4", "electron-builder-squirrel-windows": "22.11.4",
"electron-devtools-installer": "^3.1.1", "electron-devtools-installer": "^3.1.1",
@ -60,7 +64,8 @@
"npm": "^6.14.11", "npm": "^6.14.11",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"semver": "^7.3.4", "semver": "^7.3.4",
"tar": "^6.1.0" "tar": "^6.1.0",
"typescript": "^4.1.3"
}, },
"hakDependencies": { "hakDependencies": {
"matrix-seshat": "^2.2.3", "matrix-seshat": "^2.2.3",

26
src/@types/global.d.ts vendored Normal file
View file

@ -0,0 +1,26 @@
/*
Copyright 2021 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { BrowserWindow } from "electron";
declare global {
namespace NodeJS {
interface Global {
mainWindow: BrowserWindow;
appQuitting: boolean;
}
}
}

View file

@ -20,32 +20,29 @@ limitations under the License.
// Squirrel on windows starts the app with various flags // Squirrel on windows starts the app with various flags
// as hooks to tell us when we've been installed/uninstalled // as hooks to tell us when we've been installed/uninstalled
// etc. // etc.
const checkSquirrelHooks = require('./squirrelhooks'); import { checkSquirrelHooks } from "./squirrelhooks";
if (checkSquirrelHooks()) return; if (checkSquirrelHooks()) process.exit(1);
const argv = require('minimist')(process.argv, { const argv = require('minimist')(process.argv, {
alias: { help: "h" }, alias: { help: "h" },
}); });
const { import { app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol, dialog } from "electron";
app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol, dialog, import AutoLaunch from "auto-launch";
} = require('electron'); import path from "path";
const AutoLaunch = require('auto-launch'); import windowStateKeeper from 'electron-window-state';
const path = require('path'); import Store from 'electron-store';
import fs, { promises as afs } from "fs";
import crypto from "crypto";
import { URL } from "url";
const tray = require('./tray'); import * as tray from "./tray";
const buildMenuTemplate = require('./vectormenu'); import { buildMenuTemplate } from './vectormenu';
const webContentsHandler = require('./webcontents-handler'); import webContentsHandler from './webcontents-handler';
const updater = require('./updater'); import * as updater from './updater';
const { getProfileFromDeeplink, protocolInit, recordSSOSession } = require('./protocol'); import { getProfileFromDeeplink, protocolInit, recordSSOSession } from './protocol';
import { _t, AppLocalization } from './language-helper';
const windowStateKeeper = require('electron-window-state');
const Store = require('electron-store');
const fs = require('fs');
const afs = fs.promises;
const crypto = require('crypto');
let keytar; let keytar;
try { try {
keytar = require('keytar'); keytar = require('keytar');
@ -57,8 +54,6 @@ try {
} }
} }
const { _t, AppLocalization } = require('./language-helper');
let seshatSupported = false; let seshatSupported = false;
let Seshat; let Seshat;
let SeshatRecovery; let SeshatRecovery;
@ -259,7 +254,13 @@ async function moveAutoLauncher() {
} }
const eventStorePath = path.join(app.getPath('userData'), 'EventStore'); const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
const store = new Store({ name: "electron-config" }); const store = new Store<{
warnBeforeExit?: boolean;
minimizeToTray?: boolean;
spellCheckerEnabled?: boolean;
autoHideMenuBar?: boolean;
locale?: string | string[];
}>({ name: "electron-config" });
let eventIndex = null; let eventIndex = null;
@ -1016,7 +1017,7 @@ function beforeQuit() {
} }
app.on('before-quit', beforeQuit); app.on('before-quit', beforeQuit);
app.on('before-quit-for-update', beforeQuit); autoUpdater.on('before-quit-for-update', beforeQuit);
app.on('second-instance', (ev, commandLine, workingDirectory) => { app.on('second-instance', (ev, commandLine, workingDirectory) => {
// If other instance launched with --hidden then skip showing window // If other instance launched with --hidden then skip showing window

View file

@ -14,15 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const counterpart = require('counterpart'); import counterpart from "counterpart";
import type Store from 'electron-store';
const DEFAULT_LOCALE = "en"; const DEFAULT_LOCALE = "en";
function _td(text) { export function _td(text: string): string {
return text; return text;
} }
function _t(text, variables = {}) { type SubstitutionValue = number | string;
interface IVariables {
[key: string]: SubstitutionValue;
count?: number;
}
export function _t(text: string, variables: IVariables = {}): string {
const args = Object.assign({ interpolate: false }, variables); const args = Object.assign({ interpolate: false }, variables);
const { count } = args; const { count } = args;
@ -55,11 +63,17 @@ function _t(text, variables = {}) {
return translated; return translated;
} }
class AppLocalization { type Component = () => void;
constructor({ store, components = [] }) {
// TODO: Should be static field, but that doesn't parse without Babel
this.STORE_KEY = "locale";
type TypedStore = Store<{ locale?: string | string[] }>;
export class AppLocalization {
private static readonly STORE_KEY = "locale";
private readonly store: TypedStore;
private readonly localizedComponents: Set<Component>;
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN")); counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
counterpart.setFallbackLocale('en'); counterpart.setFallbackLocale('en');
counterpart.setSeparator('|'); counterpart.setSeparator('|');
@ -69,15 +83,15 @@ class AppLocalization {
} }
this.store = store; this.store = store;
if (this.store.has(this.STORE_KEY)) { if (this.store.has(AppLocalization.STORE_KEY)) {
const locales = this.store.get(this.STORE_KEY); const locales = this.store.get(AppLocalization.STORE_KEY);
this.setAppLocale(locales); this.setAppLocale(locales);
} }
this.resetLocalizedUI(); this.resetLocalizedUI();
} }
fetchTranslationJson(locale) { public fetchTranslationJson(locale: string): Record<string, string> {
try { try {
console.log("Fetching translation json for locale: " + locale); console.log("Fetching translation json for locale: " + locale);
return require(`./i18n/strings/${locale}.json`); return require(`./i18n/strings/${locale}.json`);
@ -87,11 +101,7 @@ class AppLocalization {
} }
} }
get languageTranslationJson() { public setAppLocale(locales: string | string[]): void {
return this.translationJsonMap.get(this.language);
}
setAppLocale(locales) {
console.log(`Changing application language to ${locales}`); console.log(`Changing application language to ${locales}`);
if (!Array.isArray(locales)) { if (!Array.isArray(locales)) {
@ -105,13 +115,14 @@ class AppLocalization {
} }
}); });
// @ts-ignore - this looks like a bug but is out of scope for this conversion
counterpart.setLocale(locales); counterpart.setLocale(locales);
this.store.set(this.STORE_KEY, locales); this.store.set(AppLocalization.STORE_KEY, locales);
this.resetLocalizedUI(); this.resetLocalizedUI();
} }
resetLocalizedUI() { public resetLocalizedUI(): void {
console.log("Resetting the UI components after locale change"); console.log("Resetting the UI components after locale change");
this.localizedComponents.forEach(componentSetup => { this.localizedComponents.forEach(componentSetup => {
if (typeof componentSetup === "function") { if (typeof componentSetup === "function") {
@ -120,9 +131,3 @@ class AppLocalization {
}); });
} }
} }
module.exports = {
AppLocalization,
_t,
_td,
};

View file

@ -1,102 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const { app } = require("electron");
const path = require("path");
const fs = require("fs");
const PROTOCOL = "element://";
const SEARCH_PARAM = "element-desktop-ssoid";
const STORE_FILE_NAME = "sso-sessions.json";
// we getPath userData before electron-main changes it, so this is the default value
const storePath = path.join(app.getPath("userData"), STORE_FILE_NAME);
const processUrl = (url) => {
if (!global.mainWindow) return;
console.log("Handling link: ", url);
global.mainWindow.loadURL(url.replace(PROTOCOL, "vector://"));
};
const readStore = () => {
try {
const s = fs.readFileSync(storePath, { encoding: "utf8" });
const o = JSON.parse(s);
return typeof o === "object" ? o : {};
} catch (e) {
return {};
}
};
const writeStore = (data) => {
fs.writeFileSync(storePath, JSON.stringify(data));
};
module.exports = {
recordSSOSession: (sessionID) => {
const userDataPath = app.getPath('userData');
const store = readStore();
for (const key in store) {
// ensure each instance only has one (the latest) session ID to prevent the file growing unbounded
if (store[key] === userDataPath) {
delete store[key];
break;
}
}
store[sessionID] = userDataPath;
writeStore(store);
},
getProfileFromDeeplink: (args) => {
// check if we are passed a profile in the SSO callback url
const deeplinkUrl = args.find(arg => arg.startsWith('element://'));
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
const parsedUrl = new URL(deeplinkUrl);
if (parsedUrl.protocol === 'element:') {
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
const store = readStore();
console.log("Forwarding to profile: ", store[ssoID]);
return store[ssoID];
}
}
},
protocolInit: () => {
// get all args except `hidden` as it'd mean the app would not get focused
// XXX: passing args to protocol handlers only works on Windows, so unpackaged deep-linking
// --profile/--profile-dir are passed via the SEARCH_PARAM var in the callback url
const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
if (app.isPackaged) {
app.setAsDefaultProtocolClient('element', process.execPath, args);
} else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
// special handler for running without being packaged, e.g `electron .` by passing our app path to electron
app.setAsDefaultProtocolClient('element', process.execPath, [app.getAppPath(), ...args]);
}
if (process.platform === 'darwin') {
// Protocol handler for macos
app.on('open-url', function(ev, url) {
ev.preventDefault();
processUrl(url);
});
} else {
// Protocol handler for win32/Linux
app.on('second-instance', (ev, commandLine) => {
const url = commandLine[commandLine.length - 1];
if (!url.startsWith(PROTOCOL)) return;
processUrl(url);
});
}
},
};

103
src/protocol.ts Normal file
View file

@ -0,0 +1,103 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { app } from "electron";
import { URL } from "url";
import path from "path";
import fs from "fs";
const PROTOCOL = "element://";
const SEARCH_PARAM = "element-desktop-ssoid";
const STORE_FILE_NAME = "sso-sessions.json";
// we getPath userData before electron-main changes it, so this is the default value
const storePath = path.join(app.getPath("userData"), STORE_FILE_NAME);
function processUrl(url: string): void {
if (!global.mainWindow) return;
console.log("Handling link: ", url);
global.mainWindow.loadURL(url.replace(PROTOCOL, "vector://"));
}
function readStore(): object {
try {
const s = fs.readFileSync(storePath, { encoding: "utf8" });
const o = JSON.parse(s);
return typeof o === "object" ? o : {};
} catch (e) {
return {};
}
}
function writeStore(data: object): void {
fs.writeFileSync(storePath, JSON.stringify(data));
}
export function recordSSOSession(sessionID: string): void {
const userDataPath = app.getPath('userData');
const store = readStore();
for (const key in store) {
// ensure each instance only has one (the latest) session ID to prevent the file growing unbounded
if (store[key] === userDataPath) {
delete store[key];
break;
}
}
store[sessionID] = userDataPath;
writeStore(store);
}
export function getProfileFromDeeplink(args): string | undefined {
// check if we are passed a profile in the SSO callback url
const deeplinkUrl = args.find(arg => arg.startsWith('element://'));
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
const parsedUrl = new URL(deeplinkUrl);
if (parsedUrl.protocol === 'element:') {
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
const store = readStore();
console.log("Forwarding to profile: ", store[ssoID]);
return store[ssoID];
}
}
}
export function protocolInit(): void {
// get all args except `hidden` as it'd mean the app would not get focused
// XXX: passing args to protocol handlers only works on Windows, so unpackaged deep-linking
// --profile/--profile-dir are passed via the SEARCH_PARAM var in the callback url
const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
if (app.isPackaged) {
app.setAsDefaultProtocolClient('element', process.execPath, args);
} else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
// special handler for running without being packaged, e.g `electron .` by passing our app path to electron
app.setAsDefaultProtocolClient('element', process.execPath, [app.getAppPath(), ...args]);
}
if (process.platform === 'darwin') {
// Protocol handler for macos
app.on('open-url', function(ev, url) {
ev.preventDefault();
processUrl(url);
});
} else {
// Protocol handler for win32/Linux
app.on('second-instance', (ev, commandLine) => {
const url = commandLine[commandLine.length - 1];
if (!url.startsWith(PROTOCOL)) return;
processUrl(url);
});
}
}

View file

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const path = require('path'); import path from "path";
const spawn = require('child_process').spawn; import { spawn } from "child_process";
const { app } = require('electron'); import { app } from "electron";
const fsProm = require('fs').promises; import { promises as fsProm } from "fs";
function runUpdateExe(args) { function runUpdateExe(args: string[]): Promise<void> {
// Invokes Squirrel's Update.exe which will do things for us like create shortcuts // Invokes Squirrel's Update.exe which will do things for us like create shortcuts
// Note that there's an Update.exe in the app-x.x.x directory and one in the parent // Note that there's an Update.exe in the app-x.x.x directory and one in the parent
// directory: we need to run the one in the parent directory, because it discovers // directory: we need to run the one in the parent directory, because it discovers
@ -33,7 +33,7 @@ function runUpdateExe(args) {
}); });
} }
function checkSquirrelHooks() { export function checkSquirrelHooks(): boolean {
if (process.platform !== 'win32') return false; if (process.platform !== 'win32') return false;
const cmd = process.argv[1]; const cmd = process.argv[1];
@ -82,5 +82,3 @@ function checkSquirrelHooks() {
} }
return false; return false;
} }
module.exports = checkSquirrelHooks;

View file

@ -15,26 +15,26 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const { app, Tray, Menu, nativeImage } = require('electron'); import { app, Tray, Menu, nativeImage } from "electron";
const pngToIco = require('png-to-ico'); import pngToIco from "png-to-ico";
const path = require('path'); import path from "path";
const fs = require('fs'); import fs from "fs";
const { _t } = require('./language-helper'); import { _t } from "./language-helper";
let trayIcon = null; let trayIcon: Tray = null;
exports.hasTray = function hasTray() { export function hasTray(): boolean {
return (trayIcon !== null); return (trayIcon !== null);
}; }
exports.destroy = function() { export function destroy(): void {
if (trayIcon) { if (trayIcon) {
trayIcon.destroy(); trayIcon.destroy();
trayIcon = null; trayIcon = null;
} }
}; }
const toggleWin = function() { function toggleWin(): void {
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) { if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
global.mainWindow.hide(); global.mainWindow.hide();
} else { } else {
@ -42,9 +42,14 @@ const toggleWin = function() {
if (!global.mainWindow.isVisible()) global.mainWindow.show(); if (!global.mainWindow.isVisible()) global.mainWindow.show();
global.mainWindow.focus(); global.mainWindow.focus();
} }
}; }
exports.create = function(config) { interface IConfig {
icon_path: string;
brand: string;
}
export function create(config: IConfig): void {
// no trays on darwin // no trays on darwin
if (process.platform === 'darwin' || trayIcon) return; if (process.platform === 'darwin' || trayIcon) return;
const defaultIcon = nativeImage.createFromPath(config.icon_path); const defaultIcon = nativeImage.createFromPath(config.icon_path);
@ -89,9 +94,9 @@ exports.create = function(config) {
global.mainWindow.webContents.on('page-title-updated', function(ev, title) { global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
trayIcon.setToolTip(title); trayIcon.setToolTip(title);
}); });
}; }
function initApplicationMenu() { export function initApplicationMenu(): void {
if (!trayIcon) { if (!trayIcon) {
return; return;
} }
@ -112,5 +117,3 @@ function initApplicationMenu() {
trayIcon.setContextMenu(contextMenu); trayIcon.setContextMenu(contextMenu);
} }
exports.initApplicationMenu = initApplicationMenu;

View file

@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const { app, autoUpdater, ipcMain } = require('electron'); import { app, autoUpdater, ipcMain } from "electron";
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000; const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
const INITIAL_UPDATE_DELAY_MS = 30 * 1000; const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
function installUpdate() { function installUpdate(): void {
// for some reason, quitAndInstall does not fire the // for some reason, quitAndInstall does not fire the
// before-quit event, so we need to set the flag here. // before-quit event, so we need to set the flag here.
global.appQuitting = true; global.appQuitting = true;
autoUpdater.quitAndInstall(); autoUpdater.quitAndInstall();
} }
function pollForUpdates() { function pollForUpdates(): void {
try { try {
autoUpdater.checkForUpdates(); autoUpdater.checkForUpdates();
} catch (e) { } catch (e) {
@ -34,8 +34,7 @@ function pollForUpdates() {
} }
} }
module.exports = {}; export function start(updateBaseUrl: string): void {
module.exports.start = function startAutoUpdate(updateBaseUrl) {
if (updateBaseUrl.slice(-1) !== '/') { if (updateBaseUrl.slice(-1) !== '/') {
updateBaseUrl = updateBaseUrl + '/'; updateBaseUrl = updateBaseUrl + '/';
} }
@ -80,18 +79,25 @@ module.exports.start = function startAutoUpdate(updateBaseUrl) {
// will fail if running in debug mode // will fail if running in debug mode
console.log('Couldn\'t enable update checking', err); console.log('Couldn\'t enable update checking', err);
} }
}; }
ipcMain.on('install_update', installUpdate); ipcMain.on('install_update', installUpdate);
ipcMain.on('check_updates', pollForUpdates); ipcMain.on('check_updates', pollForUpdates);
function ipcChannelSendUpdateStatus(status) { function ipcChannelSendUpdateStatus(status: boolean | string): void {
if (!global.mainWindow) return; if (!global.mainWindow) return;
global.mainWindow.webContents.send('check_updates', status); global.mainWindow.webContents.send('check_updates', status);
} }
interface ICachedUpdate {
releaseNotes: string;
releaseName: string;
releaseDate: Date;
updateURL : string;
}
// cache the latest update which has been downloaded as electron offers no api to read it // cache the latest update which has been downloaded as electron offers no api to read it
let latestUpdateDownloaded; let latestUpdateDownloaded: ICachedUpdate;
autoUpdater.on('update-available', function() { autoUpdater.on('update-available', function() {
ipcChannelSendUpdateStatus(true); ipcChannelSendUpdateStatus(true);
}).on('update-not-available', function() { }).on('update-not-available', function() {

View file

@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
const { app, shell, Menu } = require('electron'); import { app, shell, Menu, MenuItem, MenuItemConstructorOptions } from 'electron';
const { _t } = require('./language-helper'); import { _t } from './language-helper';
const isMac = process.platform === 'darwin'; const isMac = process.platform === 'darwin';
function buildMenuTemplate() { export function buildMenuTemplate(): Menu {
// Menu template from http://electron.atom.io/docs/api/menu/, edited // Menu template from http://electron.atom.io/docs/api/menu/, edited
const template = [ const template: Array<(MenuItemConstructorOptions) | (MenuItem)> = [
{ {
label: _t('Edit'), label: _t('Edit'),
accelerator: 'e', accelerator: 'e',
@ -48,7 +48,7 @@ function buildMenuTemplate() {
label: _t('Paste'), label: _t('Paste'),
}, },
{ {
role: 'pasteandmatchstyle', role: 'pasteAndMatchStyle',
label: _t('Paste and Match Style'), label: _t('Paste and Match Style'),
}, },
{ {
@ -56,7 +56,7 @@ function buildMenuTemplate() {
label: _t('Delete'), label: _t('Delete'),
}, },
{ {
role: 'selectall', role: 'selectAll',
label: _t('Select All'), label: _t('Select All'),
}, },
], ],
@ -67,30 +67,30 @@ function buildMenuTemplate() {
submenu: [ submenu: [
{ type: 'separator' }, { type: 'separator' },
{ {
role: 'resetzoom', role: 'resetZoom',
accelerator: 'CmdOrCtrl+Num0', accelerator: 'CmdOrCtrl+Num0',
visible: false, visible: false,
}, },
{ {
role: 'zoomin', role: 'zoomIn',
accelerator: 'CmdOrCtrl+NumAdd', accelerator: 'CmdOrCtrl+NumAdd',
visible: false, visible: false,
}, },
{ {
role: 'zoomout', role: 'zoomOut',
accelerator: 'CmdOrCtrl+NumSub', accelerator: 'CmdOrCtrl+NumSub',
visible: false, visible: false,
}, },
{ {
role: 'resetzoom', role: 'resetZoom',
label: _t('Actual Size'), label: _t('Actual Size'),
}, },
{ {
role: 'zoomin', role: 'zoomIn',
label: _t('Zoom In'), label: _t('Zoom In'),
}, },
{ {
role: 'zoomout', role: 'zoomOut',
label: _t('Zoom Out'), label: _t('Zoom Out'),
}, },
{ type: 'separator' }, { type: 'separator' },
@ -104,7 +104,7 @@ function buildMenuTemplate() {
label: _t('Toggle Full Screen'), label: _t('Toggle Full Screen'),
}, },
{ {
role: 'toggledevtools', role: 'toggleDevTools',
label: _t('Toggle Developer Tools'), label: _t('Toggle Developer Tools'),
}, },
], ],
@ -166,7 +166,7 @@ function buildMenuTemplate() {
label: _t('Hide'), label: _t('Hide'),
}, },
{ {
role: 'hideothers', role: 'hideOthers',
label: _t('Hide Others'), label: _t('Hide Others'),
}, },
{ {
@ -182,17 +182,17 @@ function buildMenuTemplate() {
}); });
// Edit menu. // Edit menu.
// This has a 'speech' section on macOS // This has a 'speech' section on macOS
template[1].submenu.push( (template[1].submenu as MenuItemConstructorOptions[]).push(
{ type: 'separator' }, { type: 'separator' },
{ {
label: _t('Speech'), label: _t('Speech'),
submenu: [ submenu: [
{ {
role: 'startspeaking', role: 'startSpeaking',
label: _t('Start Speaking'), label: _t('Start Speaking'),
}, },
{ {
role: 'stopspeaking', role: 'stopSpeaking',
label: _t('Stop Speaking'), label: _t('Stop Speaking'),
}, },
], ],
@ -243,6 +243,3 @@ function buildMenuTemplate() {
return Menu.buildFromTemplate(template); return Menu.buildFromTemplate(template);
} }
module.exports = buildMenuTemplate;

View file

@ -1,19 +1,49 @@
const { clipboard, nativeImage, Menu, MenuItem, shell, dialog, ipcMain } = require('electron'); /*
const url = require('url'); Copyright 2021 New Vector Ltd
const fs = require('fs');
const request = require('request'); Licensed under the Apache License, Version 2.0 (the "License");
const path = require('path'); you may not use this file except in compliance with the License.
const { _t } = require('./language-helper'); You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import {
clipboard,
nativeImage,
Menu,
MenuItem,
shell,
dialog,
ipcMain,
NativeImage,
WebContents,
ContextMenuParams,
DownloadItem,
MenuItemConstructorOptions,
IpcMainEvent,
} from 'electron';
import url from 'url';
import fs from 'fs';
import request from 'request';
import path from 'path';
import { _t } from './language-helper';
const MAILTO_PREFIX = "mailto:"; const MAILTO_PREFIX = "mailto:";
const PERMITTED_URL_SCHEMES = [ const PERMITTED_URL_SCHEMES: string[] = [
'http:', 'http:',
'https:', 'https:',
MAILTO_PREFIX, MAILTO_PREFIX,
]; ];
function safeOpenURL(target) { function safeOpenURL(target: string): void {
// openExternal passes the target to open/start/xdg-open, // openExternal passes the target to open/start/xdg-open,
// so put fairly stringent limits on what can be opened // so put fairly stringent limits on what can be opened
// (for instance, open /bin/sh does indeed open a terminal // (for instance, open /bin/sh does indeed open a terminal
@ -28,7 +58,7 @@ function safeOpenURL(target) {
} }
} }
function onWindowOrNavigate(ev, target) { function onWindowOrNavigate(ev: Event, target: string): void {
// always prevent the default: if something goes wrong, // always prevent the default: if something goes wrong,
// we don't want to end up opening it in the electron // we don't want to end up opening it in the electron
// app, as we could end up opening any sort of random // app, as we could end up opening any sort of random
@ -37,7 +67,7 @@ function onWindowOrNavigate(ev, target) {
safeOpenURL(target); safeOpenURL(target);
} }
function writeNativeImage(filePath, img) { function writeNativeImage(filePath: string, img: NativeImage): Promise<void> {
switch (filePath.split('.').pop().toLowerCase()) { switch (filePath.split('.').pop().toLowerCase()) {
case "jpg": case "jpg":
case "jpeg": case "jpeg":
@ -50,7 +80,7 @@ function writeNativeImage(filePath, img) {
} }
} }
function onLinkContextMenu(ev, params) { function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: WebContents): void {
let url = params.linkURL || params.srcURL; let url = params.linkURL || params.srcURL;
if (url.startsWith('vector://vector/webapp')) { if (url.startsWith('vector://vector/webapp')) {
@ -76,7 +106,7 @@ function onLinkContextMenu(ev, params) {
label: _t('Copy image'), label: _t('Copy image'),
accelerator: 'c', accelerator: 'c',
click() { click() {
ev.sender.copyImageAt(params.x, params.y); webContents.copyImageAt(params.x, params.y);
}, },
})); }));
} }
@ -140,8 +170,8 @@ function onLinkContextMenu(ev, params) {
ev.preventDefault(); ev.preventDefault();
} }
function _CutCopyPasteSelectContextMenus(params) { function CutCopyPasteSelectContextMenus(params: ContextMenuParams): MenuItemConstructorOptions[] {
const options = []; const options: MenuItemConstructorOptions[] = [];
if (params.misspelledWord) { if (params.misspelledWord) {
params.dictionarySuggestions.forEach(word => { params.dictionarySuggestions.forEach(word => {
@ -180,10 +210,10 @@ function _CutCopyPasteSelectContextMenus(params) {
accelerator: 'p', accelerator: 'p',
enabled: params.editFlags.canPaste, enabled: params.editFlags.canPaste,
}, { }, {
role: 'pasteandmatchstyle', role: 'pasteAndMatchStyle',
enabled: params.editFlags.canPaste, enabled: params.editFlags.canPaste,
}, { }, {
role: 'selectall', role: 'selectAll',
label: _t("Select All"), label: _t("Select All"),
accelerator: 'a', accelerator: 'a',
enabled: params.editFlags.canSelectAll, enabled: params.editFlags.canSelectAll,
@ -192,7 +222,7 @@ function _CutCopyPasteSelectContextMenus(params) {
} }
function onSelectedContextMenu(ev, params) { function onSelectedContextMenu(ev, params) {
const items = _CutCopyPasteSelectContextMenus(params); const items = CutCopyPasteSelectContextMenus(params);
const popupMenu = Menu.buildFromTemplate(items); const popupMenu = Menu.buildFromTemplate(items);
// popup() requires an options object even for no options // popup() requires an options object even for no options
@ -200,12 +230,13 @@ function onSelectedContextMenu(ev, params) {
ev.preventDefault(); ev.preventDefault();
} }
function onEditableContextMenu(ev, params) { function onEditableContextMenu(ev: Event, params: ContextMenuParams) {
const items = [ const items: MenuItemConstructorOptions[] = [
{ role: 'undo' }, { role: 'undo' },
{ role: 'redo', enabled: params.editFlags.canRedo }, { role: 'redo', enabled: params.editFlags.canRedo },
{ type: 'separator' }, { type: 'separator' },
].concat(_CutCopyPasteSelectContextMenus(params)); ...CutCopyPasteSelectContextMenus(params),
];
const popupMenu = Menu.buildFromTemplate(items); const popupMenu = Menu.buildFromTemplate(items);
@ -214,20 +245,20 @@ function onEditableContextMenu(ev, params) {
ev.preventDefault(); ev.preventDefault();
} }
ipcMain.on('userDownloadOpen', function(ev, { path }) { ipcMain.on('userDownloadOpen', function(ev: IpcMainEvent, { path }) {
shell.openPath(path); shell.openPath(path);
}); });
module.exports = (webContents) => { export default (webContents: WebContents): void => {
webContents.on('new-window', onWindowOrNavigate); webContents.on('new-window', onWindowOrNavigate);
webContents.on('will-navigate', (ev, target) => { webContents.on('will-navigate', (ev: Event, target: string): void => {
if (target.startsWith("vector://")) return; if (target.startsWith("vector://")) return;
return onWindowOrNavigate(ev, target); return onWindowOrNavigate(ev, target);
}); });
webContents.on('context-menu', function(ev, params) { webContents.on('context-menu', function(ev: Event, params: ContextMenuParams): void {
if (params.linkURL || params.srcURL) { if (params.linkURL || params.srcURL) {
onLinkContextMenu(ev, params); onLinkContextMenu(ev, params, webContents);
} else if (params.selectionText) { } else if (params.selectionText) {
onSelectedContextMenu(ev, params); onSelectedContextMenu(ev, params);
} else if (params.isEditable) { } else if (params.isEditable) {
@ -235,7 +266,7 @@ module.exports = (webContents) => {
} }
}); });
webContents.session.on('will-download', (event, item) => { webContents.session.on('will-download', (event: Event, item: DownloadItem): void => {
item.once('done', (event, state) => { item.once('done', (event, state) => {
if (state === 'completed') { if (state === 'completed') {
const savePath = item.getSavePath(); const savePath = item.getSavePath();

25
tsconfig.json Normal file
View file

@ -0,0 +1,25 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"target": "es2016",
"noImplicitAny": false,
"sourceMap": false,
"outDir": "./lib",
"declaration": true,
"types": [
"node"
],
"lib": [
"es2019",
"dom"
]
},
"include": [
"./src/**/*.ts"
]
}

220
yarn.lock
View file

@ -127,6 +127,22 @@
ajv "^6.12.0" ajv "^6.12.0"
ajv-keywords "^3.4.1" ajv-keywords "^3.4.1"
"@electron/get@^1.0.1":
version "1.12.4"
resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.4.tgz#a5971113fc1bf8fa12a8789dc20152a7359f06ab"
integrity sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg==
dependencies:
debug "^4.1.1"
env-paths "^2.2.0"
fs-extra "^8.1.0"
got "^9.6.0"
progress "^2.0.3"
semver "^6.2.0"
sumchecker "^3.0.1"
optionalDependencies:
global-agent "^2.0.2"
global-tunnel-ng "^2.7.1"
"@electron/universal@1.0.5": "@electron/universal@1.0.5":
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37" resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.5.tgz#b812340e4ef21da2b3ee77b2b4d35c9b86defe37"
@ -482,11 +498,21 @@
dependencies: dependencies:
defer-to-connect "^1.0.1" defer-to-connect "^1.0.1"
"@types/auto-launch@^5.0.1":
version "5.0.1"
resolved "https://registry.yarnpkg.com/@types/auto-launch/-/auto-launch-5.0.1.tgz#388a047edc0e754d8e8978cbd9ed4672b36be2c4"
integrity sha512-+KQ+/koZ7sJXnf5cnCANofY6yXAdYJNEoVZEuWcwJfuWbUp9u6l09I7KhwD+ivU+cdz7JId4V5ukxscWtHdSuw==
"@types/color-name@^1.1.1": "@types/color-name@^1.1.1":
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
"@types/counterpart@^0.18.1":
version "0.18.1"
resolved "https://registry.yarnpkg.com/@types/counterpart/-/counterpart-0.18.1.tgz#b1b784d9e54d9879f0a8cb12f2caedab65430fe8"
integrity sha512-PRuFlBBkvdDOtxlIASzTmkEFar+S66Ek48NVVTWMUjtJAdn5vyMSN8y6IZIoIymGpR36q2nZbIYazBWyFxL+IQ==
"@types/debug@^4.1.5": "@types/debug@^4.1.5":
version "4.1.5" version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
@ -522,6 +548,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.21.tgz#d934aacc22424fe9622ebf6857370c052eae464e" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.21.tgz#d934aacc22424fe9622ebf6857370c052eae464e"
integrity sha512-cHYfKsnwllYhjOzuC5q1VpguABBeecUp24yFluHpn/BQaVxB1CuQ1FSRZCzrPxrkIfWISXV2LbeoBthLWg0+0A== integrity sha512-cHYfKsnwllYhjOzuC5q1VpguABBeecUp24yFluHpn/BQaVxB1CuQ1FSRZCzrPxrkIfWISXV2LbeoBthLWg0+0A==
"@types/node@^14.6.2":
version "14.17.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.4.tgz#218712242446fc868d0e007af29a4408c7765bc0"
integrity sha512-8kQ3+wKGRNN0ghtEn7EGps/B8CzuBz1nXZEIGGLP2GnwbqYn4dbTs7k+VKLTq1HvZLRCIDtN3Snx1Ege8B7L5A==
"@types/plist@^3.0.1": "@types/plist@^3.0.1":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01"
@ -998,6 +1029,11 @@ bmp-js@^0.1.0:
resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233"
integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM=
boolean@^3.0.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2"
integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==
boxen@^1.2.1: boxen@^1.2.1:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
@ -1033,7 +1069,7 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0" balanced-match "^1.0.0"
concat-map "0.0.1" concat-map "0.0.1"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3:
version "0.2.13" version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
@ -1433,7 +1469,7 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
concat-stream@^1.5.0: concat-stream@^1.5.0, concat-stream@^1.6.2:
version "1.6.2" version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@ -1459,6 +1495,14 @@ conf@^7.1.2:
pkg-up "^3.1.0" pkg-up "^3.1.0"
semver "^7.3.2" semver "^7.3.2"
config-chain@^1.1.11:
version "1.1.13"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
config-chain@^1.1.12: config-chain@^1.1.12:
version "1.1.12" version "1.1.12"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
@ -1508,6 +1552,11 @@ copy-concurrently@^1.0.0:
rimraf "^2.5.4" rimraf "^2.5.4"
run-queue "^1.0.0" run-queue "^1.0.0"
core-js@^3.6.5:
version "3.15.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.1.tgz#6c08ab88abdf56545045ccf5fd81f47f407e7f1a"
integrity sha512-h8VbZYnc9pDzueiS2610IULDkpFFPunHwIpl8yRwFahAEEdSpHlTy3h3z3rKq5h11CaUdBEeRViu9AYvbxiMeg==
core-util-is@1.0.2, core-util-is@~1.0.0: core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -1618,6 +1667,13 @@ debug@3.1.0:
dependencies: dependencies:
ms "2.0.0" ms "2.0.0"
debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^3.1.0: debug@^3.1.0:
version "3.2.7" version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@ -1729,6 +1785,11 @@ detect-newline@^2.1.0:
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
detect-node@^2.0.4:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
dezalgo@^1.0.0, dezalgo@~1.0.3: dezalgo@^1.0.0, dezalgo@~1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456"
@ -1928,6 +1989,15 @@ electron-window-state@^5.0.3:
jsonfile "^4.0.0" jsonfile "^4.0.0"
mkdirp "^0.5.1" mkdirp "^0.5.1"
electron@12.0.11:
version "12.0.11"
resolved "https://registry.yarnpkg.com/electron/-/electron-12.0.11.tgz#555dc1cf663e320f2f2cbdf89319352b08fc59f2"
integrity sha512-6gPjcce3QCeAWZ8UVAqVy6os+86D5BcxgkIzlROxX89u+du/i7WpZXF5F1vgv419rspds9OHejP3JrJnoUGh6w==
dependencies:
"@electron/get" "^1.0.1"
"@types/node" "^14.6.2"
extract-zip "^1.0.3"
emoji-regex@^7.0.1: emoji-regex@^7.0.1:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@ -1938,6 +2008,11 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
encodeurl@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
encoding@^0.1.11: encoding@^0.1.11:
version "0.1.13" version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
@ -2008,6 +2083,11 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1" is-date-object "^1.0.1"
is-symbol "^1.0.2" is-symbol "^1.0.2"
es6-error@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
es6-promise@^4.0.3: es6-promise@^4.0.3:
version "4.2.8" version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@ -2035,6 +2115,11 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-config-google@^0.14.0: eslint-config-google@^0.14.0:
version "0.14.0" version "0.14.0"
resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.14.0.tgz#4f5f8759ba6e11b424294a219dbfa18c508bcc1a" resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.14.0.tgz#4f5f8759ba6e11b424294a219dbfa18c508bcc1a"
@ -2200,6 +2285,16 @@ extend@^3.0.0, extend@~3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extract-zip@^1.0.3:
version "1.7.0"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927"
integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==
dependencies:
concat-stream "^1.6.2"
debug "^2.6.9"
mkdirp "^0.5.4"
yauzl "^2.10.0"
extsprintf@1.3.0: extsprintf@1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@ -2230,6 +2325,13 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=
dependencies:
pend "~1.2.0"
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.2" version "3.5.2"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
@ -2548,6 +2650,19 @@ glob@^7.1.3, glob@^7.1.4:
once "^1.3.0" once "^1.3.0"
path-is-absolute "^1.0.0" path-is-absolute "^1.0.0"
global-agent@^2.0.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc"
integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==
dependencies:
boolean "^3.0.1"
core-js "^3.6.5"
es6-error "^4.1.1"
matcher "^3.0.0"
roarr "^2.15.3"
semver "^7.3.2"
serialize-error "^7.0.1"
global-dirs@^0.1.0: global-dirs@^0.1.0:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445"
@ -2562,6 +2677,16 @@ global-dirs@^3.0.0:
dependencies: dependencies:
ini "2.0.0" ini "2.0.0"
global-tunnel-ng@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
dependencies:
encodeurl "^1.0.2"
lodash "^4.17.10"
npm-conf "^1.1.3"
tunnel "^0.0.6"
global@~4.3.0: global@~4.3.0:
version "4.3.2" version "4.3.2"
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
@ -2582,6 +2707,13 @@ globals@^12.1.0:
dependencies: dependencies:
type-fest "^0.8.1" type-fest "^0.8.1"
globalthis@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
dependencies:
define-properties "^1.1.3"
got@^6.7.1: got@^6.7.1:
version "6.7.1" version "6.7.1"
resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@ -3175,7 +3307,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
json-stringify-safe@~5.0.1: json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
@ -3546,7 +3678,7 @@ lodash.without@~4.4.0:
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
lodash@^4.17.15, lodash@^4.17.20: lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.20:
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -3621,6 +3753,13 @@ make-fetch-happen@^5.0.0:
socks-proxy-agent "^4.0.0" socks-proxy-agent "^4.0.0"
ssri "^6.0.0" ssri "^6.0.0"
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
dependencies:
escape-string-regexp "^4.0.0"
"matrix-web-i18n@github:matrix-org/matrix-web-i18n": "matrix-web-i18n@github:matrix-org/matrix-web-i18n":
version "1.1.2" version "1.1.2"
resolved "https://codeload.github.com/matrix-org/matrix-web-i18n/tar.gz/63f9119bc0bc304e83d4e8e22364caa7850e7671" resolved "https://codeload.github.com/matrix-org/matrix-web-i18n/tar.gz/63f9119bc0bc304e83d4e8e22364caa7850e7671"
@ -3765,7 +3904,7 @@ mkdirp@^0.5.0, mkdirp@~0.5.0:
dependencies: dependencies:
minimist "0.0.8" minimist "0.0.8"
mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5:
version "0.5.5" version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@ -3943,6 +4082,14 @@ npm-cache-filename@~1.0.2:
resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11"
integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=
npm-conf@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
dependencies:
config-chain "^1.1.11"
pify "^3.0.0"
npm-install-checks@^3.0.2: npm-install-checks@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9" resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.2.tgz#ab2e32ad27baa46720706908e5b14c1852de44d9"
@ -4478,6 +4625,11 @@ path-type@^2.0.0:
dependencies: dependencies:
pify "^2.0.0" pify "^2.0.0"
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
performance-now@^2.1.0: performance-now@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
@ -4570,7 +4722,7 @@ process@~0.5.1:
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
progress@^2.0.0: progress@^2.0.0, progress@^2.0.3:
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
@ -4984,6 +5136,18 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies: dependencies:
glob "^7.1.3" glob "^7.1.3"
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
dependencies:
boolean "^3.0.1"
detect-node "^2.0.4"
globalthis "^1.0.1"
json-stringify-safe "^5.0.1"
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
run-queue@^1.0.0, run-queue@^1.0.3: run-queue@^1.0.0, run-queue@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
@ -5018,6 +5182,11 @@ sax@>=0.6.0, sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver-diff@^2.0.0: semver-diff@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"
@ -5061,6 +5230,13 @@ semver@^7.3.5:
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
dependencies:
type-fest "^0.13.1"
set-blocking@^2.0.0, set-blocking@~2.0.0: set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@ -5211,7 +5387,7 @@ split-on-first@^1.0.0:
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
sprintf-js@^1.0.3: sprintf-js@^1.0.3, sprintf-js@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
@ -5397,6 +5573,13 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
dependencies:
debug "^4.1.0"
supports-color@^5.3.0: supports-color@^5.3.0:
version "5.5.0" version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@ -5581,6 +5764,11 @@ tunnel-agent@^0.6.0:
dependencies: dependencies:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
tweetnacl@^0.14.3, tweetnacl@~0.14.0: tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5" version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@ -5593,6 +5781,11 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies: dependencies:
prelude-ls "^1.2.1" prelude-ls "^1.2.1"
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
type-fest@^0.16.0: type-fest@^0.16.0:
version "0.16.0" version "0.16.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860"
@ -5620,6 +5813,11 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@^4.1.3:
version "4.3.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
uid-number@0.0.6: uid-number@0.0.6:
version "0.0.6" version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
@ -6114,6 +6312,14 @@ yargs@^8.0.2:
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^7.0.0" yargs-parser "^7.0.0"
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
zip-stream@^4.1.0: zip-stream@^4.1.0:
version "4.1.0" version "4.1.0"
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79"