From bcb4071993d8d656babf08ffad521f506aac53f7 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 1 Jun 2021 11:17:30 +0100 Subject: [PATCH 001/129] Strip hash from urls being previewed to de-duplicate --- src/client.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/client.js b/src/client.js index cb60705ef..4c71adf50 100644 --- a/src/client.js +++ b/src/client.js @@ -3368,6 +3368,10 @@ MatrixClient.prototype.getUrlPreview = function(url, ts, callback) { // Surely 60-second accuracy is enough for anyone. ts = Math.floor(ts / 60000) * 60000; + const parsed = new URL(url); + parsed.hash = ""; // strip the hash as it won't affect the preview + url = parsed.toString(); + const key = ts + "_" + url; // If there's already a request in flight (or we've handled it), return that instead. From c04d79d9a0402896bda4d375b21ca69c4291ae84 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Tue, 8 Jun 2021 21:39:37 -0400 Subject: [PATCH 002/129] initial work on symmetric algorithm for key backups --- src/crypto/SecretStorage.js | 12 +--- src/crypto/aes.js | 13 +++++ src/crypto/backup.ts | 113 ++++++++++++++++++++++++++++++++++++ src/crypto/index.js | 4 +- 4 files changed, 131 insertions(+), 11 deletions(-) diff --git a/src/crypto/SecretStorage.js b/src/crypto/SecretStorage.js index a1ed647f0..5e506007a 100644 --- a/src/crypto/SecretStorage.js +++ b/src/crypto/SecretStorage.js @@ -18,14 +18,12 @@ import { EventEmitter } from 'events'; import { logger } from '../logger'; import * as olmlib from './olmlib'; import { randomString } from '../randomstring'; -import { encryptAES, decryptAES } from './aes'; +import { encryptAES, decryptAES, calculateKeyCheck } from './aes'; import { encodeBase64 } from "./olmlib"; export const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2"; -const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - /** * Implements Secure Secret Storage and Sharing (MSC1946) * @module crypto/SecretStorage @@ -99,7 +97,7 @@ export class SecretStorage extends EventEmitter { keyInfo.passphrase = opts.passphrase; } if (opts.key) { - const { iv, mac } = await SecretStorage._calculateKeyCheck(opts.key); + const { iv, mac } = await calculateKeyCheck(opts.key); keyInfo.iv = iv; keyInfo.mac = mac; } @@ -171,7 +169,7 @@ export class SecretStorage extends EventEmitter { async checkKey(key, info) { if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { if (info.mac) { - const { mac } = await SecretStorage._calculateKeyCheck(key, info.iv); + const { mac } = await calculateKeyCheck(key, info.iv); return info.mac.replace(/=+$/g, '') === mac.replace(/=+$/g, ''); } else { // if we have no information, we have to assume the key is right @@ -182,10 +180,6 @@ export class SecretStorage extends EventEmitter { } } - static async _calculateKeyCheck(key, iv) { - return await encryptAES(ZERO_STR, key, "", iv); - } - /** * Store an encrypted secret on the server * diff --git a/src/crypto/aes.js b/src/crypto/aes.js index c121b6e2b..4e6c2668e 100644 --- a/src/crypto/aes.js +++ b/src/crypto/aes.js @@ -249,3 +249,16 @@ export function decryptAES(...args) { return subtleCrypto ? decryptBrowser(...args) : decryptNode(...args); } +// string of zeroes, for calculating the key check +const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + +/** Calculate the MAC for checking the key. + * + * @param {Uint8Array} key the key to use + * @param {string} [iv] The initialization vector as a base64-encoded string. + * If omitted, a random initialization vector will be created. + * @return {Promise} An object that contains, `mac` and `iv` properties. + */ +export function calculateKeyCheck(key, iv = undefined) { + return encryptAES(ZERO_STR, key, "", iv); +} diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 79b7e9752..49a1eb056 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -29,6 +29,8 @@ import { keyFromPassphrase } from './key_passphrase'; import { sleep } from "../utils"; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { encodeRecoveryKey } from './recoverykey'; +import { encryptAES, decryptAES, calculateKeyCheck } from './aes'; +import { getCrypto } from '../utils'; const KEY_BACKUP_KEYS_PER_REQUEST = 200; @@ -644,8 +646,119 @@ export class Curve25519 implements BackupAlgorithm { } } +// FIXME: this should go into ./aes +interface AesData { + iv: string, + ciphertext: string, + mac: string, +} + +function randomBytes(size: number): Uint8Array { + const crypto: {randomBytes: (number) => Uint8Array} | undefined = getCrypto() as any; + if (crypto) { + // nodejs version + return crypto.randomBytes(size); + } + if (typeof window !== "undefined" && window.crypto) { + // browser version + const buf = new Uint8Array(size); + window.crypto.getRandomValues(buf); + return buf; + } + throw new Error("No usable crypto implementation"); +} + +export class Aes256 implements BackupAlgorithm { + public static algorithmName = "org.matrix.mscxxxx.v1.aes-hmac-sha2"; + + constructor( + public authData: AuthData, + private key: Uint8Array, + ) {} + + public static async init( + authData: AuthData, + getKey: () => Promise, + ): Promise { + if (!authData) { + throw new Error("auth_data missing"); + } + const key = await getKey() + if (authData.mac) { + const { mac } = await calculateKeyCheck(key, authData.iv); + if (authData.mac.replace(/=+$/g, '') !== mac.replace(/=+/g, '')) { + throw new Error("Key does not match"); + } + } + return new Aes256(authData, key); + } + + public static async prepare( + key: string | Uint8Array | null, + ): Promise<[Uint8Array, AuthData]> { + let outKey: Uint8Array; + const authData: AuthData = {}; + if (!key) { + outKey = randomBytes(32); + } else if (key instanceof Uint8Array) { + outKey = new Uint8Array(key); + } else { + const derivation = await keyFromPassphrase(key); + authData.private_key_salt = derivation.salt; + authData.private_key_iterations = derivation.iterations; + outKey = derivation.key; + } + + const { iv, mac } = await calculateKeyCheck(outKey); + authData.iv = iv; + authData.mac = mac; + + return [outKey, authData]; + } + + async encryptSession(data: Record): Promise { + const plainText: Record = Object.assign({}, data); + delete plainText.session_id; + delete plainText.room_id; + delete plainText.first_known_index; + return await encryptAES(JSON.stringify(plainText), this.key, data.session_id); + } + + async decryptSessions(sessions: Record): Promise[]> { + const keys = []; + + for (const [sessionId, sessionData] of Object.entries(sessions)) { + try { + const decrypted = JSON.parse(decryptAES( + sessionData, this.key, sessionId, + )); + decrypted.session_id = sessionId; + keys.push(decrypted); + } catch (e) { + logger.log("Failed to decrypt megolm session from backup", e, sessionData); + } + } + return keys; + } + + async keyMatches(key: Uint8Array): Promise { + if (this.authData.mac) { + const { mac } = await calculateKeyCheck(key, this.authData.iv); + return this.authData.mac.replace(/=+$/g, '') === mac.replace(/=+/g, ''); + } else { + // if we have no information, we have to assume the key is right + return true; + } + } + + public free(): void { + this.key.fill(0); + } +} + export const algorithmsByName: Record = { [Curve25519.algorithmName]: Curve25519, + [Aes256.algorithmName]: Aes256, }; export const DefaultAlgorithm: BackupAlgorithmClass = Curve25519; diff --git a/src/crypto/index.js b/src/crypto/index.js index a1171b5f5..3a8c844b3 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -54,7 +54,7 @@ import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChan import { ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel"; import { IllegalMethod } from "./verification/IllegalMethod"; import { KeySignatureUploadError } from "../errors"; -import { decryptAES, encryptAES } from './aes'; +import { decryptAES, encryptAES, calculateKeyCheck } from './aes'; import { DehydrationManager } from './dehydration'; import { MatrixEvent } from "../models/event"; import { BackupManager } from "./backup"; @@ -711,7 +711,7 @@ Crypto.prototype.bootstrapSecretStorage = async function({ if (key) { const privateKey = key[1]; builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey); - const { iv, mac } = await SecretStorage._calculateKeyCheck(privateKey); + const { iv, mac } = await calculateKeyCheck(privateKey); keyInfo.iv = iv; keyInfo.mac = mac; From cf21d64aa8f6fa1dc4ad81d3c116450c5ef10a88 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 9 Jun 2021 13:02:47 -0400 Subject: [PATCH 003/129] allow backup algorithm to determine whether restored keys should be trusted --- src/client.ts | 4 +++- src/crypto/backup.ts | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index e3acfeb9a..e8794bba8 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2490,6 +2490,8 @@ export class MatrixClient extends EventEmitter { const algorithm = await BackupManager.makeAlgorithm(backupInfo, async () => { return privKey; }); + const untrusted = algorithm.untrusted; + try { // If the pubkey computed from the private data we've been given // doesn't match the one in the auth_data, the user has entered @@ -2557,7 +2559,7 @@ export class MatrixClient extends EventEmitter { await this.importRoomKeys(keys, { progressCallback, - untrusted: true, + untrusted, source: "backup", }); diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 49a1eb056..9a748af29 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -71,6 +71,7 @@ interface BackupAlgorithmClass { } interface BackupAlgorithm { + untrusted: boolean; encryptSession(data: Record): Promise; decryptSessions(ciphertexts: Record): Promise[]>; authData: AuthData; @@ -589,6 +590,8 @@ export class Curve25519 implements BackupAlgorithm { } } + public get untrusted() { return true; } + public async encryptSession(data: Record): Promise { const plainText: Record = Object.assign({}, data); delete plainText.session_id; @@ -716,6 +719,8 @@ export class Aes256 implements BackupAlgorithm { return [outKey, authData]; } + public get untrusted() { return false; } + async encryptSession(data: Record): Promise { const plainText: Record = Object.assign({}, data); delete plainText.session_id; From e5b475ad8935957ac183937129a73147a3469b42 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 10:05:29 +0100 Subject: [PATCH 004/129] Create Typescript types for JoinRule, GuestAccess, HistoryVisibility, including join_rule=restricted --- src/@types/partials.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/@types/partials.ts b/src/@types/partials.ts index 771c60b47..0a7de3a1e 100644 --- a/src/@types/partials.ts +++ b/src/@types/partials.ts @@ -37,3 +37,23 @@ export enum Preset { TrustedPrivateChat = "trusted_private_chat", PublicChat = "public_chat", } +// Knock and private are reserved keywords which are not yet implemented. +export enum JoinRule { + Public = "public", + Invite = "invite", + Private = "private", // reserved keyword, not yet implemented. + Knock = "knock", // MSC2403 - only valid inside experimental room versions at this time. + Restricted = "restricted", // MSC3083 - only valid inside experimental room versions at this time. +} + +export enum GuestAccess { + CanJoin = "can_join", + Forbidden = "forbidden", +} + +export enum HistoryVisibility { + Invited = "invited", + Joined = "joined", + Shared = "shared", + WorldReadable = "world_readable", +} From fc029a9b9e2008a63303b977f6ae478bd6861774 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 11:39:43 +0100 Subject: [PATCH 005/129] Add MSC3244 types --- src/client.ts | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/client.ts b/src/client.ts index f34044081..02dbaae43 100644 --- a/src/client.ts +++ b/src/client.ts @@ -348,6 +348,30 @@ export interface IStoredClientOpts extends IStartClientOpts { canResetEntireTimeline: ResetTimelineCallback; } +export enum RoomVersionStability { + Stable = "stable", + Unstable = "unstable", +} + +export interface IRoomVersionsCapability { + default: string; + available: Record; + "org.matrix.msc3244.room_capabilities"?: Record; // MSC3244 +} + +export interface IChangePasswordCapability { + enabled: boolean; +} + +interface ICapabilities { + [key: string]: any; + "m.change_password"?: IChangePasswordCapability; + "m.room_versions"?: IRoomVersionsCapability; +} + /** * Represents a Matrix Client. Only directly construct this if you want to use * custom modules. Normally, {@link createClient} should be used @@ -408,7 +432,7 @@ export class MatrixClient extends EventEmitter { protected serverVersionsPromise: Promise; protected cachedCapabilities: { - capabilities: Record; + capabilities: ICapabilities; expiration: number; }; protected clientWellKnown: any; @@ -1058,7 +1082,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves to the capabilities of the homeserver * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getCapabilities(fresh = false): Promise> { + public getCapabilities(fresh = false): Promise { const now = new Date().getTime(); if (this.cachedCapabilities && !fresh) { @@ -1076,7 +1100,7 @@ export class MatrixClient extends EventEmitter { return null; // otherwise consume the error }).then((r) => { if (!r) r = {}; - const capabilities = r["capabilities"] || {}; + const capabilities: ICapabilities = r["capabilities"] || {}; // If the capabilities missed the cache, cache it for a shorter amount // of time to try and refresh them later. @@ -1085,7 +1109,7 @@ export class MatrixClient extends EventEmitter { : 60000 + (Math.random() * 5000); this.cachedCapabilities = { - capabilities: capabilities, + capabilities, expiration: now + cacheMs, }; From 3d5774ac9efe7b31c6b7c7fd2b1776d5d4928a83 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 22 Jun 2021 16:07:05 +0100 Subject: [PATCH 006/129] Update early MSC3083 support --- src/@types/partials.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/@types/partials.ts b/src/@types/partials.ts index 0a7de3a1e..23d3b9b4c 100644 --- a/src/@types/partials.ts +++ b/src/@types/partials.ts @@ -46,6 +46,10 @@ export enum JoinRule { Restricted = "restricted", // MSC3083 - only valid inside experimental room versions at this time. } +export enum RestrictedAllowType { + RoomMembership = "m.room_membership", // MSC3083 - only valid inside experimental room versions at this time. +} + export enum GuestAccess { CanJoin = "can_join", Forbidden = "forbidden", From 8c9799d64cf0c09fad33d4a8509ee833545237ce Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 23 Jun 2021 18:20:00 -0400 Subject: [PATCH 007/129] add tests and some fixes --- spec/unit/crypto/backup.spec.js | 156 +++++++++++++++++++++++++++++--- src/crypto/backup.ts | 4 +- 2 files changed, 143 insertions(+), 17 deletions(-) diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index 1bb8a39f8..ea03b6e5c 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -52,7 +52,7 @@ const ENCRYPTED_EVENT = new MatrixEvent({ origin_server_ts: 1507753886000, }); -const KEY_BACKUP_DATA = { +const CURVE25519_KEY_BACKUP_DATA = { first_message_index: 0, forwarded_count: 0, is_verified: false, @@ -73,7 +73,26 @@ const KEY_BACKUP_DATA = { }, }; -const BACKUP_INFO = { +const AES256_KEY_BACKUP_DATA = { + first_message_index: 0, + forwarded_count: 0, + is_verified: false, + session_data: { + iv: 'b3Jqqvm5S9QdmXrzssspLQ', + ciphertext: 'GOOASO3E9ThogkG0zMjEduGLM3u9jHZTkS7AvNNbNj3q1znwk4OlaVKXce' + + '7ynofiiYIiS865VlOqrKEEXv96XzRyUpgn68e3WsicwYl96EtjIEh/iY003PG2Qd' + + 'EluT899Ax7PydpUHxEktbWckMppYomUR5q8x1KI1SsOQIiJaIGThmIMPANRCFiK0' + + 'WQj+q+dnhzx4lt9AFqU5bKov8qKnw2qGYP7/+6RmJ0Kpvs8tG6lrcNDEHtFc2r0r' + + 'KKubDypo0Vc8EWSwsAHdKa36ewRavpreOuE8Z9RLfY0QIR1ecXrMqW0CdGFr7H3P' + + 'vcjF8sjwvQAavzxEKT1WMGizSMLeKWo2mgZ5cKnwV5HGUAw596JQvKs9laG2U89K' + + 'YrT0sH30vi62HKzcBLcDkWkUSNYPz7UiZ1MM0L380UA+1ZOXSOmtBA9xxzzbc8Xd' + + 'fRimVgklGdxrxjzuNLYhL2BvVH4oPWonD9j0bvRwE6XkimdbGQA8HB7UmXXjE8WA' + + 'RgaDHkfzoA3g3aeQ', + mac: 'uR988UYgGL99jrvLLPX3V1ows+UYbktTmMxPAo2kxnU', + }, +}; + +const CURVE25519_BACKUP_INFO = { algorithm: "m.megolm_backup.v1.curve25519-aes-sha2", version: 1, auth_data: { @@ -81,6 +100,14 @@ const BACKUP_INFO = { }, }; +const AES256_BACKUP_INFO = { + algorithm: "org.matrix.mscxxxx.v1.aes-hmac-sha2", + version: 1, + auth_data: { + // FIXME: add iv and mac + }, +}; + const keys = {}; function getCrossSigningKey(type) { @@ -144,7 +171,7 @@ describe("MegolmBackup", function() { mockCrypto.backupKey.set_recipient_key( "hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo", ); - mockCrypto.backupInfo = BACKUP_INFO; + mockCrypto.backupInfo = CURVE25519_BACKUP_INFO; mockStorage = new MockStorageApi(); sessionStore = new WebStorageSessionStore(mockStorage); @@ -228,7 +255,7 @@ describe("MegolmBackup", function() { }); }); - it('sends backups to the server', function() { + it('sends backups to the server (Curve25519 version)', function() { const groupSession = new Olm.OutboundGroupSession(); groupSession.create(); const ibGroupSession = new Olm.InboundGroupSession(); @@ -306,6 +333,88 @@ describe("MegolmBackup", function() { }); }); + it('sends backups to the server (AES-256 version)', function() { + const groupSession = new Olm.OutboundGroupSession(); + groupSession.create(); + const ibGroupSession = new Olm.InboundGroupSession(); + ibGroupSession.create(groupSession.session_key()); + + const client = makeTestClient(sessionStore, cryptoStore); + + megolmDecryption = new MegolmDecryption({ + userId: '@user:id', + crypto: mockCrypto, + olmDevice: olmDevice, + baseApis: client, + roomId: ROOM_ID, + }); + + megolmDecryption.olmlib = mockOlmLib; + + return client.initCrypto() + .then(() => { + return client.crypto.storeSessionBackupPrivateKey(new Uint8Array(32)); + }) + .then(() => { + return cryptoStore.doTxn( + "readwrite", + [cryptoStore.STORE_SESSION], + (txn) => { + cryptoStore.addEndToEndInboundGroupSession( + "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", + groupSession.session_id(), + { + forwardingCurve25519KeyChain: undefined, + keysClaimed: { + ed25519: "SENDER_ED25519", + }, + room_id: ROOM_ID, + session: ibGroupSession.pickle(olmDevice._pickleKey), + }, + txn); + }); + }) + .then(() => { + client.enableKeyBackup({ + algorithm: "org.matrix.mscxxxx.v1.aes-hmac-sha2", + version: 1, + auth_data: { + iv: "PsCAtR7gMc4xBd9YS3A9Ow", + mac: "ZSDsTFEZK7QzlauCLMleUcX96GQZZM7UNtk4sripSqQ", + }, + }); + let numCalls = 0; + return new Promise((resolve, reject) => { + client.http.authedRequest = function( + callback, method, path, queryParams, data, opts, + ) { + ++numCalls; + expect(numCalls).toBeLessThanOrEqual(1); + if (numCalls >= 2) { + // exit out of retry loop if there's something wrong + reject(new Error("authedRequest called too many timmes")); + return Promise.resolve({}); + } + expect(method).toBe("PUT"); + expect(path).toBe("/room_keys/keys"); + expect(queryParams.version).toBe(1); + expect(data.rooms[ROOM_ID].sessions).toBeDefined(); + expect(data.rooms[ROOM_ID].sessions).toHaveProperty( + groupSession.session_id(), + ); + resolve(); + return Promise.resolve({}); + }; + client.crypto._backupManager.backupGroupSession( + "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", + groupSession.session_id(), + ); + }).then(() => { + expect(numCalls).toBe(1); + }); + }); + }); + it('signs backups with the cross-signing master key', async function() { const groupSession = new Olm.OutboundGroupSession(); groupSession.create(); @@ -512,30 +621,47 @@ describe("MegolmBackup", function() { client.stopClient(); }); - it('can restore from backup', function() { + it('can restore from backup (Curve25519 version)', function() { client.http.authedRequest = function() { - return Promise.resolve(KEY_BACKUP_DATA); + return Promise.resolve(CURVE25519_KEY_BACKUP_DATA); }; return client.restoreKeyBackupWithRecoveryKey( "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", ROOM_ID, SESSION_ID, - BACKUP_INFO, + CURVE25519_BACKUP_INFO, ).then(() => { return megolmDecryption.decryptEvent(ENCRYPTED_EVENT); }).then((res) => { expect(res.clearEvent.content).toEqual('testytest'); - expect(res.untrusted).toBeTruthy(); // keys from backup are untrusted + expect(res.untrusted).toBeTruthy(); // keys from Curve25519 backup are untrusted }); }); - it('can restore backup by room', function() { + it('can restore from backup (AES-256 version)', function() { + client.http.authedRequest = function() { + return Promise.resolve(AES256_KEY_BACKUP_DATA); + }; + return client.restoreKeyBackupWithRecoveryKey( + "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", + ROOM_ID, + SESSION_ID, + AES256_BACKUP_INFO, + ).then(() => { + return megolmDecryption.decryptEvent(ENCRYPTED_EVENT); + }).then((res) => { + expect(res.clearEvent.content).toEqual('testytest'); + expect(res.untrusted).toBeFalsy(); // keys from AES backup are trusted + }); + }); + + it('can restore backup by room (Curve25519 version)', function() { client.http.authedRequest = function() { return Promise.resolve({ rooms: { [ROOM_ID]: { sessions: { - [SESSION_ID]: KEY_BACKUP_DATA, + [SESSION_ID]: CURVE25519_KEY_BACKUP_DATA, }, }, }, @@ -543,7 +669,7 @@ describe("MegolmBackup", function() { }; return client.restoreKeyBackupWithRecoveryKey( "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", - null, null, BACKUP_INFO, + null, null, CURVE25519_BACKUP_INFO, ).then(() => { return megolmDecryption.decryptEvent(ENCRYPTED_EVENT); }).then((res) => { @@ -562,14 +688,14 @@ describe("MegolmBackup", function() { const cachedNull = await client.crypto.getSessionBackupPrivateKey(); expect(cachedNull).toBeNull(); client.http.authedRequest = function() { - return Promise.resolve(KEY_BACKUP_DATA); + return Promise.resolve(CURVE25519_KEY_BACKUP_DATA); }; await new Promise((resolve) => { client.restoreKeyBackupWithRecoveryKey( "EsTc LW2K PGiF wKEA 3As5 g5c4 BXwk qeeJ ZJV8 Q9fu gUMN UE4d", ROOM_ID, SESSION_ID, - BACKUP_INFO, + CURVE25519_BACKUP_INFO, { cacheCompleteCallback: resolve }, ); }); @@ -578,11 +704,11 @@ describe("MegolmBackup", function() { }); it("fails if an known algorithm is used", async function() { - const BAD_BACKUP_INFO = Object.assign({}, BACKUP_INFO, { + const BAD_BACKUP_INFO = Object.assign({}, CURVE25519_BACKUP_INFO, { algorithm: "this.algorithm.does.not.exist", }); client.http.authedRequest = function() { - return Promise.resolve(KEY_BACKUP_DATA); + return Promise.resolve(CURVE25519_KEY_BACKUP_DATA); }; await expect(client.restoreKeyBackupWithRecoveryKey( diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 9a748af29..ef8f41d9d 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -734,8 +734,8 @@ export class Aes256 implements BackupAlgorithm { for (const [sessionId, sessionData] of Object.entries(sessions)) { try { - const decrypted = JSON.parse(decryptAES( - sessionData, this.key, sessionId, + const decrypted = JSON.parse(await decryptAES( + sessionData.session_data, this.key, sessionId, )); decrypted.session_id = sessionId; keys.push(decrypted); From 558da5528b675edc75c56f8beba92ee46a4a4922 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 30 Jun 2021 21:53:11 -0400 Subject: [PATCH 008/129] fix validity checks for backup info --- src/client.ts | 33 +++++++++++++++------------------ src/crypto/backup.ts | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/client.ts b/src/client.ts index e8794bba8..f5a055e15 100644 --- a/src/client.ts +++ b/src/client.ts @@ -33,7 +33,6 @@ import { EventTimeline } from "./models/event-timeline"; import { PushAction, PushProcessor } from "./pushprocessor"; import { AutoDiscovery } from "./autodiscovery"; import { MatrixError } from "./http-api"; -import * as olmlib from "./crypto/olmlib"; import { decodeBase64, encodeBase64 } from "./crypto/olmlib"; import { ReEmitter } from './ReEmitter'; import { RoomList } from './crypto/RoomList'; @@ -2054,28 +2053,26 @@ export class MatrixClient extends EventEmitter { * Get information about the current key backup. * @returns {Promise} Information object from API or null */ - public getKeyBackupVersion(): Promise { - return this.http.authedRequest( - undefined, "GET", "/room_keys/version", undefined, undefined, - { prefix: PREFIX_UNSTABLE }, - ).then((res) => { - if (res.algorithm !== olmlib.MEGOLM_BACKUP_ALGORITHM) { - const err = "Unknown backup algorithm: " + res.algorithm; - return Promise.reject(err); - } else if (!(typeof res.auth_data === "object") - || !res.auth_data.public_key) { - const err = "Invalid backup data returned"; - return Promise.reject(err); - } else { - return res; - } - }).catch((e) => { + public async getKeyBackupVersion(): Promise { + let res; + try { + res = await this.http.authedRequest( + undefined, "GET", "/room_keys/version", undefined, undefined, + { prefix: PREFIX_UNSTABLE }, + ); + } catch (e) { if (e.errcode === 'M_NOT_FOUND') { return null; } else { throw e; } - }); + } + try { + BackupManager.checkBackupVersion(res); + } catch (e) { + throw e; + } + return res; } /** diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index ef8f41d9d..5f2b96da2 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -68,6 +68,8 @@ interface BackupAlgorithmClass { prepare( key: string | Uint8Array | null, ): Promise<[Uint8Array, AuthData]>; + + checkBackupVersion(info: BackupInfo): void; } interface BackupAlgorithm { @@ -96,6 +98,24 @@ export class BackupManager { return this.backupInfo && this.backupInfo.version; } + /** + * Performs a quick check to ensure that the backup info looks sane. + * + * Throws an error if a problem is detected. + * + * @param {BackupInfo} info the key backup info + */ + public static checkBackupVersion(info: BackupInfo): void { + const Algorithm = algorithmsByName[info.algorithm]; + if (!Algorithm) { + throw new Error("Unknown backup algorithm: " + info.algorithm); + } + if (!(typeof info.auth_data === "object")) { + throw new Error("Invalid backup data returned"); + } + return Algorithm.checkBackupVersion(info); + } + public static async makeAlgorithm(info: BackupInfo, getKey: GetKey): Promise { const Algorithm = algorithmsByName[info.algorithm]; if (!Algorithm) { @@ -264,7 +284,6 @@ export class BackupManager { !backupInfo || !backupInfo.algorithm || !backupInfo.auth_data || - !backupInfo.auth_data.public_key || !backupInfo.auth_data.signatures ) { logger.info("Key backup is absent or missing required data"); @@ -590,6 +609,12 @@ export class Curve25519 implements BackupAlgorithm { } } + public static checkBackupVersion(info: BackupInfo): void { + if (!info.auth_data.public_key) { + throw new Error("Invalid backup data returned"); + } + } + public get untrusted() { return true; } public async encryptSession(data: Record): Promise { @@ -719,6 +744,12 @@ export class Aes256 implements BackupAlgorithm { return [outKey, authData]; } + public static checkBackupVersion(info: BackupInfo): void { + if (!info.auth_data.iv || !info.auth_data.mac) { + throw new Error("Invalid backup data returned"); + } + } + public get untrusted() { return false; } async encryptSession(data: Record): Promise { From f506882bf826f00562d090464507077e22bb3a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 2 Jul 2021 09:47:47 +0200 Subject: [PATCH 009/129] Call setEventMetadata() for filtered timelineSets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/models/event-timeline.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/models/event-timeline.js b/src/models/event-timeline.js index 288659611..6debc0db9 100644 --- a/src/models/event-timeline.js +++ b/src/models/event-timeline.js @@ -299,15 +299,16 @@ EventTimeline.prototype.setNeighbouringTimeline = function(neighbour, direction) */ EventTimeline.prototype.addEvent = function(event, atStart) { const stateContext = atStart ? this._startState : this._endState; - - // only call setEventMetadata on the unfiltered timelineSets const timelineSet = this.getTimelineSet(); - if (timelineSet.room && - timelineSet.room.getUnfilteredTimelineSet() === timelineSet) { + + if (timelineSet.room) { EventTimeline.setEventMetadata(event, stateContext, atStart); - // modify state - if (event.isState()) { + // modify state but only on unfiltered timelineSets + if ( + event.isState() && + timelineSet.room.getUnfilteredTimelineSet() === timelineSet + ) { stateContext.setStateEvents([event]); // it is possible that the act of setting the state event means we // can set more metadata (specifically sender/target props), so try @@ -347,15 +348,16 @@ EventTimeline.prototype.addEvent = function(event, atStart) { * @param {bool} toStartOfTimeline if true the event's forwardLooking flag is set false */ EventTimeline.setEventMetadata = function(event, stateContext, toStartOfTimeline) { - // set sender and target properties - event.sender = stateContext.getSentinelMember( - event.getSender(), - ); - if (event.getType() === "m.room.member") { - event.target = stateContext.getSentinelMember( - event.getStateKey(), - ); + // We always check if the event doesn't already have the property. We do + // this to avoid overriding non-sentinel members by sentinel ones when + // adding the event to a filtered timeline + if (!event.sender) { + event.sender = stateContext.getSentinelMember(event.getSender()); } + if (!event.target && event.getType() === "m.room.member") { + event.target = stateContext.getSentinelMember(event.getStateKey()); + } + if (event.isState()) { // room state has no concept of 'old' or 'current', but we want the // room state to regress back to previous values if toStartOfTimeline From d9d19fdc63fe8da711ee7cfdba8f2ce575ba3adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 2 Jul 2021 09:51:26 +0200 Subject: [PATCH 010/129] delint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/models/event-timeline.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/event-timeline.js b/src/models/event-timeline.js index 6debc0db9..c166fc6f4 100644 --- a/src/models/event-timeline.js +++ b/src/models/event-timeline.js @@ -306,7 +306,7 @@ EventTimeline.prototype.addEvent = function(event, atStart) { // modify state but only on unfiltered timelineSets if ( - event.isState() && + event.isState() && timelineSet.room.getUnfilteredTimelineSet() === timelineSet ) { stateContext.setStateEvents([event]); From aad33bd1b73e68685b84526873128f1f5f3be84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Fri, 2 Jul 2021 11:04:54 +0200 Subject: [PATCH 011/129] Formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/models/event-timeline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/event-timeline.ts b/src/models/event-timeline.ts index 12abd55e4..b5bb83db7 100644 --- a/src/models/event-timeline.ts +++ b/src/models/event-timeline.ts @@ -354,7 +354,7 @@ export class EventTimeline { // modify state but only on unfiltered timelineSets if ( event.isState() && - timelineSet.room.getUnfilteredTimelineSet() === timelineSet + timelineSet.room.getUnfilteredTimelineSet() === timelineSet ) { stateContext.setStateEvents([event]); // it is possible that the act of setting the state event means we From bbe1ba7328ccec237702a566bb37577c0e05e08d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 2 Jul 2021 14:38:17 +0100 Subject: [PATCH 012/129] Improve typing --- src/@types/requests.ts | 3 ++- src/client.ts | 14 +++++++++----- src/models/MSC3089Branch.ts | 4 ++-- src/models/MSC3089TreeSpace.ts | 6 +++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/@types/requests.ts b/src/@types/requests.ts index eaf682831..d979121ce 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -15,6 +15,7 @@ limitations under the License. */ import { Callback } from "../client"; +import { IContent } from "../models/event"; import { Preset, Visibility } from "./partials"; // allow camelcase as these are things go onto the wire @@ -82,7 +83,7 @@ export interface IInvite3PID { export interface ICreateRoomStateEvent { type: string; state_key?: string; // defaults to an empty string - content: object; + content: IContent; } export interface ICreateRoomOpts { diff --git a/src/client.ts b/src/client.ts index a57760e78..89a3c7b16 100644 --- a/src/client.ts +++ b/src/client.ts @@ -403,6 +403,10 @@ export interface ISignedKey { algorithms: string[]; device_id: string; } + +export interface IEventIdResponse { + event_id: string; +} /* eslint-enable camelcase */ export type KeySignatures = Record>; @@ -2990,7 +2994,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomName(roomId: string, name: string, callback?: Callback): Promise { + public setRoomName(roomId: string, name: string, callback?: Callback): Promise { return this.sendStateEvent(roomId, "m.room.name", { name: name }, undefined, callback); } @@ -3001,7 +3005,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomTopic(roomId: string, topic: string, callback?: Callback): Promise { + public setRoomTopic(roomId: string, topic: string, callback?: Callback): Promise { return this.sendStateEvent(roomId, "m.room.topic", { topic: topic }, undefined, callback); } @@ -4185,7 +4189,7 @@ export class MatrixClient extends EventEmitter { */ public _unstable_setStatusMessage(newMessage: string): Promise { // eslint-disable-line camelcase const type = "im.vector.user_status"; - return Promise.all(this.getRooms().map((room) => { + return Promise.all(this.getRooms().map((room): Promise => { const isJoined = room.getMyMembership() === "join"; const looksLikeDm = room.getInvitedAndJoinedMemberCount() === 2; if (!isJoined || !looksLikeDm) { @@ -4673,7 +4677,7 @@ export class MatrixClient extends EventEmitter { guest_access: opts.allowJoin ? "can_join" : "forbidden", }, ""); - let readPromise = Promise.resolve(); + let readPromise = Promise.resolve(undefined); if (opts.allowRead) { readPromise = this.sendStateEvent(roomId, "m.room.history_visibility", { history_visibility: "world_readable", @@ -6341,7 +6345,7 @@ export class MatrixClient extends EventEmitter { content: any, stateKey = "", callback?: Callback, - ): Promise { // TODO: Types + ): Promise { const pathParams = { $roomId: roomId, $eventType: eventType, diff --git a/src/models/MSC3089Branch.ts b/src/models/MSC3089Branch.ts index 87acee0f8..7bb8c356e 100644 --- a/src/models/MSC3089Branch.ts +++ b/src/models/MSC3089Branch.ts @@ -70,8 +70,8 @@ export class MSC3089Branch { * @param {string} name The new name for this file. * @returns {Promise} Resolves when complete. */ - public setName(name: string): Promise { - return this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { + public async setName(name: string): Promise { + await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { ...this.indexEvent.getContent(), name: name, }, this.id); diff --git a/src/models/MSC3089TreeSpace.ts b/src/models/MSC3089TreeSpace.ts index 77966d9fb..20585eab0 100644 --- a/src/models/MSC3089TreeSpace.ts +++ b/src/models/MSC3089TreeSpace.ts @@ -111,8 +111,8 @@ export class MSC3089TreeSpace { * @param {string} name The new name for the space. * @returns {Promise} Resolves when complete. */ - public setName(name: string): Promise { - return this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, ""); + public async setName(name: string): Promise { + await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, ""); } /** @@ -190,7 +190,7 @@ export class MSC3089TreeSpace { } pls['users'] = users; - return this.client.sendStateEvent(this.roomId, EventType.RoomPowerLevels, pls, ""); + await this.client.sendStateEvent(this.roomId, EventType.RoomPowerLevels, pls, ""); } /** From 9e66026bdc616657f22e994453beabad5be2e1b5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 6 Jul 2021 10:08:40 +0100 Subject: [PATCH 013/129] Export MSC3244 type --- src/client.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/client.ts b/src/client.ts index 7de54f8eb..5b3ce63e4 100644 --- a/src/client.ts +++ b/src/client.ts @@ -366,13 +366,15 @@ export enum RoomVersionStability { Unstable = "unstable", } +export interface IRoomCapability { // MSC3244 + preferred: string | null; + support: string[]; +} + export interface IRoomVersionsCapability { default: string; available: Record; - "org.matrix.msc3244.room_capabilities"?: Record; // MSC3244 + "org.matrix.msc3244.room_capabilities"?: Record; // MSC3244 } export interface IChangePasswordCapability { From 8c0f5b4e31dfe515f29c7e4e9d832f63baf57ffc Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 16:48:57 +0200 Subject: [PATCH 014/129] Update event.ts: Add io.element.functional_members --- src/@types/event.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/@types/event.ts b/src/@types/event.ts index f7b22992e..4b1dd18ac 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -33,6 +33,7 @@ export enum EventType { RoomGuestAccess = "m.room.guest_access", RoomServerAcl = "m.room.server_acl", RoomTombstone = "m.room.tombstone", + RoomFunctionalMembers = "io.element.functional_members", /** * @deprecated Should not be used. */ From d60affc1b88e5372b4676f9aba8da73144a0873d Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 18:35:34 +0200 Subject: [PATCH 015/129] room.calculateRoomName: Exclude service members --- src/models/room.ts | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/models/room.ts b/src/models/room.ts index 9970ae595..d53613759 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2039,20 +2039,41 @@ export class Room extends EventEmitter { // -1 because these numbers include the syncing user const inviteJoinCount = joinedMemberCount + invitedMemberCount - 1; + // get service members (e.g. helper bots) for exclusion + let excludedUserIds: string[] = []; + const mFunctionalMembers = this.currentState.getStateEvents(EventType.RoomFunctionalMembers, ""); + if (mFunctionalMembers && mFunctionalMembers.getContent() && Array.isArray(mFunctionalMembers.getContent().service_members)) { + excludedUserIds = mRoomName.getContent().service_members; + } + // get members that are NOT ourselves and are actually in the room. let otherNames = null; if (this.summaryHeroes) { // if we have a summary, the member state events // should be in the room state - otherNames = this.summaryHeroes.map((userId) => { + otherNames = []; + this.summaryHeroes.forEach((userId) => { + // filter service members + if (excludedUserIds.includes(userId)) { + inviteJoinCount--; + return; + } const member = this.getMember(userId); - return member ? member.name : userId; + otherNames.push(member ? member.name : userId); }); } else { let otherMembers = this.currentState.getMembers().filter((m) => { return m.userId !== userId && (m.membership === "invite" || m.membership === "join"); }); + otherMembers = otherMembers.filter((userId) => { + // filter service members + if (excludedUserIds.includes(userId)) { + inviteJoinCount--; + return false; + } + return true; + }); // make sure members have stable order otherMembers.sort((a, b) => a.userId.localeCompare(b.userId)); // only 5 first members, immitate summaryHeroes @@ -2065,7 +2086,7 @@ export class Room extends EventEmitter { } const myMembership = this.getMyMembership(); - // if I have created a room and invited people throuh + // if I have created a room and invited people through // 3rd party invites if (myMembership == 'join') { const thirdPartyInvites = From a248bbc46b941c92d871954de0eda6b1bdd4d1d0 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 18:58:07 +0200 Subject: [PATCH 016/129] Update src/models/room.ts Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index d53613759..6e4e8daaa 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2042,7 +2042,7 @@ export class Room extends EventEmitter { // get service members (e.g. helper bots) for exclusion let excludedUserIds: string[] = []; const mFunctionalMembers = this.currentState.getStateEvents(EventType.RoomFunctionalMembers, ""); - if (mFunctionalMembers && mFunctionalMembers.getContent() && Array.isArray(mFunctionalMembers.getContent().service_members)) { + if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { excludedUserIds = mRoomName.getContent().service_members; } From 4700dc0375c13bba4559041a12213bc690c10a32 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 18:59:02 +0200 Subject: [PATCH 017/129] Remove trailing spaces --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index 6e4e8daaa..189056386 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2045,7 +2045,7 @@ export class Room extends EventEmitter { if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { excludedUserIds = mRoomName.getContent().service_members; } - + // get members that are NOT ourselves and are actually in the room. let otherNames = null; if (this.summaryHeroes) { From d219c2f4627f15fb4c623c00a5db2692690f58df Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 19:07:20 +0200 Subject: [PATCH 018/129] Fix mistakes --- src/models/room.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/room.ts b/src/models/room.ts index 189056386..630ab47f0 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2037,13 +2037,13 @@ export class Room extends EventEmitter { const joinedMemberCount = this.currentState.getJoinedMemberCount(); const invitedMemberCount = this.currentState.getInvitedMemberCount(); // -1 because these numbers include the syncing user - const inviteJoinCount = joinedMemberCount + invitedMemberCount - 1; + let inviteJoinCount = joinedMemberCount + invitedMemberCount - 1; // get service members (e.g. helper bots) for exclusion let excludedUserIds: string[] = []; const mFunctionalMembers = this.currentState.getStateEvents(EventType.RoomFunctionalMembers, ""); if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { - excludedUserIds = mRoomName.getContent().service_members; + excludedUserIds = mFunctionalMembers.getContent().service_members; } // get members that are NOT ourselves and are actually in the room. @@ -2066,7 +2066,7 @@ export class Room extends EventEmitter { return m.userId !== userId && (m.membership === "invite" || m.membership === "join"); }); - otherMembers = otherMembers.filter((userId) => { + otherMembers = otherMembers.filter(({userId}) => { // filter service members if (excludedUserIds.includes(userId)) { inviteJoinCount--; From 0074b71cbf460b265fb2f0c3add058228861ba12 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 19:10:25 +0200 Subject: [PATCH 019/129] Fix object-curly-spacing linting errors --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index 630ab47f0..8c62ed77d 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2066,7 +2066,7 @@ export class Room extends EventEmitter { return m.userId !== userId && (m.membership === "invite" || m.membership === "join"); }); - otherMembers = otherMembers.filter(({userId}) => { + otherMembers = otherMembers.filter(({ userId }) => { // filter service members if (excludedUserIds.includes(userId)) { inviteJoinCount--; From c4263692f0095b86f6015fe0880e634d8f001081 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 19:34:44 +0200 Subject: [PATCH 020/129] Update event.ts --- src/@types/event.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/@types/event.ts b/src/@types/event.ts index 4b1dd18ac..730cbc5fe 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -33,7 +33,6 @@ export enum EventType { RoomGuestAccess = "m.room.guest_access", RoomServerAcl = "m.room.server_acl", RoomTombstone = "m.room.tombstone", - RoomFunctionalMembers = "io.element.functional_members", /** * @deprecated Should not be used. */ @@ -145,6 +144,13 @@ export const UNSTABLE_MSC3089_LEAF = new UnstableValue("m.leaf", "org.matrix.msc */ export const UNSTABLE_MSC3089_BRANCH = new UnstableValue("m.branch", "org.matrix.msc3089.branch"); +/** + * Functional members type for declaring a purpose of room members (e.g. helpful bots). + * Note that this reference is UNSTABLE and subject to breaking changes, including its + * eventual removal. + */ +export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = "io.element.functional_members"); + export interface IEncryptedFile { url: string; mimetype?: string; From 96420a75abd7a1f7be9c03551a2c8661ae4c2d85 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 6 Jul 2021 19:35:56 +0200 Subject: [PATCH 021/129] room.ts: Use UNSTABLE_ELEMENT_FUNCTIONAL_USERS --- src/models/room.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/room.ts b/src/models/room.ts index 8c62ed77d..744169b01 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -30,7 +30,7 @@ import { RoomMember } from "./room-member"; import { IRoomSummary, RoomSummary } from "./room-summary"; import { logger } from '../logger'; import { ReEmitter } from '../ReEmitter'; -import { EventType, RoomCreateTypeField, RoomType } from "../@types/event"; +import { EventType, RoomCreateTypeField, RoomType, UNSTABLE_ELEMENT_FUNCTIONAL_USERS } from "../@types/event"; import { IRoomVersionsCapability, MatrixClient, RoomVersionStability } from "../client"; import { ResizeMethod } from "../@types/partials"; import { Filter } from "../filter"; @@ -2041,7 +2041,7 @@ export class Room extends EventEmitter { // get service members (e.g. helper bots) for exclusion let excludedUserIds: string[] = []; - const mFunctionalMembers = this.currentState.getStateEvents(EventType.RoomFunctionalMembers, ""); + const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS, ""); if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { excludedUserIds = mFunctionalMembers.getContent().service_members; } From ab679c2216a9da00c5813c1ba17009532fb0b0c5 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Wed, 7 Jul 2021 00:39:26 +0200 Subject: [PATCH 022/129] Update src/@types/event.ts --- src/@types/event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/@types/event.ts b/src/@types/event.ts index 730cbc5fe..0c8d81da8 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -149,7 +149,7 @@ export const UNSTABLE_MSC3089_BRANCH = new UnstableValue("m.branch", "org.matrix * Note that this reference is UNSTABLE and subject to breaking changes, including its * eventual removal. */ -export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = "io.element.functional_members"); +export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue("io.element.functional_members"); export interface IEncryptedFile { url: string; From f0ae9b01000b870fcce269ca645cfcbe4d24f1dd Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 7 Jul 2021 16:11:14 +0200 Subject: [PATCH 023/129] Do not generate a lockfile when running in CI --- release.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release.sh b/release.sh index 7ee2777da..e2ef78263 100755 --- a/release.sh +++ b/release.sh @@ -100,7 +100,7 @@ fi # global cache here to ensure we get the right thing. yarn cache clean # Ensure all dependencies are updated -yarn install --ignore-scripts +yarn install --ignore-scripts --pure-lockfile if [ -z "$skip_changelog" ]; then # update_changelog doesn't have a --version flag @@ -225,7 +225,7 @@ if [ $dodist -eq 0 ]; then pushd "$builddir" git clone "$projdir" . git checkout "$rel_branch" - yarn install + yarn install --pure-lockfile # We haven't tagged yet, so tell the dist script what version # it's building DIST_VERSION="$tag" yarn dist From 79f74fdff4d1f1461d5420af4d813a01972b67c9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 7 Jul 2021 17:54:46 +0100 Subject: [PATCH 024/129] Improve return type for getUrlPreview --- src/client.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index a94ff04b3..da2d24547 100644 --- a/src/client.ts +++ b/src/client.ts @@ -414,6 +414,19 @@ interface IUploadKeySignaturesResponse { }>>; } +export interface IPreviewUrlResponse { + [key: string]: string | number; + "og:title": string; + "og:type": string; + "og:url": string; + "og:image"?: string; + "og:image:type"?: string; + "og:image:height"?: number; + "og:image:width"?: number; + "og:description"?: string; + "matrix:image:size"?: number; +} + /** * Represents a Matrix Client. Only directly construct this if you want to use * custom modules. Normally, {@link createClient} should be used @@ -3695,7 +3708,7 @@ export class MatrixClient extends EventEmitter { * @return {module:http-api.MatrixError} Rejects: with an error response. * May return synthesized attributes if the URL lacked OG meta. */ - public getUrlPreview(url: string, ts: number, callback?: Callback): Promise { + public getUrlPreview(url: string, ts: number, callback?: Callback): Promise { // bucket the timestamp to the nearest minute to prevent excessive spam to the server // Surely 60-second accuracy is enough for anyone. ts = Math.floor(ts / 60000) * 60000; From c34d4e777f8d0e568c15292d0dd24b24979bc664 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 19:37:22 +0100 Subject: [PATCH 025/129] Convert SecretStorage to TypeScript --- src/client.ts | 12 +- src/crypto/EncryptionSetup.ts | 4 +- .../{SecretStorage.js => SecretStorage.ts} | 294 ++++++++++-------- src/crypto/api.ts | 14 +- src/crypto/dehydration.ts | 2 +- src/crypto/index.ts | 32 +- src/matrix.ts | 12 +- 7 files changed, 206 insertions(+), 164 deletions(-) rename src/crypto/{SecretStorage.js => SecretStorage.ts} (63%) diff --git a/src/client.ts b/src/client.ts index 637cf9cba..9106e5277 100644 --- a/src/client.ts +++ b/src/client.ts @@ -64,7 +64,8 @@ import { import { IIdentityServerProvider } from "./@types/IIdentityServerProvider"; import type Request from "request"; import { MatrixScheduler } from "./scheduler"; -import { ICryptoCallbacks, ISecretStorageKeyInfo, NotificationCountType } from "./matrix"; +import { ICryptoCallbacks, NotificationCountType } from "./matrix"; +import { ISecretStorageKeyInfo } from "./crypto/SecretStorage"; import { MemoryCryptoStore } from "./crypto/store/memory-crypto-store"; import { LocalStorageCryptoStore } from "./crypto/store/localStorage-crypto-store"; import { IndexedDBCryptoStore } from "./crypto/store/indexeddb-crypto-store"; @@ -83,7 +84,6 @@ import { IEncryptedEventInfo, IImportRoomKeysOpts, IRecoveryKey, - ISecretStorageKey, } from "./crypto/api"; import { CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from "./crypto/CrossSigning"; import { Room } from "./models/room"; @@ -1841,7 +1841,9 @@ export class MatrixClient extends EventEmitter { * keyId: {string} the ID of the key * keyInfo: {object} details about the key (iv, mac, passphrase) */ - public addSecretStorageKey(algorithm: string, opts: IAddSecretStorageKeyOpts, keyName?: string): ISecretStorageKey { + public addSecretStorageKey( + algorithm: string, opts: IAddSecretStorageKeyOpts, keyName?: string, + ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -1857,7 +1859,7 @@ export class MatrixClient extends EventEmitter { * for. Defaults to the default key ID if not provided. * @return {boolean} Whether we have the key. */ - public hasSecretStorageKey(keyId?: string): boolean { + public hasSecretStorageKey(keyId?: string): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -1910,7 +1912,7 @@ export class MatrixClient extends EventEmitter { * with, or null if it is not present or not encrypted with a trusted * key */ - public isSecretStored(name: string, checkKey: boolean): Record { + public isSecretStored(name: string, checkKey: boolean): Promise> { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 140c4cadb..ccf8aeb47 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -9,10 +9,10 @@ import { CrossSigningKeys, ICrossSigningKey, ICryptoCallbacks, - ISecretStorageKeyInfo, ISignedKey, KeySignatures, } from "../matrix"; +import { ISecretStorageKeyInfo } from "./SecretStorage"; import { IKeyBackupInfo } from "./keybackup"; interface ICrossSigningKeys { @@ -337,7 +337,7 @@ class SSSSCryptoCallbacks { constructor(private readonly delegateCryptoCallbacks: ICryptoCallbacks) {} public async getSecretStorageKey( - { keys }: { keys: Record }, + { keys }: { keys: Record }, name: string, ): Promise<[string, Uint8Array]> { for (const keyId of Object.keys(keys)) { diff --git a/src/crypto/SecretStorage.js b/src/crypto/SecretStorage.ts similarity index 63% rename from src/crypto/SecretStorage.js rename to src/crypto/SecretStorage.ts index f57c61cb1..3b2fca435 100644 --- a/src/crypto/SecretStorage.js +++ b/src/crypto/SecretStorage.ts @@ -1,5 +1,5 @@ /* -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. +Copyright 2019 - 2021 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. @@ -14,61 +14,107 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { EventEmitter } from 'events'; import { logger } from '../logger'; import * as olmlib from './olmlib'; import { randomString } from '../randomstring'; -import { encryptAES, decryptAES } from './aes'; +import { encryptAES, decryptAES, IEncryptedPayload } from './aes'; import { encodeBase64 } from "./olmlib"; +import { ICryptoCallbacks, MatrixClient, MatrixEvent } from '../matrix'; +import { IAddSecretStorageKeyOpts, IPassphraseInfo } from './api'; +import { EventEmitter } from 'stream'; -export const SECRET_STORAGE_ALGORITHM_V1_AES - = "m.secret_storage.v1.aes-hmac-sha2"; +export const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2"; const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +export interface ISecretStorageKeyInfo { + name: string; + algorithm: string; + // technically the below are specific to AES keys. If we ever introduce another type, + // we can split into separate interfaces. + iv: string; + mac: string; + passphrase: IPassphraseInfo; +} + +export type SecretStorageKeyTuple = [keyId: string, keyInfo: ISecretStorageKeyInfo]; + +export interface ISecretRequest { + requestId: string; + promise: Promise; + cancel: (reason: string) => void; +} + +export interface IAccountDataClient extends EventEmitter { + getAccountDataFromServer: (string) => Promise; + getAccountData: (string) => object; + setAccountData: (string, object) => Promise; +} + +interface ISecretRequestInternal { + name: string; + devices: Array; + resolve: (string) => void; + reject: (Error) => void; +} + +interface IDecryptors { + encrypt: (string) => Promise; + decrypt: (IEncryptedPayload) => Promise; +} + /** * Implements Secure Secret Storage and Sharing (MSC1946) * @module crypto/SecretStorage */ -export class SecretStorage extends EventEmitter { - constructor(baseApis, cryptoCallbacks) { - super(); - this._baseApis = baseApis; - this._cryptoCallbacks = cryptoCallbacks; - this._requests = {}; - this._incomingRequests = {}; +export class SecretStorage { + private accountDataAdapter: IAccountDataClient; + private baseApis: MatrixClient; + private cryptoCallbacks: ICryptoCallbacks; + private requests = new Map(); + + // In it's pure javascript days, this was relying on some proper Javascript-style + // type-abuse where sometimes we'd pass in a fake client object with just the account + // data methods implemented, which is all this class needs unless you use the secret + // sharing code, so it was fine. As a low-touch TypeScript migration, this now has + // an extra, optional param for a real matrix client, so you can not pass it as long + // as you don't request any secrets. + // A better solution would probably be to split this class up into secret storage and + // secret sharing which are really two separate things, even though they share an MSC. + constructor(accountDataClient: IAccountDataClient, cryptoCallbacks: ICryptoCallbacks, matrixClient?: MatrixClient) { + this.accountDataAdapter = accountDataClient; + this.baseApis = matrixClient; + this.cryptoCallbacks = cryptoCallbacks; } - async getDefaultKeyId() { - const defaultKey = await this._baseApis.getAccountDataFromServer( + public async getDefaultKeyId(): Promise { + const defaultKey = await this.accountDataAdapter.getAccountDataFromServer( 'm.secret_storage.default_key', ); if (!defaultKey) return null; return defaultKey.key; } - setDefaultKeyId(keyId) { - return new Promise(async (resolve, reject) => { + public setDefaultKeyId(keyId: string) { + return new Promise((resolve, reject) => { const listener = (ev) => { if ( ev.getType() === 'm.secret_storage.default_key' && ev.getContent().key === keyId ) { - this._baseApis.removeListener('accountData', listener); + this.accountDataAdapter.removeListener('accountData', listener); resolve(); } }; - this._baseApis.on('accountData', listener); + this.accountDataAdapter.on('accountData', listener); - try { - await this._baseApis.setAccountData( - 'm.secret_storage.default_key', - { key: keyId }, - ); - } catch (e) { - this._baseApis.removeListener('accountData', listener); + this.accountDataAdapter.setAccountData( + 'm.secret_storage.default_key', + { key: keyId }, + ).catch(e => { + this.accountDataAdapter.removeListener('accountData', listener); reject(e); - } + }); }); } @@ -85,10 +131,12 @@ export class SecretStorage extends EventEmitter { * keyId: {string} the ID of the key * keyInfo: {object} details about the key (iv, mac, passphrase) */ - async addKey(algorithm, opts, keyId) { - const keyInfo = { algorithm }; + public async addKey( + algorithm: string, opts: IAddSecretStorageKeyOpts, keyId?: string, + ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { + const keyInfo = { algorithm } as ISecretStorageKeyInfo; - if (!opts) opts = {}; + if (!opts) opts = {} as IAddSecretStorageKeyOpts; if (opts.name) { keyInfo.name = opts.name; @@ -104,20 +152,20 @@ export class SecretStorage extends EventEmitter { keyInfo.mac = mac; } } else { - throw new Error(`Unknown key algorithm ${opts.algorithm}`); + throw new Error(`Unknown key algorithm ${algorithm}`); } if (!keyId) { do { keyId = randomString(32); } while ( - await this._baseApis.getAccountDataFromServer( + await this.accountDataAdapter.getAccountDataFromServer( `m.secret_storage.key.${keyId}`, ) ); } - await this._baseApis.setAccountData( + await this.accountDataAdapter.setAccountData( `m.secret_storage.key.${keyId}`, keyInfo, ); @@ -134,8 +182,9 @@ export class SecretStorage extends EventEmitter { * for. Defaults to the default key ID if not provided. * @returns {Array?} If the key was found, the return value is an array of * the form [keyId, keyInfo]. Otherwise, null is returned. + * XXX: why is this an array when addKey returns an object? */ - async getKey(keyId) { + public async getKey(keyId: string): Promise { if (!keyId) { keyId = await this.getDefaultKeyId(); } @@ -143,7 +192,7 @@ export class SecretStorage extends EventEmitter { return null; } - const keyInfo = await this._baseApis.getAccountDataFromServer( + const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, ); return keyInfo ? [keyId, keyInfo] : null; @@ -156,8 +205,8 @@ export class SecretStorage extends EventEmitter { * for. Defaults to the default key ID if not provided. * @return {boolean} Whether we have the key. */ - async hasKey(keyId) { - return !!(await this.getKey(keyId)); + public async hasKey(keyId?: string): Promise { + return Boolean(await this.getKey(keyId)); } /** @@ -168,7 +217,7 @@ export class SecretStorage extends EventEmitter { * * @return {boolean} whether or not the key matches */ - async checkKey(key, info) { + public async checkKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise { if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { if (info.mac) { const { mac } = await SecretStorage._calculateKeyCheck(key, info.iv); @@ -182,7 +231,7 @@ export class SecretStorage extends EventEmitter { } } - static async _calculateKeyCheck(key, iv) { + public static async _calculateKeyCheck(key: Uint8Array, iv?: string): Promise { return await encryptAES(ZERO_STR, key, "", iv); } @@ -194,7 +243,7 @@ export class SecretStorage extends EventEmitter { * @param {Array} keys The IDs of the keys to use to encrypt the secret * or null/undefined to use the default key. */ - async store(name, secret, keys) { + public async store(name: string, secret: string, keys?: Array): Promise { const encrypted = {}; if (!keys) { @@ -211,7 +260,7 @@ export class SecretStorage extends EventEmitter { for (const keyId of keys) { // get key information from key storage - const keyInfo = await this._baseApis.getAccountDataFromServer( + const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, ); if (!keyInfo) { @@ -221,7 +270,7 @@ export class SecretStorage extends EventEmitter { // encrypt secret, based on the algorithm if (keyInfo.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { const keys = { [keyId]: keyInfo }; - const [, encryption] = await this._getSecretStorageKey(keys, name); + const [, encryption] = await this.getSecretStorageKey(keys, name); encrypted[keyId] = await encryption.encrypt(secret); } else { logger.warn("unknown algorithm for secret storage key " + keyId @@ -231,34 +280,7 @@ export class SecretStorage extends EventEmitter { } // save encrypted secret - await this._baseApis.setAccountData(name, { encrypted }); - } - - /** - * Temporary method to fix up existing accounts where secrets - * are incorrectly stored without the 'encrypted' level - * - * @param {string} name The name of the secret - * @param {object} secretInfo The account data object - * @returns {object} The fixed object or null if no fix was performed - */ - async _fixupStoredSecret(name, secretInfo) { - // We assume the secret was only stored passthrough for 1 - // key - this was all the broken code supported. - const keys = Object.keys(secretInfo); - if ( - keys.length === 1 && keys[0] !== 'encrypted' && - secretInfo[keys[0]].passthrough - ) { - const hasKey = await this.hasKey(keys[0]); - if (hasKey) { - logger.log("Fixing up passthrough secret: " + name); - await this.storePassthrough(name, keys[0]); - const newData = await this._baseApis.getAccountDataFromServer(name); - return newData; - } - } - return null; + await this.accountDataAdapter.setAccountData(name, { encrypted }); } /** @@ -268,24 +290,20 @@ export class SecretStorage extends EventEmitter { * * @return {string} the contents of the secret */ - async get(name) { - let secretInfo = await this._baseApis.getAccountDataFromServer(name); + async get(name: string): Promise { + const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name); if (!secretInfo) { return; } if (!secretInfo.encrypted) { - // try to fix it up - secretInfo = await this._fixupStoredSecret(name, secretInfo); - if (!secretInfo || !secretInfo.encrypted) { - throw new Error("Content is not encrypted!"); - } + throw new Error("Content is not encrypted!"); } // get possible keys to decrypt const keys = {}; for (const keyId of Object.keys(secretInfo.encrypted)) { // get key information from key storage - const keyInfo = await this._baseApis.getAccountDataFromServer( + const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, ); const encInfo = secretInfo.encrypted[keyId]; @@ -306,7 +324,7 @@ export class SecretStorage extends EventEmitter { let decryption; try { // fetch private key from app - [keyId, decryption] = await this._getSecretStorageKey(keys, name); + [keyId, decryption] = await this.getSecretStorageKey(keys, name); const encInfo = secretInfo.encrypted[keyId]; @@ -331,16 +349,12 @@ export class SecretStorage extends EventEmitter { * with, or null if it is not present or not encrypted with a trusted * key */ - async isStored(name, checkKey) { + async isStored(name: string, checkKey: boolean): Promise> { // check if secret exists - let secretInfo = await this._baseApis.getAccountDataFromServer(name); + const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name); if (!secretInfo) return null; if (!secretInfo.encrypted) { - // try to fix it up - secretInfo = await this._fixupStoredSecret(name, secretInfo); - if (!secretInfo || !secretInfo.encrypted) { - return null; - } + return null; } if (checkKey === undefined) checkKey = true; @@ -350,7 +364,7 @@ export class SecretStorage extends EventEmitter { // filter secret encryption keys with supported algorithm for (const keyId of Object.keys(secretInfo.encrypted)) { // get key information from key storage - const keyInfo = await this._baseApis.getAccountDataFromServer( + const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, ); if (!keyInfo) continue; @@ -371,45 +385,48 @@ export class SecretStorage extends EventEmitter { * * @param {string} name the name of the secret to request * @param {string[]} devices the devices to request the secret from - * - * @return {string} the contents of the secret */ - request(name, devices) { - const requestId = this._baseApis.makeTxnId(); + request(name: string, devices: Array): ISecretRequest { + const requestId = this.baseApis.makeTxnId(); - const requestControl = this._requests[requestId] = { + let resolve: (string) => void; + let reject: (Error) => void; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + this.requests.set(requestId, { name, devices, - }; - const promise = new Promise((resolve, reject) => { - requestControl.resolve = resolve; - requestControl.reject = reject; + resolve, + reject, }); + const cancel = (reason) => { // send cancellation event const cancelData = { action: "request_cancellation", - requesting_device_id: this._baseApis.deviceId, + requesting_device_id: this.baseApis.deviceId, request_id: requestId, }; const toDevice = {}; for (const device of devices) { toDevice[device] = cancelData; } - this._baseApis.sendToDevice("m.secret.request", { - [this._baseApis.getUserId()]: toDevice, + this.baseApis.sendToDevice("m.secret.request", { + [this.baseApis.getUserId()]: toDevice, }); // and reject the promise so that anyone waiting on it will be // notified - requestControl.reject(new Error(reason || "Cancelled")); + reject(new Error(reason || "Cancelled")); }; // send request to devices const requestData = { name, action: "request", - requesting_device_id: this._baseApis.deviceId, + requesting_device_id: this.baseApis.deviceId, request_id: requestId, }; const toDevice = {}; @@ -417,21 +434,21 @@ export class SecretStorage extends EventEmitter { toDevice[device] = requestData; } logger.info(`Request secret ${name} from ${devices}, id ${requestId}`); - this._baseApis.sendToDevice("m.secret.request", { - [this._baseApis.getUserId()]: toDevice, + this.baseApis.sendToDevice("m.secret.request", { + [this.baseApis.getUserId()]: toDevice, }); return { - request_id: requestId, + requestId, promise, cancel, }; } - async _onRequestReceived(event) { + public async onRequestReceived(event: MatrixEvent): Promise { const sender = event.getSender(); const content = event.getContent(); - if (sender !== this._baseApis.getUserId() + if (sender !== this.baseApis.getUserId() || !(content.name && content.action && content.requesting_device_id && content.request_id)) { // ignore requests from anyone else, for now @@ -440,34 +457,45 @@ export class SecretStorage extends EventEmitter { const deviceId = content.requesting_device_id; // check if it's a cancel if (content.action === "request_cancellation") { + /* + Looks like we intended to emit events when we got cancelations, but + we never put anything in the _incomingRequests object, and the request + itself doesn't use events anyway so if we were to wire up cancellations, + they probably ought to use the same callback interface. I'm leaving them + disabled for now while converting this file to typescript. if (this._incomingRequests[deviceId] && this._incomingRequests[deviceId][content.request_id]) { - logger.info("received request cancellation for secret (" + sender - + ", " + deviceId + ", " + content.request_id + ")"); - this._baseApis.emit("crypto.secrets.requestCancelled", { + logger.info( + "received request cancellation for secret (" + sender + + ", " + deviceId + ", " + content.request_id + ")", + ); + this.baseApis.emit("crypto.secrets.requestCancelled", { user_id: sender, device_id: deviceId, request_id: content.request_id, }); } + */ } else if (content.action === "request") { - if (deviceId === this._baseApis.deviceId) { + if (deviceId === this.baseApis.deviceId) { // no point in trying to send ourself the secret return; } // check if we have the secret - logger.info("received request for secret (" + sender - + ", " + deviceId + ", " + content.request_id + ")"); - if (!this._cryptoCallbacks.onSecretRequested) { + logger.info( + "received request for secret (" + sender + + ", " + deviceId + ", " + content.request_id + ")", + ); + if (!this.cryptoCallbacks.onSecretRequested) { return; } - const secret = await this._cryptoCallbacks.onSecretRequested( + const secret = await this.cryptoCallbacks.onSecretRequested( sender, deviceId, content.request_id, content.name, - this._baseApis.checkDeviceTrust(sender, deviceId), + this.baseApis.checkDeviceTrust(sender, deviceId), ); if (secret) { logger.info(`Preparing ${content.name} secret for ${deviceId}`); @@ -480,25 +508,25 @@ export class SecretStorage extends EventEmitter { }; const encryptedContent = { algorithm: olmlib.OLM_ALGORITHM, - sender_key: this._baseApis.crypto.olmDevice.deviceCurve25519Key, + sender_key: this.baseApis.crypto.olmDevice.deviceCurve25519Key, ciphertext: {}, }; await olmlib.ensureOlmSessionsForDevices( - this._baseApis.crypto.olmDevice, - this._baseApis, + this.baseApis.crypto.olmDevice, + this.baseApis, { [sender]: [ - this._baseApis.getStoredDevice(sender, deviceId), + this.baseApis.getStoredDevice(sender, deviceId), ], }, ); await olmlib.encryptMessageForDevice( encryptedContent.ciphertext, - this._baseApis.getUserId(), - this._baseApis.deviceId, - this._baseApis.crypto.olmDevice, + this.baseApis.getUserId(), + this.baseApis.deviceId, + this.baseApis.crypto.olmDevice, sender, - this._baseApis.getStoredDevice(sender, deviceId), + this.baseApis.getStoredDevice(sender, deviceId), payload, ); const contentMap = { @@ -508,26 +536,26 @@ export class SecretStorage extends EventEmitter { }; logger.info(`Sending ${content.name} secret for ${deviceId}`); - this._baseApis.sendToDevice("m.room.encrypted", contentMap); + this.baseApis.sendToDevice("m.room.encrypted", contentMap); } else { logger.info(`Request denied for ${content.name} secret for ${deviceId}`); } } } - _onSecretReceived(event) { - if (event.getSender() !== this._baseApis.getUserId()) { + public onSecretReceived(event: MatrixEvent): void { + if (event.getSender() !== this.baseApis.getUserId()) { // we shouldn't be receiving secrets from anyone else, so ignore // because someone could be trying to send us bogus data return; } const content = event.getContent(); logger.log("got secret share for request", content.request_id); - const requestControl = this._requests[content.request_id]; + const requestControl = this.requests.get(content.request_id); if (requestControl) { // make sure that the device that sent it is one of the devices that // we requested from - const deviceInfo = this._baseApis.crypto.deviceList.getDeviceByIdentityKey( + const deviceInfo = this.baseApis.crypto.deviceList.getDeviceByIdentityKey( olmlib.OLM_ALGORITHM, event.getSenderKey(), ); @@ -550,12 +578,14 @@ export class SecretStorage extends EventEmitter { } } - async _getSecretStorageKey(keys, name) { - if (!this._cryptoCallbacks.getSecretStorageKey) { + private async getSecretStorageKey( + keys: Record, name: string, + ): Promise<[string, IDecryptors]> { + if (!this.cryptoCallbacks.getSecretStorageKey) { throw new Error("No getSecretStorageKey callback supplied"); } - const returned = await this._cryptoCallbacks.getSecretStorageKey({ keys }, name); + const returned = await this.cryptoCallbacks.getSecretStorageKey({ keys }, name); if (!returned) { throw new Error("getSecretStorageKey callback returned falsey"); @@ -571,10 +601,10 @@ export class SecretStorage extends EventEmitter { if (keys[keyId].algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { const decryption = { - encrypt: async function(secret) { + encrypt: async function(secret: string): Promise { return await encryptAES(secret, privateKey, name); }, - decrypt: async function(encInfo) { + decrypt: async function(encInfo: IEncryptedPayload): Promise { return await decryptAES(encInfo, privateKey, name); }, }; diff --git a/src/crypto/api.ts b/src/crypto/api.ts index 8daafb6d7..a15f8bd5c 100644 --- a/src/crypto/api.ts +++ b/src/crypto/api.ts @@ -16,7 +16,7 @@ limitations under the License. import { DeviceInfo } from "./deviceinfo"; import { IKeyBackupInfo } from "./keybackup"; -import { ISecretStorageKeyInfo } from "../matrix"; +import { ISecretStorageKeyInfo } from "./SecretStorage"; // TODO: Merge this with crypto.js once converted @@ -112,9 +112,17 @@ export interface ISecretStorageKey { keyInfo: ISecretStorageKeyInfo; } +export interface IPassphraseInfo { + algorithm: "m.pbkdf2"; + iterations: number; + salt: string; + bits: number; +} + export interface IAddSecretStorageKeyOpts { - // depends on algorithm - // TODO: Types + name: string; + passphrase: IPassphraseInfo; + key: Uint8Array; } export interface IImportOpts { diff --git a/src/crypto/dehydration.ts b/src/crypto/dehydration.ts index 95fb77752..ef441e7d8 100644 --- a/src/crypto/dehydration.ts +++ b/src/crypto/dehydration.ts @@ -19,7 +19,7 @@ import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store'; import { decryptAES, encryptAES } from './aes'; import anotherjson from "another-json"; import { logger } from '../logger'; -import { ISecretStorageKeyInfo } from "../matrix"; +import { ISecretStorageKeyInfo } from "./SecretStorage"; // FIXME: these types should eventually go in a different file type Signatures = Record>; diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 1af4cfcc3..0b717c5b7 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -33,7 +33,14 @@ import { DeviceInfo, IDevice } from "./deviceinfo"; import * as algorithms from "./algorithms"; import { createCryptoStoreCacheCallbacks, CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from './CrossSigning'; import { EncryptionSetupBuilder } from "./EncryptionSetup"; -import { SECRET_STORAGE_ALGORITHM_V1_AES, SecretStorage } from './SecretStorage'; +import { + SECRET_STORAGE_ALGORITHM_V1_AES, + SecretStorage, + ISecretStorageKeyInfo, + SecretStorageKeyTuple, + ISecretRequest, +} from './SecretStorage'; +import { IAddSecretStorageKeyOpts } from "./api"; import { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager'; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from './verification/QRCode'; @@ -359,7 +366,8 @@ export class Crypto extends EventEmitter { const cacheCallbacks = createCryptoStoreCacheCallbacks(cryptoStore, this.olmDevice); this.crossSigningInfo = new CrossSigningInfo(userId, cryptoCallbacks, cacheCallbacks); - this.secretStorage = new SecretStorage(baseApis, cryptoCallbacks); + // Yes, we pass the client twice here: see SecretStorage + this.secretStorage = new SecretStorage(baseApis, cryptoCallbacks, baseApis); this.dehydrationManager = new DehydrationManager(this); // Assuming no app-supplied callback, default to getting from SSSS. @@ -970,15 +978,17 @@ export class Crypto extends EventEmitter { logger.log("Secure Secret Storage ready"); } - public addSecretStorageKey(algorithm: string, opts: any, keyID: string): any { // TODO types + public addSecretStorageKey( + algorithm: string, opts: IAddSecretStorageKeyOpts, keyID: string, + ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { return this.secretStorage.addKey(algorithm, opts, keyID); } - public hasSecretStorageKey(keyID: string): boolean { + public hasSecretStorageKey(keyID: string): Promise { return this.secretStorage.hasKey(keyID); } - public getSecretStorageKey(keyID?: string): any { // TODO types + public getSecretStorageKey(keyID?: string): Promise { return this.secretStorage.getKey(keyID); } @@ -990,11 +1000,13 @@ export class Crypto extends EventEmitter { return this.secretStorage.get(name); } - public isSecretStored(name: string, checkKey?: boolean): any { // TODO types + public isSecretStored( + name: string, checkKey?: boolean, + ): Promise> { return this.secretStorage.isStored(name, checkKey); } - public requestSecret(name: string, devices: string[]): Promise { // TODO types + public requestSecret(name: string, devices: string[]): ISecretRequest { // TODO types if (!devices) { devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId)); } @@ -1009,7 +1021,7 @@ export class Crypto extends EventEmitter { return this.secretStorage.setDefaultKeyId(k); } - public checkSecretStorageKey(key: string, info: any): Promise { // TODO types + public checkSecretStorageKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise { return this.secretStorage.checkKey(key, info); } @@ -2996,9 +3008,9 @@ export class Crypto extends EventEmitter { } else if (event.getType() == "m.room_key_request") { this.onRoomKeyRequestEvent(event); } else if (event.getType() === "m.secret.request") { - this.secretStorage._onRequestReceived(event); + this.secretStorage.onRequestReceived(event); } else if (event.getType() === "m.secret.send") { - this.secretStorage._onSecretReceived(event); + this.secretStorage.onSecretReceived(event); } else if (event.getType() === "org.matrix.room_key.withheld") { this.onRoomKeyWithheldEvent(event); } else if (event.getContent().transaction_id) { diff --git a/src/matrix.ts b/src/matrix.ts index 2cce6867a..fbda72fe5 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -20,6 +20,7 @@ import { MatrixScheduler } from "./scheduler"; import { MatrixClient } from "./client"; import { ICreateClientOpts } from "./client"; import { DeviceTrustLevel } from "./crypto/CrossSigning"; +import { ISecretStorageKeyInfo } from "./crypto/SecretStorage"; export * from "./client"; export * from "./http-api"; @@ -122,17 +123,6 @@ export interface ICryptoCallbacks { getBackupKey?: () => Promise; } -// TODO: Move this to `SecretStorage` once converted -export interface ISecretStorageKeyInfo { - passphrase?: { - algorithm: "m.pbkdf2"; - iterations: number; - salt: string; - }; - iv?: string; - mac?: string; -} - /** * Construct a Matrix Client. Similar to {@link module:client.MatrixClient} * except that the 'request', 'store' and 'scheduler' dependencies are satisfied. From 5c6d3724b0b66ec59a7f983c43606611a3b5572d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:21:44 +0100 Subject: [PATCH 026/129] Move some interfaces around --- src/client.ts | 2 +- src/crypto/EncryptionSetup.ts | 2 +- src/crypto/SecretStorage.ts | 12 +----------- src/crypto/api.ts | 11 ++++++++++- src/crypto/dehydration.ts | 2 +- src/crypto/index.ts | 3 +-- src/matrix.ts | 2 +- 7 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/client.ts b/src/client.ts index 9106e5277..0067a4fa7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -65,7 +65,7 @@ import { IIdentityServerProvider } from "./@types/IIdentityServerProvider"; import type Request from "request"; import { MatrixScheduler } from "./scheduler"; import { ICryptoCallbacks, NotificationCountType } from "./matrix"; -import { ISecretStorageKeyInfo } from "./crypto/SecretStorage"; +import { ISecretStorageKeyInfo } from "./crypto/api"; import { MemoryCryptoStore } from "./crypto/store/memory-crypto-store"; import { LocalStorageCryptoStore } from "./crypto/store/localStorage-crypto-store"; import { IndexedDBCryptoStore } from "./crypto/store/indexeddb-crypto-store"; diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index ccf8aeb47..406abc512 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -12,7 +12,7 @@ import { ISignedKey, KeySignatures, } from "../matrix"; -import { ISecretStorageKeyInfo } from "./SecretStorage"; +import { ISecretStorageKeyInfo } from "./api"; import { IKeyBackupInfo } from "./keybackup"; interface ICrossSigningKeys { diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 3b2fca435..0668b0b3a 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -20,23 +20,13 @@ import { randomString } from '../randomstring'; import { encryptAES, decryptAES, IEncryptedPayload } from './aes'; import { encodeBase64 } from "./olmlib"; import { ICryptoCallbacks, MatrixClient, MatrixEvent } from '../matrix'; -import { IAddSecretStorageKeyOpts, IPassphraseInfo } from './api'; +import { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from './api'; import { EventEmitter } from 'stream'; export const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha2"; const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; -export interface ISecretStorageKeyInfo { - name: string; - algorithm: string; - // technically the below are specific to AES keys. If we ever introduce another type, - // we can split into separate interfaces. - iv: string; - mac: string; - passphrase: IPassphraseInfo; -} - export type SecretStorageKeyTuple = [keyId: string, keyInfo: ISecretStorageKeyInfo]; export interface ISecretRequest { diff --git a/src/crypto/api.ts b/src/crypto/api.ts index a15f8bd5c..57f48c18c 100644 --- a/src/crypto/api.ts +++ b/src/crypto/api.ts @@ -16,7 +16,6 @@ limitations under the License. import { DeviceInfo } from "./deviceinfo"; import { IKeyBackupInfo } from "./keybackup"; -import { ISecretStorageKeyInfo } from "./SecretStorage"; // TODO: Merge this with crypto.js once converted @@ -107,6 +106,16 @@ export interface ICreateSecretStorageOpts { getKeyBackupPassphrase?: () => Promise; } +export interface ISecretStorageKeyInfo { + name: string; + algorithm: string; + // technically the below are specific to AES keys. If we ever introduce another type, + // we can split into separate interfaces. + iv: string; + mac: string; + passphrase: IPassphraseInfo; +} + export interface ISecretStorageKey { keyId: string; keyInfo: ISecretStorageKeyInfo; diff --git a/src/crypto/dehydration.ts b/src/crypto/dehydration.ts index ef441e7d8..0267e457e 100644 --- a/src/crypto/dehydration.ts +++ b/src/crypto/dehydration.ts @@ -19,7 +19,7 @@ import { IndexedDBCryptoStore } from '../crypto/store/indexeddb-crypto-store'; import { decryptAES, encryptAES } from './aes'; import anotherjson from "another-json"; import { logger } from '../logger'; -import { ISecretStorageKeyInfo } from "./SecretStorage"; +import { ISecretStorageKeyInfo } from "./api"; // FIXME: these types should eventually go in a different file type Signatures = Record>; diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 0b717c5b7..184557653 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -36,11 +36,10 @@ import { EncryptionSetupBuilder } from "./EncryptionSetup"; import { SECRET_STORAGE_ALGORITHM_V1_AES, SecretStorage, - ISecretStorageKeyInfo, SecretStorageKeyTuple, ISecretRequest, } from './SecretStorage'; -import { IAddSecretStorageKeyOpts } from "./api"; +import { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from "./api"; import { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager'; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from './verification/QRCode'; diff --git a/src/matrix.ts b/src/matrix.ts index fbda72fe5..78906a716 100644 --- a/src/matrix.ts +++ b/src/matrix.ts @@ -20,7 +20,7 @@ import { MatrixScheduler } from "./scheduler"; import { MatrixClient } from "./client"; import { ICreateClientOpts } from "./client"; import { DeviceTrustLevel } from "./crypto/CrossSigning"; -import { ISecretStorageKeyInfo } from "./crypto/SecretStorage"; +import { ISecretStorageKeyInfo } from "./crypto/api"; export * from "./client"; export * from "./http-api"; From 0544ab2617aae5b64b2a586c6a3273b46ee42684 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:52:07 +0100 Subject: [PATCH 027/129] Add return type Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 0668b0b3a..49c6c2452 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -85,7 +85,7 @@ export class SecretStorage { return defaultKey.key; } - public setDefaultKeyId(keyId: string) { + public setDefaultKeyId(keyId: string): Promise { return new Promise((resolve, reject) => { const listener = (ev) => { if ( From 11b490c77f30a55f8b50b4a54305d840643d04ff Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:54:48 +0100 Subject: [PATCH 028/129] Line breaks Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/client.ts | 4 +++- src/crypto/SecretStorage.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 0067a4fa7..d3305b2ca 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1842,7 +1842,9 @@ export class MatrixClient extends EventEmitter { * keyInfo: {object} details about the key (iv, mac, passphrase) */ public addSecretStorageKey( - algorithm: string, opts: IAddSecretStorageKeyOpts, keyName?: string, + algorithm: string, + opts: IAddSecretStorageKeyOpts, + keyName?: string, ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 49c6c2452..404b7901f 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -122,7 +122,9 @@ export class SecretStorage { * keyInfo: {object} details about the key (iv, mac, passphrase) */ public async addKey( - algorithm: string, opts: IAddSecretStorageKeyOpts, keyId?: string, + algorithm: string, + opts: IAddSecretStorageKeyOpts, + keyId?: string, ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { const keyInfo = { algorithm } as ISecretStorageKeyInfo; From c701e2e6d3be032cb5426ccfd601ee9d10b97da0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:55:23 +0100 Subject: [PATCH 029/129] Inline members in ctor Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 404b7901f..b5260ff5a 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -71,11 +71,11 @@ export class SecretStorage { // as you don't request any secrets. // A better solution would probably be to split this class up into secret storage and // secret sharing which are really two separate things, even though they share an MSC. - constructor(accountDataClient: IAccountDataClient, cryptoCallbacks: ICryptoCallbacks, matrixClient?: MatrixClient) { - this.accountDataAdapter = accountDataClient; - this.baseApis = matrixClient; - this.cryptoCallbacks = cryptoCallbacks; - } + constructor( + private readonly accountDataClient: IAccountDataClient, + private readonly cryptoCallbacks: ICryptoCallbacks, + private readonly matrixClient?: MatrixClient, + ) {} public async getDefaultKeyId(): Promise { const defaultKey = await this.accountDataAdapter.getAccountDataFromServer( From 3c9b846116cab3711b3aa37bfb0a9ea83bf9e530 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:56:55 +0100 Subject: [PATCH 030/129] Shorthand Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index b5260ff5a..96ad103aa 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -43,7 +43,7 @@ export interface IAccountDataClient extends EventEmitter { interface ISecretRequestInternal { name: string; - devices: Array; + devices: string[]; resolve: (string) => void; reject: (Error) => void; } @@ -235,7 +235,7 @@ export class SecretStorage { * @param {Array} keys The IDs of the keys to use to encrypt the secret * or null/undefined to use the default key. */ - public async store(name: string, secret: string, keys?: Array): Promise { + public async store(name: string, secret: string, keys?: string[]): Promise { const encrypted = {}; if (!keys) { From d11c95a23fac887c7222cbdf42954b16a15f524d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:57:40 +0100 Subject: [PATCH 031/129] Add type Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 96ad103aa..042bc6b35 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -87,7 +87,7 @@ export class SecretStorage { public setDefaultKeyId(keyId: string): Promise { return new Promise((resolve, reject) => { - const listener = (ev) => { + const listener = (ev: MatrixEvent): void => { if ( ev.getType() === 'm.secret_storage.default_key' && ev.getContent().key === keyId From 87d9fe24f5c0e1158c96b2d403dc0991de2920d5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:58:08 +0100 Subject: [PATCH 032/129] Shorthand Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 042bc6b35..d61de4abe 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -378,7 +378,7 @@ export class SecretStorage { * @param {string} name the name of the secret to request * @param {string[]} devices the devices to request the secret from */ - request(name: string, devices: Array): ISecretRequest { + request(name: string, devices: string[]): ISecretRequest { const requestId = this.baseApis.makeTxnId(); let resolve: (string) => void; From 41b816538e89c58421ccb8e4fc01b9bb68ba4f68 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:58:47 +0100 Subject: [PATCH 033/129] Line break Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/SecretStorage.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index d61de4abe..ddae9ff77 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -571,7 +571,8 @@ export class SecretStorage { } private async getSecretStorageKey( - keys: Record, name: string, + keys: Record, + name: string, ): Promise<[string, IDecryptors]> { if (!this.cryptoCallbacks.getSecretStorageKey) { throw new Error("No getSecretStorageKey callback supplied"); From ef08c35c6fbe4506b52904df0653f1afab48c534 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 20:59:32 +0100 Subject: [PATCH 034/129] Line break Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 184557653..7a8a35d75 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1000,7 +1000,8 @@ export class Crypto extends EventEmitter { } public isSecretStored( - name: string, checkKey?: boolean, + name: string, + checkKey?: boolean, ): Promise> { return this.secretStorage.isStored(name, checkKey); } From e7a198dc0c1b9b02d697b375eb20a4b0119ca57a Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:00:02 +0100 Subject: [PATCH 035/129] Line breaks Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 7a8a35d75..9d82910ed 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -978,7 +978,9 @@ export class Crypto extends EventEmitter { } public addSecretStorageKey( - algorithm: string, opts: IAddSecretStorageKeyOpts, keyID: string, + algorithm: string, + opts: IAddSecretStorageKeyOpts, + keyID: string, ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { return this.secretStorage.addKey(algorithm, opts, keyID); } From 79c6d0180c13e4b22cbfd867c500bc5831638eec Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:04:07 +0100 Subject: [PATCH 036/129] remove TODO --- src/crypto/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 9d82910ed..85488165f 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -1008,7 +1008,7 @@ export class Crypto extends EventEmitter { return this.secretStorage.isStored(name, checkKey); } - public requestSecret(name: string, devices: string[]): ISecretRequest { // TODO types + public requestSecret(name: string, devices: string[]): ISecretRequest { if (!devices) { devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId)); } From 33398e78cd228d58a5ab2d8321fee896712cb118 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:05:45 +0100 Subject: [PATCH 037/129] Fix duplicate inlined / explicit members --- src/crypto/SecretStorage.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index ddae9ff77..8b2b4b908 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -58,9 +58,6 @@ interface IDecryptors { * @module crypto/SecretStorage */ export class SecretStorage { - private accountDataAdapter: IAccountDataClient; - private baseApis: MatrixClient; - private cryptoCallbacks: ICryptoCallbacks; private requests = new Map(); // In it's pure javascript days, this was relying on some proper Javascript-style @@ -72,9 +69,9 @@ export class SecretStorage { // A better solution would probably be to split this class up into secret storage and // secret sharing which are really two separate things, even though they share an MSC. constructor( - private readonly accountDataClient: IAccountDataClient, + private readonly accountDataAdapter: IAccountDataClient, private readonly cryptoCallbacks: ICryptoCallbacks, - private readonly matrixClient?: MatrixClient, + private readonly baseApis?: MatrixClient, ) {} public async getDefaultKeyId(): Promise { From dbd737c87d989e611abb26176e254e8bbda42759 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:10:13 +0100 Subject: [PATCH 038/129] param names & comment any --- src/crypto/SecretStorage.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 8b2b4b908..5d6f24464 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -36,9 +36,10 @@ export interface ISecretRequest { } export interface IAccountDataClient extends EventEmitter { - getAccountDataFromServer: (string) => Promise; - getAccountData: (string) => object; - setAccountData: (string, object) => Promise; + // Subset of MatrixClient (which also uses any for the event content) + getAccountDataFromServer: (eventType: string) => Promise; + getAccountData: (eventType: string) => MatrixEvent; + setAccountData: (eventType: string, content: any) => Promise; } interface ISecretRequestInternal { From 8cc250e19df2019b94a8245ca35dc5ac762ab85f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:10:51 +0100 Subject: [PATCH 039/129] param names --- src/crypto/SecretStorage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 5d6f24464..9e83fe349 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -50,8 +50,8 @@ interface ISecretRequestInternal { } interface IDecryptors { - encrypt: (string) => Promise; - decrypt: (IEncryptedPayload) => Promise; + encrypt: (plaintext: string) => Promise; + decrypt: (ciphertext: IEncryptedPayload) => Promise; } /** From 64a1c83accc43e1b2cff78c6ca7d4e27236b4f4b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:11:11 +0100 Subject: [PATCH 040/129] param names --- src/crypto/SecretStorage.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 9e83fe349..54b407da5 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -45,8 +45,8 @@ export interface IAccountDataClient extends EventEmitter { interface ISecretRequestInternal { name: string; devices: string[]; - resolve: (string) => void; - reject: (Error) => void; + resolve: (reason: string) => void; + reject: (error: Error) => void; } interface IDecryptors { From fd2d106f2ab7968addf0a491246ed70a2a040f2e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:14:34 +0100 Subject: [PATCH 041/129] extract SecretStorageKeyObject --- src/crypto/SecretStorage.ts | 4 +++- src/crypto/index.ts | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 54b407da5..5ddef3323 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -27,7 +27,9 @@ export const SECRET_STORAGE_ALGORITHM_V1_AES = "m.secret_storage.v1.aes-hmac-sha const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; +// Some of the key functions use a tuple and some use an object... export type SecretStorageKeyTuple = [keyId: string, keyInfo: ISecretStorageKeyInfo]; +export type SecretStorageKeyObject = {keyId: string, keyInfo: ISecretStorageKeyInfo}; export interface ISecretRequest { requestId: string; @@ -123,7 +125,7 @@ export class SecretStorage { algorithm: string, opts: IAddSecretStorageKeyOpts, keyId?: string, - ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { + ): Promise { const keyInfo = { algorithm } as ISecretStorageKeyInfo; if (!opts) opts = {} as IAddSecretStorageKeyOpts; diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 85488165f..49fcc5449 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -38,6 +38,7 @@ import { SecretStorage, SecretStorageKeyTuple, ISecretRequest, + SecretStorageKeyObject, } from './SecretStorage'; import { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from "./api"; import { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager'; @@ -981,7 +982,7 @@ export class Crypto extends EventEmitter { algorithm: string, opts: IAddSecretStorageKeyOpts, keyID: string, - ): Promise<{keyId: string, keyInfo: ISecretStorageKeyInfo}> { + ): Promise { return this.secretStorage.addKey(algorithm, opts, keyID); } From 9019bce84356e874d49e5e91c39b31891b7da950 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 7 Jul 2021 16:16:07 -0400 Subject: [PATCH 042/129] mark session as untrusted when the session data has the untrusted flag --- src/crypto/algorithms/megolm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 138566892..4986bbfff 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -1622,7 +1622,7 @@ MegolmDecryption.prototype._buildKeyForwardingMessage = async function( */ MegolmDecryption.prototype.importRoomKey = function(session, opts = {}) { const extraSessionData = {}; - if (opts.untrusted) { + if (opts.untrusted || session.untrusted) { extraSessionData.untrusted = true; } if (session["org.matrix.msc3061.shared_history"]) { From 5fbce3b9287e4cc7e2f8e41a69c130bb1bb490d4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:18:14 +0100 Subject: [PATCH 043/129] Consistent values between various account data interfaces --- src/crypto/EncryptionSetup.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 406abc512..278a17ed4 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -246,7 +246,7 @@ export class EncryptionSetupOperation { * implementing the methods related to account data in MatrixClient */ class AccountDataClientAdapter extends EventEmitter { - public readonly values = new Map(); + public readonly values = new Map(); /** * @param {Object.} existingValues existing account data @@ -259,7 +259,7 @@ class AccountDataClientAdapter extends EventEmitter { * @param {String} type * @return {Promise} the content of the account data */ - public getAccountDataFromServer(type: string): Promise { + public getAccountDataFromServer(type: string): Promise { return Promise.resolve(this.getAccountData(type)); } @@ -267,7 +267,7 @@ class AccountDataClientAdapter extends EventEmitter { * @param {String} type * @return {Object} the content of the account data */ - public getAccountData(type: string): object { + public getAccountData(type: string): MatrixEvent { const modifiedValue = this.values.get(type); if (modifiedValue) { return modifiedValue; @@ -284,7 +284,7 @@ class AccountDataClientAdapter extends EventEmitter { * @param {Object} content * @return {Promise} */ - public setAccountData(type: string, content: object): Promise { + public setAccountData(type: string, content: any): Promise { const lastEvent = this.values.get(type); this.values.set(type, content); // ensure accountData is emitted on the next tick, From 1fd1ba2ada6c3813f1f16bf08b1946dffc3826a8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:19:51 +0100 Subject: [PATCH 044/129] de-underscore --- src/crypto/SecretStorage.ts | 6 +++--- src/crypto/index.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 5ddef3323..2ebc7b5c3 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -139,7 +139,7 @@ export class SecretStorage { keyInfo.passphrase = opts.passphrase; } if (opts.key) { - const { iv, mac } = await SecretStorage._calculateKeyCheck(opts.key); + const { iv, mac } = await SecretStorage.calculateKeyCheck(opts.key); keyInfo.iv = iv; keyInfo.mac = mac; } @@ -212,7 +212,7 @@ export class SecretStorage { public async checkKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise { if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { if (info.mac) { - const { mac } = await SecretStorage._calculateKeyCheck(key, info.iv); + const { mac } = await SecretStorage.calculateKeyCheck(key, info.iv); return info.mac.replace(/=+$/g, '') === mac.replace(/=+$/g, ''); } else { // if we have no information, we have to assume the key is right @@ -223,7 +223,7 @@ export class SecretStorage { } } - public static async _calculateKeyCheck(key: Uint8Array, iv?: string): Promise { + public static async calculateKeyCheck(key: Uint8Array, iv?: string): Promise { return await encryptAES(ZERO_STR, key, "", iv); } diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 49fcc5449..285a1247b 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -797,7 +797,7 @@ export class Crypto extends EventEmitter { if (key) { const privateKey = key[1]; builder.ssssCryptoCallbacks.addPrivateKey(keyId, keyInfo, privateKey); - const { iv, mac } = await SecretStorage._calculateKeyCheck(privateKey); + const { iv, mac } = await SecretStorage.calculateKeyCheck(privateKey); keyInfo.iv = iv; keyInfo.mac = mac; From 29b403da456535fbe071831e05d85e4b5cc49f1d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:20:48 +0100 Subject: [PATCH 045/129] visibility --- src/crypto/SecretStorage.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 2ebc7b5c3..fa89c7164 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -282,7 +282,7 @@ export class SecretStorage { * * @return {string} the contents of the secret */ - async get(name: string): Promise { + public async get(name: string): Promise { const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name); if (!secretInfo) { return; @@ -341,7 +341,7 @@ export class SecretStorage { * with, or null if it is not present or not encrypted with a trusted * key */ - async isStored(name: string, checkKey: boolean): Promise> { + public async isStored(name: string, checkKey: boolean): Promise> { // check if secret exists const secretInfo = await this.accountDataAdapter.getAccountDataFromServer(name); if (!secretInfo) return null; @@ -378,7 +378,7 @@ export class SecretStorage { * @param {string} name the name of the secret to request * @param {string[]} devices the devices to request the secret from */ - request(name: string, devices: string[]): ISecretRequest { + public request(name: string, devices: string[]): ISecretRequest { const requestId = this.baseApis.makeTxnId(); let resolve: (string) => void; From 8d9de370991b686e23680f643c0b8b5c0acdc03a Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Jul 2021 21:21:22 +0100 Subject: [PATCH 046/129] type for reason --- src/crypto/SecretStorage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index fa89c7164..4f6d613d5 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -394,7 +394,7 @@ export class SecretStorage { reject, }); - const cancel = (reason) => { + const cancel = (reason: string) => { // send cancellation event const cancelData = { action: "request_cancellation", From c8a7820cb36f871a165d9e48f7583565e1766ba9 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 7 Jul 2021 19:46:01 -0400 Subject: [PATCH 047/129] fix types --- src/crypto/backup.ts | 12 ++++++------ src/crypto/index.ts | 1 + src/crypto/key_passphrase.ts | 9 ++------- src/crypto/keybackup.ts | 10 ++++++---- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 505409af2..ae87ce706 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -78,7 +78,7 @@ interface BackupAlgorithmClass { key: string | Uint8Array | null, ): Promise<[Uint8Array, AuthData]>; - checkBackupVersion(info: BackupInfo): void; + checkBackupVersion(info: IKeyBackupInfo): void; } interface BackupAlgorithm { @@ -112,9 +112,9 @@ export class BackupManager { * * Throws an error if a problem is detected. * - * @param {BackupInfo} info the key backup info + * @param {IKeyBackupInfo} info the key backup info */ - public static checkBackupVersion(info: BackupInfo): void { + public static checkBackupVersion(info: IKeyBackupInfo): void { const Algorithm = algorithmsByName[info.algorithm]; if (!Algorithm) { throw new Error("Unknown backup algorithm: " + info.algorithm); @@ -273,7 +273,7 @@ export class BackupManager { /** * Check if the given backup info is trusted. * - * @param {object} backupInfo key backup info dict from /room_keys/version + * @param {IKeyBackupInfo} backupInfo key backup info dict from /room_keys/version * @return {object} { * usable: [bool], // is the backup trusted, true iff there is a sig that is valid & from a trusted device * sigs: [ @@ -619,7 +619,7 @@ export class Curve25519 implements BackupAlgorithm { } } - public static checkBackupVersion(info: BackupInfo): void { + public static checkBackupVersion(info: IKeyBackupInfo): void { if (!info.auth_data.public_key) { throw new Error("Invalid backup data returned"); } @@ -754,7 +754,7 @@ export class Aes256 implements BackupAlgorithm { return [outKey, authData]; } - public static checkBackupVersion(info: BackupInfo): void { + public static checkBackupVersion(info: IKeyBackupInfo): void { if (!info.auth_data.iv || !info.auth_data.mac) { throw new Error("Invalid backup data returned"); } diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 12b05ffac..74f0df5a4 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -126,6 +126,7 @@ export interface IMegolmSessionData { session_id: string; session_key: string; algorithm: string; + untrusted?: boolean; } /* eslint-enable camelcase */ diff --git a/src/crypto/key_passphrase.ts b/src/crypto/key_passphrase.ts index ca11e7d2f..89aefc803 100644 --- a/src/crypto/key_passphrase.ts +++ b/src/crypto/key_passphrase.ts @@ -15,18 +15,13 @@ limitations under the License. */ import { randomString } from '../randomstring'; +import { IKeyBackupInfo } from "./keybackup"; const DEFAULT_ITERATIONS = 500000; const DEFAULT_BITSIZE = 256; -/* eslint-disable camelcase */ -interface IAuthData { - private_key_salt: string; - private_key_iterations: number; - private_key_bits?: number; -} -/* eslint-enable camelcase */ +type IAuthData = IKeyBackupInfo["auth_data"]; interface IKey { key: Uint8Array; diff --git a/src/crypto/keybackup.ts b/src/crypto/keybackup.ts index 123f18f76..d2cb481fa 100644 --- a/src/crypto/keybackup.ts +++ b/src/crypto/keybackup.ts @@ -35,11 +35,13 @@ export interface IKeyBackupRoomSessions { export interface IKeyBackupInfo { algorithm: string; auth_data: { - public_key: string; - signatures: ISignatures; - private_key_salt: string; - private_key_iterations: number; + public_key?: string; + signatures?: ISignatures; + private_key_salt?: string; + private_key_iterations?: number; private_key_bits?: number; + iv?: string; + mac?: string; }; count?: number; etag?: string; From e275301e8b3cff54b6069b01c0cb7695df70e8d3 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 7 Jul 2021 19:50:16 -0400 Subject: [PATCH 048/129] lint --- src/crypto/backup.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index ae87ce706..1ef551547 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -684,13 +684,6 @@ export class Curve25519 implements BackupAlgorithm { } } -// FIXME: this should go into ./aes -interface AesData { - iv: string, - ciphertext: string, - mac: string, -} - function randomBytes(size: number): Uint8Array { const crypto: {randomBytes: (number) => Uint8Array} | undefined = getCrypto() as any; if (crypto) { @@ -721,7 +714,7 @@ export class Aes256 implements BackupAlgorithm { if (!authData) { throw new Error("auth_data missing"); } - const key = await getKey() + const key = await getKey(); if (authData.mac) { const { mac } = await calculateKeyCheck(key, authData.iv); if (authData.mac.replace(/=+$/g, '') !== mac.replace(/=+/g, '')) { From 9f4c5af6653d39ba0566ad7b212a2aa5e412a2aa Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 7 Jul 2021 20:19:23 -0400 Subject: [PATCH 049/129] fix test --- spec/unit/crypto/backup.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index 7f122c2bb..1f2cf8e6c 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -405,7 +405,7 @@ describe("MegolmBackup", function() { resolve(); return Promise.resolve({}); }; - client.crypto._backupManager.backupGroupSession( + client.crypto.backupManager.backupGroupSession( "F0Q2NmyJNgUVj9DGsb4ZQt3aVxhVcUQhg7+gvW0oyKI", groupSession.session_id(), ); From 8bee38367ad41c999acc6744a31131f5e0963467 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 8 Jul 2021 10:14:53 -0400 Subject: [PATCH 050/129] use the MSC number --- src/crypto/backup.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 1ef551547..1ac9a77ac 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -700,7 +700,7 @@ function randomBytes(size: number): Uint8Array { } export class Aes256 implements BackupAlgorithm { - public static algorithmName = "org.matrix.mscxxxx.v1.aes-hmac-sha2"; + public static algorithmName = "org.matrix.msc3270.v1.aes-hmac-sha2"; constructor( public authData: AuthData, From ef8e4d6d350dd71d1fe1147f645a40fe98e1cb78 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 8 Jul 2021 11:19:46 -0400 Subject: [PATCH 051/129] fix the tests that got broken by the last commit --- spec/unit/crypto/backup.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index 1f2cf8e6c..bbd2a6d8e 100644 --- a/spec/unit/crypto/backup.spec.js +++ b/spec/unit/crypto/backup.spec.js @@ -101,7 +101,7 @@ const CURVE25519_BACKUP_INFO = { }; const AES256_BACKUP_INFO = { - algorithm: "org.matrix.mscxxxx.v1.aes-hmac-sha2", + algorithm: "org.matrix.msc3270.v1.aes-hmac-sha2", version: 1, auth_data: { // FIXME: add iv and mac @@ -376,7 +376,7 @@ describe("MegolmBackup", function() { }) .then(() => { client.enableKeyBackup({ - algorithm: "org.matrix.mscxxxx.v1.aes-hmac-sha2", + algorithm: "org.matrix.msc3270.v1.aes-hmac-sha2", version: 1, auth_data: { iv: "PsCAtR7gMc4xBd9YS3A9Ow", From 1a17b138ce29b0fd7cf0aaadab630442453c9946 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 8 Jul 2021 21:12:45 +0100 Subject: [PATCH 052/129] Attempt to fix megolm key not being in SSSS If the account has both a key backup and SSSS enabled but the key backup key isn't stored in SSSS, try to save it there by getting it from either the cache or the user (if perhaps it's the same as their security passphrase but lost a passthrough entry). Fixes https://github.com/vector-im/element-web/issues/17886 --- src/crypto/index.ts | 47 ++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 285a1247b..4b5b5a5b6 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -951,22 +951,39 @@ export class Crypto extends EventEmitter { builder.addSessionBackup(data); } - // Cache the session backup key - const sessionBackupKey = await secretStorage.get('m.megolm_backup.v1'); - if (sessionBackupKey) { - logger.info("Got session backup key from secret storage: caching"); - // fix up the backup key if it's in the wrong format, and replace - // in secret storage - const fixedBackupKey = fixBackupKey(sessionBackupKey); - if (fixedBackupKey) { - await secretStorage.store("m.megolm_backup.v1", - fixedBackupKey, [newKeyId || oldKeyId], - ); + if (this.backupManager.getKeyBackupEnabled()) { + // Cache the session backup key + const sessionBackupKey = await secretStorage.get('m.megolm_backup.v1'); + if (sessionBackupKey) { + logger.info("Got session backup key from secret storage: caching"); + // fix up the backup key if it's in the wrong format, and replace + // in secret storage + const fixedBackupKey = fixBackupKey(sessionBackupKey); + if (fixedBackupKey) { + await secretStorage.store("m.megolm_backup.v1", + fixedBackupKey, [newKeyId || oldKeyId], + ); + } + const decodedBackupKey = new Uint8Array(olmlib.decodeBase64( + fixedBackupKey || sessionBackupKey, + )); + await builder.addSessionBackupPrivateKeyToCache(decodedBackupKey); + } else { + // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in + // the cache or the user can provide one, and if so, write it to SSSS + const backupKey = await this.getSessionBackupPrivateKey() || await getKeyBackupPassphrase(); + if (!backupKey) { + // This will require user intervention to recover from since we don't have the key + // backup key anywhere. It's possible that this is a legacy setup where the SSSS + // master key is the same as the key backup key, but we can't assume that it is: + // we'd have to at least check it against the backup. Alternatively, the user could + // just set up a new key backup and the key for the new backup will be stored. + logger.error("Key backup is enabled but couldn't get key backup key!"); + return; + } + logger.info("Got session backup key from cache/user that wasn't in SSSS: saving to SSSS"); + await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(backupKey)); } - const decodedBackupKey = new Uint8Array(olmlib.decodeBase64( - fixedBackupKey || sessionBackupKey, - )); - await builder.addSessionBackupPrivateKeyToCache(decodedBackupKey); } const operation = builder.buildOperation(); From 964aa6d94a5eb9d05b0980b755eff49fee90c81d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 8 Jul 2021 21:20:34 +0100 Subject: [PATCH 053/129] Update comment --- src/crypto/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 4b5b5a5b6..cad5800ac 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -974,10 +974,9 @@ export class Crypto extends EventEmitter { const backupKey = await this.getSessionBackupPrivateKey() || await getKeyBackupPassphrase(); if (!backupKey) { // This will require user intervention to recover from since we don't have the key - // backup key anywhere. It's possible that this is a legacy setup where the SSSS - // master key is the same as the key backup key, but we can't assume that it is: - // we'd have to at least check it against the backup. Alternatively, the user could - // just set up a new key backup and the key for the new backup will be stored. + // backup key anywhere. The user should probably just set up a new key backup and + // the key for the new backup will be stored. If we hit this scenario in the wild + // with any frequency, we should do more than just log an error. logger.error("Key backup is enabled but couldn't get key backup key!"); return; } From 05a20ab56fd0b27b40a2c365c71084a82959ca53 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 8 Jul 2021 21:30:50 +0100 Subject: [PATCH 054/129] Fix up keys even if key backup isn't enabled Mostly because that's what the test tests, so let's keep that behaviour the same. --- src/crypto/index.ts | 60 ++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index cad5800ac..0c0bd863b 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -951,38 +951,36 @@ export class Crypto extends EventEmitter { builder.addSessionBackup(data); } - if (this.backupManager.getKeyBackupEnabled()) { - // Cache the session backup key - const sessionBackupKey = await secretStorage.get('m.megolm_backup.v1'); - if (sessionBackupKey) { - logger.info("Got session backup key from secret storage: caching"); - // fix up the backup key if it's in the wrong format, and replace - // in secret storage - const fixedBackupKey = fixBackupKey(sessionBackupKey); - if (fixedBackupKey) { - await secretStorage.store("m.megolm_backup.v1", - fixedBackupKey, [newKeyId || oldKeyId], - ); - } - const decodedBackupKey = new Uint8Array(olmlib.decodeBase64( - fixedBackupKey || sessionBackupKey, - )); - await builder.addSessionBackupPrivateKeyToCache(decodedBackupKey); - } else { - // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in - // the cache or the user can provide one, and if so, write it to SSSS - const backupKey = await this.getSessionBackupPrivateKey() || await getKeyBackupPassphrase(); - if (!backupKey) { - // This will require user intervention to recover from since we don't have the key - // backup key anywhere. The user should probably just set up a new key backup and - // the key for the new backup will be stored. If we hit this scenario in the wild - // with any frequency, we should do more than just log an error. - logger.error("Key backup is enabled but couldn't get key backup key!"); - return; - } - logger.info("Got session backup key from cache/user that wasn't in SSSS: saving to SSSS"); - await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(backupKey)); + // Cache the session backup key + const sessionBackupKey = await secretStorage.get('m.megolm_backup.v1'); + if (sessionBackupKey) { + logger.info("Got session backup key from secret storage: caching"); + // fix up the backup key if it's in the wrong format, and replace + // in secret storage + const fixedBackupKey = fixBackupKey(sessionBackupKey); + if (fixedBackupKey) { + await secretStorage.store("m.megolm_backup.v1", + fixedBackupKey, [newKeyId || oldKeyId], + ); } + const decodedBackupKey = new Uint8Array(olmlib.decodeBase64( + fixedBackupKey || sessionBackupKey, + )); + await builder.addSessionBackupPrivateKeyToCache(decodedBackupKey); + } else if (this.backupManager.getKeyBackupEnabled()) { + // key backup is enabled but we don't have a session backup key in SSSS: see if we have one in + // the cache or the user can provide one, and if so, write it to SSSS + const backupKey = await this.getSessionBackupPrivateKey() || await getKeyBackupPassphrase(); + if (!backupKey) { + // This will require user intervention to recover from since we don't have the key + // backup key anywhere. The user should probably just set up a new key backup and + // the key for the new backup will be stored. If we hit this scenario in the wild + // with any frequency, we should do more than just log an error. + logger.error("Key backup is enabled but couldn't get key backup key!"); + return; + } + logger.info("Got session backup key from cache/user that wasn't in SSSS: saving to SSSS"); + await secretStorage.store("m.megolm_backup.v1", olmlib.encodeBase64(backupKey)); } const operation = builder.buildOperation(); From ac02f30dc8386504b63c4183ddfc9e469c5df840 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 8 Jul 2021 18:10:37 -0400 Subject: [PATCH 055/129] improve types --- src/@types/signed.ts | 4 ++++ src/crypto/backup.ts | 45 +++++++++++++++++++++--------------- src/crypto/key_passphrase.ts | 9 ++++++-- src/crypto/keybackup.ts | 26 +++++++++++++-------- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/@types/signed.ts b/src/@types/signed.ts index 4c39825cc..a209f3781 100644 --- a/src/@types/signed.ts +++ b/src/@types/signed.ts @@ -19,3 +19,7 @@ export interface ISignatures { [keyId: string]: string; }; } + +export interface ISigned { + signatures?: ISignatures; +} diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 1ac9a77ac..d9719a05d 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -31,7 +31,8 @@ import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { encodeRecoveryKey } from './recoverykey'; import { encryptAES, decryptAES, calculateKeyCheck } from './aes'; import { getCrypto } from '../utils'; -import { IKeyBackupInfo } from "./keybackup"; +import { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo } from "./keybackup"; +import { UnstableValue } from "../NamespacedValue"; const KEY_BACKUP_KEYS_PER_REQUEST = 200; @@ -302,7 +303,7 @@ export class BackupManager { const trustedPubkey = this.baseApis.crypto.sessionStore.getLocalTrustedBackupPubKey(); - if (backupInfo.auth_data.public_key === trustedPubkey) { + if ("public_key" in backupInfo.auth_data && backupInfo.auth_data.public_key === trustedPubkey) { logger.info("Backup public key " + trustedPubkey + " is trusted locally"); ret.trusted_locally = true; } @@ -572,23 +573,26 @@ export class BackupManager { export class Curve25519 implements BackupAlgorithm { public static algorithmName = "m.megolm_backup.v1.curve25519-aes-sha2"; + public authData: ICurve25519AuthData; constructor( - public authData: AuthData, + authData: AuthData, private publicKey: any, // FIXME: PkEncryption private getKey: () => Promise, - ) {} + ) { + this.authData = authData as ICurve25519AuthData; + } public static async init( authData: AuthData, getKey: () => Promise, ): Promise { - if (!authData || !authData.public_key) { + if (!authData || !("public_key" in authData)) { throw new Error("auth_data missing required information"); } const publicKey = new global.Olm.PkEncryption(); publicKey.set_recipient_key(authData.public_key); - return new Curve25519(authData, publicKey, getKey); + return new Curve25519(authData as ICurve25519AuthData, publicKey, getKey); } public static async prepare( @@ -596,7 +600,7 @@ export class Curve25519 implements BackupAlgorithm { ): Promise<[Uint8Array, AuthData]> { const decryption = new global.Olm.PkDecryption(); try { - const authData: Partial = {}; + const authData: Partial = {}; if (!key) { authData.public_key = decryption.generate_key(); } else if (key instanceof Uint8Array) { @@ -620,7 +624,7 @@ export class Curve25519 implements BackupAlgorithm { } public static checkBackupVersion(info: IKeyBackupInfo): void { - if (!info.auth_data.public_key) { + if (!("public_key" in info.auth_data)) { throw new Error("Invalid backup data returned"); } } @@ -685,12 +689,12 @@ export class Curve25519 implements BackupAlgorithm { } function randomBytes(size: number): Uint8Array { - const crypto: {randomBytes: (number) => Uint8Array} | undefined = getCrypto() as any; + const crypto: {randomBytes: (n: number) => Uint8Array} | undefined = getCrypto() as any; if (crypto) { // nodejs version return crypto.randomBytes(size); } - if (typeof window !== "undefined" && window.crypto) { + if (window?.crypto) { // browser version const buf = new Uint8Array(size); window.crypto.getRandomValues(buf); @@ -699,16 +703,21 @@ function randomBytes(size: number): Uint8Array { throw new Error("No usable crypto implementation"); } +const UNSTABLE_MSC3270_NAME = new UnstableValue(null, "org.matrix.msc3270.v1.aes-hmac-sha2"); + export class Aes256 implements BackupAlgorithm { - public static algorithmName = "org.matrix.msc3270.v1.aes-hmac-sha2"; + public static algorithmName = UNSTABLE_MSC3270_NAME.name; + public readonly authData: IAes256AuthData; constructor( - public authData: AuthData, - private key: Uint8Array, - ) {} + authData: AuthData, + private readonly key: Uint8Array, + ) { + this.authData = authData as IAes256AuthData; + } public static async init( - authData: AuthData, + authData: IAes256AuthData, getKey: () => Promise, ): Promise { if (!authData) { @@ -728,7 +737,7 @@ export class Aes256 implements BackupAlgorithm { key: string | Uint8Array | null, ): Promise<[Uint8Array, AuthData]> { let outKey: Uint8Array; - const authData: AuthData = {}; + const authData: Partial = {}; if (!key) { outKey = randomBytes(32); } else if (key instanceof Uint8Array) { @@ -744,11 +753,11 @@ export class Aes256 implements BackupAlgorithm { authData.iv = iv; authData.mac = mac; - return [outKey, authData]; + return [outKey, authData as AuthData]; } public static checkBackupVersion(info: IKeyBackupInfo): void { - if (!info.auth_data.iv || !info.auth_data.mac) { + if (!("iv" in info.auth_data && "mac" in info.auth_data)) { throw new Error("Invalid backup data returned"); } } diff --git a/src/crypto/key_passphrase.ts b/src/crypto/key_passphrase.ts index 89aefc803..474031160 100644 --- a/src/crypto/key_passphrase.ts +++ b/src/crypto/key_passphrase.ts @@ -15,13 +15,18 @@ limitations under the License. */ import { randomString } from '../randomstring'; -import { IKeyBackupInfo } from "./keybackup"; const DEFAULT_ITERATIONS = 500000; const DEFAULT_BITSIZE = 256; -type IAuthData = IKeyBackupInfo["auth_data"]; +/* eslint-disable camelcase */ +interface IAuthData { + private_key_salt?: string; + private_key_iterations?: number; + private_key_bits?: number; +} +/* eslint-enable camelcase */ interface IKey { key: Uint8Array; diff --git a/src/crypto/keybackup.ts b/src/crypto/keybackup.ts index d2cb481fa..13c5621b9 100644 --- a/src/crypto/keybackup.ts +++ b/src/crypto/keybackup.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { ISignatures } from "../@types/signed"; +import { ISigned } from "../@types/signed"; export interface IKeyBackupSession { first_message_index: number; // eslint-disable-line camelcase @@ -32,17 +32,23 @@ export interface IKeyBackupRoomSessions { } /* eslint-disable camelcase */ +export interface ICurve25519AuthData { + public_key: string; + private_key_salt?: string; + private_key_iterations?: number; + private_key_bits?: number; +} + +export interface IAes256AuthData { + iv: string; + mac: string; + private_key_salt?: string; + private_key_iterations?: number; +} + export interface IKeyBackupInfo { algorithm: string; - auth_data: { - public_key?: string; - signatures?: ISignatures; - private_key_salt?: string; - private_key_iterations?: number; - private_key_bits?: number; - iv?: string; - mac?: string; - }; + auth_data: ISigned & (ICurve25519AuthData | IAes256AuthData); count?: number; etag?: string; version?: string; // number contained within From d639a29501ae0f54b275bdd71a712e79a03fe6f7 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 8 Jul 2021 18:47:22 -0400 Subject: [PATCH 056/129] more type improvements --- src/crypto/backup.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index d9719a05d..abe30798e 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -573,15 +573,12 @@ export class BackupManager { export class Curve25519 implements BackupAlgorithm { public static algorithmName = "m.megolm_backup.v1.curve25519-aes-sha2"; - public authData: ICurve25519AuthData; constructor( - authData: AuthData, + public authData: ICurve25519AuthData, private publicKey: any, // FIXME: PkEncryption private getKey: () => Promise, - ) { - this.authData = authData as ICurve25519AuthData; - } + ) {} public static async init( authData: AuthData, @@ -707,14 +704,11 @@ const UNSTABLE_MSC3270_NAME = new UnstableValue(null, "org.matrix.msc3270.v1.aes export class Aes256 implements BackupAlgorithm { public static algorithmName = UNSTABLE_MSC3270_NAME.name; - public readonly authData: IAes256AuthData; constructor( - authData: AuthData, + public readonly authData: IAes256AuthData, private readonly key: Uint8Array, - ) { - this.authData = authData as IAes256AuthData; - } + ) {} public static async init( authData: IAes256AuthData, From 96e6e7b1e82b002d7d70bc0d14780b23550eab44 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Fri, 9 Jul 2021 16:44:39 +0200 Subject: [PATCH 057/129] Update event.ts --- src/@types/event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/@types/event.ts b/src/@types/event.ts index 0c8d81da8..32aa8cf8f 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -149,7 +149,7 @@ export const UNSTABLE_MSC3089_BRANCH = new UnstableValue("m.branch", "org.matrix * Note that this reference is UNSTABLE and subject to breaking changes, including its * eventual removal. */ -export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue("io.element.functional_members"); +export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue("io.element.functional_members", "io.element.functional_members"); export interface IEncryptedFile { url: string; From 116085e92745a8fb005e30ec64a6aa5a4182016f Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Sat, 10 Jul 2021 03:08:51 +0200 Subject: [PATCH 058/129] Fix linter error --- src/@types/event.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/@types/event.ts b/src/@types/event.ts index 32aa8cf8f..2c6a47928 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -149,7 +149,9 @@ export const UNSTABLE_MSC3089_BRANCH = new UnstableValue("m.branch", "org.matrix * Note that this reference is UNSTABLE and subject to breaking changes, including its * eventual removal. */ -export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue("io.element.functional_members", "io.element.functional_members"); +export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue( + "io.element.functional_members", + "io.element.functional_members"); export interface IEncryptedFile { url: string; From d7e6cee19c6249f38f4a6fe2bd1ac93142d0257b Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Sat, 10 Jul 2021 03:44:03 +0200 Subject: [PATCH 059/129] Update room.ts --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index 744169b01..70ce826e2 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2041,7 +2041,7 @@ export class Room extends EventEmitter { // get service members (e.g. helper bots) for exclusion let excludedUserIds: string[] = []; - const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS, ""); + const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.unstable, ""); if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { excludedUserIds = mFunctionalMembers.getContent().service_members; } From 17efcad6fe393304228f3746eca3009e77e4f39a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Jul 2021 15:43:47 +0100 Subject: [PATCH 060/129] Improve and consolidate typing --- src/@types/partials.ts | 7 + src/@types/requests.ts | 29 +- src/@types/search.ts | 118 +++++ src/@types/spaces.ts | 40 ++ src/@types/synapse.ts | 40 ++ src/client.ts | 921 ++++++++++++++++++++------------- src/content-helpers.ts | 14 +- src/crypto/EncryptionSetup.ts | 7 +- src/crypto/RoomList.ts | 6 +- src/crypto/SecretStorage.ts | 10 +- src/crypto/algorithms/base.ts | 3 +- src/crypto/backup.ts | 37 +- src/crypto/dehydration.ts | 10 +- src/crypto/index.ts | 41 +- src/crypto/keybackup.ts | 1 + src/crypto/olmlib.ts | 6 +- src/filter.ts | 4 +- src/models/MSC3089Branch.ts | 4 +- src/models/MSC3089TreeSpace.ts | 6 +- src/models/room.ts | 9 +- src/models/search-result.js | 60 --- src/models/search-result.ts | 60 +++ src/store/index.ts | 11 +- src/store/memory.ts | 2 +- src/store/stub.ts | 3 +- src/sync.ts | 2 +- 26 files changed, 953 insertions(+), 498 deletions(-) create mode 100644 src/@types/search.ts create mode 100644 src/@types/spaces.ts create mode 100644 src/@types/synapse.ts delete mode 100644 src/models/search-result.js create mode 100644 src/models/search-result.ts diff --git a/src/@types/partials.ts b/src/@types/partials.ts index ecdc6525a..0d82c0bc0 100644 --- a/src/@types/partials.ts +++ b/src/@types/partials.ts @@ -39,3 +39,10 @@ export enum Preset { } export type ResizeMethod = "crop" | "scale"; + +// TODO move to http-api after TSification +export interface IAbortablePromise extends Promise { + abort(): void; +} + +export type IdServerUnbindResult = "no-support" | "success"; diff --git a/src/@types/requests.ts b/src/@types/requests.ts index eaf682831..e31618193 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -16,6 +16,8 @@ limitations under the License. import { Callback } from "../client"; import { Preset, Visibility } from "./partials"; +import { SearchKey } from "./search"; +import { IRoomEventFilter } from "../filter"; // allow camelcase as these are things go onto the wire /* eslint-disable camelcase */ @@ -63,12 +65,12 @@ export interface IGuestAccessOpts { } export interface ISearchOpts { - keys?: string[]; + keys?: SearchKey[]; query: string; } export interface IEventSearchOpts { - filter: any; // TODO: Types + filter?: IRoomEventFilter; term: string; } @@ -104,9 +106,11 @@ export interface IRoomDirectoryOptions { server?: string; limit?: number; since?: string; - - // TODO: Proper types - filter?: any & {generic_search_term: string}; + filter?: { + generic_search_term: string; + }; + include_all_networks?: boolean; + third_party_instance_id?: string; } export interface IUploadOpts { @@ -119,4 +123,19 @@ export interface IUploadOpts { progressHandler?: (state: {loaded: number, total: number}) => void; } +export interface IAddThreePidOnlyBody { + auth?: { + type: string; + session?: string; + }; + client_secret: string; + sid: string; +} + +export interface IBindThreePidBody { + client_secret: string; + id_server: string; + id_access_token: string; + sid: string; +} /* eslint-enable camelcase */ diff --git a/src/@types/search.ts b/src/@types/search.ts new file mode 100644 index 000000000..f1af733cd --- /dev/null +++ b/src/@types/search.ts @@ -0,0 +1,118 @@ +/* +Copyright 2021 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. +*/ + +// Types relating to the /search API + +import { IRoomEvent, IStateEvent } from "../sync-accumulator"; +import { IRoomEventFilter } from "../filter"; +import { SearchResult } from "../models/search-result"; + +/* eslint-disable camelcase */ +export interface IEventWithRoomId extends IRoomEvent { + room_id: string; +} + +export interface IStateEventWithRoomId extends IStateEvent { + room_id: string; +} + +export interface IMatrixProfile { + avatar_url?: string; + displayname?: string; +} + +export interface IResultContext { + events_before: IEventWithRoomId[]; + events_after: IEventWithRoomId[]; + profile_info: Record; + start?: string; + end?: string; +} + +export interface ISearchResult { + rank: number; + result: IEventWithRoomId; + context: IResultContext; +} + +enum GroupKey { + RoomId = "room_id", + Sender = "sender", +} + +export interface IResultRoomEvents { + count: number; + highlights: string[]; + results: ISearchResult[]; + state?: { [roomId: string]: IStateEventWithRoomId[] }; + groups?: { + [groupKey in GroupKey]: { + [value: string]: { + next_batch?: string; + order: number; + results: string[]; + } + }; + } + next_batch?: string; +} + +interface IResultCategories { + room_events: IResultRoomEvents; +} + +export type SearchKey = "content.body" | "content.name" | "content.topic"; + +export enum SearchOrderBy { + Recent = "recent", + Rank = "rank", +} + +export interface ISearchRequestBody { + search_categories: { + room_events: { + search_term: string; + keys?: SearchKey[]; + filter?: IRoomEventFilter; + order_by?: SearchOrderBy; + event_context?: { + before_limit?: number; + after_limit?: number; + include_profile?: boolean; + }; + include_state?: boolean; + groupings?: { + group_by: { + key: GroupKey; + }[]; + } + }; + }; +} + +export interface ISearchResponse { + search_categories: IResultCategories; +} + +export interface ISearchResults { + _query?: ISearchRequestBody; + results: SearchResult[]; + highlights: string[]; + count?: number; + next_batch?: string; + pendingRequest?: Promise; +} +/* eslint-enable camelcase */ diff --git a/src/@types/spaces.ts b/src/@types/spaces.ts new file mode 100644 index 000000000..17e677d44 --- /dev/null +++ b/src/@types/spaces.ts @@ -0,0 +1,40 @@ +/* +Copyright 2021 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 { IPublicRoomsChunk } from "../client"; + +// Types relating to Rooms of type `m.space` and related APIs + +/* eslint-disable camelcase */ +export interface ISpaceSummaryRoom extends IPublicRoomsChunk { + num_refs: number; + room_type: string; +} + +export interface ISpaceSummaryEvent { + room_id: string; + event_id: string; + origin_server_ts: number; + type: string; + state_key: string; + content: { + order?: string; + suggested?: boolean; + auto_join?: boolean; + via?: string[]; + }; +} +/* eslint-enable camelcase */ diff --git a/src/@types/synapse.ts b/src/@types/synapse.ts new file mode 100644 index 000000000..1d4ce41ac --- /dev/null +++ b/src/@types/synapse.ts @@ -0,0 +1,40 @@ +/* +Copyright 2021 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 { IdServerUnbindResult } from "./partials"; + +// Types relating to Synapse Admin APIs + +/* eslint-disable camelcase */ +export interface ISynapseAdminWhoisResponse { + user_id: string; + devices: { + [deviceId: string]: { + sessions: { + connections: { + ip: string; + last_seen: number; // millis since epoch + user_agent: string; + }[]; + }[]; + }; + }; +} + +export interface ISynapseAdminDeactivateResponse { + id_server_unbind_result: IdServerUnbindResult; +} +/* eslint-enable camelcase */ diff --git a/src/client.ts b/src/client.ts index e5424224c..516a3b0dd 100644 --- a/src/client.ts +++ b/src/client.ts @@ -20,22 +20,22 @@ limitations under the License. */ import { EventEmitter } from "events"; -import { SyncApi } from "./sync"; -import { EventStatus, IDecryptOptions, MatrixEvent } from "./models/event"; +import { ISyncStateData, SyncApi } from "./sync"; +import { EventStatus, IContent, IDecryptOptions, MatrixEvent } from "./models/event"; import { StubStore } from "./store/stub"; import { createNewMatrixCall, MatrixCall } from "./webrtc/call"; -import { Filter } from "./filter"; +import { Filter, IFilterDefinition } from "./filter"; import { CallEventHandler } from './webrtc/callEventHandler'; import * as utils from './utils'; import { sleep } from './utils'; import { Group } from "./models/group"; -import { EventTimeline } from "./models/event-timeline"; +import { Direction, EventTimeline } from "./models/event-timeline"; import { PushAction, PushProcessor } from "./pushprocessor"; import { AutoDiscovery } from "./autodiscovery"; import * as olmlib from "./crypto/olmlib"; import { decodeBase64, encodeBase64 } from "./crypto/olmlib"; import { ReEmitter } from './ReEmitter'; -import { RoomList } from './crypto/RoomList'; +import { IRoomEncryption, RoomList } from './crypto/RoomList'; import { logger } from './logger'; import { SERVICE_TYPES } from './service-types'; import { @@ -47,36 +47,39 @@ import { PREFIX_UNSTABLE, retryNetworkOperation, } from "./http-api"; -import { Crypto, fixBackupKey, IBootstrapCrossSigningOpts, IMegolmSessionData, isCryptoAvailable } from './crypto'; +import { + Crypto, + fixBackupKey, + IBootstrapCrossSigningOpts, + ICheckOwnCrossSigningTrustOpts, + IMegolmSessionData, + isCryptoAvailable, + VerificationMethod, +} from './crypto'; import { DeviceInfo, IDevice } from "./crypto/deviceinfo"; import { decodeRecoveryKey } from './crypto/recoverykey'; import { keyFromAuthData } from './crypto/key_passphrase'; import { User } from "./models/user"; import { getHttpUriForMxc } from "./content-repo"; import { SearchResult } from "./models/search-result"; -import { DEHYDRATION_ALGORITHM, IDehydratedDevice, IDehydratedDeviceKeyInfo } from "./crypto/dehydration"; import { + DEHYDRATION_ALGORITHM, + IDehydratedDevice, + IDehydratedDeviceKeyInfo, + IDeviceKeys, + IOneTimeKey, +} from "./crypto/dehydration"; +import { + IKeyBackupInfo, IKeyBackupPrepareOpts, IKeyBackupRestoreOpts, IKeyBackupRestoreResult, - IKeyBackupInfo, + IKeyBackupSession, } from "./crypto/keybackup"; import { IIdentityServerProvider } from "./@types/IIdentityServerProvider"; import type Request from "request"; import { MatrixScheduler } from "./scheduler"; -import { ICryptoCallbacks, NotificationCountType } from "./matrix"; -import { ISecretStorageKeyInfo } from "./crypto/api"; -import { MemoryCryptoStore } from "./crypto/store/memory-crypto-store"; -import { LocalStorageCryptoStore } from "./crypto/store/localStorage-crypto-store"; -import { IndexedDBCryptoStore } from "./crypto/store/indexeddb-crypto-store"; -import { MemoryStore } from "./store/memory"; -import { LocalIndexedDBStoreBackend } from "./store/indexeddb-local-backend"; -import { RemoteIndexedDBStoreBackend } from "./store/indexeddb-remote-backend"; -import { SyncState } from "./sync.api"; -import { EventTimelineSet } from "./models/event-timeline-set"; -import { VerificationRequest } from "./crypto/verification/request/VerificationRequest"; -import { Base as Verification } from "./crypto/verification/Base"; -import * as ContentHelpers from "./content-helpers"; +import { ICryptoCallbacks, IMinimalEvent, IRoomEvent, IStateEvent, NotificationCountType } from "./matrix"; import { CrossSigningKey, IAddSecretStorageKeyOpts, @@ -84,10 +87,21 @@ import { IEncryptedEventInfo, IImportRoomKeysOpts, IRecoveryKey, + ISecretStorageKeyInfo, } from "./crypto/api"; -import { CrossSigningInfo, DeviceTrustLevel, UserTrustLevel } from "./crypto/CrossSigning"; +import { MemoryCryptoStore } from "./crypto/store/memory-crypto-store"; +import { LocalStorageCryptoStore } from "./crypto/store/localStorage-crypto-store"; +import { IndexedDBCryptoStore } from "./crypto/store/indexeddb-crypto-store"; +import { SyncState } from "./sync.api"; +import { EventTimelineSet } from "./models/event-timeline-set"; +import { VerificationRequest } from "./crypto/verification/request/VerificationRequest"; +import { Base as Verification } from "./crypto/verification/Base"; +import * as ContentHelpers from "./content-helpers"; +import { CrossSigningInfo, DeviceTrustLevel, ICacheCallbacks, UserTrustLevel } from "./crypto/CrossSigning"; import { Room } from "./models/room"; import { + IAddThreePidOnlyBody, + IBindThreePidBody, ICreateRoomOpts, IEventSearchOpts, IGuestAccessOpts, @@ -102,23 +116,37 @@ import { } from "./@types/requests"; import { EventType, + MsgType, + RelationType, RoomCreateTypeField, RoomType, UNSTABLE_MSC3088_ENABLED, UNSTABLE_MSC3088_PURPOSE, UNSTABLE_MSC3089_TREE_SUBTYPE, } from "./@types/event"; -import { IImageInfo, Preset } from "./@types/partials"; +import { IAbortablePromise, IdServerUnbindResult, IImageInfo, Preset, Visibility } from "./@types/partials"; import { EventMapper, eventMapperFor, MapperOpts } from "./event-mapper"; import url from "url"; import { randomString } from "./randomstring"; import { ReadStream } from "fs"; import { WebStorageSessionStore } from "./store/session/webstorage"; -import { BackupManager, IKeyBackupCheck, IPreparedKeyBackupVersion, TrustInfo } from "./crypto/backup"; +import { BackupManager, IKeyBackup, IKeyBackupCheck, IPreparedKeyBackupVersion, TrustInfo } from "./crypto/backup"; import { DEFAULT_TREE_POWER_LEVELS_TEMPLATE, MSC3089TreeSpace } from "./models/MSC3089TreeSpace"; import { ISignatures } from "./@types/signed"; +import { IStore } from "./store"; +import { ISecretRequest } from "./crypto/SecretStorage"; +import { + IEventWithRoomId, + ISearchRequestBody, + ISearchResponse, + ISearchResults, + IStateEventWithRoomId, + SearchOrderBy, +} from "./@types/search"; +import { ISynapseAdminDeactivateResponse, ISynapseAdminWhoisResponse } from "./@types/synapse"; +import { ISpaceSummaryEvent, ISpaceSummaryRoom } from "./@types/spaces"; -export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; +export type Store = IStore; export type SessionStore = WebStorageSessionStore; export type CryptoStore = MemoryCryptoStore | LocalStorageCryptoStore | IndexedDBCryptoStore; @@ -132,7 +160,7 @@ const TURN_CHECK_INTERVAL = 10 * 60 * 1000; // poll for turn credentials every 1 interface IOlmDevice { pickledAccount: string; - sessions: Array>; + sessions: Array>; pickleKey: string; } @@ -261,7 +289,7 @@ export interface ICreateClientOpts { */ unstableClientRelationAggregation?: boolean; - verificationMethods?: Array; + verificationMethods?: Array; /** * Whether relaying calls through a TURN server should be forced. Default false. @@ -404,7 +432,6 @@ export interface ISignedKey { algorithms: string[]; device_id: string; } -/* eslint-enable camelcase */ export type KeySignatures = Record>; interface IUploadKeySignaturesResponse { @@ -427,6 +454,233 @@ export interface IPreviewUrlResponse { "matrix:image:size"?: number; } +interface ITurnServerResponse { + uris: string[]; + username: string; + password: string; + ttl: number; +} + +interface ITurnServer { + urls: string[]; + username: string; + credential: string; +} + +interface IServerVersions { + versions: string; + unstable_features: Record; +} + +interface IClientWellKnown { + [key: string]: any; + "m.homeserver": { + base_url: string; + }; + "m.identity_server"?: { + base_url: string; + }; +} + +interface IKeyBackupPath { + path: string; + queryData?: { + version: string; + }; +} + +interface IMediaConfig { + "m.upload.size"?: number; +} + +interface IThirdPartySigned { + sender: string; + mxid: string; + token: string; + signatures: ISignatures; +} + +interface IJoinRequestBody { + third_party_signed?: IThirdPartySigned; +} + +interface ITagMetadata { + [key: string]: any; + order: number; +} + +interface IMessagesResponse { + start: string; + end: string; + chunk: IRoomEvent[]; + state: IStateEvent[]; +} + +interface IRequestTokenResponse { + sid: string; + submit_url?: string; +} + +interface IRequestMsisdnTokenResponse extends IRequestTokenResponse { + msisdn: string; + success: boolean; + intl_fmt: string; +} + +interface IUploadKeysRequest { + device_keys?: Required; + one_time_keys?: { + [userId: string]: { + [deviceId: string]: number; + }; + }; + "org.matrix.msc2732.fallback_keys"?: Record; +} + +interface IOpenIDToken { + access_token: string; + token_type: "Bearer" | string; + matrix_server_name: string; + expires_in: number; +} + +interface IRoomInitialSyncResponse { + room_id: string; + membership: "invite" | "join" | "leave" | "ban", + messages?: { + start?: string; + end?: string; + chunk: IEventWithRoomId[]; + }; + state?: IStateEventWithRoomId[]; + visibility: Visibility; + account_data?: IMinimalEvent[]; + presence: any; // undocumented +} + +interface IJoinedMembersResponse { + joined: { + [userId: string]: { + display_name: string; + avatar_url: string; + }; + }; +} + +export interface IPublicRoomsChunk { + room_id: string; + name?: string; + avatar_url?: string; + topic?: string; + canonical_alias?: string; + aliases?: string[]; + world_readable: boolean; + guest_can_join: boolean; + num_joined_members: number; +} + +interface IPublicRoomsResponse { + chunk: IPublicRoomsChunk[]; + next_batch?: string; + prev_batch?: string; + total_room_count_estimate?: number; +} + +interface IUserDirectoryResponse { + results: { + user_id: string; + display_name?: string; + avatar_url?: string; + }[]; + limited: boolean; +} + +interface IThreepid { + medium: "email" | "msisdn"; + address: string; + validated_at: number; + added_at: number; +} + +interface IMyDevice { + device_id: string; + display_name?: string; + last_seen_ip?: string; + last_seen_ts?: number; +} + +interface IPusher { + pushkey: string; + kind: string; + app_id: string; + app_display_name: string; + device_display_name: string; + profile_tag?: string; + lang: string; + data: { + url?: string; + format?: string; + brand?: string; // undocumented + }; +} + +interface IDownloadKeyResult { + failures: { [serverName: string]: object }; + device_keys: { + [userId: string]: { + [deviceId: string]: IDeviceKeys & { + unsigned?: { + device_display_name: string; + }; + }; + } + }; +} + +interface IClaimOTKsResult { + failures: { [serverName: string]: object }; + one_time_keys: { + [userId: string]: { + [deviceId: string]: string; + }; + }; +} + +export interface IFieldType { + regexp: string; + placeholder: string; +} + +export interface IInstance { + desc: string; + icon?: string; + fields: object; + network_id: string; + // XXX: this is undocumented but we rely on it. + instance_id: string; +} + +export interface IProtocol { + user_fields: string[]; + location_fields: string[]; + icon: string; + field_types: Record; + instances: IInstance[]; +} + +interface IThirdPartyLocation { + alias: string; + protocol: string; + fields: object; +} + +interface IThirdPartyUser { + userid: string; + protocol: string; + fields: object; +} +/* eslint-enable camelcase */ + /** * Represents a Matrix Client. Only directly construct this if you want to use * custom modules. Normally, {@link createClient} should be used @@ -445,7 +699,7 @@ export class MatrixClient extends EventEmitter { public scheduler: MatrixScheduler; public clientRunning = false; public timelineSupport = false; - public urlPreviewCache: { [key: string]: Promise } = {}; // TODO: Types + public urlPreviewCache: { [key: string]: Promise } = {}; public unstableClientRelationAggregation = false; public identityServer: IIdentityServerProvider; public sessionStore: SessionStore; // XXX: Intended private, used in code. @@ -465,10 +719,10 @@ export class MatrixClient extends EventEmitter { protected canSupportVoip = false; protected peekSync: SyncApi = null; protected isGuestAccount = false; - protected ongoingScrollbacks: {[roomId: string]: {promise?: Promise, errorTs?: number}} = {}; // TODO: Types + protected ongoingScrollbacks: {[roomId: string]: {promise?: Promise, errorTs?: number}} = {}; protected notifTimelineSet: EventTimelineSet = null; protected cryptoStore: CryptoStore; - protected verificationMethods: string[]; + protected verificationMethods: VerificationMethod[]; protected fallbackICEServerAllowed = false; protected roomList: RoomList; protected syncApi: SyncApi; @@ -476,7 +730,7 @@ export class MatrixClient extends EventEmitter { protected syncLeftRoomsPromise: Promise; protected syncedLeftRooms = false; protected clientOpts: IStoredClientOpts; - protected clientWellKnownIntervalID: number; + protected clientWellKnownIntervalID: NodeJS.Timeout; protected canResetTimelineCallback: ResetTimelineCallback; // The pushprocessor caches useful things, so keep one and re-use it @@ -484,17 +738,17 @@ export class MatrixClient extends EventEmitter { // Promise to a response of the server's /versions response // TODO: This should expire: https://github.com/matrix-org/matrix-js-sdk/issues/1020 - protected serverVersionsPromise: Promise; + protected serverVersionsPromise: Promise; protected cachedCapabilities: { capabilities: ICapabilities; expiration: number; }; - protected clientWellKnown: any; - protected clientWellKnownPromise: Promise; - protected turnServers: any[] = []; // TODO: Types + protected clientWellKnown: IClientWellKnown; + protected clientWellKnownPromise: Promise; + protected turnServers: ITurnServer[] = []; protected turnServersExpiry = 0; - protected checkTurnServersIntervalID: number; + protected checkTurnServersIntervalID: NodeJS.Timeout; protected exportedOlmDeviceToImport: IOlmDevice; protected txnCtr = 0; @@ -714,7 +968,7 @@ export class MatrixClient extends EventEmitter { if (this.canSupportVoip) { this.checkTurnServersIntervalID = setInterval(() => { this.checkTurnServers(); - }, TURN_CHECK_INTERVAL) as any as number; // XXX: Typecast because we know better + }, TURN_CHECK_INTERVAL); // noinspection ES6MissingAwait this.checkTurnServers(); } @@ -726,7 +980,7 @@ export class MatrixClient extends EventEmitter { } // shallow-copy the opts dict before modifying and storing it - this.clientOpts = Object.assign({}, opts); // XXX: Typecast because we're about to add the missing props + this.clientOpts = Object.assign({}, opts) as IStoredClientOpts; this.clientOpts.crypto = this.crypto; this.clientOpts.canResetEntireTimeline = (roomId) => { if (!this.canResetTimelineCallback) { @@ -738,11 +992,9 @@ export class MatrixClient extends EventEmitter { this.syncApi.sync(); if (this.clientOpts.clientWellKnownPollPeriod !== undefined) { - this.clientWellKnownIntervalID = - // XXX: Typecast on timer ID because we know better - setInterval(() => { - this.fetchClientWellKnown(); - }, 1000 * this.clientOpts.clientWellKnownPollPeriod) as any as number; + this.clientWellKnownIntervalID = setInterval(() => { + this.fetchClientWellKnown(); + }, 1000 * this.clientOpts.clientWellKnownPollPeriod); this.fetchClientWellKnown(); } } @@ -1055,7 +1307,7 @@ export class MatrixClient extends EventEmitter { * this object. * @return {?Object} */ - public getSyncStateData(): any { // TODO: Unify types. + public getSyncStateData(): ISyncStateData | null { if (!this.syncApi) { return null; } @@ -1505,7 +1757,7 @@ export class MatrixClient extends EventEmitter { return this.crypto.beginKeyVerification(method, userId, deviceId); } - public checkSecretStorageKey(key: any, info: any): Promise { // TODO: Types + public checkSecretStorageKey(key: Uint8Array, info: ISecretStorageKeyInfo): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -1635,9 +1887,9 @@ export class MatrixClient extends EventEmitter { /** * Check the copy of our cross-signing key that we have in the device list and * see if we can get the private key. If so, mark it as trusted. - * @param {Object} opts TODO + * @param {Object} opts ICheckOwnCrossSigningTrustOpts object */ - public checkOwnCrossSigningTrust(opts?: any): Promise { // TODO: Types + public checkOwnCrossSigningTrust(opts?: ICheckOwnCrossSigningTrustOpts): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -1659,7 +1911,11 @@ export class MatrixClient extends EventEmitter { return this.crypto.checkCrossSigningPrivateKey(privateKey, expectedPublicKey); } - public legacyDeviceVerification(userId: string, deviceId: string, method: string): Promise { + public legacyDeviceVerification( + userId: string, + deviceId: string, + method: VerificationMethod, + ): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -1942,9 +2198,9 @@ export class MatrixClient extends EventEmitter { * @param {string} name the name of the secret to request * @param {string[]} devices the devices to request the secret from * - * @return {string} the contents of the secret + * @return {ISecretRequest} the secret request object */ - public requestSecret(name: string, devices: string[]): any { // TODO types + public requestSecret(name: string, devices: string[]): ISecretRequest { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -2045,7 +2301,7 @@ export class MatrixClient extends EventEmitter { * @param {object} config The encryption config for the room. * @return {Promise} A promise that will resolve when encryption is set up. */ - public setRoomEncryption(roomId: string, config: any): Promise { + public setRoomEncryption(roomId: string, config: IRoomEncryption): Promise { if (!this.crypto) { throw new Error("End-to-End encryption disabled"); } @@ -2067,7 +2323,7 @@ export class MatrixClient extends EventEmitter { // if there is an 'm.room.encryption' event in this room, it should be // encrypted (independently of whether we actually support encryption) - const ev = room.currentState.getStateEvents("m.room.encryption", ""); + const ev = room.currentState.getStateEvents(EventType.RoomEncryption, ""); if (ev) { return true; } @@ -2101,7 +2357,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} a promise which resolves to a list of * session export objects */ - public exportRoomKeys(): Promise { // TODO: Types + public exportRoomKeys(): Promise { if (!this.crypto) { return Promise.reject(new Error("End-to-end encryption disabled")); } @@ -2342,7 +2598,7 @@ export class MatrixClient extends EventEmitter { ); } - private makeKeyBackupPath(roomId: string, sessionId: string, version: string): { path: string, queryData: any } { + private makeKeyBackupPath(roomId: string, sessionId: string, version: string): IKeyBackupPath { let path; if (sessionId !== undefined) { path = utils.encodeUri("/room_keys/keys/$roomId/$sessionId", { @@ -2356,11 +2612,8 @@ export class MatrixClient extends EventEmitter { } else { path = "/room_keys/keys"; } - const queryData = version === undefined ? undefined : { version: version }; - return { - path: path, - queryData: queryData, - }; + const queryData = version === undefined ? undefined : { version }; + return { path, queryData }; } /** @@ -2372,8 +2625,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} a promise that will resolve when the keys * are uploaded */ - // TODO: Verify types - public sendKeyBackup(roomId: string, sessionId: string, version: string, data: any): Promise { + public sendKeyBackup(roomId: string, sessionId: string, version: string, data: IKeyBackup): Promise { if (!this.crypto) { throw new Error("End-to-end encryption disabled"); } @@ -2566,9 +2818,7 @@ export class MatrixClient extends EventEmitter { let totalKeyCount = 0; let keys = []; - const path = this.makeKeyBackupPath( - targetRoomId, targetSessionId, backupInfo.version, - ); + const path = this.makeKeyBackupPath(targetRoomId, targetSessionId, backupInfo.version); const algorithm = await BackupManager.makeAlgorithm(backupInfo, async () => { return privKey; }); @@ -2606,9 +2856,7 @@ export class MatrixClient extends EventEmitter { if (!roomData.sessions) continue; totalKeyCount += Object.keys(roomData.sessions).length; - const roomKeys = await algorithm.decryptSessions( - roomData.sessions, - ); + const roomKeys = await algorithm.decryptSessions(roomData.sessions); for (const k of roomKeys) { k.room_id = roomId; keys.push(k); @@ -2616,9 +2864,7 @@ export class MatrixClient extends EventEmitter { } } else if (res.sessions) { totalKeyCount = Object.keys(res.sessions).length; - keys = await algorithm.decryptSessions( - res.sessions, - ); + keys = await algorithm.decryptSessions(res.sessions); for (const k of keys) { k.room_id = targetRoomId; } @@ -2720,7 +2966,7 @@ export class MatrixClient extends EventEmitter { * @param {module:client.callback} callback Optional. * @return {Promise} Resolves with an object containing the config. */ - public getMediaConfig(callback?: Callback): Promise { // TODO: Types + public getMediaConfig(callback?: Callback): Promise { return this.http.authedRequest( callback, "GET", "/config", undefined, undefined, { prefix: PREFIX_MEDIA_R0, @@ -2760,7 +3006,7 @@ export class MatrixClient extends EventEmitter { const replacedRooms = new Set(); for (const r of allRooms) { - const createEvent = r.currentState.getStateEvents('m.room.create', ''); + const createEvent = r.currentState.getStateEvents(EventType.RoomCreate, ''); // invites are included in this list and we don't know their create events yet if (createEvent) { const predecessor = createEvent.getContent()['predecessor']; @@ -2771,7 +3017,7 @@ export class MatrixClient extends EventEmitter { } return allRooms.filter((r) => { - const tombstone = r.currentState.getStateEvents('m.room.tombstone', ''); + const tombstone = r.currentState.getStateEvents(EventType.RoomTombstone, ''); if (tombstone && replacedRooms.has(r.roomId)) { return false; } @@ -2803,10 +3049,10 @@ export class MatrixClient extends EventEmitter { * @param {string} eventType The event type * @param {Object} content the contents object for the event * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: an empty object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setAccountData(eventType: EventType | string, content: any, callback?: Callback): Promise { + public setAccountData(eventType: EventType | string, content: IContent, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/user/$userId/account_data/$type", { $userId: this.credentials.userId, $type: eventType, @@ -2838,7 +3084,7 @@ export class MatrixClient extends EventEmitter { * data event. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async getAccountDataFromServer(eventType: string): Promise { + public async getAccountDataFromServer(eventType: string): Promise> { if (this.isInitialSyncComplete()) { const event = this.store.getAccountData(eventType); if (!event) { @@ -2878,10 +3124,10 @@ export class MatrixClient extends EventEmitter { * Sets the users that the current user should ignore. * @param {string[]} userIds the user IDs to ignore * @param {module:client.callback} [callback] Optional. - * @return {Promise} Resolves: Account data event + * @return {Promise} Resolves: an empty object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setIgnoredUsers(userIds: string[], callback?: Callback): Promise { + public setIgnoredUsers(userIds: string[], callback?: Callback): Promise<{}> { const content = { ignored_users: {} }; userIds.map((u) => content.ignored_users[u] = {}); return this.setAccountData("m.ignored_user_list", content, callback); @@ -2924,7 +3170,7 @@ export class MatrixClient extends EventEmitter { return Promise.resolve(room); } - let signPromise = Promise.resolve(); + let signPromise: Promise = Promise.resolve(); if (opts.inviteSignUrl) { signPromise = this.http.requestOtherUrl( @@ -2941,11 +3187,10 @@ export class MatrixClient extends EventEmitter { const reqOpts = { qsStringifyOptions: { arrayFormat: 'repeat' } }; try { - const data: any = {}; - // XXX: Explicit cast due to underlying types not existing - const signedInviteObj = >(await signPromise); + const data: IJoinRequestBody = {}; + const signedInviteObj = await signPromise; if (signedInviteObj) { - data['third_party_signed'] = signedInviteObj; + data.third_party_signed = signedInviteObj; } const path = utils.encodeUri("/join/$roomid", { $roomid: roomIdOrAlias }); @@ -2971,10 +3216,10 @@ export class MatrixClient extends EventEmitter { * @param {MatrixEvent} event The event to resend. * @param {Room} room Optional. The room the event is in. Will update the * timeline entry if provided. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public resendEvent(event: MatrixEvent, room: Room): Promise { // TODO: Types + public resendEvent(event: MatrixEvent, room: Room): Promise { this.updatePendingEventStatus(room, event, EventStatus.SENDING); return this.encryptAndSendEvent(room, event); } @@ -3008,8 +3253,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomName(roomId: string, name: string, callback?: Callback): Promise { - return this.sendStateEvent(roomId, "m.room.name", { name: name }, undefined, callback); + public setRoomName(roomId: string, name: string, callback?: Callback): Promise { + return this.sendStateEvent(roomId, EventType.RoomName, { name: name }, undefined, callback); } /** @@ -3019,8 +3264,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomTopic(roomId: string, topic: string, callback?: Callback): Promise { - return this.sendStateEvent(roomId, "m.room.topic", { topic: topic }, undefined, callback); + public setRoomTopic(roomId: string, topic: string, callback?: Callback): Promise { + return this.sendStateEvent(roomId, EventType.RoomTopic, { topic: topic }, undefined, callback); } /** @@ -3044,18 +3289,16 @@ export class MatrixClient extends EventEmitter { * @param {string} tagName name of room tag to be set * @param {object} metadata associated with that tag to be stored * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomTag(roomId: string, tagName: string, metadata: any, callback?: Callback): Promise { // TODO: Types + public setRoomTag(roomId: string, tagName: string, metadata: ITagMetadata, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/user/$userId/rooms/$roomId/tags/$tag", { $userId: this.credentials.userId, $roomId: roomId, $tag: tagName, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, metadata, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, metadata); } /** @@ -3081,18 +3324,21 @@ export class MatrixClient extends EventEmitter { * @param {string} eventType event type to be set * @param {object} content event content * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomAccountData(roomId: string, eventType: string, content: any, callback?: Callback): Promise { + public setRoomAccountData( + roomId: string, + eventType: string, + content: Record, + callback?: Callback, + ): Promise<{}> { const path = utils.encodeUri("/user/$userId/rooms/$roomId/account_data/$type", { $userId: this.credentials.userId, $roomId: roomId, $type: eventType, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, content, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, content); } /** @@ -3102,7 +3348,7 @@ export class MatrixClient extends EventEmitter { * @param {Number} powerLevel * @param {MatrixEvent} event * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public setPowerLevel( @@ -3111,11 +3357,11 @@ export class MatrixClient extends EventEmitter { powerLevel: number, event: MatrixEvent, callback?: Callback, - ): Promise { + ): Promise { let content = { users: {}, }; - if (event && event.getType() === "m.room.power_levels") { + if (event?.getType() === EventType.RoomPowerLevels) { // take a copy of the content to ensure we don't corrupt // existing client state with a failed power level change content = utils.deepCopy(event.getContent()) as typeof content; @@ -3124,9 +3370,7 @@ export class MatrixClient extends EventEmitter { const path = utils.encodeUri("/rooms/$roomId/state/m.room.power_levels", { $roomId: roomId, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, content, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, content); } /** @@ -3135,13 +3379,13 @@ export class MatrixClient extends EventEmitter { * @param {Object} content * @param {string} txnId Optional. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendEvent( roomId: string, eventType: string, - content: any, + content: IContent, txnId?: string, callback?: Callback, ): Promise { @@ -3153,7 +3397,7 @@ export class MatrixClient extends EventEmitter { * @param {object} eventObject An object with the partial structure of an event, to which event_id, user_id, room_id and origin_server_ts will be added. * @param {string} txnId the txnId. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ private sendCompleteEvent( @@ -3419,15 +3663,20 @@ export class MatrixClient extends EventEmitter { * @param {Object} content * @param {string} txnId Optional. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public sendMessage(roomId: string, content: any, txnId?: string, callback?: Callback): Promise { + public sendMessage( + roomId: string, + content: IContent, + txnId?: string, + callback?: Callback, + ): Promise { if (utils.isFunction(txnId)) { callback = txnId as any as Callback; // for legacy txnId = undefined; } - return this.sendEvent(roomId, "m.room.message", content, txnId, callback); + return this.sendEvent(roomId, EventType.RoomMessage, content, txnId, callback); } /** @@ -3435,7 +3684,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} txnId Optional. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendTextMessage( @@ -3453,7 +3702,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} txnId Optional. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendNotice(roomId: string, body: string, txnId?: string, callback?: Callback): Promise { @@ -3466,7 +3715,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} txnId Optional. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendEmoteMessage( @@ -3485,7 +3734,7 @@ export class MatrixClient extends EventEmitter { * @param {Object} info * @param {string} text * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendImageMessage( @@ -3500,7 +3749,7 @@ export class MatrixClient extends EventEmitter { text = undefined; } const content = { - msgtype: "m.image", + msgtype: MsgType.Image, url: url, info: info, body: text, @@ -3514,7 +3763,7 @@ export class MatrixClient extends EventEmitter { * @param {Object} info * @param {string} text * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendStickerMessage( @@ -3541,7 +3790,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} htmlBody * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendHtmlMessage( @@ -3559,7 +3808,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} htmlBody * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendHtmlNotice( @@ -3577,7 +3826,7 @@ export class MatrixClient extends EventEmitter { * @param {string} body * @param {string} htmlBody * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to a ISendEventResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public sendHtmlEmote( @@ -3594,12 +3843,12 @@ export class MatrixClient extends EventEmitter { * Send a receipt. * @param {Event} event The event being acknowledged * @param {string} receiptType The kind of receipt e.g. "m.read" - * @param {object} opts Additional content to send alongside the receipt. + * @param {object} body Additional content to send alongside the receipt. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public sendReceipt(event: MatrixEvent, receiptType: string, body: any, callback?: Callback): Promise { + public sendReceipt(event: MatrixEvent, receiptType: string, body: any, callback?: Callback): Promise<{}> { if (typeof (body) === 'function') { callback = body as any as Callback; // legacy body = {}; @@ -3614,9 +3863,7 @@ export class MatrixClient extends EventEmitter { $receiptType: receiptType, $eventId: event.getId(), }); - const promise = this.http.authedRequest( - callback, "POST", path, undefined, body || {}, - ); + const promise = this.http.authedRequest(callback, "POST", path, undefined, body || {}); const room = this.getRoom(event.getRoomId()); if (room) { @@ -3633,10 +3880,10 @@ export class MatrixClient extends EventEmitter { * other users and homeservers. Default false (send to everyone). This * property is unstable and may change in the future. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async sendReadReceipt(event: MatrixEvent, opts: { hidden?: boolean }, callback?: Callback): Promise { + public async sendReadReceipt(event: MatrixEvent, opts: { hidden?: boolean }, callback?: Callback): Promise<{}> { if (typeof (opts) === 'function') { callback = opts as any as Callback; // legacy opts = {}; @@ -3676,7 +3923,7 @@ export class MatrixClient extends EventEmitter { rmEventId: string, rrEvent: MatrixEvent, opts: { hidden?: boolean }, - ): Promise { // TODO: Types + ): Promise<{}> { const room = this.getRoom(roomId); if (room && room.hasPendingEvent(rmEventId)) { throw new Error(`Cannot set read marker to a pending event (${rmEventId})`); @@ -3750,10 +3997,10 @@ export class MatrixClient extends EventEmitter { * @param {boolean} isTyping * @param {Number} timeoutMs * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public sendTyping(roomId: string, isTyping: boolean, timeoutMs: number, callback?: Callback): Promise { + public sendTyping(roomId: string, isTyping: boolean, timeoutMs: number, callback?: Callback): Promise<{}> { if (this.isGuest()) { return Promise.resolve({}); // guests cannot send typing notifications so don't bother. } @@ -3768,9 +4015,7 @@ export class MatrixClient extends EventEmitter { if (isTyping) { data.timeout = timeoutMs ? timeoutMs : 20000; } - return this.http.authedRequest( - callback, "PUT", path, undefined, data, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, data); } /** @@ -3794,7 +4039,7 @@ export class MatrixClient extends EventEmitter { const upgradeHistory = [currentRoom]; // Work backwards first, looking at create events. - let createEvent = currentRoom.currentState.getStateEvents("m.room.create", ""); + let createEvent = currentRoom.currentState.getStateEvents(EventType.RoomCreate, ""); while (createEvent) { logger.log(`Looking at ${createEvent.getId()}`); const predecessor = createEvent.getContent()['predecessor']; @@ -3804,8 +4049,7 @@ export class MatrixClient extends EventEmitter { if (!refRoom) break; // end of the chain if (verifyLinks) { - const tombstone = refRoom.currentState - .getStateEvents("m.room.tombstone", ""); + const tombstone = refRoom.currentState.getStateEvents(EventType.RoomTombstone, ""); if (!tombstone || tombstone.getContent()['replacement_room'] !== refRoom.roomId) { @@ -3815,7 +4059,7 @@ export class MatrixClient extends EventEmitter { // Insert at the front because we're working backwards from the currentRoom upgradeHistory.splice(0, 0, refRoom); - createEvent = refRoom.currentState.getStateEvents("m.room.create", ""); + createEvent = refRoom.currentState.getStateEvents(EventType.RoomCreate, ""); } else { // No further create events to look at break; @@ -3823,14 +4067,14 @@ export class MatrixClient extends EventEmitter { } // Work forwards next, looking at tombstone events - let tombstoneEvent = currentRoom.currentState.getStateEvents("m.room.tombstone", ""); + let tombstoneEvent = currentRoom.currentState.getStateEvents(EventType.RoomTombstone, ""); while (tombstoneEvent) { const refRoom = this.getRoom(tombstoneEvent.getContent()['replacement_room']); if (!refRoom) break; // end of the chain if (refRoom.roomId === currentRoom.roomId) break; // Tombstone is referencing it's own room if (verifyLinks) { - createEvent = refRoom.currentState.getStateEvents("m.room.create", ""); + createEvent = refRoom.currentState.getStateEvents(EventType.RoomCreate, ""); if (!createEvent || !createEvent.getContent()['predecessor']) break; const predecessor = createEvent.getContent()['predecessor']; @@ -3848,7 +4092,7 @@ export class MatrixClient extends EventEmitter { // Set the current room to the reference room so we know where we're at currentRoom = refRoom; - tombstoneEvent = currentRoom.currentState.getStateEvents("m.room.tombstone", ""); + tombstoneEvent = currentRoom.currentState.getStateEvents(EventType.RoomTombstone, ""); } return upgradeHistory; @@ -4124,10 +4368,13 @@ export class MatrixClient extends EventEmitter { * @param {string} info The kind of info to set (e.g. 'avatar_url') * @param {Object} data The JSON object to set. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: to an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setProfileInfo(info: string, data: any, callback?: Callback): Promise { + // eslint-disable-next-line camelcase + public setProfileInfo(info: "avatar_url", data: { avatar_url: string }, callback?: Callback): Promise<{}>; + public setProfileInfo(info: "displayname", data: { displayname: string }, callback?: Callback): Promise<{}>; + public setProfileInfo(info: string, data: object, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/profile/$userId/$info", { $userId: this.credentials.userId, $info: info, @@ -4143,10 +4390,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: {} an empty object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async setDisplayName(name: string, callback?: Callback): Promise { - const prom = await this.setProfileInfo( - "displayname", { displayname: name }, callback, - ); + public async setDisplayName(name: string, callback?: Callback): Promise<{}> { + const prom = await this.setProfileInfo("displayname", { displayname: name }, callback); // XXX: synthesise a profile update for ourselves because Synapse is broken and won't const user = this.getUser(this.getUserId()); if (user) { @@ -4162,10 +4407,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: {} an empty object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async setAvatarUrl(url: string, callback?: Callback): Promise { - const prom = await this.setProfileInfo( - "avatar_url", { avatar_url: url }, callback, - ); + public async setAvatarUrl(url: string, callback?: Callback): Promise<{}> { + const prom = await this.setProfileInfo("avatar_url", { avatar_url: url }, callback); // XXX: synthesise a profile update for ourselves because Synapse is broken and won't const user = this.getUser(this.getUserId()); if (user) { @@ -4207,20 +4450,14 @@ export class MatrixClient extends EventEmitter { */ public _unstable_setStatusMessage(newMessage: string): Promise { // eslint-disable-line camelcase const type = "im.vector.user_status"; - return Promise.all(this.getRooms().map((room) => { + return Promise.all(this.getRooms().map(async (room) => { const isJoined = room.getMyMembership() === "join"; const looksLikeDm = room.getInvitedAndJoinedMemberCount() === 2; - if (!isJoined || !looksLikeDm) { - return Promise.resolve(); - } + if (!isJoined || !looksLikeDm) return; // Check power level separately as it's a bit more expensive. const maySend = room.currentState.mayClientSendStateEvent(type, this); - if (!maySend) { - return Promise.resolve(); - } - return this.sendStateEvent(room.roomId, type, { - status: newMessage, - }, this.getUserId()); + if (!maySend) return; + await this.sendStateEvent(room.roomId, type, { status: newMessage }, this.getUserId()); })).then(); // .then to fix return type } @@ -4318,8 +4555,9 @@ export class MatrixClient extends EventEmitter { room.roomId, room.oldState.paginationToken, limit, - 'b'); - }).then((res: any) => { // TODO: Types + Direction.Backward, + ); + }).then((res: IMessagesResponse) => { const matrixEvents = res.chunk.map(this.getEventMapper()); if (res.state) { const stateEvents = res.state.map(this.getEventMapper()); @@ -4354,7 +4592,7 @@ export class MatrixClient extends EventEmitter { /** * @param {object} [options] - * @param {boolean} options.preventReEmit don't reemit events emitted on an event mapped by this mapper on the client + * @param {boolean} options.preventReEmit don't re-emit events emitted on an event mapped by this mapper on the client * @param {boolean} options.decrypt decrypt event proactively * @return {Function} */ @@ -4460,16 +4698,14 @@ export class MatrixClient extends EventEmitter { roomId: string, fromToken: string, limit: number, - dir: string, + dir: Direction, timelineFilter?: Filter, - ): Promise { // TODO: Types - const path = utils.encodeUri( - "/rooms/$roomId/messages", { $roomId: roomId }, - ); + ): Promise { + const path = utils.encodeUri("/rooms/$roomId/messages", { $roomId: roomId }); if (limit === undefined) { limit = 30; } - const params: any = { + const params: Record = { from: fromToken, limit: limit, dir: dir, @@ -4691,13 +4927,13 @@ export class MatrixClient extends EventEmitter { * @return {module:http-api.MatrixError} Rejects: with an error response. */ public setGuestAccess(roomId: string, opts: IGuestAccessOpts): Promise { - const writePromise = this.sendStateEvent(roomId, "m.room.guest_access", { + const writePromise = this.sendStateEvent(roomId, EventType.RoomGuestAccess, { guest_access: opts.allowJoin ? "can_join" : "forbidden", }, ""); - let readPromise = Promise.resolve(); + let readPromise: Promise = Promise.resolve(); if (opts.allowRead) { - readPromise = this.sendStateEvent(roomId, "m.room.history_visibility", { + readPromise = this.sendStateEvent(roomId, EventType.RoomHistoryVisibility, { history_visibility: "world_readable", }, ""); } @@ -4724,7 +4960,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink?: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/register/email/requestToken", { @@ -4756,7 +4992,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink?: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/register/msisdn/requestToken", { @@ -4791,7 +5027,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/3pid/email/requestToken", { @@ -4823,7 +5059,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/3pid/msisdn/requestToken", { @@ -4860,7 +5096,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/password/email/requestToken", { @@ -4891,7 +5127,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/password/msisdn/requestToken", { @@ -4912,7 +5148,10 @@ export class MatrixClient extends EventEmitter { * @param {object} params Parameters for the POST request * @return {Promise} Resolves: As requestEmailToken */ - private async requestTokenFromEndpoint(endpoint: string, params: any): Promise { + private async requestTokenFromEndpoint( + endpoint: string, + params: Record, + ): Promise { const postParams = Object.assign({}, params); // If the HS supports separate add and bind, then requestToken endpoints @@ -4936,10 +5175,7 @@ export class MatrixClient extends EventEmitter { } } - return this.http.request( - undefined, "POST", endpoint, undefined, - postParams, - ); + return this.http.request(undefined, "POST", endpoint, undefined, postParams); } /** @@ -4974,7 +5210,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomMutePushRule(scope: string, roomId: string, mute: string): any { // TODO: Types + public setRoomMutePushRule(scope: string, roomId: string, mute: string): Promise | void { let deferred; let hasDontNotifyRule; @@ -5041,8 +5277,8 @@ export class MatrixClient extends EventEmitter { } } - public searchMessageText(opts: ISearchOpts, callback?: Callback): Promise { // TODO: Types - const roomEvents: any = { + public searchMessageText(opts: ISearchOpts, callback?: Callback): Promise { + const roomEvents: ISearchRequestBody["search_categories"]["room_events"] = { search_term: opts.query, }; @@ -5079,7 +5315,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public searchRoomEvents(opts: IEventSearchOpts): Promise { // TODO: Types + public searchRoomEvents(opts: IEventSearchOpts): Promise { // TODO: support groups const body = { @@ -5087,7 +5323,7 @@ export class MatrixClient extends EventEmitter { room_events: { search_term: opts.term, filter: opts.filter, - order_by: "recent", + order_by: SearchOrderBy.Recent, event_context: { before_limit: 1, after_limit: 1, @@ -5097,7 +5333,7 @@ export class MatrixClient extends EventEmitter { }, }; - const searchResults = { + const searchResults: ISearchResults = { _query: body, results: [], highlights: [], @@ -5113,7 +5349,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: updated result object * @return {Error} Rejects: with an error response. */ - public backPaginateRoomEventsSearch(searchResults: any): Promise { // TODO: Types + public backPaginateRoomEventsSearch(searchResults: T): Promise { // TODO: we should implement a backoff (as per scrollback()) to deal more // nicely with HTTP errors. @@ -5123,7 +5359,7 @@ export class MatrixClient extends EventEmitter { if (searchResults.pendingRequest) { // already a request in progress - return the existing promise - return searchResults.pendingRequest; + return searchResults.pendingRequest as Promise; } const searchOpts = { @@ -5150,8 +5386,9 @@ export class MatrixClient extends EventEmitter { * @return {Object} searchResults * @private */ - public processRoomEventsSearch(searchResults: any, response: any): any { // XXX: Intended private, used in code - const roomEvents = response.search_categories.room_events; // eslint-disable-line camelcase + // XXX: Intended private, used in code + public processRoomEventsSearch(searchResults: T, response: ISearchResponse): T { + const roomEvents = response.search_categories.room_events; searchResults.count = roomEvents.count; searchResults.next_batch = roomEvents.next_batch; @@ -5212,7 +5449,7 @@ export class MatrixClient extends EventEmitter { * @return {Filter} Resolves to a Filter object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public createFilter(content: any): Promise { // TODO: Types + public createFilter(content: IFilterDefinition): Promise { const path = utils.encodeUri("/user/$userId/filter", { $userId: this.credentials.userId, }); @@ -5232,7 +5469,7 @@ export class MatrixClient extends EventEmitter { * @param {string} filterId The filter ID to retrieve * @param {boolean} allowCached True to allow cached filters to be returned. * Default: True. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: a Filter object * @return {module:http-api.MatrixError} Rejects: with an error response. */ public getFilter(userId: string, filterId: string, allowCached: boolean): Promise { @@ -5322,7 +5559,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Token object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getOpenIdToken(): Promise { // TODO: Types + public getOpenIdToken(): Promise { const path = utils.encodeUri("/user/$userId/openid/request_token", { $userId: this.credentials.userId, }); @@ -5332,7 +5569,7 @@ export class MatrixClient extends EventEmitter { ); } - private startCallEventHandler = () => { + private startCallEventHandler = (): void => { if (this.isInitialSyncComplete()) { this.callEventHandler.start(); this.off("sync", this.startCallEventHandler); @@ -5341,10 +5578,10 @@ export class MatrixClient extends EventEmitter { /** * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: ITurnServerResponse object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public turnServer(callback?: Callback): Promise { // TODO: Types + public turnServer(callback?: Callback): Promise { return this.http.authedRequest(callback, "GET", "/voip/turnServer"); } @@ -5352,7 +5589,7 @@ export class MatrixClient extends EventEmitter { * Get the TURN servers for this home server. * @return {Array} The servers or an empty list. */ - public getTurnServers(): any[] { // TODO: Types + public getTurnServers(): ITurnServer[] { return this.turnServers || []; } @@ -5383,7 +5620,7 @@ export class MatrixClient extends EventEmitter { if (res.uris) { logger.log("Got TURN URIs: " + res.uris + " refresh in " + res.ttl + " secs"); // map the response to a format that can be fed to RTCPeerConnection - const servers = { + const servers: ITurnServer = { urls: res.uris, username: res.username, credential: res.password, @@ -5454,14 +5691,12 @@ export class MatrixClient extends EventEmitter { * @param {string} userId the User ID to look up. * @return {object} the whois response - see Synapse docs for information. */ - public whoisSynapseUser(userId: string): Promise { + public whoisSynapseUser(userId: string): Promise { const path = utils.encodeUri( "/_synapse/admin/v1/whois/$userId", { $userId: userId }, ); - return this.http.authedRequest( - undefined, 'GET', path, undefined, undefined, { prefix: '' }, - ); + return this.http.authedRequest(undefined, 'GET', path, undefined, undefined, { prefix: '' }); } /** @@ -5470,7 +5705,7 @@ export class MatrixClient extends EventEmitter { * @param {string} userId the User ID to deactivate. * @return {object} the deactivate response - see Synapse docs for information. */ - public deactivateSynapseUser(userId: string): Promise { + public deactivateSynapseUser(userId: string): Promise { const path = utils.encodeUri( "/_synapse/admin/v1/deactivate/$userId", { $userId: userId }, @@ -5480,21 +5715,19 @@ export class MatrixClient extends EventEmitter { ); } - private async fetchClientWellKnown() { + private async fetchClientWellKnown(): Promise { // `getRawClientConfig` does not throw or reject on network errors, instead // it absorbs errors and returns `{}`. - this.clientWellKnownPromise = AutoDiscovery.getRawClientConfig( - this.getDomain(), - ); + this.clientWellKnownPromise = AutoDiscovery.getRawClientConfig(this.getDomain()); this.clientWellKnown = await this.clientWellKnownPromise; this.emit("WellKnown.client", this.clientWellKnown); } - public getClientWellKnown(): any { + public getClientWellKnown(): IClientWellKnown { return this.clientWellKnown; } - public waitForClientWellKnown(): Promise { + public waitForClientWellKnown(): Promise { return this.clientWellKnownPromise; } @@ -5505,7 +5738,7 @@ export class MatrixClient extends EventEmitter { * @param {object} opts the complete set of client options * @return {Promise} for store operation */ - public storeClientOptions() { // XXX: Intended private, used in code + public storeClientOptions(): Promise { // XXX: Intended private, used in code const primTypes = ["boolean", "string", "number"]; const serializableOpts = Object.entries(this.clientOpts) .filter(([key, value]) => { @@ -5543,7 +5776,7 @@ export class MatrixClient extends EventEmitter { * unstable APIs it supports * @return {Promise} The server /versions response */ - public getVersions(): Promise { // TODO: Types + public getVersions(): Promise { if (this.serverVersionsPromise) { return this.serverVersionsPromise; } @@ -5743,14 +5976,14 @@ export class MatrixClient extends EventEmitter { originalEvent = mapper(result.original_event); } let events = result.chunk.map(mapper); - if (fetchedEventType === "m.room.encrypted") { + if (fetchedEventType === EventType.RoomMessageEncrypted) { const allEvents = originalEvent ? events.concat(originalEvent) : events; await Promise.all(allEvents.map(e => { return new Promise(resolve => e.once("Event.decrypted", resolve)); })); events = events.filter(e => e.getType() === eventType); } - if (originalEvent && relationType === "m.replace") { + if (originalEvent && relationType === RelationType.Replace) { events = events.filter(e => e.getSender() === originalEvent.getSender()); } return { @@ -5765,7 +5998,7 @@ export class MatrixClient extends EventEmitter { * triggering a user interaction. * @return {object} */ - public getCrossSigningCacheCallbacks(): any { // TODO: Types + public getCrossSigningCacheCallbacks(): ICacheCallbacks { // XXX: Private member access return this.crypto?.crossSigningInfo.getCacheCallbacks(); } @@ -6129,9 +6362,7 @@ export class MatrixClient extends EventEmitter { */ public deactivateAccount(auth?: any, erase?: boolean): Promise<{}> { if (typeof (erase) === 'function') { - throw new Error( - 'deactivateAccount no longer accepts a callback parameter', - ); + throw new Error('deactivateAccount no longer accepts a callback parameter'); } const body: any = {}; @@ -6142,9 +6373,7 @@ export class MatrixClient extends EventEmitter { body.erase = erase; } - return this.http.authedRequest( - undefined, "POST", '/account/deactivate', undefined, body, - ); + return this.http.authedRequest(undefined, "POST", '/account/deactivate', undefined, body); } /** @@ -6175,14 +6404,13 @@ export class MatrixClient extends EventEmitter { * @param {string} options.name The name to give this room. * @param {string} options.topic The topic to give this room. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: {room_id: {string}, - * room_alias: {string(opt)}} + * @return {Promise} Resolves: {room_id: {string}} * @return {module:http-api.MatrixError} Rejects: with an error response. */ public async createRoom( options: ICreateRoomOpts, callback?: Callback, - ): Promise<{ room_id: string, room_alias?: string }> { // eslint-disable-line camelcase + ): Promise<{ room_id: string }> { // eslint-disable-line camelcase // some valid options include: room_alias_name, visibility, invite // inject the id_access_token if inviting 3rd party addresses @@ -6202,9 +6430,7 @@ export class MatrixClient extends EventEmitter { } } - return this.http.authedRequest( - callback, "POST", "/createRoom", undefined, options, - ); + return this.http.authedRequest(callback, "POST", "/createRoom", undefined, options); } /** @@ -6249,7 +6475,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public roomState(roomId: string, callback?: Callback): Promise { // TODO: Types + public roomState(roomId: string, callback?: Callback): Promise { const path = utils.encodeUri("/rooms/$roomId/state", { $roomId: roomId }); return this.http.authedRequest(callback, "GET", path); } @@ -6263,7 +6489,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves to an object containing the event. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public fetchRoomEvent(roomId: string, eventId: string, callback?: Callback): Promise { // TODO: Types + public fetchRoomEvent( + roomId: string, + eventId: string, + callback?: Callback, + ): Promise { const path = utils.encodeUri( "/rooms/$roomId/event/$eventId", { $roomId: roomId, @@ -6288,7 +6518,7 @@ export class MatrixClient extends EventEmitter { excludeMembership?: string[], atEventId?: string, callback?: Callback, - ): Promise<{ [userId: string]: any }> { + ): Promise<{ [userId: string]: IStateEventWithRoomId }> { const queryParams: any = {}; if (includeMembership) { queryParams.membership = includeMembership; @@ -6333,7 +6563,12 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getStateEvent(roomId: string, eventType: string, stateKey: string, callback?: Callback): Promise { + public getStateEvent( + roomId: string, + eventType: string, + stateKey: string, + callback?: Callback, + ): Promise { const pathParams = { $roomId: roomId, $eventType: eventType, @@ -6363,7 +6598,7 @@ export class MatrixClient extends EventEmitter { content: any, stateKey = "", callback?: Callback, - ): Promise { // TODO: Types + ): Promise { const pathParams = { $roomId: roomId, $eventType: eventType, @@ -6373,9 +6608,7 @@ export class MatrixClient extends EventEmitter { if (stateKey !== undefined) { path = utils.encodeUri(path + "/$stateKey", pathParams); } - return this.http.authedRequest( - callback, "PUT", path, undefined, content, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, content); } /** @@ -6385,7 +6618,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public roomInitialSync(roomId: string, limit: number, callback?: Callback): Promise { // TODO: Types + public roomInitialSync(roomId: string, limit: number, callback?: Callback): Promise { if (utils.isFunction(limit)) { callback = limit as any as Callback; // legacy limit = undefined; @@ -6432,9 +6665,7 @@ export class MatrixClient extends EventEmitter { "m.hidden": Boolean(opts ? opts.hidden : false), }; - return this.http.authedRequest( - undefined, "POST", path, undefined, content, - ); + return this.http.authedRequest(undefined, "POST", path, undefined, content); } /** @@ -6453,7 +6684,7 @@ export class MatrixClient extends EventEmitter { * and their profile data. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getJoinedRoomMembers(roomId: string): Promise { // TODO: Types + public getJoinedRoomMembers(roomId: string): Promise { const path = utils.encodeUri("/rooms/$roomId/joined_members", { $roomId: roomId, }); @@ -6473,7 +6704,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public publicRooms(options: IRoomDirectoryOptions, callback?: Callback): Promise { // TODO: Types + public publicRooms(options: IRoomDirectoryOptions, callback?: Callback): Promise { if (typeof (options) == 'function') { callback = options; options = {}; @@ -6491,9 +6722,7 @@ export class MatrixClient extends EventEmitter { if (Object.keys(options).length === 0 && Object.keys(queryParams).length === 0) { return this.http.authedRequest(callback, "GET", "/publicRooms"); } else { - return this.http.authedRequest( - callback, "POST", "/publicRooms", queryParams, options, - ); + return this.http.authedRequest(callback, "POST", "/publicRooms", queryParams, options); } } @@ -6502,19 +6731,17 @@ export class MatrixClient extends EventEmitter { * @param {string} alias The room alias to create. * @param {string} roomId The room ID to link the alias to. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO. + * @return {Promise} Resolves: an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public createAlias(alias: string, roomId: string, callback?: Callback): Promise { // TODO: Types + public createAlias(alias: string, roomId: string, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/directory/room/$alias", { $alias: alias, }); const data = { room_id: roomId, }; - return this.http.authedRequest( - callback, "PUT", path, undefined, data, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, data); } /** @@ -6522,16 +6749,14 @@ export class MatrixClient extends EventEmitter { * and you must have sufficient access to do this operation. * @param {string} alias The room alias to delete. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO. + * @return {Promise} Resolves: an empty object. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public deleteAlias(alias: string, callback?: Callback): Promise { // TODO: Types + public deleteAlias(alias: string, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/directory/room/$alias", { $alias: alias, }); - return this.http.authedRequest( - callback, "DELETE", path, undefined, undefined, - ); + return this.http.authedRequest(callback, "DELETE", path, undefined, undefined); } /** @@ -6544,8 +6769,7 @@ export class MatrixClient extends EventEmitter { const path = utils.encodeUri("/rooms/$roomId/aliases", { $roomId: roomId }); const prefix = PREFIX_UNSTABLE + "/org.matrix.msc2432"; - return this.http.authedRequest(callback, "GET", path, - null, null, { prefix }); + return this.http.authedRequest(callback, "GET", path, null, null, { prefix }); } /** @@ -6563,18 +6787,16 @@ export class MatrixClient extends EventEmitter { const path = utils.encodeUri("/directory/room/$alias", { $alias: alias, }); - return this.http.authedRequest( - callback, "GET", path, - ); + return this.http.authedRequest(callback, "GET", path); } /** * @param {string} roomAlias * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: Object with room_id and servers. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public resolveRoomAlias(roomAlias: string, callback?: Callback): Promise { // TODO: Types + public resolveRoomAlias(roomAlias: string, callback?: Callback): Promise<{ room_id: string, servers: string[] }> { // TODO: deprecate this or getRoomIdForAlias const path = utils.encodeUri("/directory/room/$alias", { $alias: roomAlias }); return this.http.request(callback, "GET", path); @@ -6587,7 +6809,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getRoomDirectoryVisibility(roomId: string, callback?: Callback): Promise { // TODO: Types + public getRoomDirectoryVisibility(roomId: string, callback?: Callback): Promise<{ visibility: Visibility }> { const path = utils.encodeUri("/directory/list/room/$roomId", { $roomId: roomId, }); @@ -6604,17 +6826,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setRoomDirectoryVisibility( - roomId: string, - visibility: "public" | "private", - callback?: Callback, - ): Promise { // TODO: Types + public setRoomDirectoryVisibility(roomId: string, visibility: Visibility, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/directory/list/room/$roomId", { $roomId: roomId, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, { "visibility": visibility }, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, { visibility }); } /** @@ -6653,7 +6869,7 @@ export class MatrixClient extends EventEmitter { * apply a limit if unspecified. * @return {Promise} Resolves: an array of results. */ - public searchUserDirectory(opts: { term: string, limit?: number }): Promise { // TODO: Types + public searchUserDirectory(opts: { term: string, limit?: number }): Promise { const body: any = { search_term: opts.term, }; @@ -6662,9 +6878,7 @@ export class MatrixClient extends EventEmitter { body.limit = opts.limit; } - return this.http.authedRequest( - undefined, "POST", "/user_directory/search", undefined, body, - ); + return this.http.authedRequest(undefined, "POST", "/user_directory/search", undefined, body); } /** @@ -6710,7 +6924,7 @@ export class MatrixClient extends EventEmitter { public uploadContent( file: File | String | Buffer | ReadStream | Blob, opts?: IUploadOpts, - ): Promise { // TODO: Advanced types + ): IAbortablePromise { // TODO: Advanced types return this.http.uploadContent(file, opts); } @@ -6719,7 +6933,7 @@ export class MatrixClient extends EventEmitter { * @param {Promise} promise The promise returned from uploadContent * @return {boolean} true if canceled, otherwise false */ - public cancelUpload(promise: Promise): boolean { // TODO: Advanced types + public cancelUpload(promise: IAbortablePromise): boolean { return this.http.cancelUpload(promise); } @@ -6743,7 +6957,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getProfileInfo(userId: string, info?: string, callback?: Callback): Promise { // TODO: Types + public getProfileInfo( + userId: string, + info?: string, + callback?: Callback, + ): Promise<{ avatar_url?: string, displayname?: string }> { if (utils.isFunction(info)) { callback = info as any as Callback; // legacy info = undefined; @@ -6762,11 +6980,9 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getThreePids(callback?: Callback): Promise { // TODO: Types + public getThreePids(callback?: Callback): Promise<{ threepids: IThreepid[] }> { const path = "/account/3pid"; - return this.http.authedRequest( - callback, "GET", path, undefined, undefined, - ); + return this.http.authedRequest(callback, "GET", path, undefined, undefined); } /** @@ -6805,13 +7021,10 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async addThreePidOnly(data: any): Promise { // TODO: Types + public async addThreePidOnly(data: IAddThreePidOnlyBody): Promise<{}> { const path = "/account/3pid/add"; - const prefix = await this.isVersionSupported("r0.6.0") ? - PREFIX_R0 : PREFIX_UNSTABLE; - return this.http.authedRequest( - undefined, "POST", path, null, data, { prefix }, - ); + const prefix = await this.isVersionSupported("r0.6.0") ? PREFIX_R0 : PREFIX_UNSTABLE; + return this.http.authedRequest(undefined, "POST", path, null, data, { prefix }); } /** @@ -6828,7 +7041,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async bindThreePid(data: any): Promise { // TODO: Types + public async bindThreePid(data: IBindThreePidBody): Promise<{}> { const path = "/account/3pid/bind"; const prefix = await this.isVersionSupported("r0.6.0") ? PREFIX_R0 : PREFIX_UNSTABLE; @@ -6848,18 +7061,19 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async unbindThreePid(medium: string, address: string): Promise { + public async unbindThreePid( + medium: string, + address: string, + // eslint-disable-next-line camelcase + ): Promise<{ id_server_unbind_result: IdServerUnbindResult }> { const path = "/account/3pid/unbind"; const data = { medium, address, id_server: this.getIdentityServerUrl(true), }; - const prefix = await this.isVersionSupported("r0.6.0") ? - PREFIX_R0 : PREFIX_UNSTABLE; - return this.http.authedRequest( - undefined, "POST", path, null, data, { prefix }, - ); + const prefix = await this.isVersionSupported("r0.6.0") ? PREFIX_R0 : PREFIX_UNSTABLE; + return this.http.authedRequest(undefined, "POST", path, null, data, { prefix }); } /** @@ -6870,13 +7084,13 @@ export class MatrixClient extends EventEmitter { * (generally the empty JSON object) * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public deleteThreePid(medium: string, address: string): Promise { + public deleteThreePid( + medium: string, + address: string, + // eslint-disable-next-line camelcase + ): Promise<{ id_server_unbind_result: IdServerUnbindResult }> { const path = "/account/3pid/delete"; - const data = { - 'medium': medium, - 'address': address, - }; - return this.http.authedRequest(undefined, "POST", path, null, data); + return this.http.authedRequest(undefined, "POST", path, null, { medium, address }); } /** @@ -6904,10 +7118,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getDevices(): Promise { // TODO: Types - return this.http.authedRequest( - undefined, 'GET', "/devices", undefined, undefined, - ); + public getDevices(): Promise<{ devices: IMyDevice[] }> { + return this.http.authedRequest(undefined, 'GET', "/devices", undefined, undefined); } /** @@ -6916,13 +7128,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getDevice(deviceId: string): Promise { // TODO: Types + public getDevice(deviceId: string): Promise { const path = utils.encodeUri("/devices/$device_id", { $device_id: deviceId, }); - return this.http.authedRequest( - undefined, 'GET', path, undefined, undefined, - ); + return this.http.authedRequest(undefined, 'GET', path, undefined, undefined); } /** @@ -6933,7 +7143,8 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setDeviceDetails(deviceId: string, body: any): Promise { // TODO: Types + // eslint-disable-next-line camelcase + public setDeviceDetails(deviceId: string, body: { display_name: string }): Promise<{}> { const path = utils.encodeUri("/devices/$device_id", { $device_id: deviceId, }); @@ -6989,11 +7200,9 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Array of objects representing pushers * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getPushers(callback?: Callback): Promise { // TODO: Types + public getPushers(callback?: Callback): Promise<{ pushers: IPusher[] }> { const path = "/pushers"; - return this.http.authedRequest( - callback, "GET", path, undefined, undefined, - ); + return this.http.authedRequest(callback, "GET", path, undefined, undefined); } /** @@ -7004,11 +7213,9 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Empty json object on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setPusher(pusher: any, callback?: Callback): Promise { // TODO: Types + public setPusher(pusher: IPusher, callback?: Callback): Promise<{}> { const path = "/pushers/set"; - return this.http.authedRequest( - callback, "POST", path, null, pusher, - ); + return this.http.authedRequest(callback, "POST", path, null, pusher); } /** @@ -7028,18 +7235,16 @@ export class MatrixClient extends EventEmitter { * @param {string} ruleId * @param {Object} body * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public addPushRule(scope: string, kind: string, ruleId: string, body: any, callback?: Callback): Promise { // TODO: Types + public addPushRule(scope: string, kind: string, ruleId: string, body: any, callback?: Callback): Promise<{}> { // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, $ruleId: ruleId, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, body, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, body); } /** @@ -7047,10 +7252,10 @@ export class MatrixClient extends EventEmitter { * @param {string} kind * @param {string} ruleId * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves: an empty object {} * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public deletePushRule(scope: string, kind: string, ruleId: string, callback?: Callback): Promise { // TODO: Types + public deletePushRule(scope: string, kind: string, ruleId: string, callback?: Callback): Promise<{}> { // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -7075,7 +7280,7 @@ export class MatrixClient extends EventEmitter { ruleId: string, enabled: boolean, callback?: Callback, - ): Promise { // TODO: Types + ): Promise<{}> { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", { $kind: kind, $ruleId: ruleId, @@ -7101,7 +7306,7 @@ export class MatrixClient extends EventEmitter { ruleId: string, actions: string[], callback?: Callback, - ): Promise { // TODO: Types + ): Promise<{}> { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", { $kind: kind, $ruleId: ruleId, @@ -7121,16 +7326,14 @@ export class MatrixClient extends EventEmitter { * @return {module:http-api.MatrixError} Rejects: with an error response. */ public search( - opts: { body: any, next_batch?: string }, // eslint-disable-line camelcase + opts: { body: ISearchRequestBody, next_batch?: string }, // eslint-disable-line camelcase callback?: Callback, - ): Promise { // TODO: Types + ): Promise { const queryParams: any = {}; if (opts.next_batch) { queryParams.next_batch = opts.next_batch; } - return this.http.authedRequest( - callback, "POST", "/search", queryParams, opts.body, - ); + return this.http.authedRequest(callback, "POST", "/search", queryParams, opts.body); } /** @@ -7146,7 +7349,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object. Rejects: with * an error response ({@link module:http-api.MatrixError}). */ - public uploadKeysRequest(content: any, opts?: any, callback?: Callback): Promise { + public uploadKeysRequest( + content: IUploadKeysRequest, + opts?: void, + callback?: Callback, + ): Promise { return this.http.authedRequest(callback, "POST", "/keys/upload", undefined, content); } @@ -7172,12 +7379,10 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object. Rejects: with * an error response ({@link module:http-api.MatrixError}). */ - public downloadKeysForUsers(userIds: string[], opts: { token?: string }): Promise { // TODO: Types + public downloadKeysForUsers(userIds: string[], opts: { token?: string }): Promise { if (utils.isFunction(opts)) { // opts used to be 'callback'. - throw new Error( - 'downloadKeysForUsers no longer accepts a callback parameter', - ); + throw new Error('downloadKeysForUsers no longer accepts a callback parameter'); } opts = opts || {}; @@ -7207,7 +7412,11 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object. Rejects: with * an error response ({@link module:http-api.MatrixError}). */ - public claimOneTimeKeys(devices: string[], keyAlgorithm = "signed_curve25519", timeout?: number): Promise { // TODO: Types + public claimOneTimeKeys( + devices: string[], + keyAlgorithm = "signed_curve25519", + timeout?: number, + ): Promise { const queries = {}; if (keyAlgorithm === undefined) { @@ -7239,7 +7448,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: result object. Rejects: with * an error response ({@link module:http-api.MatrixError}). */ - public getKeyChanges(oldToken: string, newToken: string): Promise { // TODO: Types + public getKeyChanges(oldToken: string, newToken: string): Promise<{ changed: string[], left: string[] }> { const qps = { from: oldToken, to: newToken, @@ -7689,15 +7898,13 @@ export class MatrixClient extends EventEmitter { * this HS * @return {Promise} Resolves to the result object */ - public getThirdpartyProtocols(): Promise { // TODO: Types + public getThirdpartyProtocols(): Promise<{ [protocol: string]: IProtocol }> { return this.http.authedRequest( undefined, "GET", "/thirdparty/protocols", undefined, undefined, ).then((response) => { // sanity check if (!response || typeof (response) !== 'object') { - throw new Error( - `/thirdparty/protocols did not return an object: ${response}`, - ); + throw new Error(`/thirdparty/protocols did not return an object: ${response}`); } return response; }); @@ -7711,7 +7918,10 @@ export class MatrixClient extends EventEmitter { * response to getThirdpartyProtocols() * @return {Promise} Resolves to the result object */ - public getThirdpartyLocation(protocol: string, params: any): Promise { // TODO: Types + public getThirdpartyLocation( + protocol: string, + params: { searchFields?: string[] }, + ): Promise { const path = utils.encodeUri("/thirdparty/location/$protocol", { $protocol: protocol, }); @@ -7727,7 +7937,7 @@ export class MatrixClient extends EventEmitter { * response to getThirdpartyProtocols() * @return {Promise} Resolves to the result object */ - public getThirdpartyUser(protocol: string, params: any): Promise { // TODO: Types + public getThirdpartyUser(protocol: string, params: any): Promise { // TODO: Types const path = utils.encodeUri("/thirdparty/user/$protocol", { $protocol: protocol, }); @@ -7737,9 +7947,7 @@ export class MatrixClient extends EventEmitter { public getTerms(serviceType: SERVICE_TYPES, baseUrl: string): Promise { // TODO: Types const url = this.termsUrlForService(serviceType, baseUrl); - return this.http.requestOtherUrl( - undefined, 'GET', url, - ); + return this.http.requestOtherUrl(undefined, 'GET', url); } public agreeToTerms( @@ -7752,9 +7960,7 @@ export class MatrixClient extends EventEmitter { const headers = { Authorization: "Bearer " + accessToken, }; - return this.http.requestOtherUrl( - undefined, 'POST', url, null, { user_accepts: termsUrls }, { headers }, - ); + return this.http.requestOtherUrl(undefined, 'POST', url, null, { user_accepts: termsUrls }, { headers }); } /** @@ -7765,7 +7971,7 @@ export class MatrixClient extends EventEmitter { * @param {string} reason The reason the content is being reported. May be blank. * @returns {Promise} Resolves to an empty object if successful */ - public reportEvent(roomId: string, eventId: string, score: number, reason: string): Promise { // TODO: Types + public reportEvent(roomId: string, eventId: string, score: number, reason: string): Promise<{}> { const path = utils.encodeUri("/rooms/$roomId/report/$eventId", { $roomId: roomId, $eventId: eventId, @@ -7791,7 +7997,10 @@ export class MatrixClient extends EventEmitter { autoJoinOnly?: boolean, limit?: number, batch?: string, - ): Promise { // TODO: Types + ): Promise<{ + rooms: ISpaceSummaryRoom[]; + events: ISpaceSummaryEvent[]; + }> { const path = utils.encodeUri("/rooms/$roomId/spaces", { $roomId: roomId, }); diff --git a/src/content-helpers.ts b/src/content-helpers.ts index 061073c5e..a75b2fd87 100644 --- a/src/content-helpers.ts +++ b/src/content-helpers.ts @@ -17,6 +17,8 @@ limitations under the License. /** @module ContentHelpers */ +import { MsgType } from "./@types/event"; + /** * Generates the content for a HTML Message event * @param {string} body the plaintext body of the message @@ -25,7 +27,7 @@ limitations under the License. */ export function makeHtmlMessage(body: string, htmlBody: string) { return { - msgtype: "m.text", + msgtype: MsgType.Text, format: "org.matrix.custom.html", body: body, formatted_body: htmlBody, @@ -40,7 +42,7 @@ export function makeHtmlMessage(body: string, htmlBody: string) { */ export function makeHtmlNotice(body: string, htmlBody: string) { return { - msgtype: "m.notice", + msgtype: MsgType.Notice, format: "org.matrix.custom.html", body: body, formatted_body: htmlBody, @@ -55,7 +57,7 @@ export function makeHtmlNotice(body: string, htmlBody: string) { */ export function makeHtmlEmote(body: string, htmlBody: string) { return { - msgtype: "m.emote", + msgtype: MsgType.Emote, format: "org.matrix.custom.html", body: body, formatted_body: htmlBody, @@ -69,7 +71,7 @@ export function makeHtmlEmote(body: string, htmlBody: string) { */ export function makeTextMessage(body: string) { return { - msgtype: "m.text", + msgtype: MsgType.Text, body: body, }; } @@ -81,7 +83,7 @@ export function makeTextMessage(body: string) { */ export function makeNotice(body: string) { return { - msgtype: "m.notice", + msgtype: MsgType.Notice, body: body, }; } @@ -93,7 +95,7 @@ export function makeNotice(body: string) { */ export function makeEmoteMessage(body: string) { return { - msgtype: "m.emote", + msgtype: MsgType.Emote, body: body, }; } diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 278a17ed4..8b538afa2 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -109,8 +109,8 @@ export class EncryptionSetupBuilder { * @param {Object} content * @return {Promise} */ - public setAccountData(type: string, content: object): Promise { - return this.accountDataClientAdapter.setAccountData(type, content); + public async setAccountData(type: string, content: object): Promise { + await this.accountDataClientAdapter.setAccountData(type, content); } /** @@ -284,7 +284,7 @@ class AccountDataClientAdapter extends EventEmitter { * @param {Object} content * @return {Promise} */ - public setAccountData(type: string, content: any): Promise { + public setAccountData(type: string, content: any): Promise<{}> { const lastEvent = this.values.get(type); this.values.set(type, content); // ensure accountData is emitted on the next tick, @@ -293,6 +293,7 @@ class AccountDataClientAdapter extends EventEmitter { return Promise.resolve().then(() => { const event = new MatrixEvent({ type, content }); this.emit("accountData", event, lastEvent); + return {}; }); } } diff --git a/src/crypto/RoomList.ts b/src/crypto/RoomList.ts index ab653f456..b2835362f 100644 --- a/src/crypto/RoomList.ts +++ b/src/crypto/RoomList.ts @@ -24,10 +24,10 @@ import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { CryptoStore } from "../client"; /* eslint-disable camelcase */ -interface IRoomEncryption { +export interface IRoomEncryption { algorithm: string; - rotation_period_ms: number; - rotation_period_msgs: number; + rotation_period_ms?: number; + rotation_period_msgs?: number; } /* eslint-enable camelcase */ diff --git a/src/crypto/SecretStorage.ts b/src/crypto/SecretStorage.ts index 017851194..fb5665fa6 100644 --- a/src/crypto/SecretStorage.ts +++ b/src/crypto/SecretStorage.ts @@ -37,9 +37,9 @@ export interface ISecretRequest { export interface IAccountDataClient extends EventEmitter { // Subset of MatrixClient (which also uses any for the event content) - getAccountDataFromServer: (eventType: string) => Promise; + getAccountDataFromServer: (eventType: string) => Promise>; getAccountData: (eventType: string) => MatrixEvent; - setAccountData: (eventType: string, content: any) => Promise; + setAccountData: (eventType: string, content: any) => Promise<{}>; } interface ISecretRequestInternal { @@ -174,7 +174,7 @@ export class SecretStorage { * the form [keyId, keyInfo]. Otherwise, null is returned. * XXX: why is this an array when addKey returns an object? */ - public async getKey(keyId: string): Promise { + public async getKey(keyId: string): Promise { if (!keyId) { keyId = await this.getDefaultKeyId(); } @@ -184,7 +184,7 @@ export class SecretStorage { const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, - ); + ) as ISecretStorageKeyInfo; return keyInfo ? [keyId, keyInfo] : null; } @@ -248,7 +248,7 @@ export class SecretStorage { // get key information from key storage const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, - ); + ) as ISecretStorageKeyInfo; if (!keyInfo) { throw new Error("Unknown key: " + keyId); } diff --git a/src/crypto/algorithms/base.ts b/src/crypto/algorithms/base.ts index 7f687774b..89fa7034d 100644 --- a/src/crypto/algorithms/base.ts +++ b/src/crypto/algorithms/base.ts @@ -26,6 +26,7 @@ import { OlmDevice } from "../OlmDevice"; import { MatrixEvent, RoomMember } from "../.."; import { Crypto, IEventDecryptionResult, IMegolmSessionData, IncomingRoomKeyRequest } from ".."; import { DeviceInfo } from "../deviceinfo"; +import { IRoomEncryption } from "../RoomList"; /** * map of registered encryption algorithm classes. A map from string to {@link @@ -52,7 +53,7 @@ interface IParams { olmDevice: OlmDevice; baseApis: MatrixClient; roomId: string; - config: object; + config: IRoomEncryption & object; } /** diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index abe30798e..fbbdec933 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -31,7 +31,7 @@ import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { encodeRecoveryKey } from './recoverykey'; import { encryptAES, decryptAES, calculateKeyCheck } from './aes'; import { getCrypto } from '../utils'; -import { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo } from "./keybackup"; +import { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo, IKeyBackupSession } from "./keybackup"; import { UnstableValue } from "../NamespacedValue"; const KEY_BACKUP_KEYS_PER_REQUEST = 200; @@ -85,12 +85,22 @@ interface BackupAlgorithmClass { interface BackupAlgorithm { untrusted: boolean; encryptSession(data: Record): Promise; - decryptSessions(ciphertexts: Record): Promise[]>; + decryptSessions(ciphertexts: Record): Promise[]>; authData: AuthData; keyMatches(key: ArrayLike): Promise; free(): void; } +export interface IKeyBackup { + rooms: { + [roomId: string]: { + sessions: { + [sessionId: string]: IKeyBackupSession; + }; + }; + } +} + /** * Manages the key backup. */ @@ -464,11 +474,11 @@ export class BackupManager { let remaining = await this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup(); this.baseApis.crypto.emit("crypto.keyBackupSessionsRemaining", remaining); - const data = {}; + const rooms: IKeyBackup["rooms"] = {}; for (const session of sessions) { const roomId = session.sessionData.room_id; - if (data[roomId] === undefined) { - data[roomId] = { sessions: {} }; + if (rooms[roomId] === undefined) { + rooms[roomId] = { sessions: {} }; } const sessionData = await this.baseApis.crypto.olmDevice.exportInboundGroupSession( @@ -487,7 +497,7 @@ export class BackupManager { ); const verified = this.baseApis.crypto.checkDeviceInfoTrust(userId, device).isVerified(); - data[roomId]['sessions'][session.sessionId] = { + rooms[roomId]['sessions'][session.sessionId] = { first_message_index: sessionData.first_known_index, forwarded_count: forwardedCount, is_verified: verified, @@ -495,10 +505,7 @@ export class BackupManager { }; } - await this.baseApis.sendKeyBackup( - undefined, undefined, this.backupInfo.version, - { rooms: data }, - ); + await this.baseApis.sendKeyBackup(undefined, undefined, this.backupInfo.version, { rooms }); await this.baseApis.crypto.cryptoStore.unmarkSessionsNeedingBackup(sessions); remaining = await this.baseApis.crypto.cryptoStore.countSessionsNeedingBackup(); @@ -636,7 +643,9 @@ export class Curve25519 implements BackupAlgorithm { return this.publicKey.encrypt(JSON.stringify(plainText)); } - public async decryptSessions(sessions: Record>): Promise[]> { + public async decryptSessions( + sessions: Record, + ): Promise[]> { const privKey = await this.getKey(); const decryption = new global.Olm.PkDecryption(); try { @@ -766,14 +775,12 @@ export class Aes256 implements BackupAlgorithm { return await encryptAES(JSON.stringify(plainText), this.key, data.session_id); } - async decryptSessions(sessions: Record): Promise[]> { + async decryptSessions(sessions: Record): Promise[]> { const keys = []; for (const [sessionId, sessionData] of Object.entries(sessions)) { try { - const decrypted = JSON.parse(await decryptAES( - sessionData.session_data, this.key, sessionId, - )); + const decrypted = JSON.parse(await decryptAES(sessionData.session_data, this.key, sessionId)); decrypted.session_id = sessionId; keys.push(decrypted); } catch (e) { diff --git a/src/crypto/dehydration.ts b/src/crypto/dehydration.ts index 0267e457e..80791b901 100644 --- a/src/crypto/dehydration.ts +++ b/src/crypto/dehydration.ts @@ -36,7 +36,7 @@ export interface IDehydratedDeviceKeyInfo { passphrase?: string; } -interface DeviceKeys { +export interface IDeviceKeys { algorithms: Array; device_id: string; // eslint-disable-line camelcase user_id: string; // eslint-disable-line camelcase @@ -44,7 +44,7 @@ interface DeviceKeys { signatures?: Signatures; } -export interface OneTimeKey { +export interface IOneTimeKey { key: string; fallback?: boolean; signatures?: Signatures; @@ -222,7 +222,7 @@ export class DehydrationManager { // send the keys to the server const deviceId = dehydrateResult.device_id; logger.log("Preparing device keys", deviceId); - const deviceKeys: DeviceKeys = { + const deviceKeys: IDeviceKeys = { algorithms: this.crypto.supportedAlgorithms, device_id: deviceId, user_id: this.crypto.userId, @@ -244,7 +244,7 @@ export class DehydrationManager { logger.log("Preparing one-time keys"); const oneTimeKeys = {}; for (const [keyId, key] of Object.entries(otks.curve25519)) { - const k: OneTimeKey = { key }; + const k: IOneTimeKey = { key }; const signature = account.sign(anotherjson.stringify(k)); k.signatures = { [this.crypto.userId]: { @@ -257,7 +257,7 @@ export class DehydrationManager { logger.log("Preparing fallback keys"); const fallbackKeys = {}; for (const [keyId, key] of Object.entries(fallbacks.curve25519)) { - const k: OneTimeKey = { key, fallback: true }; + const k: IOneTimeKey = { key, fallback: true }; const signature = account.sign(anotherjson.stringify(k)); k.signatures = { [this.crypto.userId]: { diff --git a/src/crypto/index.ts b/src/crypto/index.ts index a33a36f98..39a976964 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -44,7 +44,7 @@ import { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } from "./api"; import { OutgoingRoomKeyRequestManager } from './OutgoingRoomKeyRequestManager'; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { ReciprocateQRCode, SCAN_QR_CODE_METHOD, SHOW_QR_CODE_METHOD } from './verification/QRCode'; -import { SAS } from './verification/SAS'; +import { SAS as SASVerification } from './verification/SAS'; import { keyFromPassphrase } from './key_passphrase'; import { decodeRecoveryKey, encodeRecoveryKey } from './recoverykey'; import { VerificationRequest } from "./verification/request/VerificationRequest"; @@ -53,7 +53,7 @@ import { ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDevi import { IllegalMethod } from "./verification/IllegalMethod"; import { KeySignatureUploadError } from "../errors"; import { decryptAES, encryptAES, calculateKeyCheck } from './aes'; -import { DehydrationManager } from './dehydration'; +import { DehydrationManager, IDeviceKeys, IOneTimeKey } from './dehydration'; import { BackupManager } from "./backup"; import { IStore } from "../store"; import { Room } from "../models/room"; @@ -61,7 +61,7 @@ import { RoomMember } from "../models/room-member"; import { MatrixEvent } from "../models/event"; import { MatrixClient, IKeysUploadResponse, SessionStore, CryptoStore, ISignedKey } from "../client"; import type { EncryptionAlgorithm, DecryptionAlgorithm } from "./algorithms/base"; -import type { RoomList } from "./RoomList"; +import type { IRoomEncryption, RoomList } from "./RoomList"; import { IRecoveryKey, IEncryptedEventInfo } from "./api"; import { IKeyBackupInfo } from "./keybackup"; import { ISyncStateData } from "../sync"; @@ -70,7 +70,7 @@ const DeviceVerification = DeviceInfo.DeviceVerification; const defaultVerificationMethods = { [ReciprocateQRCode.NAME]: ReciprocateQRCode, - [SAS.NAME]: SAS, + [SASVerification.NAME]: SASVerification, // These two can't be used for actual verification, but we do // need to be able to define them here for the verification flows @@ -82,10 +82,13 @@ const defaultVerificationMethods = { /** * verification method names */ -export const verificationMethods = { - RECIPROCATE_QR_CODE: ReciprocateQRCode.NAME, - SAS: SAS.NAME, -}; +// legacy export identifier +export enum verificationMethods { + RECIPROCATE_QR_CODE = ReciprocateQRCode.NAME, + SAS = SASVerification.NAME, +} + +export type VerificationMethod = verificationMethods; export function isCryptoAvailable(): boolean { return Boolean(global.Olm); @@ -142,6 +145,10 @@ interface IDeviceVerificationUpgrade { crossSigningInfo: CrossSigningInfo; } +export interface ICheckOwnCrossSigningTrustOpts { + allowPrivateKeyRequests?: boolean; +} + /** * @typedef {Object} module:crypto~OlmSessionResult * @property {module:crypto/deviceinfo} device device info @@ -1418,7 +1425,7 @@ export class Crypto extends EventEmitter { */ async checkOwnCrossSigningTrust({ allowPrivateKeyRequests = false, - } = {}) { + }: ICheckOwnCrossSigningTrustOpts = {}): Promise { const userId = this.userId; // Before proceeding, ensure our cross-signing public keys have been @@ -1772,7 +1779,7 @@ export class Crypto extends EventEmitter { return this.signObject(deviceKeys).then(() => { return this.baseApis.uploadKeysRequest({ - device_keys: deviceKeys, + device_keys: deviceKeys as Required, }); }); } @@ -1904,9 +1911,9 @@ export class Crypto extends EventEmitter { private async uploadOneTimeKeys() { const promises = []; - const fallbackJson = {}; + const fallbackJson: Record = {}; if (this.getNeedsNewFallback()) { - const fallbackKeys = await this.olmDevice.getFallbackKey(); + const fallbackKeys = await this.olmDevice.getFallbackKey() as Record>; for (const [keyId, key] of Object.entries(fallbackKeys.curve25519)) { const k = { key, fallback: true }; fallbackJson["signed_curve25519:" + keyId] = k; @@ -2252,7 +2259,7 @@ export class Crypto extends EventEmitter { public async legacyDeviceVerification( userId: string, deviceId: string, - method: string, + method: VerificationMethod, ): VerificationRequest { const transactionId = ToDeviceChannel.makeTransactionId(); const channel = new ToDeviceChannel( @@ -2465,7 +2472,7 @@ export class Crypto extends EventEmitter { */ public async setRoomEncryption( roomId: string, - config: any, // TODO types + config: IRoomEncryption, inhibitDeviceQuery?: boolean, ): Promise { // ignore crypto events with no algorithm defined @@ -2522,8 +2529,8 @@ export class Crypto extends EventEmitter { crypto: this, olmDevice: this.olmDevice, baseApis: this.baseApis, - roomId: roomId, - config: config, + roomId, + config, }); this.roomEncryptors[roomId] = alg; @@ -2878,7 +2885,7 @@ export class Crypto extends EventEmitter { */ public async onCryptoEvent(event: MatrixEvent): Promise { const roomId = event.getRoomId(); - const content = event.getContent(); + const content = event.getContent(); try { // inhibit the device list refresh for now - it will happen once we've diff --git a/src/crypto/keybackup.ts b/src/crypto/keybackup.ts index 13c5621b9..4d8981ff8 100644 --- a/src/crypto/keybackup.ts +++ b/src/crypto/keybackup.ts @@ -24,6 +24,7 @@ export interface IKeyBackupSession { ciphertext: string; ephemeral: string; mac: string; + iv: string; }; } diff --git a/src/crypto/olmlib.ts b/src/crypto/olmlib.ts index 7a5e3a26c..d00c249ea 100644 --- a/src/crypto/olmlib.ts +++ b/src/crypto/olmlib.ts @@ -28,7 +28,7 @@ import OlmDevice from "./OlmDevice"; import { DeviceInfo } from "./deviceinfo"; import { logger } from '../logger'; import * as utils from "../utils"; -import { OneTimeKey } from "./dehydration"; +import { IOneTimeKey } from "./dehydration"; import { MatrixClient } from "../client"; enum Algorithm { @@ -407,7 +407,7 @@ export async function ensureOlmSessionsForDevices( async function _verifyKeyAndStartSession( olmDevice: OlmDevice, - oneTimeKey: OneTimeKey, + oneTimeKey: IOneTimeKey, userId: string, deviceInfo: DeviceInfo, ): Promise { @@ -465,7 +465,7 @@ export interface IObject { */ export async function verifySignature( olmDevice: OlmDevice, - obj: OneTimeKey | IObject, + obj: IOneTimeKey | IObject, signingUserId: string, signingDeviceId: string, signingKey: string, diff --git a/src/filter.ts b/src/filter.ts index 859aeb0c7..618c727c3 100644 --- a/src/filter.ts +++ b/src/filter.ts @@ -39,7 +39,7 @@ function setProp(obj: object, keyNesting: string, val: any) { } /* eslint-disable camelcase */ -interface IFilterDefinition { +export interface IFilterDefinition { event_fields?: string[]; event_format?: "client" | "federation"; presence?: IFilterComponent; @@ -47,7 +47,7 @@ interface IFilterDefinition { room?: IRoomFilter; } -interface IRoomEventFilter extends IFilterComponent { +export interface IRoomEventFilter extends IFilterComponent { lazy_load_members?: boolean; include_redundant_members?: boolean; } diff --git a/src/models/MSC3089Branch.ts b/src/models/MSC3089Branch.ts index 87acee0f8..7bb8c356e 100644 --- a/src/models/MSC3089Branch.ts +++ b/src/models/MSC3089Branch.ts @@ -70,8 +70,8 @@ export class MSC3089Branch { * @param {string} name The new name for this file. * @returns {Promise} Resolves when complete. */ - public setName(name: string): Promise { - return this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { + public async setName(name: string): Promise { + await this.client.sendStateEvent(this.roomId, UNSTABLE_MSC3089_BRANCH.name, { ...this.indexEvent.getContent(), name: name, }, this.id); diff --git a/src/models/MSC3089TreeSpace.ts b/src/models/MSC3089TreeSpace.ts index 77966d9fb..20585eab0 100644 --- a/src/models/MSC3089TreeSpace.ts +++ b/src/models/MSC3089TreeSpace.ts @@ -111,8 +111,8 @@ export class MSC3089TreeSpace { * @param {string} name The new name for the space. * @returns {Promise} Resolves when complete. */ - public setName(name: string): Promise { - return this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, ""); + public async setName(name: string): Promise { + await this.client.sendStateEvent(this.roomId, EventType.RoomName, { name }, ""); } /** @@ -190,7 +190,7 @@ export class MSC3089TreeSpace { } pls['users'] = users; - return this.client.sendStateEvent(this.roomId, EventType.RoomPowerLevels, pls, ""); + await this.client.sendStateEvent(this.roomId, EventType.RoomPowerLevels, pls, ""); } /** diff --git a/src/models/room.ts b/src/models/room.ts index 9970ae595..716da1214 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -31,7 +31,7 @@ import { IRoomSummary, RoomSummary } from "./room-summary"; import { logger } from '../logger'; import { ReEmitter } from '../ReEmitter'; import { EventType, RoomCreateTypeField, RoomType } from "../@types/event"; -import { IRoomVersionsCapability, MatrixClient, RoomVersionStability } from "../client"; +import { IRoomVersionsCapability, MatrixClient, PendingEventOrdering, RoomVersionStability } from "../client"; import { ResizeMethod } from "../@types/partials"; import { Filter } from "../filter"; import { RoomState } from "./room-state"; @@ -64,7 +64,7 @@ function synthesizeReceipt(userId: string, event: MatrixEvent, receiptType: stri interface IOpts { storageToken?: string; - pendingEventOrdering?: "chronological" | "detached"; + pendingEventOrdering?: PendingEventOrdering; timelineSupport?: boolean; unstableClientRelationAggregation?: boolean; lazyLoadMembers?: boolean; @@ -218,7 +218,7 @@ export class Room extends EventEmitter { this.setMaxListeners(100); this.reEmitter = new ReEmitter(this); - opts.pendingEventOrdering = opts.pendingEventOrdering || "chronological"; + opts.pendingEventOrdering = opts.pendingEventOrdering || PendingEventOrdering.Chronological; if (["chronological", "detached"].indexOf(opts.pendingEventOrdering) === -1) { throw new Error( "opts.pendingEventOrdering MUST be either 'chronological' or " + @@ -665,8 +665,7 @@ export class Room extends EventEmitter { private async loadMembers(): Promise<{ memberEvents: MatrixEvent[], fromServer: boolean }> { // were the members loaded from the server? let fromServer = false; - let rawMembersEvents = - await this.client.store.getOutOfBandMembers(this.roomId); + let rawMembersEvents = await this.client.store.getOutOfBandMembers(this.roomId); if (rawMembersEvents === null) { fromServer = true; rawMembersEvents = await this.loadMembersFromServer(); diff --git a/src/models/search-result.js b/src/models/search-result.js deleted file mode 100644 index fcf8bb43f..000000000 --- a/src/models/search-result.js +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket Ltd -Copyright 2019 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. -*/ - -/** - * @module models/search-result - */ - -import { EventContext } from "./event-context"; - -/** - * Construct a new SearchResult - * - * @param {number} rank where this SearchResult ranks in the results - * @param {event-context.EventContext} eventContext the matching event and its - * context - * - * @constructor - */ -export function SearchResult(rank, eventContext) { - this.rank = rank; - this.context = eventContext; -} - -/** - * Create a SearchResponse from the response to /search - * @static - * @param {Object} jsonObj - * @param {function} eventMapper - * @return {SearchResult} - */ - -SearchResult.fromJson = function(jsonObj, eventMapper) { - const jsonContext = jsonObj.context || {}; - const events_before = jsonContext.events_before || []; - const events_after = jsonContext.events_after || []; - - const context = new EventContext(eventMapper(jsonObj.result)); - - context.setPaginateToken(jsonContext.start, true); - context.addEvents(events_before.map(eventMapper), true); - context.addEvents(events_after.map(eventMapper), false); - context.setPaginateToken(jsonContext.end, false); - - return new SearchResult(jsonObj.rank, context); -}; - diff --git a/src/models/search-result.ts b/src/models/search-result.ts new file mode 100644 index 000000000..83271fba2 --- /dev/null +++ b/src/models/search-result.ts @@ -0,0 +1,60 @@ +/* +Copyright 2015 - 2021 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. +*/ + +/** + * @module models/search-result + */ + +import { EventContext } from "./event-context"; +import { EventMapper } from "../event-mapper"; +import { IResultContext, ISearchResult } from "../@types/search"; + +export class SearchResult { + /** + * Create a SearchResponse from the response to /search + * @static + * @param {Object} jsonObj + * @param {function} eventMapper + * @return {SearchResult} + */ + + static fromJson(jsonObj: ISearchResult, eventMapper: EventMapper): SearchResult { + const jsonContext = jsonObj.context || {} as IResultContext; + const eventsBefore = jsonContext.events_before || []; + const eventsAfter = jsonContext.events_after || []; + + const context = new EventContext(eventMapper(jsonObj.result)); + + context.setPaginateToken(jsonContext.start, true); + context.addEvents(eventsBefore.map(eventMapper), true); + context.addEvents(eventsAfter.map(eventMapper), false); + context.setPaginateToken(jsonContext.end, false); + + return new SearchResult(jsonObj.rank, context); + } + + /** + * Construct a new SearchResult + * + * @param {number} rank where this SearchResult ranks in the results + * @param {event-context.EventContext} context the matching event and its + * context + * + * @constructor + */ + constructor(public readonly rank: number, public readonly context: EventContext) {} +} + diff --git a/src/store/index.ts b/src/store/index.ts index 80cdc8a1a..e835d3791 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -22,6 +22,7 @@ import { MatrixEvent } from "../models/event"; import { Filter } from "../filter"; import { RoomSummary } from "../models/room-summary"; import { IMinimalEvent, IGroups, IRooms } from "../sync-accumulator"; +import { IStartClientOpts } from "../client"; export interface ISavedSync { nextBatch: string; @@ -35,6 +36,8 @@ export interface ISavedSync { * @constructor */ export interface IStore { + readonly accountData: Record; // type : content + /** @return {Promise} whether or not the database was newly created in this session. */ isNewlyCreated(): Promise; @@ -194,7 +197,7 @@ export interface IStore { /** * Save does nothing as there is no backing data store. */ - save(force: boolean): void; + save(force?: boolean): void; /** * Startup does nothing. @@ -222,13 +225,13 @@ export interface IStore { */ deleteAllData(): Promise; - getOutOfBandMembers(roomId: string): Promise; + getOutOfBandMembers(roomId: string): Promise; - setOutOfBandMembers(roomId: string, membershipEvents: MatrixEvent[]): Promise; + setOutOfBandMembers(roomId: string, membershipEvents: object[]): Promise; clearOutOfBandMembers(roomId: string): Promise; - getClientOptions(): Promise; + getClientOptions(): Promise; storeClientOptions(options: object): Promise; } diff --git a/src/store/memory.ts b/src/store/memory.ts index 452eb0c9a..94090f9c5 100644 --- a/src/store/memory.ts +++ b/src/store/memory.ts @@ -59,7 +59,7 @@ export class MemoryStore implements IStore { // filterId: Filter // } private filters: Record> = {}; - private accountData: Record = {}; // type : content + public accountData: Record = {}; // type : content private readonly localStorage: Storage; private oobMembers: Record = {}; // roomId: [member events] private clientOptions = {}; diff --git a/src/store/stub.ts b/src/store/stub.ts index 1a136d1d1..97ed0165e 100644 --- a/src/store/stub.ts +++ b/src/store/stub.ts @@ -33,9 +33,10 @@ import { RoomSummary } from "../models/room-summary"; * @constructor */ export class StubStore implements IStore { + public readonly accountData = {}; // stub private fromToken: string = null; - /** @return {Promise} whether or not the database was newly created in this session. */ + /** @return {Promise} whether or not the database was newly created in this session. */ public isNewlyCreated(): Promise { return Promise.resolve(true); } diff --git a/src/sync.ts b/src/sync.ts index 831c7b084..465c31983 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -318,7 +318,7 @@ export class SyncApi { this._peekRoom = this.createRoom(roomId); return this.client.roomInitialSync(roomId, 20).then((response) => { // make sure things are init'd - response.messages = response.messages || {}; + response.messages = response.messages || { chunk: [] }; response.messages.chunk = response.messages.chunk || []; response.state = response.state || []; From 3bff5430f69ad187f195810ccd446cdcd2e896b2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 10 Jul 2021 15:55:19 +0100 Subject: [PATCH 061/129] delint --- src/@types/search.ts | 6 +++--- src/client.ts | 6 ++++-- src/crypto/backup.ts | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/@types/search.ts b/src/@types/search.ts index f1af733cd..0aa8a34a4 100644 --- a/src/@types/search.ts +++ b/src/@types/search.ts @@ -64,9 +64,9 @@ export interface IResultRoomEvents { next_batch?: string; order: number; results: string[]; - } + }; }; - } + }; next_batch?: string; } @@ -98,7 +98,7 @@ export interface ISearchRequestBody { group_by: { key: GroupKey; }[]; - } + }; }; }; } diff --git a/src/client.ts b/src/client.ts index 516a3b0dd..0c2a83f39 100644 --- a/src/client.ts +++ b/src/client.ts @@ -546,7 +546,7 @@ interface IOpenIDToken { interface IRoomInitialSyncResponse { room_id: string; - membership: "invite" | "join" | "leave" | "ban", + membership: "invite" | "join" | "leave" | "ban"; messages?: { start?: string; end?: string; @@ -633,7 +633,7 @@ interface IDownloadKeyResult { device_display_name: string; }; }; - } + }; }; } @@ -6796,6 +6796,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Object with room_id and servers. * @return {module:http-api.MatrixError} Rejects: with an error response. */ + // eslint-disable-next-line camelcase public resolveRoomAlias(roomAlias: string, callback?: Callback): Promise<{ room_id: string, servers: string[] }> { // TODO: deprecate this or getRoomIdForAlias const path = utils.encodeUri("/directory/room/$alias", { $alias: roomAlias }); @@ -6961,6 +6962,7 @@ export class MatrixClient extends EventEmitter { userId: string, info?: string, callback?: Callback, + // eslint-disable-next-line camelcase ): Promise<{ avatar_url?: string, displayname?: string }> { if (utils.isFunction(info)) { callback = info as any as Callback; // legacy diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index fbbdec933..82f90a6c7 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -98,7 +98,7 @@ export interface IKeyBackup { [sessionId: string]: IKeyBackupSession; }; }; - } + }; } /** From 67189ad323488c88087a57c3fd000f1c092482b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Sun, 11 Jul 2021 10:47:42 +0200 Subject: [PATCH 062/129] Use an enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/models/event-timeline.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/event-timeline.ts b/src/models/event-timeline.ts index b5bb83db7..c89da5c0b 100644 --- a/src/models/event-timeline.ts +++ b/src/models/event-timeline.ts @@ -22,6 +22,7 @@ import { RoomState } from "./room-state"; import { EventTimelineSet } from "./event-timeline-set"; import { MatrixEvent } from "./event"; import { Filter } from "../filter"; +import { EventType } from "../@types/event"; export enum Direction { Backward = "b", @@ -55,7 +56,7 @@ export class EventTimeline { if (!event.sender) { event.sender = stateContext.getSentinelMember(event.getSender()); } - if (!event.target && event.getType() === "m.room.member") { + if (!event.target && event.getType() === EventType.RoomMember) { event.target = stateContext.getSentinelMember(event.getStateKey()); } From 3c77a8772aa4c72013a79aae1c5f240bd9344259 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 11 Jul 2021 20:54:51 -0600 Subject: [PATCH 063/129] Add minimal types for "notification settings" UI For https://github.com/vector-im/element-web/issues/17782 --- src/@types/PushRules.ts | 154 ++++++++++++++++++++++++++++++++++++++++ src/@types/threepids.ts | 28 ++++++++ src/client.ts | 17 +++-- 3 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 src/@types/PushRules.ts create mode 100644 src/@types/threepids.ts diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts new file mode 100644 index 000000000..74b1b16b7 --- /dev/null +++ b/src/@types/PushRules.ts @@ -0,0 +1,154 @@ +/* +Copyright 2021 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. +*/ + +export enum PushRuleActionName { + DontNotify = "dont_notify", + Notify = "notify", + Coalesce = "coalesce", +} + +export enum TweakName { + Highlight = "highlight", + Sound = "sound", +} + +export type Tweak = { + set_tweak: N; // eslint-disable-line camel-case + value: V; +} + +export type TweakHighlight = Tweak; +export type TweakSound = Tweak; + +export type Tweaks = TweakHighlight | TweakSound; + +export enum ConditionOperator { + ExactEquals = "==", + LessThan = "<", + GreaterThan = ">", + GreaterThanOrEqual = ">=", + LessThanOrEqual = "<=", +} + +export type PushRuleAction = Tweaks | PushRuleActionName; + +export type MemberCountCondition + + = `${Op}${N}` | (Op extends ConditionOperator.ExactEquals ? `${N}` : never); + +export type AnyMemberCountCondition = MemberCountCondition; + +export const DMMemberCountCondition: MemberCountCondition<2> = "2"; + +export function isDmMemberCountCondition(condition: AnyMemberCountCondition): boolean { + return condition === "==2" || condition === "2"; +} + +export enum ConditionKind { + EventMatch = "event_match", + ContainsDisplayName = "contains_display_name", + RoomMemberCount = "room_member_count", + SenderNotificationPermission = "sender_notification_permission", +} + +export enum PushRuleKind { + Override = "override", + ContentSpecific = "content", + RoomSpecific = "room", + SenderSpecific = "sender", + Underride = "underride", +} + +export type PushRuleSet = { + [k in PushRuleKind]?: IPushRule[]; +}; + +export interface IPushRule { + actions: PushRuleAction[]; + conditions?: PushRuleCondition[]; + default: boolean; + enabled: boolean; + pattern?: string; + rule_id: RuleId | string; // eslint-disable-line camel-case +} + +export interface IAnnotatedPushRule extends IPushRule { + kind: PushRuleKind; +} + +export interface IPushRuleCondition { + [k: string]: any; // for custom conditions, there can be other fields here + kind: N; +} + +export interface IEventMatchCondition extends IPushRuleCondition { + key: string; + pattern: string; +} + +export interface IContainsDisplayNameCondition extends IPushRuleCondition { + // no additional fields +} + +export interface IRoomMemberCountCondition extends IPushRuleCondition { + is: AnyMemberCountCondition; +} + +export interface ISenderNotificationPermissionCondition + extends IPushRuleCondition { + key: string; +} + +export type PushRuleCondition = IPushRuleCondition + | IEventMatchCondition + | IContainsDisplayNameCondition + | IRoomMemberCountCondition + | ISenderNotificationPermissionCondition; + +export interface IPushRules { + global: PushRuleSet; + device?: PushRuleSet; +} + +export enum RuleId { + Master = ".m.rule.master", + ContainsDisplayName = ".m.rule.contains_display_name", + ContainsUserName = ".m.rule.contains_user_name", + AtRoomNotification = ".m.rule.roomnotif", + DM = ".m.rule.room_one_to_one", + EncryptedDM = ".m.rule.encrypted_room_one_to_one", + Message = ".m.rule.message", + EncryptedMessage = ".m.rule.encrypted", + InviteToSelf = ".m.rule.invite_for_me", + MemberEvent = ".m.rule.member_event", + IncomingCall = ".m.rule.call", + SuppressNotices = ".m.rule.suppress_notices", + Tombstone = ".m.rule.tombstone", +} + +export interface IPusher { + app_display_name: string; // eslint-disable-line camel-case + app_id: string; // eslint-disable-line camel-case + data: { + format?: string; // TODO: Types + url?: string; // TODO: Required if kind==http + }, + device_display_name: string; // eslint-disable-line camel-case + kind: string; // TODO: Types + lang: string; + profile_tag?: string; // eslint-disable-line camel-case + pushkey: string; +} diff --git a/src/@types/threepids.ts b/src/@types/threepids.ts new file mode 100644 index 000000000..387917010 --- /dev/null +++ b/src/@types/threepids.ts @@ -0,0 +1,28 @@ +/* +Copyright 2021 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. +*/ + +export enum ThreepidMedium { + Email = "email", + Phone = "msisdn", +} + +// TODO: Are these types universal, or specific to just /account/3pid? +export interface IThirdPartyIdentifier { + added_at: number; // eslint-disable-line camel-case + address: string; + medium: ThreepidMedium; + validated_at: number; // eslint-disable-line camel-case +} diff --git a/src/client.ts b/src/client.ts index e5424224c..930e48347 100644 --- a/src/client.ts +++ b/src/client.ts @@ -117,6 +117,8 @@ import { WebStorageSessionStore } from "./store/session/webstorage"; import { BackupManager, IKeyBackupCheck, IPreparedKeyBackupVersion, TrustInfo } from "./crypto/backup"; import { DEFAULT_TREE_POWER_LEVELS_TEMPLATE, MSC3089TreeSpace } from "./models/MSC3089TreeSpace"; import { ISignatures } from "./@types/signed"; +import { IPusher, IPushRules } from "./@types/PushRules"; +import { IThirdPartyIdentifier } from "./@types/threepids"; export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; export type SessionStore = WebStorageSessionStore; @@ -3636,7 +3638,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async sendReadReceipt(event: MatrixEvent, opts: { hidden?: boolean }, callback?: Callback): Promise { + public async sendReadReceipt(event: MatrixEvent, opts?: { hidden?: boolean }, callback?: Callback): Promise { if (typeof (opts) === 'function') { callback = opts as any as Callback; // legacy opts = {}; @@ -6759,10 +6761,10 @@ export class MatrixClient extends EventEmitter { /** * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves to a list of the user's threepids. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getThreePids(callback?: Callback): Promise { // TODO: Types + public getThreePids(callback?: Callback): Promise<{ threepids: IThirdPartyIdentifier[] }> { const path = "/account/3pid"; return this.http.authedRequest( callback, "GET", path, undefined, undefined, @@ -6989,7 +6991,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Array of objects representing pushers * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getPushers(callback?: Callback): Promise { // TODO: Types + public getPushers(callback?: Callback): Promise<{ pushers: IPusher[] }> { // TODO: Types const path = "/pushers"; return this.http.authedRequest( callback, "GET", path, undefined, undefined, @@ -7004,7 +7006,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: Empty json object on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setPusher(pusher: any, callback?: Callback): Promise { // TODO: Types + public setPusher(pusher: any, callback?: Callback): Promise<{}> { const path = "/pushers/set"; return this.http.authedRequest( callback, "POST", path, null, pusher, @@ -7012,11 +7014,12 @@ export class MatrixClient extends EventEmitter { } /** + * Get the push rules for the account from the server. * @param {module:client.callback} callback Optional. - * @return {Promise} Resolves: TODO + * @return {Promise} Resolves to the push rules. * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public getPushRules(callback?: Callback): Promise { // TODO: Types + public getPushRules(callback?: Callback): Promise { return this.http.authedRequest(callback, "GET", "/pushrules/").then(rules => { return PushProcessor.rewriteDefaultRules(rules); }); From fb7184e6fb74e6c897e5a94d94d86ffee25a1e1b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 11 Jul 2021 20:56:52 -0600 Subject: [PATCH 064/129] Reorganize types a bit --- src/@types/PushRules.ts | 57 +++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index 74b1b16b7..f379a0a98 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -64,31 +64,6 @@ export enum ConditionKind { SenderNotificationPermission = "sender_notification_permission", } -export enum PushRuleKind { - Override = "override", - ContentSpecific = "content", - RoomSpecific = "room", - SenderSpecific = "sender", - Underride = "underride", -} - -export type PushRuleSet = { - [k in PushRuleKind]?: IPushRule[]; -}; - -export interface IPushRule { - actions: PushRuleAction[]; - conditions?: PushRuleCondition[]; - default: boolean; - enabled: boolean; - pattern?: string; - rule_id: RuleId | string; // eslint-disable-line camel-case -} - -export interface IAnnotatedPushRule extends IPushRule { - kind: PushRuleKind; -} - export interface IPushRuleCondition { [k: string]: any; // for custom conditions, there can be other fields here kind: N; @@ -118,9 +93,13 @@ export type PushRuleCondition = IPushRuleCondition | IRoomMemberCountCondition | ISenderNotificationPermissionCondition; -export interface IPushRules { - global: PushRuleSet; - device?: PushRuleSet; + +export enum PushRuleKind { + Override = "override", + ContentSpecific = "content", + RoomSpecific = "room", + SenderSpecific = "sender", + Underride = "underride", } export enum RuleId { @@ -139,6 +118,28 @@ export enum RuleId { Tombstone = ".m.rule.tombstone", } +export type PushRuleSet = { + [k in PushRuleKind]?: IPushRule[]; +}; + +export interface IPushRule { + actions: PushRuleAction[]; + conditions?: PushRuleCondition[]; + default: boolean; + enabled: boolean; + pattern?: string; + rule_id: RuleId | string; // eslint-disable-line camel-case +} + +export interface IAnnotatedPushRule extends IPushRule { + kind: PushRuleKind; +} + +export interface IPushRules { + global: PushRuleSet; + device?: PushRuleSet; +} + export interface IPusher { app_display_name: string; // eslint-disable-line camel-case app_id: string; // eslint-disable-line camel-case From 11e25ea9a260db3d9e01dfc24e37cb48fd2038d5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 11 Jul 2021 21:02:33 -0600 Subject: [PATCH 065/129] Appease linter --- src/@types/PushRules.ts | 24 ++++++++++++++---------- src/@types/requests.ts | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index f379a0a98..4a3017b99 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +// allow camelcase as these are things that go onto the wire +/* eslint-disable camelcase */ + export enum PushRuleActionName { DontNotify = "dont_notify", Notify = "notify", @@ -26,9 +29,9 @@ export enum TweakName { } export type Tweak = { - set_tweak: N; // eslint-disable-line camel-case + set_tweak: N; value: V; -} +}; export type TweakHighlight = Tweak; export type TweakSound = Tweak; @@ -49,7 +52,7 @@ export type MemberCountCondition = `${Op}${N}` | (Op extends ConditionOperator.ExactEquals ? `${N}` : never); -export type AnyMemberCountCondition = MemberCountCondition; +export type AnyMemberCountCondition = MemberCountCondition; export const DMMemberCountCondition: MemberCountCondition<2> = "2"; @@ -93,7 +96,6 @@ export type PushRuleCondition = IPushRuleCondition | IRoomMemberCountCondition | ISenderNotificationPermissionCondition; - export enum PushRuleKind { Override = "override", ContentSpecific = "content", @@ -128,7 +130,7 @@ export interface IPushRule { default: boolean; enabled: boolean; pattern?: string; - rule_id: RuleId | string; // eslint-disable-line camel-case + rule_id: RuleId | string; } export interface IAnnotatedPushRule extends IPushRule { @@ -141,15 +143,17 @@ export interface IPushRules { } export interface IPusher { - app_display_name: string; // eslint-disable-line camel-case - app_id: string; // eslint-disable-line camel-case + app_display_name: string; + app_id: string; data: { format?: string; // TODO: Types url?: string; // TODO: Required if kind==http - }, - device_display_name: string; // eslint-disable-line camel-case + }; + device_display_name: string; kind: string; // TODO: Types lang: string; - profile_tag?: string; // eslint-disable-line camel-case + profile_tag?: string; pushkey: string; } + +/* eslint-enable camelcase */ diff --git a/src/@types/requests.ts b/src/@types/requests.ts index eaf682831..551a0027f 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -17,7 +17,7 @@ limitations under the License. import { Callback } from "../client"; import { Preset, Visibility } from "./partials"; -// allow camelcase as these are things go onto the wire +// allow camelcase as these are things that go onto the wire /* eslint-disable camelcase */ export interface IJoinRoomOpts { From 5f2ed4450e66b9cdebeeab7647a613b07d8de17c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sun, 11 Jul 2021 21:04:10 -0600 Subject: [PATCH 066/129] -- --- src/@types/threepids.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/@types/threepids.ts b/src/@types/threepids.ts index 387917010..2b1a03378 100644 --- a/src/@types/threepids.ts +++ b/src/@types/threepids.ts @@ -21,8 +21,8 @@ export enum ThreepidMedium { // TODO: Are these types universal, or specific to just /account/3pid? export interface IThirdPartyIdentifier { - added_at: number; // eslint-disable-line camel-case + added_at: number; // eslint-disable-line camelcase address: string; medium: ThreepidMedium; - validated_at: number; // eslint-disable-line camel-case + validated_at: number; // eslint-disable-line camelcase } From e3f7c848d7f725a09d2542740c6e24d82d4cd322 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 08:44:34 +0100 Subject: [PATCH 067/129] iterate types based on PR review --- src/client.ts | 7 +++---- src/crypto/EncryptionSetup.ts | 16 ++++++++++++++++ src/filter.ts | 2 +- src/models/room.ts | 7 ++++--- src/store/index.ts | 6 +++--- src/store/indexeddb.ts | 6 +++--- src/store/memory.ts | 9 +++++---- src/store/stub.ts | 6 +++--- 8 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/client.ts b/src/client.ts index 0c2a83f39..7cc9c601a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -490,6 +490,7 @@ interface IKeyBackupPath { } interface IMediaConfig { + [key: string]: any; // extensible "m.upload.size"?: number; } @@ -4374,14 +4375,12 @@ export class MatrixClient extends EventEmitter { // eslint-disable-next-line camelcase public setProfileInfo(info: "avatar_url", data: { avatar_url: string }, callback?: Callback): Promise<{}>; public setProfileInfo(info: "displayname", data: { displayname: string }, callback?: Callback): Promise<{}>; - public setProfileInfo(info: string, data: object, callback?: Callback): Promise<{}> { + public setProfileInfo(info: "avatar_url" | "displayname", data: object, callback?: Callback): Promise<{}> { const path = utils.encodeUri("/profile/$userId/$info", { $userId: this.credentials.userId, $info: info, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, data, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, data); } /** diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 8b538afa2..faa4bd2e8 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -1,3 +1,19 @@ +/* +Copyright 2021 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 { logger } from "../logger"; import { MatrixEvent } from "../models/event"; import { EventEmitter } from "events"; diff --git a/src/filter.ts b/src/filter.ts index 618c727c3..8cbd2a67e 100644 --- a/src/filter.ts +++ b/src/filter.ts @@ -86,7 +86,7 @@ export class Filter { * @param {Object} jsonObj * @return {Filter} */ - static fromJson(userId: string, filterId: string, jsonObj: IFilterDefinition): Filter { + public static fromJson(userId: string, filterId: string, jsonObj: IFilterDefinition): Filter { const filter = new Filter(userId, filterId); filter.setDefinition(jsonObj); return filter; diff --git a/src/models/room.ts b/src/models/room.ts index 716da1214..65abbd099 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -25,7 +25,7 @@ import { EventTimeline } from "./event-timeline"; import { getHttpUriForMxc } from "../content-repo"; import * as utils from "../utils"; import { normalize } from "../utils"; -import { EventStatus, MatrixEvent } from "./event"; +import { EventStatus, IEvent, MatrixEvent } from "./event"; import { RoomMember } from "./room-member"; import { IRoomSummary, RoomSummary } from "./room-summary"; import { logger } from '../logger'; @@ -35,6 +35,7 @@ import { IRoomVersionsCapability, MatrixClient, PendingEventOrdering, RoomVersio import { ResizeMethod } from "../@types/partials"; import { Filter } from "../filter"; import { RoomState } from "./room-state"; +import { IMinimalEvent } from "../sync-accumulator"; // These constants are used as sane defaults when the homeserver doesn't support // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be @@ -649,7 +650,7 @@ export class Room extends EventEmitter { } } - private async loadMembersFromServer(): Promise { + private async loadMembersFromServer(): Promise { const lastSyncToken = this.client.store.getSyncToken(); const queryString = utils.encodeParams({ not_membership: "leave", @@ -712,7 +713,7 @@ export class Room extends EventEmitter { if (fromServer) { const oobMembers = this.currentState.getMembers() .filter((m) => m.isOutOfBand()) - .map((m) => m.events.member.event); + .map((m) => m.events.member.event as IEvent); logger.log(`LL: telling store to write ${oobMembers.length}` + ` members for room ${this.roomId}`); const store = this.client.store; diff --git a/src/store/index.ts b/src/store/index.ts index e835d3791..01650f86a 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -18,7 +18,7 @@ import { EventType } from "../@types/event"; import { Group } from "../models/group"; import { Room } from "../models/room"; import { User } from "../models/user"; -import { MatrixEvent } from "../models/event"; +import { IEvent, MatrixEvent } from "../models/event"; import { Filter } from "../filter"; import { RoomSummary } from "../models/room-summary"; import { IMinimalEvent, IGroups, IRooms } from "../sync-accumulator"; @@ -225,9 +225,9 @@ export interface IStore { */ deleteAllData(): Promise; - getOutOfBandMembers(roomId: string): Promise; + getOutOfBandMembers(roomId: string): Promise; - setOutOfBandMembers(roomId: string, membershipEvents: object[]): Promise; + setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise; clearOutOfBandMembers(roomId: string): Promise; diff --git a/src/store/indexeddb.ts b/src/store/indexeddb.ts index f7f9fb8b9..aed61dae2 100644 --- a/src/store/indexeddb.ts +++ b/src/store/indexeddb.ts @@ -22,7 +22,7 @@ import { MemoryStore, IOpts as IBaseOpts } from "./memory"; import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend.js"; import { RemoteIndexedDBStoreBackend } from "./indexeddb-remote-backend.js"; import { User } from "../models/user"; -import { MatrixEvent } from "../models/event"; +import { IEvent, MatrixEvent } from "../models/event"; import { logger } from '../logger'; import { ISavedSync } from "./index"; @@ -247,7 +247,7 @@ export class IndexedDBStore extends MemoryStore { * @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members * @returns {null} in case the members for this room haven't been stored yet */ - public getOutOfBandMembers = this.degradable((roomId: string): Promise => { + public getOutOfBandMembers = this.degradable((roomId: string): Promise => { return this.backend.getOutOfBandMembers(roomId); }, "getOutOfBandMembers"); @@ -259,7 +259,7 @@ export class IndexedDBStore extends MemoryStore { * @param {event[]} membershipEvents the membership events to store * @returns {Promise} when all members have been stored */ - public setOutOfBandMembers = this.degradable((roomId: string, membershipEvents: MatrixEvent[]): Promise => { + public setOutOfBandMembers = this.degradable((roomId: string, membershipEvents: IEvent[]): Promise => { super.setOutOfBandMembers(roomId, membershipEvents); return this.backend.setOutOfBandMembers(roomId, membershipEvents); }, "setOutOfBandMembers"); diff --git a/src/store/memory.ts b/src/store/memory.ts index 94090f9c5..00dceb711 100644 --- a/src/store/memory.ts +++ b/src/store/memory.ts @@ -23,12 +23,13 @@ import { EventType } from "../@types/event"; import { Group } from "../models/group"; import { Room } from "../models/room"; import { User } from "../models/user"; -import { MatrixEvent } from "../models/event"; +import { IEvent, MatrixEvent } from "../models/event"; import { RoomState } from "../models/room-state"; import { RoomMember } from "../models/room-member"; import { Filter } from "../filter"; import { ISavedSync, IStore } from "./index"; import { RoomSummary } from "../models/room-summary"; +import { IMinimalEvent } from "../sync-accumulator"; function isValidFilterId(filterId: string): boolean { const isValidStr = typeof filterId === "string" && @@ -61,7 +62,7 @@ export class MemoryStore implements IStore { private filters: Record> = {}; public accountData: Record = {}; // type : content private readonly localStorage: Storage; - private oobMembers: Record = {}; // roomId: [member events] + private oobMembers: Record = {}; // roomId: [member events] private clientOptions = {}; constructor(opts: IOpts = {}) { @@ -415,7 +416,7 @@ export class MemoryStore implements IStore { * @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members * @returns {null} in case the members for this room haven't been stored yet */ - public getOutOfBandMembers(roomId: string): Promise { + public getOutOfBandMembers(roomId: string): Promise { return Promise.resolve(this.oobMembers[roomId] || null); } @@ -427,7 +428,7 @@ export class MemoryStore implements IStore { * @param {event[]} membershipEvents the membership events to store * @returns {Promise} when all members have been stored */ - public setOutOfBandMembers(roomId: string, membershipEvents: MatrixEvent[]): Promise { + public setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise { this.oobMembers[roomId] = membershipEvents; return Promise.resolve(); } diff --git a/src/store/stub.ts b/src/store/stub.ts index 97ed0165e..f7adb9b3e 100644 --- a/src/store/stub.ts +++ b/src/store/stub.ts @@ -23,7 +23,7 @@ import { EventType } from "../@types/event"; import { Group } from "../models/group"; import { Room } from "../models/room"; import { User } from "../models/user"; -import { MatrixEvent } from "../models/event"; +import { IEvent, MatrixEvent } from "../models/event"; import { Filter } from "../filter"; import { ISavedSync, IStore } from "./index"; import { RoomSummary } from "../models/room-summary"; @@ -265,11 +265,11 @@ export class StubStore implements IStore { return Promise.resolve(); } - public getOutOfBandMembers(): Promise { + public getOutOfBandMembers(): Promise { return Promise.resolve(null); } - public setOutOfBandMembers(roomId: string, membershipEvents: MatrixEvent[]): Promise { + public setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise { return Promise.resolve(); } From b33429317cf2d25d37aca06c7c7b57e7aac5114b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 09:02:47 +0100 Subject: [PATCH 068/129] Fix setTimeout/setInterval typing --- src/@types/global.d.ts | 6 ++++++ src/client.ts | 4 ++-- src/crypto/DeviceList.ts | 2 +- src/crypto/OutgoingRoomKeyRequestManager.ts | 4 ++-- src/sync.ts | 2 +- src/webrtc/call.ts | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index dc39bd730..d09d92f25 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -20,6 +20,12 @@ import "@matrix-org/olm"; export {}; declare global { + // use `number` as the return type in all cases for global.set{Interval,Timeout}, + // so we don't accidentally use the methods on NodeJS.Timeout - they only exist in a subset of environments. + // The overload for clear{Interval,Timeout} is resolved as expected. + function setInterval(handler: TimerHandler, timeout: number, ...arguments: any[]): number; + function setTimeout(handler: TimerHandler, timeout: number, ...arguments: any[]): number; + namespace NodeJS { interface Global { localStorage: Storage; diff --git a/src/client.ts b/src/client.ts index 7cc9c601a..c01b2b230 100644 --- a/src/client.ts +++ b/src/client.ts @@ -731,7 +731,7 @@ export class MatrixClient extends EventEmitter { protected syncLeftRoomsPromise: Promise; protected syncedLeftRooms = false; protected clientOpts: IStoredClientOpts; - protected clientWellKnownIntervalID: NodeJS.Timeout; + protected clientWellKnownIntervalID: number; protected canResetTimelineCallback: ResetTimelineCallback; // The pushprocessor caches useful things, so keep one and re-use it @@ -749,7 +749,7 @@ export class MatrixClient extends EventEmitter { protected clientWellKnownPromise: Promise; protected turnServers: ITurnServer[] = []; protected turnServersExpiry = 0; - protected checkTurnServersIntervalID: NodeJS.Timeout; + protected checkTurnServersIntervalID: number; protected exportedOlmDeviceToImport: IOlmDevice; protected txnCtr = 0; diff --git a/src/crypto/DeviceList.ts b/src/crypto/DeviceList.ts index 71d3d364d..890f3bfa3 100644 --- a/src/crypto/DeviceList.ts +++ b/src/crypto/DeviceList.ts @@ -102,7 +102,7 @@ export class DeviceList extends EventEmitter { // The time the save is scheduled for private savePromiseTime: number = null; // The timer used to delay the save - private saveTimer: NodeJS.Timeout = null; + private saveTimer: number = null; // True if we have fetched data from the server or loaded a non-empty // set of device data from the store private hasFetched: boolean = null; diff --git a/src/crypto/OutgoingRoomKeyRequestManager.ts b/src/crypto/OutgoingRoomKeyRequestManager.ts index a684b2c71..d01245722 100644 --- a/src/crypto/OutgoingRoomKeyRequestManager.ts +++ b/src/crypto/OutgoingRoomKeyRequestManager.ts @@ -78,7 +78,7 @@ export enum RoomKeyRequestState { export class OutgoingRoomKeyRequestManager { // handle for the delayed call to sendOutgoingRoomKeyRequests. Non-null // if the callback has been set, or if it is still running. - private sendOutgoingRoomKeyRequestsTimer: NodeJS.Timeout = null; + private sendOutgoingRoomKeyRequestsTimer: number = null; // sanity check to ensure that we don't end up with two concurrent runs // of sendOutgoingRoomKeyRequests @@ -366,7 +366,7 @@ export class OutgoingRoomKeyRequestManager { }); }; - this.sendOutgoingRoomKeyRequestsTimer = global.setTimeout( + this.sendOutgoingRoomKeyRequestsTimer = setTimeout( startSendingOutgoingRoomKeyRequests, SEND_KEY_REQUESTS_DELAY_MS, ); diff --git a/src/sync.ts b/src/sync.ts index 465c31983..3ac4489a5 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -135,7 +135,7 @@ export class SyncApi { private syncStateData: ISyncStateData = null; // additional data (eg. error object for failed sync) private catchingUp = false; private running = false; - private keepAliveTimer: NodeJS.Timeout = null; + private keepAliveTimer: number = null; private connectionReturnedDefer: IDeferred = null; private notifEvents: MatrixEvent[] = []; // accumulator of sync events in the current sync response private failedSyncCount = 0; // Number of consecutive failed /sync requests diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index ed1af7b90..05e64da2c 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -288,7 +288,7 @@ export class MatrixCall extends EventEmitter { // yet, null if we have but they didn't send a party ID. private opponentPartyId: string; private opponentCaps: CallCapabilities; - private inviteTimeout: NodeJS.Timeout; // in the browser it's 'number' + private inviteTimeout: number; // The logic of when & if a call is on hold is nontrivial and explained in is*OnHold // This flag represents whether we want the other party to be on hold From c0e16ac98c45134966f45ffdda1328e24f075c6d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 09:10:27 +0100 Subject: [PATCH 069/129] Update some more --- src/@types/spaces.ts | 4 ++-- src/client.ts | 10 +++++----- src/event-mapper.ts | 6 +++--- src/sync.ts | 3 +-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/@types/spaces.ts b/src/@types/spaces.ts index 17e677d44..da35bc0b9 100644 --- a/src/@types/spaces.ts +++ b/src/@types/spaces.ts @@ -14,12 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { IPublicRoomsChunk } from "../client"; +import { IPublicRoomsChunkRoom } from "../client"; // Types relating to Rooms of type `m.space` and related APIs /* eslint-disable camelcase */ -export interface ISpaceSummaryRoom extends IPublicRoomsChunk { +export interface ISpaceSummaryRoom extends IPublicRoomsChunkRoom { num_refs: number; room_type: string; } diff --git a/src/client.ts b/src/client.ts index c01b2b230..321836fb6 100644 --- a/src/client.ts +++ b/src/client.ts @@ -21,7 +21,7 @@ limitations under the License. import { EventEmitter } from "events"; import { ISyncStateData, SyncApi } from "./sync"; -import { EventStatus, IContent, IDecryptOptions, MatrixEvent } from "./models/event"; +import { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from "./models/event"; import { StubStore } from "./store/stub"; import { createNewMatrixCall, MatrixCall } from "./webrtc/call"; import { Filter, IFilterDefinition } from "./filter"; @@ -556,7 +556,7 @@ interface IRoomInitialSyncResponse { state?: IStateEventWithRoomId[]; visibility: Visibility; account_data?: IMinimalEvent[]; - presence: any; // undocumented + presence: Partial; // legacy and undocumented, api is deprecated so this won't get attention } interface IJoinedMembersResponse { @@ -568,7 +568,7 @@ interface IJoinedMembersResponse { }; } -export interface IPublicRoomsChunk { +export interface IPublicRoomsChunkRoom { room_id: string; name?: string; avatar_url?: string; @@ -581,7 +581,7 @@ export interface IPublicRoomsChunk { } interface IPublicRoomsResponse { - chunk: IPublicRoomsChunk[]; + chunk: IPublicRoomsChunkRoom[]; next_batch?: string; prev_batch?: string; total_room_count_estimate?: number; @@ -657,7 +657,7 @@ export interface IInstance { icon?: string; fields: object; network_id: string; - // XXX: this is undocumented but we rely on it. + // XXX: this is undocumented but we rely on it: https://github.com/matrix-org/matrix-doc/issues/3203 instance_id: string; } diff --git a/src/event-mapper.ts b/src/event-mapper.ts index 84b8b306f..e0a5e421b 100644 --- a/src/event-mapper.ts +++ b/src/event-mapper.ts @@ -15,9 +15,9 @@ limitations under the License. */ import { MatrixClient } from "./client"; -import { MatrixEvent } from "./models/event"; +import { IEvent, MatrixEvent } from "./models/event"; -export type EventMapper = (obj: any) => MatrixEvent; +export type EventMapper = (obj: Partial) => MatrixEvent; export interface MapperOpts { preventReEmit?: boolean; @@ -28,7 +28,7 @@ export function eventMapperFor(client: MatrixClient, options: MapperOpts): Event const preventReEmit = Boolean(options.preventReEmit); const decrypt = options.decrypt !== false; - function mapper(plainOldJsObject) { + function mapper(plainOldJsObject: Partial) { const event = new MatrixEvent(plainOldJsObject); if (event.isEncrypted()) { if (!preventReEmit) { diff --git a/src/sync.ts b/src/sync.ts index 3ac4489a5..863329808 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -329,8 +329,7 @@ export class SyncApi { const stateEvents = response.state.map(client.getEventMapper()); const messages = response.messages.chunk.map(client.getEventMapper()); - // XXX: copypasted from /sync until we kill off this - // minging v1 API stuff) + // XXX: copypasted from /sync until we kill off this minging v1 API stuff) // handle presence events (User objects) if (response.presence && Array.isArray(response.presence)) { response.presence.map(client.getEventMapper()).forEach( From e38595e735b233071cecdc0e677b4db5764928b0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 09:14:44 +0100 Subject: [PATCH 070/129] remove unused import --- src/models/room.ts | 1 - src/store/memory.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/models/room.ts b/src/models/room.ts index 65abbd099..089e60fa8 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -35,7 +35,6 @@ import { IRoomVersionsCapability, MatrixClient, PendingEventOrdering, RoomVersio import { ResizeMethod } from "../@types/partials"; import { Filter } from "../filter"; import { RoomState } from "./room-state"; -import { IMinimalEvent } from "../sync-accumulator"; // These constants are used as sane defaults when the homeserver doesn't support // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be diff --git a/src/store/memory.ts b/src/store/memory.ts index 00dceb711..424989b67 100644 --- a/src/store/memory.ts +++ b/src/store/memory.ts @@ -29,7 +29,6 @@ import { RoomMember } from "../models/room-member"; import { Filter } from "../filter"; import { ISavedSync, IStore } from "./index"; import { RoomSummary } from "../models/room-summary"; -import { IMinimalEvent } from "../sync-accumulator"; function isValidFilterId(filterId: string): boolean { const isValidStr = typeof filterId === "string" && From 1defde0f5e03b83786ce154f61e8e15dc6ef1152 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 18:36:47 +0100 Subject: [PATCH 071/129] Convert IndexedDB store & worker to Typescript --- ...ndexeddb-worker.js => indexeddb-worker.ts} | 0 src/store/index.ts | 6 +- ...-backend.js => indexeddb-local-backend.ts} | 331 +++++++++--------- src/store/indexeddb-remote-backend.js | 196 ----------- src/store/indexeddb-remote-backend.ts | 194 ++++++++++ ...re-worker.js => indexeddb-store-worker.ts} | 50 ++- src/store/indexeddb.ts | 13 +- src/store/memory.ts | 3 +- src/store/stub.ts | 3 +- src/sync-accumulator.ts | 21 +- src/utils.ts | 2 +- 11 files changed, 400 insertions(+), 419 deletions(-) rename src/{indexeddb-worker.js => indexeddb-worker.ts} (100%) rename src/store/{indexeddb-local-backend.js => indexeddb-local-backend.ts} (66%) delete mode 100644 src/store/indexeddb-remote-backend.js create mode 100644 src/store/indexeddb-remote-backend.ts rename src/store/{indexeddb-store-worker.js => indexeddb-store-worker.ts} (76%) diff --git a/src/indexeddb-worker.js b/src/indexeddb-worker.ts similarity index 100% rename from src/indexeddb-worker.js rename to src/indexeddb-worker.ts diff --git a/src/store/index.ts b/src/store/index.ts index 01650f86a..7e52d014e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -21,7 +21,7 @@ import { User } from "../models/user"; import { IEvent, MatrixEvent } from "../models/event"; import { Filter } from "../filter"; import { RoomSummary } from "../models/room-summary"; -import { IMinimalEvent, IGroups, IRooms } from "../sync-accumulator"; +import { IMinimalEvent, IGroups, IRooms, ISyncResponse } from "../sync-accumulator"; import { IStartClientOpts } from "../client"; export interface ISavedSync { @@ -185,7 +185,7 @@ export interface IStore { * @param {Object} syncData The sync data * @return {Promise} An immediately resolved promise. */ - setSyncData(syncData: object): Promise; + setSyncData(syncData: ISyncResponse): Promise; /** * We never want to save because we have nothing to save to. @@ -233,5 +233,5 @@ export interface IStore { getClientOptions(): Promise; - storeClientOptions(options: object): Promise; + storeClientOptions(options: IStartClientOpts): Promise; } diff --git a/src/store/indexeddb-local-backend.js b/src/store/indexeddb-local-backend.ts similarity index 66% rename from src/store/indexeddb-local-backend.js rename to src/store/indexeddb-local-backend.ts index 21364991c..79530227d 100644 --- a/src/store/indexeddb-local-backend.js +++ b/src/store/indexeddb-local-backend.ts @@ -1,7 +1,5 @@ /* -Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd -Copyright 2019 The Matrix.org Foundation C.I.C. +Copyright 2017 - 2021 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. @@ -16,14 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { SyncAccumulator } from "../sync-accumulator"; +import { IMinimalEvent, ISyncData, ISyncResponse, SyncAccumulator } from "../sync-accumulator"; import * as utils from "../utils"; import * as IndexedDBHelpers from "../indexeddb-helpers"; import { logger } from '../logger'; +import { IEvent, IStartClientOpts } from ".."; +import { ISavedSync } from "./index"; +import { IIndexeddbBackend, UserTuple } from "./indexeddb-backend"; const VERSION = 3; -function createDatabase(db) { +function createDatabase(db: IDBDatabase): void { // Make user store, clobber based on user ID. (userId property of User objects) db.createObjectStore("users", { keyPath: ["userId"] }); @@ -35,7 +36,7 @@ function createDatabase(db) { db.createObjectStore("sync", { keyPath: ["clobber"] }); } -function upgradeSchemaV2(db) { +function upgradeSchemaV2(db: IDBDatabase): void { const oobMembersStore = db.createObjectStore( "oob_membership_events", { keyPath: ["room_id", "state_key"], @@ -43,7 +44,7 @@ function upgradeSchemaV2(db) { oobMembersStore.createIndex("room", "room_id"); } -function upgradeSchemaV3(db) { +function upgradeSchemaV3(db: IDBDatabase): void { db.createObjectStore("client_options", { keyPath: ["clobber"] }); } @@ -58,16 +59,20 @@ function upgradeSchemaV3(db) { * @return {Promise} Resolves to an array of whatever you returned from * resultMapper. */ -function selectQuery(store, keyRange, resultMapper) { +function selectQuery( + store: IDBObjectStore, + keyRange: IDBKeyRange | IDBValidKey | undefined, + resultMapper: (cursor: IDBCursorWithValue) => T, +): Promise { const query = store.openCursor(keyRange); return new Promise((resolve, reject) => { const results = []; - query.onerror = (event) => { - reject(new Error("Query failed: " + event.target.errorCode)); + query.onerror = () => { + reject(new Error("Query failed: " + query.error)); }; // collect results - query.onsuccess = (event) => { - const cursor = event.target.result; + query.onsuccess = () => { + const cursor = query.result; if (!cursor) { resolve(results); return; // end of results @@ -78,88 +83,84 @@ function selectQuery(store, keyRange, resultMapper) { }); } -function txnAsPromise(txn) { +function txnAsPromise(txn: IDBTransaction): Promise { return new Promise((resolve, reject) => { txn.oncomplete = function(event) { resolve(event); }; - txn.onerror = function(event) { - reject(event.target.error); + txn.onerror = function() { + reject(txn.error); }; }); } -function reqAsEventPromise(req) { +function reqAsEventPromise(req: IDBRequest): Promise { return new Promise((resolve, reject) => { req.onsuccess = function(event) { resolve(event); }; - req.onerror = function(event) { - reject(event.target.error); + req.onerror = function() { + reject(req.error); }; }); } -function reqAsPromise(req) { +function reqAsPromise(req: IDBRequest): Promise { return new Promise((resolve, reject) => { req.onsuccess = () => resolve(req); req.onerror = (err) => reject(err); }); } -function reqAsCursorPromise(req) { - return reqAsEventPromise(req).then((event) => event.target.result); +function reqAsCursorPromise(req: IDBRequest): Promise { + return reqAsEventPromise(req).then((event) => req.result); } -/** - * Does the actual reading from and writing to the indexeddb - * - * Construct a new Indexed Database store backend. This requires a call to - * connect() before this store can be used. - * @constructor - * @param {Object} indexedDBInterface The Indexed DB interface e.g - * window.indexedDB - * @param {string=} dbName Optional database name. The same name must be used - * to open the same database. - */ -export function LocalIndexedDBStoreBackend( - indexedDBInterface, dbName, -) { - this.indexedDB = indexedDBInterface; - this._dbName = "matrix-js-sdk:" + (dbName || "default"); - this.db = null; - this._disconnected = true; - this._syncAccumulator = new SyncAccumulator(); - this._isNewlyCreated = false; -} +export class LocalIndexedDBStoreBackend implements IIndexeddbBackend { + public static exists(indexedDB: IDBFactory, dbName: string): boolean { + dbName = "matrix-js-sdk:" + (dbName || "default"); + return IndexedDBHelpers.exists(indexedDB, dbName); + } -LocalIndexedDBStoreBackend.exists = function(indexedDB, dbName) { - dbName = "matrix-js-sdk:" + (dbName || "default"); - return IndexedDBHelpers.exists(indexedDB, dbName); -}; + private readonly dbName: string; + private readonly syncAccumulator: SyncAccumulator; + private db: IDBDatabase = null; + private disconnected = true; + private _isNewlyCreated = false; + + /** + * Does the actual reading from and writing to the indexeddb + * + * Construct a new Indexed Database store backend. This requires a call to + * connect() before this store can be used. + * @constructor + * @param {Object} indexedDB The Indexed DB interface e.g + * window.indexedDB + * @param {string=} dbName Optional database name. The same name must be used + * to open the same database. + */ + constructor(private readonly indexedDB: IDBFactory, dbName: string) { + this.dbName = "matrix-js-sdk:" + (dbName || "default"); + this.syncAccumulator = new SyncAccumulator(); + } -LocalIndexedDBStoreBackend.prototype = { /** * Attempt to connect to the database. This can fail if the user does not * grant permission. * @return {Promise} Resolves if successfully connected. */ - connect: function() { - if (!this._disconnected) { - logger.log( - `LocalIndexedDBStoreBackend.connect: already connected or connecting`, - ); + public connect(): Promise { + if (!this.disconnected) { + logger.log(`LocalIndexedDBStoreBackend.connect: already connected or connecting`); return Promise.resolve(); } - this._disconnected = false; + this.disconnected = false; - logger.log( - `LocalIndexedDBStoreBackend.connect: connecting...`, - ); - const req = this.indexedDB.open(this._dbName, VERSION); + logger.log(`LocalIndexedDBStoreBackend.connect: connecting...`); + const req = this.indexedDB.open(this.dbName, VERSION); req.onupgradeneeded = (ev) => { - const db = ev.target.result; + const db = req.result; const oldVersion = ev.oldVersion; logger.log( `LocalIndexedDBStoreBackend.connect: upgrading from ${oldVersion}`, @@ -178,19 +179,13 @@ LocalIndexedDBStoreBackend.prototype = { }; req.onblocked = () => { - logger.log( - `can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`, - ); + logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`); }; - logger.log( - `LocalIndexedDBStoreBackend.connect: awaiting connection...`, - ); - return reqAsEventPromise(req).then((ev) => { - logger.log( - `LocalIndexedDBStoreBackend.connect: connected`, - ); - this.db = ev.target.result; + logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`); + return reqAsEventPromise(req).then(() => { + logger.log(`LocalIndexedDBStoreBackend.connect: connected`); + this.db = req.result; // add a poorly-named listener for when deleteDatabase is called // so we can close our db connections. @@ -198,27 +193,26 @@ LocalIndexedDBStoreBackend.prototype = { this.db.close(); }; - return this._init(); + return this.init(); }); - }, - /** @return {bool} whether or not the database was newly created in this session. */ - isNewlyCreated: function() { + } + + /** @return {boolean} whether or not the database was newly created in this session. */ + public isNewlyCreated(): Promise { return Promise.resolve(this._isNewlyCreated); - }, + } /** * Having connected, load initial data from the database and prepare for use * @return {Promise} Resolves on success */ - _init: function() { + private init() { return Promise.all([ - this._loadAccountData(), - this._loadSyncData(), + this.loadAccountData(), + this.loadSyncData(), ]).then(([accountData, syncData]) => { - logger.log( - `LocalIndexedDBStoreBackend: loaded initial data`, - ); - this._syncAccumulator.accumulate({ + logger.log(`LocalIndexedDBStoreBackend: loaded initial data`); + this.syncAccumulator.accumulate({ next_batch: syncData.nextBatch, rooms: syncData.roomsData, groups: syncData.groupsData, @@ -227,7 +221,7 @@ LocalIndexedDBStoreBackend.prototype = { }, }, true); }); - }, + } /** * Returns the out-of-band membership events for this room that @@ -236,8 +230,8 @@ LocalIndexedDBStoreBackend.prototype = { * @returns {Promise} the events, potentially an empty array if OOB loading didn't yield any new members * @returns {null} in case the members for this room haven't been stored yet */ - getOutOfBandMembers: function(roomId) { - return new Promise((resolve, reject) =>{ + public getOutOfBandMembers(roomId: string): Promise { + return new Promise((resolve, reject) =>{ const tx = this.db.transaction(["oob_membership_events"], "readonly"); const store = tx.objectStore("oob_membership_events"); const roomIndex = store.index("room"); @@ -252,8 +246,8 @@ LocalIndexedDBStoreBackend.prototype = { // were all known already let oobWritten = false; - request.onsuccess = (event) => { - const cursor = event.target.result; + request.onsuccess = () => { + const cursor = request.result; if (!cursor) { // Unknown room if (!membershipEvents.length && !oobWritten) { @@ -273,11 +267,10 @@ LocalIndexedDBStoreBackend.prototype = { reject(err); }; }).then((events) => { - logger.log(`LL: got ${events && events.length}` + - ` membershipEvents from storage for room ${roomId} ...`); + logger.log(`LL: got ${events && events.length} membershipEvents from storage for room ${roomId} ...`); return events; }); - }, + } /** * Stores the out-of-band membership events for this room. Note that @@ -286,7 +279,7 @@ LocalIndexedDBStoreBackend.prototype = { * @param {string} roomId * @param {event[]} membershipEvents the membership events to store */ - setOutOfBandMembers: async function(roomId, membershipEvents) { + public async setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise { logger.log(`LL: backend about to store ${membershipEvents.length}` + ` members for ${roomId}`); const tx = this.db.transaction(["oob_membership_events"], "readwrite"); @@ -307,9 +300,9 @@ LocalIndexedDBStoreBackend.prototype = { store.put(markerObject); await txnAsPromise(tx); logger.log(`LL: backend done storing for ${roomId}!`); - }, + } - clearOutOfBandMembers: async function(roomId) { + public async clearOutOfBandMembers(roomId: string): Promise { // the approach to delete all members for a room // is to get the min and max state key from the index // for that room, and then delete between those @@ -324,11 +317,11 @@ LocalIndexedDBStoreBackend.prototype = { const roomRange = IDBKeyRange.only(roomId); const minStateKeyProm = reqAsCursorPromise( - roomIndex.openKeyCursor(roomRange, "next"), - ).then((cursor) => cursor && cursor.primaryKey[1]); + roomIndex.openKeyCursor(roomRange, "next"), + ).then((cursor) => cursor && cursor.primaryKey[1]); const maxStateKeyProm = reqAsCursorPromise( - roomIndex.openKeyCursor(roomRange, "prev"), - ).then((cursor) => cursor && cursor.primaryKey[1]); + roomIndex.openKeyCursor(roomRange, "prev"), + ).then((cursor) => cursor && cursor.primaryKey[1]); const [minStateKey, maxStateKey] = await Promise.all( [minStateKeyProm, maxStateKeyProm]); @@ -341,45 +334,39 @@ LocalIndexedDBStoreBackend.prototype = { [roomId, maxStateKey], ); - logger.log(`LL: Deleting all users + marker in storage for ` + - `room ${roomId}, with key range:`, + logger.log(`LL: Deleting all users + marker in storage for room ${roomId}, with key range:`, [roomId, minStateKey], [roomId, maxStateKey]); await reqAsPromise(writeStore.delete(membersKeyRange)); - }, + } /** * Clear the entire database. This should be used when logging out of a client * to prevent mixing data between accounts. * @return {Promise} Resolved when the database is cleared. */ - clearDatabase: function() { - return new Promise((resolve, reject) => { - logger.log(`Removing indexeddb instance: ${this._dbName}`); - const req = this.indexedDB.deleteDatabase(this._dbName); + public clearDatabase(): Promise { + return new Promise((resolve) => { + logger.log(`Removing indexeddb instance: ${this.dbName}`); + const req = this.indexedDB.deleteDatabase(this.dbName); req.onblocked = () => { - logger.log( - `can't yet delete indexeddb ${this._dbName}` + - ` because it is open elsewhere`, - ); + logger.log(`can't yet delete indexeddb ${this.dbName} because it is open elsewhere`); }; - req.onerror = (ev) => { + req.onerror = () => { // in firefox, with indexedDB disabled, this fails with a // DOMError. We treat this as non-fatal, so that we can still // use the app. - logger.warn( - `unable to delete js-sdk store indexeddb: ${ev.target.error}`, - ); + logger.warn(`unable to delete js-sdk store indexeddb: ${req.error}`); resolve(); }; req.onsuccess = () => { - logger.log(`Removed indexeddb instance: ${this._dbName}`); + logger.log(`Removed indexeddb instance: ${this.dbName}`); resolve(); }; }); - }, + } /** * @param {boolean=} copy If false, the data returned is from internal @@ -390,10 +377,10 @@ LocalIndexedDBStoreBackend.prototype = { * client state to where it was at the last save, or null if there * is no saved sync data. */ - getSavedSync: function(copy) { + public getSavedSync(copy: boolean): Promise { if (copy === undefined) copy = true; - const data = this._syncAccumulator.getJSON(); + const data = this.syncAccumulator.getJSON(); if (!data.nextBatch) return Promise.resolve(null); if (copy) { // We must deep copy the stored data so that the /sync processing code doesn't @@ -402,29 +389,27 @@ LocalIndexedDBStoreBackend.prototype = { } else { return Promise.resolve(data); } - }, + } - getNextBatchToken: function() { - return Promise.resolve(this._syncAccumulator.getNextBatchToken()); - }, + public getNextBatchToken(): Promise { + return Promise.resolve(this.syncAccumulator.getNextBatchToken()); + } - setSyncData: function(syncData) { + public setSyncData(syncData: ISyncResponse): Promise { return Promise.resolve().then(() => { - this._syncAccumulator.accumulate(syncData); + this.syncAccumulator.accumulate(syncData); }); - }, + } - syncToDatabase: function(userTuples) { - const syncData = this._syncAccumulator.getJSON(true); + public async syncToDatabase(userTuples: UserTuple[]): Promise { + const syncData = this.syncAccumulator.getJSON(true); - return Promise.all([ - this._persistUserPresenceEvents(userTuples), - this._persistAccountData(syncData.accountData), - this._persistSyncData( - syncData.nextBatch, syncData.roomsData, syncData.groupsData, - ), + await Promise.all([ + this.persistUserPresenceEvents(userTuples), + this.persistAccountData(syncData.accountData), + this.persistSyncData(syncData.nextBatch, syncData.roomsData, syncData.groupsData), ]); - }, + } /** * Persist rooms /sync data along with the next batch token. @@ -433,20 +418,24 @@ LocalIndexedDBStoreBackend.prototype = { * @param {Object} groupsData The 'groups' /sync data from a SyncAccumulator * @return {Promise} Resolves if the data was persisted. */ - _persistSyncData: function(nextBatch, roomsData, groupsData) { + private persistSyncData( + nextBatch: string, + roomsData: ISyncResponse["rooms"], + groupsData: ISyncResponse["groups"], + ): Promise { logger.log("Persisting sync data up to", nextBatch); - return utils.promiseTry(() => { + return utils.promiseTry(() => { const txn = this.db.transaction(["sync"], "readwrite"); const store = txn.objectStore("sync"); store.put({ clobber: "-", // constant key so will always clobber - nextBatch: nextBatch, - roomsData: roomsData, - groupsData: groupsData, + nextBatch, + roomsData, + groupsData, }); // put == UPSERT - return txnAsPromise(txn); + return txnAsPromise(txn).then(); }); - }, + } /** * Persist a list of account data events. Events with the same 'type' will @@ -454,16 +443,16 @@ LocalIndexedDBStoreBackend.prototype = { * @param {Object[]} accountData An array of raw user-scoped account data events * @return {Promise} Resolves if the events were persisted. */ - _persistAccountData: function(accountData) { - return utils.promiseTry(() => { + private persistAccountData(accountData: IMinimalEvent[]): Promise { + return utils.promiseTry(() => { const txn = this.db.transaction(["accountData"], "readwrite"); const store = txn.objectStore("accountData"); for (let i = 0; i < accountData.length; i++) { store.put(accountData[i]); // put == UPSERT } - return txnAsPromise(txn); + return txnAsPromise(txn).then(); }); - }, + } /** * Persist a list of [user id, presence event] they are for. @@ -473,8 +462,8 @@ LocalIndexedDBStoreBackend.prototype = { * @param {Object[]} tuples An array of [userid, event] tuples * @return {Promise} Resolves if the users were persisted. */ - _persistUserPresenceEvents: function(tuples) { - return utils.promiseTry(() => { + private persistUserPresenceEvents(tuples: UserTuple[]): Promise { + return utils.promiseTry(() => { const txn = this.db.transaction(["users"], "readwrite"); const store = txn.objectStore("users"); for (const tuple of tuples) { @@ -483,9 +472,9 @@ LocalIndexedDBStoreBackend.prototype = { event: tuple[1], }); // put == UPSERT } - return txnAsPromise(txn); + return txnAsPromise(txn).then(); }); - }, + } /** * Load all user presence events from the database. This is not cached. @@ -493,64 +482,56 @@ LocalIndexedDBStoreBackend.prototype = { * sync. * @return {Promise} A list of presence events in their raw form. */ - getUserPresenceEvents: function() { - return utils.promiseTry(() => { + public getUserPresenceEvents(): Promise { + return utils.promiseTry(() => { const txn = this.db.transaction(["users"], "readonly"); const store = txn.objectStore("users"); return selectQuery(store, undefined, (cursor) => { return [cursor.value.userId, cursor.value.event]; }); }); - }, + } /** * Load all the account data events from the database. This is not cached. * @return {Promise} A list of raw global account events. */ - _loadAccountData: function() { - logger.log( - `LocalIndexedDBStoreBackend: loading account data...`, - ); - return utils.promiseTry(() => { + private loadAccountData(): Promise { + logger.log(`LocalIndexedDBStoreBackend: loading account data...`); + return utils.promiseTry(() => { const txn = this.db.transaction(["accountData"], "readonly"); const store = txn.objectStore("accountData"); return selectQuery(store, undefined, (cursor) => { return cursor.value; - }).then((result) => { - logger.log( - `LocalIndexedDBStoreBackend: loaded account data`, - ); + }).then((result: IMinimalEvent[]) => { + logger.log(`LocalIndexedDBStoreBackend: loaded account data`); return result; }); }); - }, + } /** * Load the sync data from the database. * @return {Promise} An object with "roomsData" and "nextBatch" keys. */ - _loadSyncData: function() { - logger.log( - `LocalIndexedDBStoreBackend: loading sync data...`, - ); - return utils.promiseTry(() => { + private loadSyncData(): Promise { + logger.log(`LocalIndexedDBStoreBackend: loading sync data...`); + return utils.promiseTry(() => { const txn = this.db.transaction(["sync"], "readonly"); const store = txn.objectStore("sync"); return selectQuery(store, undefined, (cursor) => { return cursor.value; - }).then((results) => { - logger.log( - `LocalIndexedDBStoreBackend: loaded sync data`, - ); + }).then((results: ISyncData[]) => { + logger.log(`LocalIndexedDBStoreBackend: loaded sync data`); if (results.length > 1) { logger.warn("loadSyncData: More than 1 sync row found."); } - return (results.length > 0 ? results[0] : {}); + return results.length > 0 ? results[0] : {} as ISyncData; }); }); - }, + } - getClientOptions: function() { + public getClientOptions(): Promise { return Promise.resolve().then(() => { const txn = this.db.transaction(["client_options"], "readonly"); const store = txn.objectStore("client_options"); @@ -560,9 +541,9 @@ LocalIndexedDBStoreBackend.prototype = { } }).then((results) => results[0]); }); - }, + } - storeClientOptions: async function(options) { + public async storeClientOptions(options: IStartClientOpts): Promise { const txn = this.db.transaction(["client_options"], "readwrite"); const store = txn.objectStore("client_options"); store.put({ @@ -570,5 +551,5 @@ LocalIndexedDBStoreBackend.prototype = { options: options, }); // put == UPSERT await txnAsPromise(txn); - }, -}; + } +} diff --git a/src/store/indexeddb-remote-backend.js b/src/store/indexeddb-remote-backend.js deleted file mode 100644 index efe57db55..000000000 --- a/src/store/indexeddb-remote-backend.js +++ /dev/null @@ -1,196 +0,0 @@ -/* -Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd -Copyright 2019 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 { logger } from '../logger'; -import { defer } from '../utils'; - -/** - * An IndexedDB store backend where the actual backend sits in a web - * worker. - * - * Construct a new Indexed Database store backend. This requires a call to - * connect() before this store can be used. - * @constructor - * @param {string} workerScript URL to the worker script - * @param {string=} dbName Optional database name. The same name must be used - * to open the same database. - * @param {Object} workerApi The web worker compatible interface object - */ -export function RemoteIndexedDBStoreBackend( - workerScript, dbName, workerApi, -) { - this._workerScript = workerScript; - this._dbName = dbName; - this._workerApi = workerApi; - this._worker = null; - this._nextSeq = 0; - // The currently in-flight requests to the actual backend - this._inFlight = { - // seq: promise, - }; - // Once we start connecting, we keep the promise and re-use it - // if we try to connect again - this._startPromise = null; -} - -RemoteIndexedDBStoreBackend.prototype = { - /** - * Attempt to connect to the database. This can fail if the user does not - * grant permission. - * @return {Promise} Resolves if successfully connected. - */ - connect: function() { - return this._ensureStarted().then(() => this._doCmd('connect')); - }, - - /** - * Clear the entire database. This should be used when logging out of a client - * to prevent mixing data between accounts. - * @return {Promise} Resolved when the database is cleared. - */ - clearDatabase: function() { - return this._ensureStarted().then(() => this._doCmd('clearDatabase')); - }, - /** @return {Promise} whether or not the database was newly created in this session. */ - isNewlyCreated: function() { - return this._doCmd('isNewlyCreated'); - }, - /** - * @return {Promise} Resolves with a sync response to restore the - * client state to where it was at the last save, or null if there - * is no saved sync data. - */ - getSavedSync: function() { - return this._doCmd('getSavedSync'); - }, - - getNextBatchToken: function() { - return this._doCmd('getNextBatchToken'); - }, - - setSyncData: function(syncData) { - return this._doCmd('setSyncData', [syncData]); - }, - - syncToDatabase: function(users) { - return this._doCmd('syncToDatabase', [users]); - }, - - /** - * Returns the out-of-band membership events for this room that - * were previously loaded. - * @param {string} roomId - * @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members - * @returns {null} in case the members for this room haven't been stored yet - */ - getOutOfBandMembers: function(roomId) { - return this._doCmd('getOutOfBandMembers', [roomId]); - }, - - /** - * Stores the out-of-band membership events for this room. Note that - * it still makes sense to store an empty array as the OOB status for the room is - * marked as fetched, and getOutOfBandMembers will return an empty array instead of null - * @param {string} roomId - * @param {event[]} membershipEvents the membership events to store - * @returns {Promise} when all members have been stored - */ - setOutOfBandMembers: function(roomId, membershipEvents) { - return this._doCmd('setOutOfBandMembers', [roomId, membershipEvents]); - }, - - clearOutOfBandMembers: function(roomId) { - return this._doCmd('clearOutOfBandMembers', [roomId]); - }, - - getClientOptions: function() { - return this._doCmd('getClientOptions'); - }, - - storeClientOptions: function(options) { - return this._doCmd('storeClientOptions', [options]); - }, - - /** - * Load all user presence events from the database. This is not cached. - * @return {Promise} A list of presence events in their raw form. - */ - getUserPresenceEvents: function() { - return this._doCmd('getUserPresenceEvents'); - }, - - _ensureStarted: function() { - if (this._startPromise === null) { - this._worker = new this._workerApi(this._workerScript); - this._worker.onmessage = this._onWorkerMessage.bind(this); - - // tell the worker the db name. - this._startPromise = this._doCmd('_setupWorker', [this._dbName]).then(() => { - logger.log("IndexedDB worker is ready"); - }); - } - return this._startPromise; - }, - - _doCmd: function(cmd, args) { - // wrap in a q so if the postMessage throws, - // the promise automatically gets rejected - return Promise.resolve().then(() => { - const seq = this._nextSeq++; - const def = defer(); - - this._inFlight[seq] = def; - - this._worker.postMessage({ - command: cmd, - seq: seq, - args: args, - }); - - return def.promise; - }); - }, - - _onWorkerMessage: function(ev) { - const msg = ev.data; - - if (msg.command == 'cmd_success' || msg.command == 'cmd_fail') { - if (msg.seq === undefined) { - logger.error("Got reply from worker with no seq"); - return; - } - - const def = this._inFlight[msg.seq]; - if (def === undefined) { - logger.error("Got reply for unknown seq " + msg.seq); - return; - } - delete this._inFlight[msg.seq]; - - if (msg.command == 'cmd_success') { - def.resolve(msg.result); - } else { - const error = new Error(msg.error.message); - error.name = msg.error.name; - def.reject(error); - } - } else { - logger.warn("Unrecognised message from worker: " + msg); - } - }, -}; diff --git a/src/store/indexeddb-remote-backend.ts b/src/store/indexeddb-remote-backend.ts new file mode 100644 index 000000000..d3b5731ee --- /dev/null +++ b/src/store/indexeddb-remote-backend.ts @@ -0,0 +1,194 @@ +/* +Copyright 2017 - 2021 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 { logger } from "../logger"; +import { defer, IDeferred } from "../utils"; +import { ISavedSync } from "./index"; +import { IStartClientOpts } from "../client"; +import { IEvent, ISyncResponse } from ".."; +import { IIndexeddbBackend, UserTuple } from "./indexeddb-backend"; + +export class RemoteIndexedDBStoreBackend implements IIndexeddbBackend { + private worker: Worker; + private nextSeq = 0; + // The currently in-flight requests to the actual backend + private inFlight: Record> = {}; // seq: promise + // Once we start connecting, we keep the promise and re-use it + // if we try to connect again + private startPromise: Promise = null; + + /** + * An IndexedDB store backend where the actual backend sits in a web + * worker. + * + * Construct a new Indexed Database store backend. This requires a call to + * connect() before this store can be used. + * @constructor + * @param {string} workerScript URL to the worker script + * @param {string=} dbName Optional database name. The same name must be used + * to open the same database. + * @param {Object} WorkerApi The web worker compatible interface object + */ + constructor( + private readonly workerScript: string, + private readonly dbName: string, + private readonly WorkerApi: typeof Worker, + ) {} + + /** + * Attempt to connect to the database. This can fail if the user does not + * grant permission. + * @return {Promise} Resolves if successfully connected. + */ + public connect(): Promise { + return this.ensureStarted().then(() => this.doCmd('connect')); + } + + /** + * Clear the entire database. This should be used when logging out of a client + * to prevent mixing data between accounts. + * @return {Promise} Resolved when the database is cleared. + */ + public clearDatabase(): Promise { + return this.ensureStarted().then(() => this.doCmd('clearDatabase')); + } + + /** @return {Promise} whether or not the database was newly created in this session. */ + public isNewlyCreated(): Promise { + return this.doCmd('isNewlyCreated'); + } + + /** + * @return {Promise} Resolves with a sync response to restore the + * client state to where it was at the last save, or null if there + * is no saved sync data. + */ + public getSavedSync(): Promise { + return this.doCmd('getSavedSync'); + } + + public getNextBatchToken(): Promise { + return this.doCmd('getNextBatchToken'); + } + + public setSyncData(syncData: ISyncResponse): Promise { + return this.doCmd('setSyncData', [syncData]); + } + + public syncToDatabase(userTuples: UserTuple[]): Promise { + return this.doCmd('syncToDatabase', [userTuples]); + } + + /** + * Returns the out-of-band membership events for this room that + * were previously loaded. + * @param {string} roomId + * @returns {event[]} the events, potentially an empty array if OOB loading didn't yield any new members + * @returns {null} in case the members for this room haven't been stored yet + */ + public getOutOfBandMembers(roomId: string): Promise { + return this.doCmd('getOutOfBandMembers', [roomId]); + } + + /** + * Stores the out-of-band membership events for this room. Note that + * it still makes sense to store an empty array as the OOB status for the room is + * marked as fetched, and getOutOfBandMembers will return an empty array instead of null + * @param {string} roomId + * @param {event[]} membershipEvents the membership events to store + * @returns {Promise} when all members have been stored + */ + public setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise { + return this.doCmd('setOutOfBandMembers', [roomId, membershipEvents]); + } + + public clearOutOfBandMembers(roomId: string): Promise { + return this.doCmd('clearOutOfBandMembers', [roomId]); + } + + public getClientOptions(): Promise { + return this.doCmd('getClientOptions'); + } + + public storeClientOptions(options: IStartClientOpts): Promise { + return this.doCmd('storeClientOptions', [options]); + } + + /** + * Load all user presence events from the database. This is not cached. + * @return {Promise} A list of presence events in their raw form. + */ + public getUserPresenceEvents(): Promise { + return this.doCmd('getUserPresenceEvents'); + } + + private ensureStarted(): Promise { + if (this.startPromise === null) { + this.worker = new this.WorkerApi(this.workerScript); + this.worker.onmessage = this.onWorkerMessage; + + // tell the worker the db name. + this.startPromise = this.doCmd('_setupWorker', [this.dbName]).then(() => { + logger.log("IndexedDB worker is ready"); + }); + } + return this.startPromise; + } + + private doCmd(command: string, args?: any): Promise { + // wrap in a q so if the postMessage throws, + // the promise automatically gets rejected + return Promise.resolve().then(() => { + const seq = this.nextSeq++; + const def = defer(); + + this.inFlight[seq] = def; + + this.worker.postMessage({ command, seq, args }); + + return def.promise; + }); + } + + private onWorkerMessage = (ev: MessageEvent): void => { + const msg = ev.data; + + if (msg.command == 'cmd_success' || msg.command == 'cmd_fail') { + if (msg.seq === undefined) { + logger.error("Got reply from worker with no seq"); + return; + } + + const def = this.inFlight[msg.seq]; + if (def === undefined) { + logger.error("Got reply for unknown seq " + msg.seq); + return; + } + delete this.inFlight[msg.seq]; + + if (msg.command == 'cmd_success') { + def.resolve(msg.result); + } else { + const error = new Error(msg.error.message); + error.name = msg.error.name; + def.reject(error); + } + } else { + logger.warn("Unrecognised message from worker: " + msg); + } + }; +} + diff --git a/src/store/indexeddb-store-worker.js b/src/store/indexeddb-store-worker.ts similarity index 76% rename from src/store/indexeddb-store-worker.js rename to src/store/indexeddb-store-worker.ts index 35af82ab4..21f0ede8d 100644 --- a/src/store/indexeddb-store-worker.js +++ b/src/store/indexeddb-store-worker.ts @@ -1,7 +1,5 @@ /* -Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd -Copyright 2019 The Matrix.org Foundation C.I.C. +Copyright 2017 - 2021 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. @@ -16,9 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend.js"; +import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend"; import { logger } from '../logger'; +interface ICmd { + command: string; + seq: number; + args?: any[]; +} + /** * This class lives in the webworker and drives a LocalIndexedDBStoreBackend * controlled by messages from the main process. @@ -35,16 +39,13 @@ import { logger } from '../logger'; * */ export class IndexedDBStoreWorker { + private backend: LocalIndexedDBStoreBackend = null; + /** * @param {function} postMessage The web worker postMessage function that * should be used to communicate back to the main script. */ - constructor(postMessage) { - this.backend = null; - this.postMessage = postMessage; - - this.onMessage = this.onMessage.bind(this); - } + constructor(private readonly postMessage: InstanceType["postMessage"]) {} /** * Passes a message event from the main script into the class. This method @@ -52,17 +53,15 @@ export class IndexedDBStoreWorker { * * @param {Object} ev The message event */ - onMessage(ev) { - const msg = ev.data; + public onMessage = (ev: MessageEvent): void => { + const msg: ICmd = ev.data; let prom; switch (msg.command) { case '_setupWorker': - this.backend = new LocalIndexedDBStoreBackend( - // this is the 'indexedDB' global (where global != window - // because it's a web worker and there is no window). - indexedDB, msg.args[0], - ); + // this is the 'indexedDB' global (where global != window + // because it's a web worker and there is no window). + this.backend = new LocalIndexedDBStoreBackend(indexedDB, msg.args[0]); prom = Promise.resolve(); break; case 'connect': @@ -72,23 +71,16 @@ export class IndexedDBStoreWorker { prom = this.backend.isNewlyCreated(); break; case 'clearDatabase': - prom = this.backend.clearDatabase().then((result) => { - // This returns special classes which can't be cloned - // across to the main script, so don't try. - return {}; - }); + prom = this.backend.clearDatabase(); break; case 'getSavedSync': prom = this.backend.getSavedSync(false); break; case 'setSyncData': - prom = this.backend.setSyncData(...msg.args); + prom = this.backend.setSyncData(msg.args[0]); break; case 'syncToDatabase': - prom = this.backend.syncToDatabase(...msg.args).then(() => { - // This also returns IndexedDB events which are not cloneable - return {}; - }); + prom = this.backend.syncToDatabase(msg.args[0]); break; case 'getUserPresenceEvents': prom = this.backend.getUserPresenceEvents(); @@ -130,7 +122,7 @@ export class IndexedDBStoreWorker { result: ret, }); }, (err) => { - logger.error("Error running command: "+msg.command); + logger.error("Error running command: " + msg.command); logger.error(err); this.postMessage.call(null, { command: 'cmd_fail', @@ -142,5 +134,5 @@ export class IndexedDBStoreWorker { }, }); }); - } + }; } diff --git a/src/store/indexeddb.ts b/src/store/indexeddb.ts index aed61dae2..b65c4eb1e 100644 --- a/src/store/indexeddb.ts +++ b/src/store/indexeddb.ts @@ -19,12 +19,14 @@ limitations under the License. import { EventEmitter } from 'events'; import { MemoryStore, IOpts as IBaseOpts } from "./memory"; -import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend.js"; -import { RemoteIndexedDBStoreBackend } from "./indexeddb-remote-backend.js"; +import { LocalIndexedDBStoreBackend } from "./indexeddb-local-backend"; +import { RemoteIndexedDBStoreBackend } from "./indexeddb-remote-backend"; import { User } from "../models/user"; import { IEvent, MatrixEvent } from "../models/event"; import { logger } from '../logger'; import { ISavedSync } from "./index"; +import { IIndexeddbBackend } from "./indexeddb-backend"; +import { ISyncResponse } from "../sync-accumulator"; /** * This is an internal module. See {@link IndexedDBStore} for the public class. @@ -50,8 +52,7 @@ export class IndexedDBStore extends MemoryStore { return LocalIndexedDBStoreBackend.exists(indexedDB, dbName); } - // TODO these should conform to one interface - public readonly backend: LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; + public readonly backend: IIndexeddbBackend; private startedUp = false; private syncTs = 0; @@ -222,7 +223,7 @@ export class IndexedDBStore extends MemoryStore { // work out changed users (this doesn't handle deletions but you // can't 'delete' users as they are just presence events). - const userTuples = []; + const userTuples: [userId: string, presenceEvent: Partial][] = []; for (const u of this.getUsers()) { if (this.userModifiedMap[u.userId] === u.getLastModifiedTime()) continue; if (!u.events.presence) continue; @@ -236,7 +237,7 @@ export class IndexedDBStore extends MemoryStore { return this.backend.syncToDatabase(userTuples); }); - public setSyncData = this.degradable((syncData: object): Promise => { + public setSyncData = this.degradable((syncData: ISyncResponse): Promise => { return this.backend.setSyncData(syncData); }, "setSyncData"); diff --git a/src/store/memory.ts b/src/store/memory.ts index 424989b67..656bd1808 100644 --- a/src/store/memory.ts +++ b/src/store/memory.ts @@ -29,6 +29,7 @@ import { RoomMember } from "../models/room-member"; import { Filter } from "../filter"; import { ISavedSync, IStore } from "./index"; import { RoomSummary } from "../models/room-summary"; +import { ISyncResponse } from "../sync-accumulator"; function isValidFilterId(filterId: string): boolean { const isValidStr = typeof filterId === "string" && @@ -340,7 +341,7 @@ export class MemoryStore implements IStore { * @param {Object} syncData The sync data * @return {Promise} An immediately resolved promise. */ - public setSyncData(syncData: object): Promise { + public setSyncData(syncData: ISyncResponse): Promise { return Promise.resolve(); } diff --git a/src/store/stub.ts b/src/store/stub.ts index f7adb9b3e..c2b4ea933 100644 --- a/src/store/stub.ts +++ b/src/store/stub.ts @@ -27,6 +27,7 @@ import { IEvent, MatrixEvent } from "../models/event"; import { Filter } from "../filter"; import { ISavedSync, IStore } from "./index"; import { RoomSummary } from "../models/room-summary"; +import { ISyncResponse } from "../sync-accumulator"; /** * Construct a stub store. This does no-ops on most store methods. @@ -213,7 +214,7 @@ export class StubStore implements IStore { * @param {Object} syncData The sync data * @return {Promise} An immediately resolved promise. */ - public setSyncData(syncData: object): Promise { + public setSyncData(syncData: ISyncResponse): Promise { return Promise.resolve(); } diff --git a/src/sync-accumulator.ts b/src/sync-accumulator.ts index 8e2c14485..0b7f65f71 100644 --- a/src/sync-accumulator.ts +++ b/src/sync-accumulator.ts @@ -40,8 +40,8 @@ export interface IEphemeral { /* eslint-disable camelcase */ interface IUnreadNotificationCounts { - highlight_count: number; - notification_count: number; + highlight_count?: number; + notification_count?: number; } export interface IRoomEvent extends IMinimalEvent { @@ -64,7 +64,7 @@ interface IState { export interface ITimeline { events: Array; - limited: boolean; + limited?: boolean; prev_batch: string; } @@ -169,6 +169,13 @@ interface IRoom { }; } +export interface ISyncData { + nextBatch: string; + accountData: IMinimalEvent[]; + roomsData: IRooms; + groupsData: IGroups; +} + /** * The purpose of this class is to accumulate /sync responses such that a * complete "initial" JSON response can be returned which accurately represents @@ -544,8 +551,8 @@ export class SyncAccumulator { * /sync response from the 'rooms' key onwards. The "accountData" key is * a list of raw events which represent global account data. */ - public getJSON(forDatabase = false): object { - const data = { + public getJSON(forDatabase = false): ISyncData { + const data: IRooms = { join: {}, invite: {}, // always empty. This is set by /sync when a room was previously @@ -575,7 +582,7 @@ export class SyncAccumulator { prev_batch: null, }, unread_notifications: roomData._unreadNotifications, - summary: roomData._summary, + summary: roomData._summary as IRoomSummary, }; // Add account data Object.keys(roomData._accountData).forEach((evType) => { @@ -678,7 +685,7 @@ export class SyncAccumulator { }); // Add account data - const accData = []; + const accData: IMinimalEvent[] = []; Object.keys(this.accountData).forEach((evType) => { accData.push(this.accountData[evType]); }); diff --git a/src/utils.ts b/src/utils.ts index 008388509..fa45f20d2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -464,7 +464,7 @@ export async function promiseMapSeries( } } -export function promiseTry(fn: () => T): Promise { +export function promiseTry(fn: () => T | Promise): Promise { return new Promise((resolve) => resolve(fn())); } From 75f630e45d2a99e52e1013766fe40bcdc3842138 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 18:39:29 +0100 Subject: [PATCH 072/129] Add missing interface --- src/store/indexeddb-backend.ts | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/store/indexeddb-backend.ts diff --git a/src/store/indexeddb-backend.ts b/src/store/indexeddb-backend.ts new file mode 100644 index 000000000..71fe8ad16 --- /dev/null +++ b/src/store/indexeddb-backend.ts @@ -0,0 +1,36 @@ +/* +Copyright 2021 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 { ISavedSync } from "./index"; +import { IEvent, IStartClientOpts, ISyncResponse } from ".."; + +export interface IIndexeddbBackend { + connect(): Promise; + syncToDatabase(userTuples: UserTuple[]): Promise; + isNewlyCreated(): Promise; + setSyncData(syncData: ISyncResponse): Promise; + getSavedSync(copy?: boolean): Promise; // TODO copy + getNextBatchToken(): Promise; + clearDatabase(): Promise; + getOutOfBandMembers(roomId: string): Promise; + setOutOfBandMembers(roomId: string, membershipEvents: IEvent[]): Promise; + clearOutOfBandMembers(roomId: string): Promise; + getUserPresenceEvents(): Promise; + getClientOptions(): Promise; + storeClientOptions(options: IStartClientOpts): Promise; +} + +export type UserTuple = [userId: string, presenceEvent: Partial]; From 1aa103d8d2fba3d1c887087a638673271d3f5e40 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 18:41:26 +0100 Subject: [PATCH 073/129] Fix spurious argument appearing on the interface and TODO --- src/store/indexeddb-backend.ts | 2 +- src/store/indexeddb-local-backend.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/store/indexeddb-backend.ts b/src/store/indexeddb-backend.ts index 71fe8ad16..78d1e9d2d 100644 --- a/src/store/indexeddb-backend.ts +++ b/src/store/indexeddb-backend.ts @@ -22,7 +22,7 @@ export interface IIndexeddbBackend { syncToDatabase(userTuples: UserTuple[]): Promise; isNewlyCreated(): Promise; setSyncData(syncData: ISyncResponse): Promise; - getSavedSync(copy?: boolean): Promise; // TODO copy + getSavedSync(): Promise; getNextBatchToken(): Promise; clearDatabase(): Promise; getOutOfBandMembers(roomId: string): Promise; diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index 79530227d..b6dd78e65 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -377,9 +377,7 @@ export class LocalIndexedDBStoreBackend implements IIndexeddbBackend { * client state to where it was at the last save, or null if there * is no saved sync data. */ - public getSavedSync(copy: boolean): Promise { - if (copy === undefined) copy = true; - + public getSavedSync(copy = true): Promise { const data = this.syncAccumulator.getJSON(); if (!data.nextBatch) return Promise.resolve(null); if (copy) { From 19d8f2bbac2cfd1dd3caffe3e022037c533fb96f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 12 Jul 2021 18:43:21 +0100 Subject: [PATCH 074/129] Use webpack worker-loader to load the IndexedDB worker instead of homegrown hack --- src/store/indexeddb-remote-backend.ts | 8 +++----- src/store/indexeddb.ts | 15 +++------------ 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/store/indexeddb-remote-backend.ts b/src/store/indexeddb-remote-backend.ts index d3b5731ee..6ff115255 100644 --- a/src/store/indexeddb-remote-backend.ts +++ b/src/store/indexeddb-remote-backend.ts @@ -37,15 +37,13 @@ export class RemoteIndexedDBStoreBackend implements IIndexeddbBackend { * Construct a new Indexed Database store backend. This requires a call to * connect() before this store can be used. * @constructor - * @param {string} workerScript URL to the worker script + * @param {Function} workerFactory Factory which produces a Worker * @param {string=} dbName Optional database name. The same name must be used * to open the same database. - * @param {Object} WorkerApi The web worker compatible interface object */ constructor( - private readonly workerScript: string, + private readonly workerFactory: () => Worker, private readonly dbName: string, - private readonly WorkerApi: typeof Worker, ) {} /** @@ -137,7 +135,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexeddbBackend { private ensureStarted(): Promise { if (this.startPromise === null) { - this.worker = new this.WorkerApi(this.workerScript); + this.worker = this.workerFactory(); this.worker.onmessage = this.onWorkerMessage; // tell the worker the db name. diff --git a/src/store/indexeddb.ts b/src/store/indexeddb.ts index b65c4eb1e..d256769e9 100644 --- a/src/store/indexeddb.ts +++ b/src/store/indexeddb.ts @@ -43,8 +43,7 @@ const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes interface IOpts extends IBaseOpts { indexedDB: IDBFactory; dbName?: string; - workerScript?: string; - workerApi?: typeof Worker; + workerFactory?: () => Worker; } export class IndexedDBStore extends MemoryStore { @@ -111,16 +110,8 @@ export class IndexedDBStore extends MemoryStore { throw new Error('Missing required option: indexedDB'); } - if (opts.workerScript) { - // try & find a webworker-compatible API - let workerApi = opts.workerApi; - if (!workerApi) { - // default to the global Worker object (which is where it in a browser) - workerApi = global.Worker; - } - this.backend = new RemoteIndexedDBStoreBackend( - opts.workerScript, opts.dbName, workerApi, - ); + if (opts.workerFactory) { + this.backend = new RemoteIndexedDBStoreBackend(opts.workerFactory, opts.dbName); } else { this.backend = new LocalIndexedDBStoreBackend(opts.indexedDB, opts.dbName); } From d5c3cb1b7fa2e8c22d7a2a5ca3c23e63b02d9e91 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 12 Jul 2021 21:50:27 -0600 Subject: [PATCH 075/129] More minimal types for pushers & push rules --- src/@types/PushRules.ts | 5 +++++ src/client.ts | 39 +++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index 4a3017b99..a4eda1b48 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -148,6 +148,7 @@ export interface IPusher { data: { format?: string; // TODO: Types url?: string; // TODO: Required if kind==http + brand?: string; // TODO: For email notifications only? }; device_display_name: string; kind: string; // TODO: Types @@ -156,4 +157,8 @@ export interface IPusher { pushkey: string; } +export interface IPusherRequest extends IPusher { + append?: boolean; +} + /* eslint-enable camelcase */ diff --git a/src/client.ts b/src/client.ts index 930e48347..27e7fcff7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -117,7 +117,7 @@ import { WebStorageSessionStore } from "./store/session/webstorage"; import { BackupManager, IKeyBackupCheck, IPreparedKeyBackupVersion, TrustInfo } from "./crypto/backup"; import { DEFAULT_TREE_POWER_LEVELS_TEMPLATE, MSC3089TreeSpace } from "./models/MSC3089TreeSpace"; import { ISignatures } from "./@types/signed"; -import { IPusher, IPushRules } from "./@types/PushRules"; +import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules"; import { IThirdPartyIdentifier } from "./@types/threepids"; export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; @@ -4991,20 +4991,20 @@ export class MatrixClient extends EventEmitter { if (!mute) { // Remove the rule only if it is a muting rule if (hasDontNotifyRule) { - deferred = this.deletePushRule(scope, "room", roomPushRule.rule_id); + deferred = this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id); } } else { if (!roomPushRule) { - deferred = this.addPushRule(scope, "room", roomId, { + deferred = this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, { actions: ["dont_notify"], }); } else if (!hasDontNotifyRule) { // Remove the existing one before setting the mute push rule // This is a workaround to SYN-590 (Push rule update fails) deferred = utils.defer(); - this.deletePushRule(scope, "room", roomPushRule.rule_id) + this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id) .then(() => { - this.addPushRule(scope, "room", roomId, { + this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, { actions: ["dont_notify"], }).then(() => { deferred.resolve(); @@ -7001,12 +7001,12 @@ export class MatrixClient extends EventEmitter { /** * Adds a new pusher or updates an existing pusher * - * @param {Object} pusher Object representing a pusher + * @param {IPusherRequest} pusher Object representing a pusher * @param {module:client.callback} callback Optional. * @return {Promise} Resolves: Empty json object on success * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public setPusher(pusher: any, callback?: Callback): Promise<{}> { + public setPusher(pusher: IPusherRequest, callback?: Callback): Promise<{}> { const path = "/pushers/set"; return this.http.authedRequest( callback, "POST", path, null, pusher, @@ -7034,7 +7034,13 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public addPushRule(scope: string, kind: string, ruleId: string, body: any, callback?: Callback): Promise { // TODO: Types + public addPushRule( + scope: string, + kind: PushRuleKind, + ruleId: RuleId | string, + body: any, + callback?: Callback, + ): Promise { // TODO: Types // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -7053,7 +7059,12 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public deletePushRule(scope: string, kind: string, ruleId: string, callback?: Callback): Promise { // TODO: Types + public deletePushRule( + scope: string, + kind: PushRuleKind, + ruleId: RuleId | string, + callback?: Callback, + ): Promise { // TODO: Types // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -7074,8 +7085,8 @@ export class MatrixClient extends EventEmitter { */ public setPushRuleEnabled( scope: string, - kind: string, - ruleId: string, + kind: PushRuleKind, + ruleId: RuleId | string, enabled: boolean, callback?: Callback, ): Promise { // TODO: Types @@ -7100,9 +7111,9 @@ export class MatrixClient extends EventEmitter { */ public setPushRuleActions( scope: string, - kind: string, - ruleId: string, - actions: string[], + kind: PushRuleKind, + ruleId: RuleId | string, + actions: PushRuleAction[], callback?: Callback, ): Promise { // TODO: Types const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", { From 33deef9f2c238265ad36c5a2e87faeb5f73d118f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 13 Jul 2021 10:33:33 +0100 Subject: [PATCH 076/129] Rework devtools and get rid of flippy tgl button --- src/crypto/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index a33a36f98..d1af36c7a 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -200,7 +200,7 @@ export class Crypto extends EventEmitter { private readonly supportedAlgorithms: string[]; private readonly outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager; private readonly toDeviceVerificationRequests: ToDeviceRequests; - private readonly inRoomVerificationRequests: InRoomRequests; + public readonly inRoomVerificationRequests: InRoomRequests; private trustCrossSignedDevices = true; // the last time we did a check for the number of one-time-keys on the server. From f9005c33e9508b1fabe12a3f4de5bdf6b502d6f3 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 13 Jul 2021 11:29:32 +0100 Subject: [PATCH 077/129] Fix casing of IIndexedDBBackend --- src/store/indexeddb-backend.ts | 2 +- src/store/indexeddb-local-backend.ts | 4 ++-- src/store/indexeddb-remote-backend.ts | 4 ++-- src/store/indexeddb.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/store/indexeddb-backend.ts b/src/store/indexeddb-backend.ts index 78d1e9d2d..4fe309f13 100644 --- a/src/store/indexeddb-backend.ts +++ b/src/store/indexeddb-backend.ts @@ -17,7 +17,7 @@ limitations under the License. import { ISavedSync } from "./index"; import { IEvent, IStartClientOpts, ISyncResponse } from ".."; -export interface IIndexeddbBackend { +export interface IIndexedDBBackend { connect(): Promise; syncToDatabase(userTuples: UserTuple[]): Promise; isNewlyCreated(): Promise; diff --git a/src/store/indexeddb-local-backend.ts b/src/store/indexeddb-local-backend.ts index b6dd78e65..9a7e803bb 100644 --- a/src/store/indexeddb-local-backend.ts +++ b/src/store/indexeddb-local-backend.ts @@ -20,7 +20,7 @@ import * as IndexedDBHelpers from "../indexeddb-helpers"; import { logger } from '../logger'; import { IEvent, IStartClientOpts } from ".."; import { ISavedSync } from "./index"; -import { IIndexeddbBackend, UserTuple } from "./indexeddb-backend"; +import { IIndexedDBBackend, UserTuple } from "./indexeddb-backend"; const VERSION = 3; @@ -116,7 +116,7 @@ function reqAsCursorPromise(req: IDBRequest): Promise req.result); } -export class LocalIndexedDBStoreBackend implements IIndexeddbBackend { +export class LocalIndexedDBStoreBackend implements IIndexedDBBackend { public static exists(indexedDB: IDBFactory, dbName: string): boolean { dbName = "matrix-js-sdk:" + (dbName || "default"); return IndexedDBHelpers.exists(indexedDB, dbName); diff --git a/src/store/indexeddb-remote-backend.ts b/src/store/indexeddb-remote-backend.ts index d3b5731ee..6525515ed 100644 --- a/src/store/indexeddb-remote-backend.ts +++ b/src/store/indexeddb-remote-backend.ts @@ -19,9 +19,9 @@ import { defer, IDeferred } from "../utils"; import { ISavedSync } from "./index"; import { IStartClientOpts } from "../client"; import { IEvent, ISyncResponse } from ".."; -import { IIndexeddbBackend, UserTuple } from "./indexeddb-backend"; +import { IIndexedDBBackend, UserTuple } from "./indexeddb-backend"; -export class RemoteIndexedDBStoreBackend implements IIndexeddbBackend { +export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend { private worker: Worker; private nextSeq = 0; // The currently in-flight requests to the actual backend diff --git a/src/store/indexeddb.ts b/src/store/indexeddb.ts index b65c4eb1e..9388ceedd 100644 --- a/src/store/indexeddb.ts +++ b/src/store/indexeddb.ts @@ -25,7 +25,7 @@ import { User } from "../models/user"; import { IEvent, MatrixEvent } from "../models/event"; import { logger } from '../logger'; import { ISavedSync } from "./index"; -import { IIndexeddbBackend } from "./indexeddb-backend"; +import { IIndexedDBBackend } from "./indexeddb-backend"; import { ISyncResponse } from "../sync-accumulator"; /** @@ -52,7 +52,7 @@ export class IndexedDBStore extends MemoryStore { return LocalIndexedDBStoreBackend.exists(indexedDB, dbName); } - public readonly backend: IIndexeddbBackend; + public readonly backend: IIndexedDBBackend; private startedUp = false; private syncTs = 0; From 56921f0961d4403e6ad9784d4231d7c9198efdaf Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Mon, 12 Jul 2021 20:35:31 +0100 Subject: [PATCH 078/129] Standardise spelling and casing of homeserver Signed-off-by: Paulo Pinto --- src/client.ts | 10 +++++----- src/http-api.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index e5424224c..90891ef64 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4778,7 +4778,7 @@ export class MatrixClient extends EventEmitter { * If an account with the given email address already exists and is * associated with an account other than the one the user is authed as, * it will either send an email to the address informing them of this - * or return M_THREEPID_IN_USE (which one is up to the Home Server). + * or return M_THREEPID_IN_USE (which one is up to the homeserver). * * @param {string} email As requestEmailToken * @param {string} clientSecret As requestEmailToken @@ -4843,7 +4843,7 @@ export class MatrixClient extends EventEmitter { * adding specific behaviour for the password resetting. Specifically, * if no account with the given email address exists, it may either * return M_THREEPID_NOT_FOUND or send an email - * to the address informing them of this (which one is up to the Home Server). + * to the address informing them of this (which one is up to the homeserver). * * requestEmailToken calls the equivalent API directly on the ID server, * therefore bypassing the password reset specific logic. @@ -5316,7 +5316,7 @@ export class MatrixClient extends EventEmitter { } /** - * Gets a bearer token from the Home Server that the user can + * Gets a bearer token from the homeserver that the user can * present to a third party in order to prove their ownership * of the Matrix account they are logged into. * @return {Promise} Resolves: Token object @@ -5349,7 +5349,7 @@ export class MatrixClient extends EventEmitter { } /** - * Get the TURN servers for this home server. + * Get the TURN servers for this homeserver. * @return {Array} The servers or an empty list. */ public getTurnServers(): any[] { // TODO: Types @@ -6668,7 +6668,7 @@ export class MatrixClient extends EventEmitter { } /** - * Upload a file to the media repository on the home server. + * Upload a file to the media repository on the homeserver. * * @param {object} file The object to upload. On a browser, something that * can be sent to XMLHttpRequest.send (typically a File). Under node.js, diff --git a/src/http-api.js b/src/http-api.js index a48c165d0..148ce87c4 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -121,7 +121,7 @@ MatrixHttpApi.prototype = { }, /** - * Upload content to the Home Server + * Upload content to the homeserver * * @param {object} file The object to upload. On a browser, something that * can be sent to XMLHttpRequest.send (typically a File). Under node.js, From ab59e9134b027580d5c067dab279150427836817 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 13 Jul 2021 14:12:55 +0100 Subject: [PATCH 079/129] Standardise casing of identity server Signed-off-by: Paulo Pinto --- CHANGELOG.md | 2 +- src/client.ts | 22 +++++++++++----------- src/http-api.js | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7baac3a3..9357bc98a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1749,7 +1749,7 @@ Changes in [2.4.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag [\#1011](https://github.com/matrix-org/matrix-js-sdk/pull/1011) * Fix POST body for v2 IS requests [\#1010](https://github.com/matrix-org/matrix-js-sdk/pull/1010) - * Add API for bulk lookup on the Identity Server + * Add API for bulk lookup on the identity server [\#1009](https://github.com/matrix-org/matrix-js-sdk/pull/1009) * Remove deprecated authedRequestWithPrefix and requestWithPrefix [\#1000](https://github.com/matrix-org/matrix-js-sdk/pull/1000) diff --git a/src/client.ts b/src/client.ts index 90891ef64..a560fb2ae 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4806,7 +4806,7 @@ export class MatrixClient extends EventEmitter { /** * Requests a text message verification token for the purposes of adding a * third party identifier to an account. - * This API proxies the Identity Server /validate/email/requestToken API, + * This API proxies the identity server /validate/email/requestToken API, * adding specific behaviour for the addition of phone numbers to an * account, as requestAdd3pidEmailToken. * @@ -4839,7 +4839,7 @@ export class MatrixClient extends EventEmitter { /** * Requests an email verification token for the purposes of resetting * the password on an account. - * This API proxies the Identity Server /validate/email/requestToken API, + * This API proxies the identity server /validate/email/requestToken API, * adding specific behaviour for the password resetting. Specifically, * if no account with the given email address exists, it may either * return M_THREEPID_NOT_FOUND or send an email @@ -4875,7 +4875,7 @@ export class MatrixClient extends EventEmitter { /** * Requests a text message verification token for the purposes of resetting * the password on an account. - * This API proxies the Identity Server /validate/email/requestToken API, + * This API proxies the identity server /validate/email/requestToken API, * adding specific behaviour for the password resetting, as requestPasswordEmailToken. * * @param {string} phoneCountry As requestRegisterMsisdnToken @@ -5819,9 +5819,9 @@ export class MatrixClient extends EventEmitter { } /** - * Get the Identity Server URL of this client + * Get the identity server URL of this client * @param {boolean} stripProto whether or not to strip the protocol from the URL - * @return {string} Identity Server URL of this client + * @return {string} Identity server URL of this client */ public getIdentityServerUrl(stripProto = false): string { if (stripProto && (this.idBaseUrl.startsWith("http://") || @@ -5832,8 +5832,8 @@ export class MatrixClient extends EventEmitter { } /** - * Set the Identity Server URL of this client - * @param {string} url New Identity Server URL + * Set the identity server URL of this client + * @param {string} url New identity server URL */ public setIdentityServerUrl(url: string) { this.idBaseUrl = utils.ensureNoTrailingSlash(url); @@ -7260,7 +7260,7 @@ export class MatrixClient extends EventEmitter { } /** - * Register with an Identity Server using the OpenID token from the user's + * Register with an identity server using the OpenID token from the user's * Homeserver, which can be retrieved via * {@link module:client~MatrixClient#getOpenIdToken}. * @@ -7274,7 +7274,7 @@ export class MatrixClient extends EventEmitter { */ public registerWithIdentityServer(hsOpenIdToken: any): Promise { // TODO: Types if (!this.idBaseUrl) { - throw new Error("No Identity Server base URL set"); + throw new Error("No identity server base URL set"); } const uri = this.idBaseUrl + PREFIX_IDENTITY_V2 + "/account/register"; @@ -7549,7 +7549,7 @@ export class MatrixClient extends EventEmitter { /** * Looks up the public Matrix ID mapping for a given 3rd party - * identifier from the Identity Server + * identifier from the identity server * * @param {string} medium The medium of the threepid, eg. 'email' * @param {string} address The textual address of the threepid @@ -7634,7 +7634,7 @@ export class MatrixClient extends EventEmitter { } /** - * Get account info from the Identity Server. This is useful as a neutral check + * Get account info from the identity server. This is useful as a neutral check * to verify that other APIs are likely to approve access by testing that the * token is valid, terms have been agreed, etc. * diff --git a/src/http-api.js b/src/http-api.js index 148ce87c4..92c6e420f 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -393,7 +393,7 @@ MatrixHttpApi.prototype = { accessToken, ) { if (!this.opts.idBaseUrl) { - throw new Error("No Identity Server base URL set"); + throw new Error("No identity server base URL set"); } const fullUri = this.opts.idBaseUrl + prefix + path; From ab3dfd48ae280cdf332ce85a1a72a6d90b1e8d77 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 13 Jul 2021 15:24:24 +0100 Subject: [PATCH 080/129] Standardise spelling of identity server Signed-off-by: Paulo Pinto --- CHANGELOG.md | 6 +++--- src/client.ts | 10 +++++----- src/interactive-auth.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9357bc98a..1efbac14c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1735,13 +1735,13 @@ Changes in [2.4.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag [\#1021](https://github.com/matrix-org/matrix-js-sdk/pull/1021) * Add getIdServer() & doesServerRequireIdServerParam() [\#1018](https://github.com/matrix-org/matrix-js-sdk/pull/1018) - * Make requestToken endpoints work without ID Server + * Make requestToken endpoints work without an identity server [\#1019](https://github.com/matrix-org/matrix-js-sdk/pull/1019) * Fix setIdentityServer [\#1016](https://github.com/matrix-org/matrix-js-sdk/pull/1016) * Change ICE fallback server and make fallback opt-in [\#1015](https://github.com/matrix-org/matrix-js-sdk/pull/1015) - * Throw an exception if trying to do an ID server request with no ID server + * Throw an exception if trying to do an identity server request with no identity server [\#1014](https://github.com/matrix-org/matrix-js-sdk/pull/1014) * Add setIdentityServerUrl [\#1013](https://github.com/matrix-org/matrix-js-sdk/pull/1013) @@ -3767,7 +3767,7 @@ Other improvements: [\#109](https://github.com/matrix-org/matrix-js-sdk/pull/109) * Refactor transmitted-messages code [\#110](https://github.com/matrix-org/matrix-js-sdk/pull/110) - * Add a method to the js sdk to look up 3pids on the ID server. + * Add a method to the js sdk to look up 3pids on the identity server. [\#113](https://github.com/matrix-org/matrix-js-sdk/pull/113) * Support for cancelling pending events [\#112](https://github.com/matrix-org/matrix-js-sdk/pull/112) diff --git a/src/client.ts b/src/client.ts index a560fb2ae..93ab31fe9 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4845,7 +4845,7 @@ export class MatrixClient extends EventEmitter { * return M_THREEPID_NOT_FOUND or send an email * to the address informing them of this (which one is up to the homeserver). * - * requestEmailToken calls the equivalent API directly on the ID server, + * requestEmailToken calls the equivalent API directly on the identity server, * therefore bypassing the password reset specific logic. * * @param {string} email As requestEmailToken @@ -4920,7 +4920,7 @@ export class MatrixClient extends EventEmitter { if (!await this.doesServerSupportSeparateAddAndBind() && this.idBaseUrl) { const idServerUrl = url.parse(this.idBaseUrl); if (!idServerUrl.host) { - throw new Error("Invalid ID server URL: " + this.idBaseUrl); + throw new Error("Invalid identity server URL: " + this.idBaseUrl); } postParams.id_server = idServerUrl.host; @@ -5884,7 +5884,7 @@ export class MatrixClient extends EventEmitter { * @param {string} sessionId * @param {Object} auth * @param {Object} bindThreepids Set key 'email' to true to bind any email - * threepid uses during registration in the ID server. Set 'msisdn' to + * threepid uses during registration in the identity server. Set 'msisdn' to * true to bind msisdn. * @param {string} guestAccessToken * @param {string} inhibitLogin @@ -7383,7 +7383,7 @@ export class MatrixClient extends EventEmitter { * Submits a MSISDN token to the identity server * * This is used when submitting the code sent by SMS to a phone number. - * The ID server has an equivalent API for email but the js-sdk does + * The identity server has an equivalent API for email but the js-sdk does * not expose this, since email is normally validated by the user clicking * a link rather than entering a code. * @@ -7396,7 +7396,7 @@ export class MatrixClient extends EventEmitter { * * @return {Promise} Resolves: Object, currently with no parameters. * @return {module:http-api.MatrixError} Rejects: with an error response. - * @throws Error if No ID server is set + * @throws Error if No identity server is set */ public async submitMsisdnToken( sid: string, diff --git a/src/interactive-auth.js b/src/interactive-auth.js index c1537fe85..cede96c93 100644 --- a/src/interactive-auth.js +++ b/src/interactive-auth.js @@ -217,7 +217,7 @@ InteractiveAuth.prototype = { /** * get the client secret used for validation sessions - * with the ID server. + * with the identity server. * * @return {string} client secret */ From dba70d4ce2ffdf5194b1f660010a077301a95771 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 13 Jul 2021 16:01:53 +0100 Subject: [PATCH 081/129] Standardise casing of integration manager Signed-off-by: Paulo Pinto --- src/service-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service-types.ts b/src/service-types.ts index 79dc99937..a292bb7c2 100644 --- a/src/service-types.ts +++ b/src/service-types.ts @@ -16,5 +16,5 @@ limitations under the License. export enum SERVICE_TYPES { IS = 'SERVICE_TYPE_IS', // An Identity Service - IM = 'SERVICE_TYPE_IM', // An Integration Manager + IM = 'SERVICE_TYPE_IM', // An integration manager } From 3f6aee144399b8ddcac4d5265f359320101eb9e1 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 13 Jul 2021 16:02:17 +0100 Subject: [PATCH 082/129] Use correct term for identity server Signed-off-by: Paulo Pinto --- src/service-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service-types.ts b/src/service-types.ts index a292bb7c2..80eeed74e 100644 --- a/src/service-types.ts +++ b/src/service-types.ts @@ -15,6 +15,6 @@ limitations under the License. */ export enum SERVICE_TYPES { - IS = 'SERVICE_TYPE_IS', // An Identity Service + IS = 'SERVICE_TYPE_IS', // An identity server IM = 'SERVICE_TYPE_IM', // An integration manager } From 5b2a53a2b4fef670eb0c2afd3cd43608f6a9cbf6 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 13 Jul 2021 16:50:36 +0100 Subject: [PATCH 083/129] Undo changes to the CHANGELOG Signed-off-by: Paulo Pinto --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1efbac14c..a7baac3a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1735,13 +1735,13 @@ Changes in [2.4.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag [\#1021](https://github.com/matrix-org/matrix-js-sdk/pull/1021) * Add getIdServer() & doesServerRequireIdServerParam() [\#1018](https://github.com/matrix-org/matrix-js-sdk/pull/1018) - * Make requestToken endpoints work without an identity server + * Make requestToken endpoints work without ID Server [\#1019](https://github.com/matrix-org/matrix-js-sdk/pull/1019) * Fix setIdentityServer [\#1016](https://github.com/matrix-org/matrix-js-sdk/pull/1016) * Change ICE fallback server and make fallback opt-in [\#1015](https://github.com/matrix-org/matrix-js-sdk/pull/1015) - * Throw an exception if trying to do an identity server request with no identity server + * Throw an exception if trying to do an ID server request with no ID server [\#1014](https://github.com/matrix-org/matrix-js-sdk/pull/1014) * Add setIdentityServerUrl [\#1013](https://github.com/matrix-org/matrix-js-sdk/pull/1013) @@ -1749,7 +1749,7 @@ Changes in [2.4.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag [\#1011](https://github.com/matrix-org/matrix-js-sdk/pull/1011) * Fix POST body for v2 IS requests [\#1010](https://github.com/matrix-org/matrix-js-sdk/pull/1010) - * Add API for bulk lookup on the identity server + * Add API for bulk lookup on the Identity Server [\#1009](https://github.com/matrix-org/matrix-js-sdk/pull/1009) * Remove deprecated authedRequestWithPrefix and requestWithPrefix [\#1000](https://github.com/matrix-org/matrix-js-sdk/pull/1000) @@ -3767,7 +3767,7 @@ Other improvements: [\#109](https://github.com/matrix-org/matrix-js-sdk/pull/109) * Refactor transmitted-messages code [\#110](https://github.com/matrix-org/matrix-js-sdk/pull/110) - * Add a method to the js sdk to look up 3pids on the identity server. + * Add a method to the js sdk to look up 3pids on the ID server. [\#113](https://github.com/matrix-org/matrix-js-sdk/pull/113) * Support for cancelling pending events [\#112](https://github.com/matrix-org/matrix-js-sdk/pull/112) From 3ff05c0947e98ec7a3ee2e598448205808460f6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Tue, 13 Jul 2021 20:11:58 +0200 Subject: [PATCH 084/129] Ignore vscode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 90a941f51..4fc51ab85 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ out # version file and tarball created by `npm pack` / `yarn pack` /git-revision.txt /matrix-js-sdk-*.tgz + +.vscode +.vscode/ From 83337eee574a1861993b5a0e767a7f7285fba02c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 13 Jul 2021 23:09:37 -0600 Subject: [PATCH 085/129] Expose MatrixEvent's internal clearEvent as a function --- src/models/event.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/models/event.ts b/src/models/event.ts index 9050f4440..922490363 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -262,6 +262,15 @@ export class MatrixEvent extends EventEmitter { this.localTimestamp = Date.now() - this.getAge(); } + /** + * Gets the clear event as it would be received over the wire. If the event + * is not encrypted, this simply returns the event as-is. + * @returns {Partial} The clear event, as known by the SDK. + */ + public getClearEvent(): Partial { + return this.clearEvent ?? this.event; + } + /** * Get the event_id for this event. * @return {string} The event ID, e.g. $143350589368169JsLZx:localhost From 45259f07737b6768a554a2722d5351deb03931e9 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 14 Jul 2021 16:16:03 +0100 Subject: [PATCH 086/129] Prepare changelog for v12.1.0-rc.1 --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7baac3a3..1868dcaeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ +Changes in [12.1.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v12.1.0-rc.1) (2021-07-14) +============================================================================================================ +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v12.0.1...v12.1.0-rc.1) + + * Add VS Code to gitignore + [\#1783](https://github.com/matrix-org/matrix-js-sdk/pull/1783) + * Make `Crypto::inRoomVerificationRequests` public + [\#1781](https://github.com/matrix-org/matrix-js-sdk/pull/1781) + * Call `setEventMetadata()` for filtered `timelineSet`s + [\#1765](https://github.com/matrix-org/matrix-js-sdk/pull/1765) + * Symmetric backup + [\#1775](https://github.com/matrix-org/matrix-js-sdk/pull/1775) + * Attempt to fix megolm key not being in SSSS + [\#1776](https://github.com/matrix-org/matrix-js-sdk/pull/1776) + * Convert SecretStorage to TypeScript + [\#1774](https://github.com/matrix-org/matrix-js-sdk/pull/1774) + * Strip hash from urls being previewed to de-duplicate + [\#1721](https://github.com/matrix-org/matrix-js-sdk/pull/1721) + * Do not generate a lockfile when running in CI + [\#1773](https://github.com/matrix-org/matrix-js-sdk/pull/1773) + * Tidy up secret requesting code + [\#1766](https://github.com/matrix-org/matrix-js-sdk/pull/1766) + * Convert Sync and SyncAccumulator to Typescript + [\#1763](https://github.com/matrix-org/matrix-js-sdk/pull/1763) + * Convert EventTimeline, EventTimelineSet and TimelineWindow to TS + [\#1762](https://github.com/matrix-org/matrix-js-sdk/pull/1762) + * Comply with new member-delimiter-style rule + [\#1764](https://github.com/matrix-org/matrix-js-sdk/pull/1764) + * Do not honor string power levels + [\#1754](https://github.com/matrix-org/matrix-js-sdk/pull/1754) + * Typescriptify some crypto stuffs + [\#1508](https://github.com/matrix-org/matrix-js-sdk/pull/1508) + * Make filterId read/write and optional + [\#1760](https://github.com/matrix-org/matrix-js-sdk/pull/1760) + Changes in [12.0.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v12.0.1) (2021-07-05) ================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v12.0.1-rc.1...v12.0.1) From d71ca8a9e03a49c5fb4db73cbd6dac04f7726cd1 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 14 Jul 2021 16:16:04 +0100 Subject: [PATCH 087/129] v12.1.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b1c92efe6..546f9679d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.0.1", + "version": "12.1.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -28,7 +28,7 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", + "main": "./lib/index.js", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -110,5 +110,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From 326b14402f5cc613bd4f2a8e6d011e6dbff6aa29 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 14 Jul 2021 10:07:43 -0600 Subject: [PATCH 088/129] Return a properly shaped event --- src/models/event.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/models/event.ts b/src/models/event.ts index 922490363..3c5f19a46 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -268,7 +268,8 @@ export class MatrixEvent extends EventEmitter { * @returns {Partial} The clear event, as known by the SDK. */ public getClearEvent(): Partial { - return this.clearEvent ?? this.event; + // clearEvent doesn't have all the fields, so we'll copy what we can from this.event + return Object.assign({}, this.event, this.clearEvent); } /** From ea4dfd003f67cf2a7baa31ad16e36c28a72b426c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 14 Jul 2021 10:09:23 -0600 Subject: [PATCH 089/129] It's not a partial anymore --- src/models/event.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/models/event.ts b/src/models/event.ts index 3c5f19a46..09cc59204 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -265,11 +265,11 @@ export class MatrixEvent extends EventEmitter { /** * Gets the clear event as it would be received over the wire. If the event * is not encrypted, this simply returns the event as-is. - * @returns {Partial} The clear event, as known by the SDK. + * @returns {IEvent} The clear event, as known by the SDK. */ - public getClearEvent(): Partial { + public getClearEvent(): IEvent { // clearEvent doesn't have all the fields, so we'll copy what we can from this.event - return Object.assign({}, this.event, this.clearEvent); + return Object.assign({}, this.event, this.clearEvent) as IEvent; } /** From 11dabf9a687706684153cc82f854bc749a1a3fe6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 14 Jul 2021 10:18:12 -0600 Subject: [PATCH 090/129] rename --- src/models/event.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/models/event.ts b/src/models/event.ts index 09cc59204..f687a9a26 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -263,11 +263,11 @@ export class MatrixEvent extends EventEmitter { } /** - * Gets the clear event as it would be received over the wire. If the event - * is not encrypted, this simply returns the event as-is. - * @returns {IEvent} The clear event, as known by the SDK. + * Gets the event as though it would appear unencrypted. If the event is already not + * encrypted, it is simply returned as-is. + * @returns {IEvent} The event in wire format. */ - public getClearEvent(): IEvent { + public getEffectiveEvent(): IEvent { // clearEvent doesn't have all the fields, so we'll copy what we can from this.event return Object.assign({}, this.event, this.clearEvent) as IEvent; } @@ -1240,15 +1240,7 @@ export class MatrixEvent extends EventEmitter { * @return {Object} */ public toJSON(): object { - const event: any = { - type: this.getType(), - sender: this.getSender(), - content: this.getContent(), - event_id: this.getId(), - origin_server_ts: this.getTs(), - unsigned: this.getUnsigned(), - room_id: this.getRoomId(), - }; + const event = this.getEffectiveEvent(); // if this is a redaction then attach the redacts key if (this.isRedaction()) { From 4bc4e1b76f77b84b7ff480a5d0d58a6f657b1422 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 14 Jul 2021 10:22:36 -0600 Subject: [PATCH 091/129] remove useless code --- src/models/event.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/models/event.ts b/src/models/event.ts index f687a9a26..55d0bf583 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -1242,11 +1242,6 @@ export class MatrixEvent extends EventEmitter { public toJSON(): object { const event = this.getEffectiveEvent(); - // if this is a redaction then attach the redacts key - if (this.isRedaction()) { - event.redacts = this.event.redacts; - } - if (!this.isEncrypted()) { return event; } From 9184a0d902581ec3082beba5af0884c5f5db2d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Wed, 14 Jul 2021 18:27:38 +0200 Subject: [PATCH 092/129] Use MSC2885 unstable prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Šimon Brandner --- src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index 7186a79a3..f6c9cef93 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3650,7 +3650,7 @@ export class MatrixClient extends EventEmitter { } const addlContent = { - "m.hidden": Boolean(opts.hidden), + "org.matrix.msc2885.hidden": Boolean(opts.hidden), }; return this.sendReceipt(event, "m.read", addlContent, callback); @@ -6429,7 +6429,7 @@ export class MatrixClient extends EventEmitter { const content = { "m.fully_read": rmEventId, "m.read": rrEventId, - "m.hidden": Boolean(opts ? opts.hidden : false), + "org.matrix.msc2885.hidden": Boolean(opts ? opts.hidden : false), }; return this.http.authedRequest( From 20bd9b525b65e215ba849dfcd8051a392be3cefb Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 19:02:03 +0100 Subject: [PATCH 093/129] Convert CONTRIBUTING to markdown Because everything else is --- CONTRIBUTING.rst => CONTRIBUTING.md | 96 +++++++++++++++-------------- 1 file changed, 50 insertions(+), 46 deletions(-) rename CONTRIBUTING.rst => CONTRIBUTING.md (63%) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.md similarity index 63% rename from CONTRIBUTING.rst rename to CONTRIBUTING.md index 532e09aac..12f6809b3 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.md @@ -6,10 +6,11 @@ willing to license their contributions under the same license as the project itself. We follow a simple 'inbound=outbound' model for contributions: the act of submitting an 'inbound' contribution means that the contributor agrees to license the code under the same terms as the project's overall 'outbound' -license - in this case, Apache Software License v2 (see ``_). +license - in this case, Apache Software License v2 (see +[LICENSE](LICENSE)). How to contribute -~~~~~~~~~~~~~~~~~ +----------------- The preferred and easiest way to contribute changes to the project is to fork it on github, and then create a pull request to ask us to pull your changes @@ -33,8 +34,7 @@ if your change breaks the build, then the PR will show that there are failed checks, so please check back after a few minutes. Code style -~~~~~~~~~~ - +---------- The js-sdk aims to target TypeScript/ES6. All new files should be written in TypeScript and existing files should use ES6 principles where possible. @@ -44,17 +44,16 @@ introduce naming problems (as default exports get aliased upon import). In general, avoid using `export default`. The remaining code-style for matrix-js-sdk is not formally documented, but -contributors are encouraged to read the code style document for matrix-react-sdk -(``_) +contributors are encouraged to read the +[code style document for matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/blob/master/code_style.md) and follow the principles set out there. Please ensure your changes match the cosmetic style of the existing project, -and **never** mix cosmetic and functional changes in the same commit, as it +and ***never*** mix cosmetic and functional changes in the same commit, as it makes it horribly hard to review otherwise. Attribution -~~~~~~~~~~~ - +----------- Everyone who contributes anything to Matrix is welcome to be listed in the AUTHORS.rst file for the project in question. Please feel free to include a change to AUTHORS.rst in your pull request to list yourself and a short @@ -64,8 +63,7 @@ from your life, please mail us your shipping address to matrix at matrix.org and we'll try to fix it :) Sign off -~~~~~~~~ - +-------- In order to have a concrete record that your contribution is intentional and you agree to license it under the same terms as the project's license, we've adopted the same lightweight approach that the Linux Kernel @@ -73,59 +71,65 @@ adopted the same lightweight approach that the Linux Kernel (https://github.com/docker/docker/blob/master/CONTRIBUTING.md), and many other projects use: the DCO (Developer Certificate of Origin: http://developercertificate.org/). This is a simple declaration that you wrote -the contribution or otherwise have the right to contribute it to Matrix:: +the contribution or otherwise have the right to contribute it to Matrix: - Developer Certificate of Origin - Version 1.1 +``` +Developer Certificate of Origin +Version 1.1 - Copyright (C) 2004, 2006 The Linux Foundation and its contributors. - 660 York Street, Suite 102, - San Francisco, CA 94110 USA +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA - Everyone is permitted to copy and distribute verbatim copies of this - license document, but changing it is not allowed. +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. - Developer's Certificate of Origin 1.1 +Developer's Certificate of Origin 1.1 - By making a contribution to this project, I certify that: +By making a contribution to this project, I certify that: - (a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or - (b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or - (c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. - (d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` If you agree to this for your contribution, then all that's needed is to -include the line in your commit or pull request comment:: +include the line in your commit or pull request comment: - Signed-off-by: Your Name +``` +Signed-off-by: Your Name +``` We accept contributions under a legally identifiable name, such as your name on government documentation or common-law names (names claimed by legitimate usage or repute). Unfortunately, we cannot accept anonymous contributions at this time. -Git allows you to add this signoff automatically when using the ``-s`` flag to -``git commit``, which uses the name and email set in your ``user.name`` and -``user.email`` git configs. +Git allows you to add this signoff automatically when using the `-s` flag to +`git commit`, which uses the name and email set in your `user.name` and +`user.email` git configs. If you forgot to sign off your commits before making your pull request and are -on Git 2.17+ you can mass signoff using rebase:: +on Git 2.17+ you can mass signoff using rebase: - git rebase --signoff origin/develop +``` +git rebase --signoff origin/develop +``` From b538c06fcb60d049e8395f5ab490ef095c35de6f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 19:45:42 +0100 Subject: [PATCH 094/129] Update contributing guidelines to for new changelog stuff --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++ CONTRIBUTING.md | 80 +++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c9d11f02c..55c0000a1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,7 @@ + + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 12f6809b3..e15eaa823 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,18 +16,76 @@ The preferred and easiest way to contribute changes to the project is to fork it on github, and then create a pull request to ask us to pull your changes into our repo (https://help.github.com/articles/using-pull-requests/) -**The single biggest thing you need to know is: please base your changes on -the develop branch - /not/ master.** +We use GitHub's pull request workflow to review the contribution, and either +ask you to make any refinements needed or merge it and make them ourselves. -We use the master branch to track the most recent release, so that folks who -blindly clone the repo and automatically check out master get something that -works. Develop is the unstable branch where all the development actually -happens: the workflow is that contributors should fork the develop branch to -make a 'feature' branch for a particular contribution, and then make a pull -request to merge this back into the matrix.org 'official' develop branch. We -use GitHub's pull request workflow to review the contribution, and either ask -you to make any refinements needed or merge it and make them ourselves. The -changes will then land on master when we next do a release. +Things that should go into your PR description: + * A changelog entry in the `Notes` section (see below) + * References to any bugs fixed by the change (in Github's `Fixes` notation) + * Notes for the reviewer that might help them to understand why the change is + necessary or how they might better review it. + +Things that should *not* go into your PR description: + * Any information on how the code works or why you chose to do it the way + you did. If this isn't obvious from your code, you haven't written enough + comments. + +We rely on information in pull request to populate the information that goes +into the changelogs our users see, both for the js-sdk itself and also for some +projects based on it. This is picked up from both tags on the pull request and +the `Notes: ` annotation in the description. By default, the PR title will be +used for the changelog entry, but you can specify more options, as follows. + +To add a longer, more detailed description of the change for the changelog: + + +*Fix llama herding bug* + +``` +Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where the 'Herd' button would not herd more than 8 Llamas if the moon was in the waxing gibbous phase +``` + +For some PRs, it's not useful to have an entry in the user-facing changelog: + +*Remove outdated comment from `Ungulates.ts`* +``` +Notes: none +``` + +Sometimes, you're fixing a bug in a downstream project, in which case you want +an entry in that project's changelog. You can do that too: + +*Fix another herding bug* +``` +Notes: Fix a bug where the `herd()` function would only work on Tuesdays +other-project notes: Fix a bug where the 'Herd' button only worked on Tuesdays +``` + +Projects that you can specify here are: + * matrix-react-sdk + * element-web + * element-desktop + +If your PR introduces a breaking change, you should indicate that in the same +`Notes` section, additionally adding the `pr-breaking` tag (see below). +There's no need to specify in the notes that it's a breaking change - this will +be added automatically based on the tag - but remember to tell the developer how +to migrate: + +*Remove legacy class* + +``` +Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead. +``` + +Other metadata can be added using tags. + * `pr-breaking`: A breaking change - adding this tag will mean the change causes a *major* version bump. + * `pr-feature`: A new feature - adding this tag will mean the change causes a *minor* version bump. + * `pr-bugfix`: A bugfix (in either code or docs). + * `pr-internal`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. + +If you don't have permission to add tags, your PR reviewer(s) can work with you +to add them: ask in the PR description or comments. We use continuous integration, and all pull requests get automatically tested: if your change breaks the build, then the PR will show that there are failed From ee5a0e7edf8ce3e1c45e227cd4bf9e753fa40571 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 19:47:46 +0100 Subject: [PATCH 095/129] Internal PRs shouldn't have changelog entries by default --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e15eaa823..35c77f671 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,7 +45,8 @@ To add a longer, more detailed description of the change for the changelog: Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where the 'Herd' button would not herd more than 8 Llamas if the moon was in the waxing gibbous phase ``` -For some PRs, it's not useful to have an entry in the user-facing changelog: +For some PRs, it's not useful to have an entry in the user-facing changelog (this is +the default for PRs tagged with `pr-internal`): *Remove outdated comment from `Ungulates.ts`* ``` @@ -82,7 +83,7 @@ Other metadata can be added using tags. * `pr-breaking`: A breaking change - adding this tag will mean the change causes a *major* version bump. * `pr-feature`: A new feature - adding this tag will mean the change causes a *minor* version bump. * `pr-bugfix`: A bugfix (in either code or docs). - * `pr-internal`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. + * `pr-internal`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one. If you don't have permission to add tags, your PR reviewer(s) can work with you to add them: ask in the PR description or comments. From e1338985544a70d9d48172b22fca1f9e9731b166 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 19:48:47 +0100 Subject: [PATCH 096/129] Fix link to CONTRIBUTING.md --- .github/PULL_REQUEST_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c9d11f02c..fb237a584 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,3 @@ - + - + From b17862e212c61217fac929732d7b66b0917e21e1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 19:55:58 +0100 Subject: [PATCH 097/129] s/tag/label/ Also make breaking change notation clearer. --- CONTRIBUTING.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 35c77f671..57bbcdb7c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,7 +32,7 @@ Things that should *not* go into your PR description: We rely on information in pull request to populate the information that goes into the changelogs our users see, both for the js-sdk itself and also for some -projects based on it. This is picked up from both tags on the pull request and +projects based on it. This is picked up from both labels on the pull request and the `Notes: ` annotation in the description. By default, the PR title will be used for the changelog entry, but you can specify more options, as follows. @@ -46,7 +46,7 @@ Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where th ``` For some PRs, it's not useful to have an entry in the user-facing changelog (this is -the default for PRs tagged with `pr-internal`): +the default for PRs labelled with `pr-internal`): *Remove outdated comment from `Ungulates.ts`* ``` @@ -67,11 +67,11 @@ Projects that you can specify here are: * element-web * element-desktop -If your PR introduces a breaking change, you should indicate that in the same -`Notes` section, additionally adding the `pr-breaking` tag (see below). -There's no need to specify in the notes that it's a breaking change - this will -be added automatically based on the tag - but remember to tell the developer how -to migrate: +If your PR introduces a breaking change, use the `Notes` section in the same +way, additionally adding the `pr-breaking` label (see below). There's no need +to specify in the notes that it's a breaking change - this will be added +automatically based on the label - but remember to tell the developer how to +migrate: *Remove legacy class* @@ -79,13 +79,13 @@ to migrate: Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead. ``` -Other metadata can be added using tags. - * `pr-breaking`: A breaking change - adding this tag will mean the change causes a *major* version bump. - * `pr-feature`: A new feature - adding this tag will mean the change causes a *minor* version bump. +Other metadata can be added using labels. + * `pr-breaking`: A breaking change - adding this label will mean the change causes a *major* version bump. + * `pr-feature`: A new feature - adding this label will mean the change causes a *minor* version bump. * `pr-bugfix`: A bugfix (in either code or docs). * `pr-internal`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one. -If you don't have permission to add tags, your PR reviewer(s) can work with you +If you don't have permission to add labels, your PR reviewer(s) can work with you to add them: ask in the PR description or comments. We use continuous integration, and all pull requests get automatically tested: From fddf0c47fb92bd697787edfb6ba94eae26657dc0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 21:57:04 +0100 Subject: [PATCH 098/129] Fix formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Šimon Brandner --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57bbcdb7c..265ea1b90 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ Things that should *not* go into your PR description: We rely on information in pull request to populate the information that goes into the changelogs our users see, both for the js-sdk itself and also for some projects based on it. This is picked up from both labels on the pull request and -the `Notes: ` annotation in the description. By default, the PR title will be +the `Notes:` annotation in the description. By default, the PR title will be used for the changelog entry, but you can specify more options, as follows. To add a longer, more detailed description of the change for the changelog: From 9c221419eff86dd43747474bfe6b10099dc46e0b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 21:57:29 +0100 Subject: [PATCH 099/129] On-brand Co-authored-by: J. Ryan Stinnett --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 265ea1b90..48f38548e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ ask you to make any refinements needed or merge it and make them ourselves. Things that should go into your PR description: * A changelog entry in the `Notes` section (see below) - * References to any bugs fixed by the change (in Github's `Fixes` notation) + * References to any bugs fixed by the change (in GitHub's `Fixes` notation) * Notes for the reviewer that might help them to understand why the change is necessary or how they might better review it. From b0726b5008c8730104266e658e28079f5c0c5462 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 21:57:48 +0100 Subject: [PATCH 100/129] On brand ourself Co-authored-by: J. Ryan Stinnett --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 48f38548e..9c54f8074 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,7 +31,7 @@ Things that should *not* go into your PR description: comments. We rely on information in pull request to populate the information that goes -into the changelogs our users see, both for the js-sdk itself and also for some +into the changelogs our users see, both for the JS SDK itself and also for some projects based on it. This is picked up from both labels on the pull request and the `Notes:` annotation in the description. By default, the PR title will be used for the changelog entry, but you can specify more options, as follows. From c4ccb9d49383f1cc99ab542af1b95068b545f8cb Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 22:00:42 +0100 Subject: [PATCH 101/129] Use a real-life example which should hopefully be clearer --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c54f8074..ba0d3af23 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,10 +59,10 @@ an entry in that project's changelog. You can do that too: *Fix another herding bug* ``` Notes: Fix a bug where the `herd()` function would only work on Tuesdays -other-project notes: Fix a bug where the 'Herd' button only worked on Tuesdays +element-web notes: Fix a bug where the 'Herd' button only worked on Tuesdays ``` -Projects that you can specify here are: +This example is for Element Web. You can specify: * matrix-react-sdk * element-web * element-desktop From 5392f616b4f0dc072bece831dc7cd9b4ae518ce8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 22:15:18 +0100 Subject: [PATCH 102/129] Use existing issues labels / scheme Co-authored-by: J. Ryan Stinnett --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba0d3af23..8f684e8dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,10 +80,10 @@ Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead. ``` Other metadata can be added using labels. - * `pr-breaking`: A breaking change - adding this label will mean the change causes a *major* version bump. - * `pr-feature`: A new feature - adding this label will mean the change causes a *minor* version bump. - * `pr-bugfix`: A bugfix (in either code or docs). - * `pr-internal`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one. + * `X-Breaking`: A breaking change - adding this label will mean the change causes a *major* version bump. + * `T-Enhancement`: A new feature - adding this label will mean the change causes a *minor* version bump. + * `T-Defect`: A bug fix (in either code or docs). + * `T-Task`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one. If you don't have permission to add labels, your PR reviewer(s) can work with you to add them: ask in the PR description or comments. From 19aedebff1e4e12b59997194c4c8280fffecccef Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 22:16:00 +0100 Subject: [PATCH 103/129] Update other label mentions --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f684e8dc..0f86aa2fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where th ``` For some PRs, it's not useful to have an entry in the user-facing changelog (this is -the default for PRs labelled with `pr-internal`): +the default for PRs labelled with `T-Task`): *Remove outdated comment from `Ungulates.ts`* ``` @@ -68,7 +68,7 @@ This example is for Element Web. You can specify: * element-desktop If your PR introduces a breaking change, use the `Notes` section in the same -way, additionally adding the `pr-breaking` label (see below). There's no need +way, additionally adding the `X-Breaking` label (see below). There's no need to specify in the notes that it's a breaking change - this will be added automatically based on the label - but remember to tell the developer how to migrate: From 45c153321ca21a2a551dc80fcb53188a0df80239 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 14 Jul 2021 22:46:22 +0100 Subject: [PATCH 104/129] Use X-Breaking-Change Apparently we already have this label in react SDK (for some reason) so let's use it. Plus, it's clearer that it's for changes rather than issues that cause things to break. --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0f86aa2fb..d90508302 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,7 +68,7 @@ This example is for Element Web. You can specify: * element-desktop If your PR introduces a breaking change, use the `Notes` section in the same -way, additionally adding the `X-Breaking` label (see below). There's no need +way, additionally adding the `X-Breaking-Change` label (see below). There's no need to specify in the notes that it's a breaking change - this will be added automatically based on the label - but remember to tell the developer how to migrate: @@ -80,7 +80,7 @@ Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead. ``` Other metadata can be added using labels. - * `X-Breaking`: A breaking change - adding this label will mean the change causes a *major* version bump. + * `X-Breaking-Change`: A breaking change - adding this label will mean the change causes a *major* version bump. * `T-Enhancement`: A new feature - adding this label will mean the change causes a *minor* version bump. * `T-Defect`: A bug fix (in either code or docs). * `T-Task`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one. From ff40b4dc4a4f4700df50f877a288b51092b2e324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 15 Jul 2021 09:41:35 +0200 Subject: [PATCH 105/129] Fix MSC number Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index f6c9cef93..662066790 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3650,7 +3650,7 @@ export class MatrixClient extends EventEmitter { } const addlContent = { - "org.matrix.msc2885.hidden": Boolean(opts.hidden), + "org.matrix.msc2285.hidden": Boolean(opts.hidden), }; return this.sendReceipt(event, "m.read", addlContent, callback); From bae5650e7a9ee54232053288c9c70a59ef85c767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Brandner?= Date: Thu, 15 Jul 2021 09:41:40 +0200 Subject: [PATCH 106/129] Fix MSC number Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 662066790..40449b903 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6429,7 +6429,7 @@ export class MatrixClient extends EventEmitter { const content = { "m.fully_read": rmEventId, "m.read": rrEventId, - "org.matrix.msc2885.hidden": Boolean(opts ? opts.hidden : false), + "org.matrix.msc2285.hidden": Boolean(opts ? opts.hidden : false), }; return this.http.authedRequest( From d383e71aca9a5cb13e220f96a13f9cb59988d75c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 15 Jul 2021 17:44:17 +0100 Subject: [PATCH 107/129] Switch callEventHandler from listening on `event` to `Room.timeline` so that it doesn't end up processing ephemerals, account data, remote echoes, etc etc --- src/webrtc/callEventHandler.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 9d62375e9..263ddbf9b 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -47,12 +47,12 @@ export class CallEventHandler { public start() { this.client.on("sync", this.evaluateEventBuffer); - this.client.on("event", this.onEvent); + this.client.on("Room.timeline", this.onRoomTimeline); } public stop() { this.client.removeListener("sync", this.evaluateEventBuffer); - this.client.removeListener("event", this.onEvent); + this.client.removeListener("Room.timeline", this.onRoomTimeline); } private evaluateEventBuffer = async () => { @@ -89,7 +89,7 @@ export class CallEventHandler { } }; - private onEvent = (event: MatrixEvent) => { + private onRoomTimeline = (event: MatrixEvent) => { this.client.decryptEventIfNeeded(event); // any call events or ones that might be once they're decrypted if (this.eventIsACall(event) || event.isBeingDecrypted()) { From 8379bb818e91819c3bc92b634930171acb9550e4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Jul 2021 13:01:27 +0100 Subject: [PATCH 108/129] Switch from url to URL constructor --- src/client.ts | 6 +----- src/interactive-auth.js | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/client.ts b/src/client.ts index 904958674..d3bceec36 100644 --- a/src/client.ts +++ b/src/client.ts @@ -126,7 +126,6 @@ import { } from "./@types/event"; import { IAbortablePromise, IdServerUnbindResult, IImageInfo, Preset, Visibility } from "./@types/partials"; import { EventMapper, eventMapperFor, MapperOpts } from "./event-mapper"; -import url from "url"; import { randomString } from "./randomstring"; import { ReadStream } from "fs"; import { WebStorageSessionStore } from "./store/session/webstorage"; @@ -5156,10 +5155,7 @@ export class MatrixClient extends EventEmitter { // If the HS supports separate add and bind, then requestToken endpoints // don't need an IS as they are all validated by the HS directly. if (!await this.doesServerSupportSeparateAddAndBind() && this.idBaseUrl) { - const idServerUrl = url.parse(this.idBaseUrl); - if (!idServerUrl.host) { - throw new Error("Invalid identity server URL: " + this.idBaseUrl); - } + const idServerUrl = new URL(this.idBaseUrl); postParams.id_server = idServerUrl.host; if ( diff --git a/src/interactive-auth.js b/src/interactive-auth.js index cede96c93..1f247388f 100644 --- a/src/interactive-auth.js +++ b/src/interactive-auth.js @@ -18,7 +18,6 @@ limitations under the License. /** @module interactive-auth */ -import url from "url"; import * as utils from "./utils"; import { logger } from './logger'; @@ -187,9 +186,7 @@ InteractiveAuth.prototype = { client_secret: this._clientSecret, }; if (await this._matrixClient.doesServerRequireIdServerParam()) { - const idServerParsedUrl = url.parse( - this._matrixClient.getIdentityServerUrl(), - ); + const idServerParsedUrl = new URL(this._matrixClient.getIdentityServerUrl()); creds.id_server = idServerParsedUrl.host; } authDict = { From 9b81b805be4421599d2eeecfa55acf6a9c48a2eb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 16 Jul 2021 13:07:01 +0100 Subject: [PATCH 109/129] create utility to decode qs into objects --- src/utils.ts | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index fa45f20d2..a392006ea 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -31,15 +31,28 @@ import type NodeCrypto from "crypto"; * @return {string} The encoded string e.g. foo=bar&baz=taz */ export function encodeParams(params: Record): string { - let qs = ""; - for (const key in params) { - if (!params.hasOwnProperty(key)) { - continue; - } - qs += "&" + encodeURIComponent(key) + "=" + - encodeURIComponent(params[key]); + return new URLSearchParams(params).toString(); +} + +export type QueryDict = Record; + +/** + * Decode a query string in `application/x-www-form-urlencoded` format. + * @param {string} query A query string to decode e.g. + * foo=bar&via=server1&server2 + * @return {Object} The decoded object, if any keys occurred multiple times + * then the value will be an array of strings, else it will be an array. + * This behaviour matches Node's qs.parse but is built on URLSearchParams + * for native web compatibility + */ +export function decodeParams(query: string): QueryDict { + const o: QueryDict = {}; + const params = new URLSearchParams(query); + for (const key of params.keys()) { + const val = params.getAll(key); + o[key] = val.length === 1 ? val[0] : val; } - return qs.substring(1); + return o; } /** From 16fe5a91d5caeedb74e6b746f665931a62c22685 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Jul 2021 16:27:50 -0600 Subject: [PATCH 110/129] Consolidate types --- src/@types/threepids.ts | 8 ++++---- src/client.ts | 24 +----------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/src/@types/threepids.ts b/src/@types/threepids.ts index 2b1a03378..65158d2e3 100644 --- a/src/@types/threepids.ts +++ b/src/@types/threepids.ts @@ -20,9 +20,9 @@ export enum ThreepidMedium { } // TODO: Are these types universal, or specific to just /account/3pid? -export interface IThirdPartyIdentifier { - added_at: number; // eslint-disable-line camelcase - address: string; +export interface IThreepid { medium: ThreepidMedium; - validated_at: number; // eslint-disable-line camelcase + address: string; + validated_at: number; + added_at: number; } diff --git a/src/client.ts b/src/client.ts index 387d28965..3d6bfce83 100644 --- a/src/client.ts +++ b/src/client.ts @@ -145,7 +145,7 @@ import { import { ISynapseAdminDeactivateResponse, ISynapseAdminWhoisResponse } from "./@types/synapse"; import { ISpaceSummaryEvent, ISpaceSummaryRoom } from "./@types/spaces"; import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules"; -import { IThirdPartyIdentifier } from "./@types/threepids"; +import { IThreepid } from "./@types/threepids"; export type Store = IStore; export type SessionStore = WebStorageSessionStore; @@ -597,13 +597,6 @@ interface IUserDirectoryResponse { limited: boolean; } -interface IThreepid { - medium: "email" | "msisdn"; - address: string; - validated_at: number; - added_at: number; -} - interface IMyDevice { device_id: string; display_name?: string; @@ -611,21 +604,6 @@ interface IMyDevice { last_seen_ts?: number; } -interface IPusher { - pushkey: string; - kind: string; - app_id: string; - app_display_name: string; - device_display_name: string; - profile_tag?: string; - lang: string; - data: { - url?: string; - format?: string; - brand?: string; // undocumented - }; -} - interface IDownloadKeyResult { failures: { [serverName: string]: object }; device_keys: { From 589c66bb128d29ac347a19e366086414538b2b2e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Jul 2021 16:30:06 -0600 Subject: [PATCH 111/129] Re-appease linter --- src/@types/threepids.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/@types/threepids.ts b/src/@types/threepids.ts index 65158d2e3..1740dec7a 100644 --- a/src/@types/threepids.ts +++ b/src/@types/threepids.ts @@ -23,6 +23,6 @@ export enum ThreepidMedium { export interface IThreepid { medium: ThreepidMedium; address: string; - validated_at: number; - added_at: number; + validated_at: number; // eslint-disable-line camelcase + added_at: number; // eslint-disable-line camelcase } From fc8cd39d1aac31d280b8614f9660ae4261b8c41a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Jul 2021 16:32:49 -0600 Subject: [PATCH 112/129] Optionalize opts --- src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.ts b/src/client.ts index 3d6bfce83..e4756c896 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3863,7 +3863,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: to an empty object * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async sendReadReceipt(event: MatrixEvent, opts: { hidden?: boolean }, callback?: Callback): Promise<{}> { + public async sendReadReceipt(event: MatrixEvent, opts?: { hidden?: boolean }, callback?: Callback): Promise<{}> { if (typeof (opts) === 'function') { callback = opts as any as Callback; // legacy opts = {}; From 7f7c3cbea50f48739a6d42a880c3bd0fbf093b8c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 16 Jul 2021 23:48:41 -0600 Subject: [PATCH 113/129] Fix exclusion types --- src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index e4756c896..08e6e5dd2 100644 --- a/src/client.ts +++ b/src/client.ts @@ -7219,7 +7219,7 @@ export class MatrixClient extends EventEmitter { public addPushRule( scope: string, kind: PushRuleKind, - ruleId: RuleId | string, + ruleId: Exclude, body: any, callback?: Callback, ): Promise { // TODO: Types @@ -7242,7 +7242,7 @@ export class MatrixClient extends EventEmitter { public deletePushRule( scope: string, kind: PushRuleKind, - ruleId: RuleId | string, + ruleId: Exclude, callback?: Callback, ): Promise { // TODO: Types // NB. Scope not uri encoded because devices need the '/' From 7129c7c7af545c8b73225541b74cc477a7e11049 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Mon, 19 Jul 2021 10:56:15 +0200 Subject: [PATCH 114/129] Update src/models/room.ts Co-authored-by: Travis Ralston --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index 70ce826e2..6e78ee4c9 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2041,7 +2041,7 @@ export class Room extends EventEmitter { // get service members (e.g. helper bots) for exclusion let excludedUserIds: string[] = []; - const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.unstable, ""); + const mFunctionalMembers = this.currentState.getStateEvents(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, ""); if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { excludedUserIds = mFunctionalMembers.getContent().service_members; } From 4a1cd159a4e74ddc8a6e6f6458650cd9d83b9b0f Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Mon, 19 Jul 2021 11:53:43 +0200 Subject: [PATCH 115/129] Update event.ts --- src/@types/event.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/@types/event.ts b/src/@types/event.ts index 2c6a47928..42c7d0529 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -148,6 +148,19 @@ export const UNSTABLE_MSC3089_BRANCH = new UnstableValue("m.branch", "org.matrix * Functional members type for declaring a purpose of room members (e.g. helpful bots). * Note that this reference is UNSTABLE and subject to breaking changes, including its * eventual removal. + * + * Schema (TypeScript): + * { + * service_members?: string[] + * } + * + * Example: + * { + * "service_members": [ + * "@helperbot:localhost", + * "@reminderbot:alice.tdl" + * ] + * } */ export const UNSTABLE_ELEMENT_FUNCTIONAL_USERS = new UnstableValue( "io.element.functional_members", From 805267f97f2599334d355151e3d263a9a0d13dee Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 19 Jul 2021 15:23:20 +0100 Subject: [PATCH 116/129] Update eslint-plugin-matrix-org --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 076bd2252..96661442b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2858,7 +2858,7 @@ eslint-config-google@^0.14.0: "eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main": version "0.3.2" - resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/e8197938dca66849ffdac4baca7c05275df12835" + resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/383a1e4a9ef7944c921efda0de2ac9635d45cb5c" eslint-rule-composer@^0.3.0: version "0.3.0" From a3d9ed19a410c65f2bd10c81eaff8a3c2ab604aa Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 19 Jul 2021 15:49:54 +0100 Subject: [PATCH 117/129] Prepare changelog for v12.1.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1868dcaeb..f352afcf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [12.1.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v12.1.0) (2021-07-19) +================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v12.1.0-rc.1...v12.1.0) + + * No changes from rc.1 + Changes in [12.1.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v12.1.0-rc.1) (2021-07-14) ============================================================================================================ [Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v12.0.1...v12.1.0-rc.1) From 830a4a741e2a0b14e589449f1ac136dd938bdbdf Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 19 Jul 2021 15:49:55 +0100 Subject: [PATCH 118/129] v12.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 546f9679d..d3f1993fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.1.0-rc.1", + "version": "12.1.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", From b936b4a2ce9ce233801fdea6c37c570e9dd579ff Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 19 Jul 2021 15:52:47 +0100 Subject: [PATCH 119/129] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d3f1993fc..0f51a2df2 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", + "main": "./src/index.ts", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -110,6 +110,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From 4cf655785e37bb0f65d4fe6df07050643a448426 Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Mon, 19 Jul 2021 17:59:11 +0200 Subject: [PATCH 120/129] Add tests --- spec/unit/room.spec.js | 238 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index 34ec05f24..20d129aed 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -3,6 +3,7 @@ import { EventStatus, MatrixEvent } from "../../src"; import { EventTimeline } from "../../src/models/event-timeline"; import { RoomState } from "../../src"; import { Room } from "../../src"; +import { UNSTABLE_ELEMENT_FUNCTIONAL_USERS } from "../../src/@types/event"; import { TestClient } from "../TestClient"; describe("Room", function() { @@ -1456,4 +1457,241 @@ describe("Room", function() { expect(room.maySendMessage()).toEqual(true); }); }); + + describe("getDefaultRoomName", function() { + it("should return 'Empty room' if a user is the only member", + function() { + const room = new Room(roomId, null, userA); + expect(room.getDefaultRoomName(userA)).toEqual("Empty room"); + }); + + it("should return a display name if one other member is in the room", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + + it("should return a display name if one other member is banned", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "ban", + room: roomId, event: true, name: "User B", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("Empty room (was User B)"); + }); + + it("should return a display name if one other member is invited", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "invite", + room: roomId, event: true, name: "User B", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + + it("should return 'Empty room (was User B)' if User B left the room", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "leave", + room: roomId, event: true, name: "User B", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("Empty room (was User B)"); + }); + + it("should return 'User B and User C' if in a room with two other users", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkMembership({ + user: userC, mship: "join", + room: roomId, event: true, name: "User C", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B and User C"); + }); + + it("should return 'User B and 2 others' if in a room with three other users", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkMembership({ + user: userC, mship: "join", + room: roomId, event: true, name: "User C", + }), + utils.mkMembership({ + user: userD, mship: "join", + room: roomId, event: true, name: "User D", + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B and 2 others"); + }); + + describe("io.element.functional_users", function() { + it("should return a display name (default behaviour) if no one is marked as a functional member", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, + content: { + service_members: [], + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + + it("should return a display name (default behaviour) if service members is a number (invalid)", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, + content: { + service_members: 1, + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + + it("should return a display name (default behaviour) if service members is a string (invalid)", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, + content: { + service_members: userB, + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + + it("should return 'Empty room' if the only other member is a functional member", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, + content: { + service_members: [userB], + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("Empty room"); + }); + + it("should return 'User B' if User B is the only other member who isn't a functional member", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkMembership({ + user: userC, mship: "join", + room: roomId, event: true, name: "User C", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, user: userA, + content: { + service_members: [userC], + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); + }); + }); }); From b8c2a578290d918da43d669aaa2042d15f32d89b Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Mon, 19 Jul 2021 18:17:39 +0200 Subject: [PATCH 121/129] Add test with multiple service_members --- spec/unit/room.spec.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index ce6806e4b..f79bc37d4 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1692,6 +1692,33 @@ describe("Room", function() { ]); expect(room.getDefaultRoomName(userA)).toEqual("User B"); }); + + it("should return 'Empty room' if all other members are functional members", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkMembership({ + user: userC, mship: "join", + room: roomId, event: true, name: "User C", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, user: userA, + content: { + service_members: [userB, userC], + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("Empty room"); + }); }); }); }); From cb2b9619abc4d6be1a47ea21d12815b0f6d1c41a Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Mon, 19 Jul 2021 18:22:29 +0200 Subject: [PATCH 122/129] Replace .indexOf() !== -1 with .includes() for readability --- spec/test-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/test-utils.js b/spec/test-utils.js index 47b2624f6..1f5db16c7 100644 --- a/spec/test-utils.js +++ b/spec/test-utils.js @@ -91,7 +91,7 @@ export function mkEvent(opts) { event.state_key = opts.skey; } else if (["m.room.name", "m.room.topic", "m.room.create", "m.room.join_rules", "m.room.power_levels", "m.room.topic", - "com.example.state"].indexOf(opts.type) !== -1) { + "com.example.state"].includes(opts.type)) { event.state_key = ""; } return opts.event ? new MatrixEvent(event) : event; From 5cf6684129a921295f5593173f16f192336fe0a2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 19 Jul 2021 22:47:32 +0100 Subject: [PATCH 123/129] Conform to new typescript eslint rules --- package.json | 1 + src/client.ts | 4 ++-- src/models/user.ts | 2 +- src/sync.ts | 10 +++++----- src/utils.ts | 8 ++++---- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 0f51a2df2..93f2a74a2 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "gendoc": "jsdoc -c jsdoc.json -P package.json", "lint": "yarn lint:types && yarn lint:js", "lint:js": "eslint --max-warnings 57 src spec", + "lint:js-fix": "eslint --fix src spec", "lint:types": "tsc --noEmit", "test": "jest", "test:watch": "jest --watch", diff --git a/src/client.ts b/src/client.ts index 08e6e5dd2..2e1c97272 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4426,7 +4426,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves: to nothing * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public _unstable_setStatusMessage(newMessage: string): Promise { // eslint-disable-line camelcase + public _unstable_setStatusMessage(newMessage: string): Promise { // eslint-disable-line const type = "im.vector.user_status"; return Promise.all(this.getRooms().map(async (room) => { const isJoined = room.getMyMembership() === "join"; @@ -5732,7 +5732,7 @@ export class MatrixClient extends EventEmitter { * @return {Promise} Resolves to a set of rooms * @return {module:http-api.MatrixError} Rejects: with an error response. */ - public async _unstable_getSharedRooms(userId: string): Promise { // eslint-disable-line camelcase + public async _unstable_getSharedRooms(userId: string): Promise { // eslint-disable-line if (!(await this.doesServerSupportUnstableFeature("uk.half-shot.msc2666"))) { throw Error('Server does not support shared_rooms API'); } diff --git a/src/models/user.ts b/src/models/user.ts index 5eff5062c..613a03a69 100644 --- a/src/models/user.ts +++ b/src/models/user.ts @@ -208,7 +208,7 @@ export class User extends EventEmitter { * @param {MatrixEvent} event The im.vector.user_status event. * @fires module:client~MatrixClient#event:"User.unstable_statusMessage" */ - // eslint-disable-next-line camelcase + // eslint-disable-next-line public unstable_updateStatusMessage(event: MatrixEvent): void { if (!event.getContent()) this.unstable_statusMessage = ""; else this.unstable_statusMessage = event.getContent()["status"]; diff --git a/src/sync.ts b/src/sync.ts index 863329808..5f0cf59a8 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -642,12 +642,12 @@ export class SyncApi { // Now wait for the saved sync to finish... debuglog("Waiting for saved sync before starting sync processing..."); await savedSyncPromise; - this._sync({ filterId }); + this.doSync({ filterId }); }; if (client.isGuest()) { // no push rules for guests, no access to POST filter for guests. - this._sync({}); + this.doSync({}); } else { // Pull the saved sync token out first, before the worker starts sending // all the sync data which could take a while. This will let us send our @@ -753,7 +753,7 @@ export class SyncApi { * @param {string} syncOptions.filterId * @param {boolean} syncOptions.hasSyncedBefore */ - private async _sync(syncOptions: ISyncOptions): Promise { + private async doSync(syncOptions: ISyncOptions): Promise { const client = this.client; if (!this.running) { @@ -850,7 +850,7 @@ export class SyncApi { } // Begin next sync - this._sync(syncOptions); + this.doSync(syncOptions); } private doSyncRequest(syncOptions: ISyncOptions, syncToken: string): IRequestPromise { @@ -955,7 +955,7 @@ export class SyncApi { catchingUp: true, }); } - this._sync(syncOptions); + this.doSync(syncOptions); }); this.currentSyncRequest = null; diff --git a/src/utils.ts b/src/utils.ts index a392006ea..deff800e5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -129,10 +129,10 @@ export function isFunction(value: any) { * @throws If the object is missing keys. */ // note using 'keys' here would shadow the 'keys' function defined above -export function checkObjectHasKeys(obj: object, keys_: string[]) { - for (let i = 0; i < keys_.length; i++) { - if (!obj.hasOwnProperty(keys_[i])) { - throw new Error("Missing required key: " + keys_[i]); +export function checkObjectHasKeys(obj: object, keys: string[]) { + for (let i = 0; i < keys.length; i++) { + if (!obj.hasOwnProperty(keys[i])) { + throw new Error("Missing required key: " + keys[i]); } } } From ea646c673b20eee2caeacb5c73ed22c66e5f3fd0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 19 Jul 2021 23:31:39 -0600 Subject: [PATCH 124/129] Actually print idb command error if there is one --- src/store/indexeddb-remote-backend.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/indexeddb-remote-backend.ts b/src/store/indexeddb-remote-backend.ts index 07be5f910..14ddee82d 100644 --- a/src/store/indexeddb-remote-backend.ts +++ b/src/store/indexeddb-remote-backend.ts @@ -185,7 +185,7 @@ export class RemoteIndexedDBStoreBackend implements IIndexedDBBackend { def.reject(error); } } else { - logger.warn("Unrecognised message from worker: " + msg); + logger.warn("Unrecognised message from worker: ", msg); } }; } From 0c06e477829910cd1899527f4b66f26ab072a6bc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 20 Jul 2021 09:15:26 +0100 Subject: [PATCH 125/129] Update eslint-plugin-matrix-org --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 96661442b..3e7da3ca2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2858,7 +2858,7 @@ eslint-config-google@^0.14.0: "eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main": version "0.3.2" - resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/383a1e4a9ef7944c921efda0de2ac9635d45cb5c" + resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/8529f1d77863db6327cf1a1a4fa65d06cc26f91b" eslint-rule-composer@^0.3.0: version "0.3.0" From afa67688f83c2af66adc0da417e76ccdecb1bc2c Mon Sep 17 00:00:00 2001 From: Christian Paul Date: Tue, 20 Jul 2021 12:51:08 +0200 Subject: [PATCH 126/129] Add test for service member who is not a room member --- spec/unit/room.spec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index f79bc37d4..be746a237 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1719,6 +1719,29 @@ describe("Room", function() { ]); expect(room.getDefaultRoomName(userA)).toEqual("Empty room"); }); + + it("should not break if an unjoined user is marked as a service user", + function() { + const room = new Room(roomId, null, userA); + room.addLiveEvents([ + utils.mkMembership({ + user: userA, mship: "join", + room: roomId, event: true, name: "User A", + }), + utils.mkMembership({ + user: userB, mship: "join", + room: roomId, event: true, name: "User B", + }), + utils.mkEvent({ + type: UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, skey: "", + room: roomId, event: true, user: userA, + content: { + service_members: [userC], + }, + }), + ]); + expect(room.getDefaultRoomName(userA)).toEqual("User B"); + }); }); }); }); From f708c473851093a149de669e49e67ead6d18e553 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Wed, 21 Jul 2021 14:18:22 +0200 Subject: [PATCH 127/129] Improve calculateRoomName performances by using Intl.Collator --- src/models/room.ts | 2 +- src/utils.ts | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index 089e60fa8..9e14d1907 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2053,7 +2053,7 @@ export class Room extends EventEmitter { (m.membership === "invite" || m.membership === "join"); }); // make sure members have stable order - otherMembers.sort((a, b) => a.userId.localeCompare(b.userId)); + otherMembers.sort((a, b) => utils.compare(a.userId, b.userId)); // only 5 first members, immitate summaryHeroes otherMembers = otherMembers.slice(0, 5); otherNames = otherMembers.map((m) => m.name); diff --git a/src/utils.ts b/src/utils.ts index a392006ea..4ab08f8b7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -683,3 +683,13 @@ export function lexicographicCompare(a: string, b: string): number { // hidden the operation in this function. return (a < b) ? -1 : ((a === b) ? 0 : 1); } + +const collator = new Intl.Collator(); +/** + * Performant language-sensitive string comparison + * @param a the first string to compare + * @param b the second string to compare + */ +export function compare(a: string, b: string): number { + return collator.compare(a, b); +} From ce2803ebaaaeb64e351524a91042df2ec02f45c8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 21 Jul 2021 15:37:19 +0100 Subject: [PATCH 128/129] yarn upgrade --- yarn.lock | 2861 +++++++++++++++++++++++++++++------------------------ 1 file changed, 1585 insertions(+), 1276 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3e7da3ca2..2a60c66a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,395 +3,429 @@ "@babel/cli@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.10.tgz#67a1015b1cd505bde1696196febf910c4c339a48" - integrity sha512-+y4ZnePpvWs1fc/LhZRTHkTesbXkyBYuOB+5CyodZqrEuETXi3zOVfpAQIdgC3lXbHLTDG9dQosxR9BhvLKDLQ== + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.14.8.tgz#fac73c0e2328a8af9fd3560c06b096bfa3730933" + integrity sha512-lcy6Lymft9Rpfqmrqdd4oTDdUx9ZwaAhAfywVrHG4771Pa6PPT0danJ1kDHBXYqh4HHSmIdA+nlmfxfxSDPtBg== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" fs-readdir-recursive "^1.1.0" glob "^7.0.0" - lodash "^4.17.19" make-dir "^2.1.0" slash "^2.0.0" source-map "^0.5.0" optionalDependencies: - "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents" + "@nicolo-ribaudo/chokidar-2" "2.1.8-no-fsevents.2" chokidar "^3.4.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== dependencies: - "@babel/highlight" "^7.10.4" + "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" - integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" + integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" - integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.8.tgz#20cdf7c84b5d86d83fac8710a8bc605a7ba3f010" + integrity sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q== dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.10" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.10" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.10" - "@babel/types" "^7.12.10" + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.8" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-module-transforms" "^7.14.8" + "@babel/helpers" "^7.14.8" + "@babel/parser" "^7.14.8" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.8" + "@babel/types" "^7.14.8" convert-source-map "^1.7.0" debug "^4.1.0" - gensync "^1.0.0-beta.1" + gensync "^1.0.0-beta.2" json5 "^2.1.2" - lodash "^4.17.19" - semver "^5.4.1" + semver "^6.3.0" source-map "^0.5.0" "@babel/eslint-parser@^7.12.10": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.13.10.tgz#e272979914f36bb6cea144c14c32bb51632696dd" - integrity sha512-/I1HQ3jGPhIpeBFeI3wO9WwWOnBYpuR0pX0KlkdGcRQAVX9prB/FCS2HBpL7BiFbzhny1YCiBH8MTZD2jJa7Hg== + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz#91be59a4f7dd60d02a3ef772d156976465596bda" + integrity sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ== dependencies: - eslint-scope "5.1.0" - eslint-visitor-keys "^1.3.0" + eslint-scope "^5.1.1" + eslint-visitor-keys "^2.1.0" semver "^6.3.0" "@babel/eslint-plugin@^7.12.10": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.13.10.tgz#6720c32d52a4fef817796c7bb55a87b80320bbe7" - integrity sha512-xsNxo099fKnJ2rArkuuMOTPxxTLZSXwbFXdH4GjqQRKTOr6S1odQlE+R3Leid56VFQ3KVAR295vVNG9fqNQVvQ== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.14.5.tgz#70b76608d49094062e8da2a2614d50fec775c00f" + integrity sha512-nzt/YMnOOIRikvSn2hk9+W2omgJBy6U8TN0R+WTTmqapA+HnZTuviZaketdTE9W7/k/+E/DfZlt1ey1NSE39pg== dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" - integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== +"@babel/generator@^7.12.11", "@babel/generator@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.8.tgz#bf86fd6af96cf3b74395a8ca409515f89423e070" + integrity sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg== dependencies: - "@babel/types" "^7.12.11" + "@babel/types" "^7.14.8" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d" - integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ== +"@babel/helper-annotate-as-pure@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" + integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.14.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" + integrity sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-explode-assignable-expression" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-compilation-targets@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" - integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" + integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== dependencies: - "@babel/compat-data" "^7.12.5" - "@babel/helper-validator-option" "^7.12.1" - browserslist "^4.14.5" - semver "^5.5.0" + "@babel/compat-data" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" - integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== +"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.14.6": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz#a6f8c3de208b1e5629424a9a63567f56501955fc" + integrity sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-member-expression-to-functions" "^7.14.7" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" -"@babel/helper-create-regexp-features-plugin@^7.12.1": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" - integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== +"@babel/helper-create-regexp-features-plugin@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" + integrity sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.14.5" regexpu-core "^4.7.1" -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== +"@babel/helper-define-polyfill-provider@^0.2.2": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" + integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" - integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== +"@babel/helper-explode-assignable-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" + integrity sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.14.5" -"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" - integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== +"@babel/helper-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4" + integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ== dependencies: - "@babel/helper-get-function-arity" "^7.12.10" - "@babel/template" "^7.12.7" - "@babel/types" "^7.12.11" + "@babel/helper-get-function-arity" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-get-function-arity@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" - integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== +"@babel/helper-get-function-arity@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" + integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.14.5" -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== +"@babel/helper-hoist-variables@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" + integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.14.5" -"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" - integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== +"@babel/helper-member-expression-to-functions@^7.14.5", "@babel/helper-member-expression-to-functions@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" + integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA== dependencies: - "@babel/types" "^7.12.7" + "@babel/types" "^7.14.5" -"@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" - integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" + integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== dependencies: - "@babel/types" "^7.12.5" + "@babel/types" "^7.14.5" -"@babel/helper-module-transforms@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" - integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== +"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.8.tgz#d4279f7e3fd5f4d5d342d833af36d4dd87d7dc49" + integrity sha512-RyE+NFOjXn5A9YU1dkpeBaduagTlZ0+fccnIcAGbv1KGUlReBj7utF7oEth8IdIBQPcux0DDgW5MFBH2xu9KcA== dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-simple-access" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/helper-validator-identifier" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - lodash "^4.17.19" + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-simple-access" "^7.14.8" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.8" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.8" + "@babel/types" "^7.14.8" -"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" - integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== +"@babel/helper-optimise-call-expression@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" + integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA== dependencies: - "@babel/types" "^7.12.10" + "@babel/types" "^7.14.5" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-remap-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" - integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== +"@babel/helper-remap-async-to-generator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz#51439c913612958f54a987a4ffc9ee587a2045d6" + integrity sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/types" "^7.12.1" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-wrap-function" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-replace-supers@^7.12.1": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" - integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== +"@babel/helper-replace-supers@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94" + integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.7" - "@babel/helper-optimise-call-expression" "^7.12.10" - "@babel/traverse" "^7.12.10" - "@babel/types" "^7.12.11" + "@babel/helper-member-expression-to-functions" "^7.14.5" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helper-simple-access@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" - integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== +"@babel/helper-simple-access@^7.14.5", "@babel/helper-simple-access@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz#82e1fec0644a7e775c74d305f212c39f8fe73924" + integrity sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.14.8" -"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" - integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== +"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz#96f486ac050ca9f44b009fbe5b7d394cab3a0ee4" + integrity sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ== dependencies: - "@babel/types" "^7.12.1" + "@babel/types" "^7.14.5" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" - integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== +"@babel/helper-split-export-declaration@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a" + integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA== dependencies: - "@babel/types" "^7.12.11" + "@babel/types" "^7.14.5" -"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz#32be33a756f29e278a0d644fa08a2c9e0f88a34c" + integrity sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow== -"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" - integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== -"@babel/helper-wrap-function@^7.10.4": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" - integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== +"@babel/helper-wrap-function@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz#5919d115bf0fe328b8a5d63bcb610f51601f2bff" + integrity sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/helper-function-name" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/helpers@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" - integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== +"@babel/helpers@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" + integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.5" - "@babel/types" "^7.12.5" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.8" + "@babel/types" "^7.14.8" -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== +"@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.14.5" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" - integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.5", "@babel/parser@^7.14.8", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.8.tgz#66fd41666b2d7b840bd5ace7f7416d5ac60208d4" + integrity sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA== -"@babel/plugin-proposal-async-generator-functions@^7.12.1": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566" - integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" + integrity sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-class-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" - integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== +"@babel/plugin-proposal-async-generator-functions@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace" + integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-dynamic-import@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" - integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" + integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-export-namespace-from@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" - integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== +"@babel/plugin-proposal-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz#158e9e10d449c3849ef3ecde94a03d9f1841b681" + integrity sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" + integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" + integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" - integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== +"@babel/plugin-proposal-json-strings@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" + integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" - integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== +"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" + integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" - integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" + integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" - integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== +"@babel/plugin-proposal-numeric-separator@^7.12.7", "@babel/plugin-proposal-numeric-separator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" + integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" + integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/compat-data" "^7.14.7" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.14.5" -"@babel/plugin-proposal-optional-catch-binding@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" - integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== +"@babel/plugin-proposal-optional-catch-binding@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" + integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" - integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== +"@babel/plugin-proposal-optional-chaining@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" + integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" - integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== +"@babel/plugin-proposal-private-methods@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" + integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" - integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== +"@babel/plugin-proposal-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" + integrity sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": +"@babel/plugin-proposal-unicode-property-regex@^7.14.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" + integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -405,14 +439,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.12.1", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" - integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== +"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -433,7 +474,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": +"@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -447,7 +488,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== @@ -461,307 +502,316 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": +"@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" - integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" - integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== +"@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-arrow-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" - integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== +"@babel/plugin-syntax-typescript@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" + integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-async-to-generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" - integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== +"@babel/plugin-transform-arrow-functions@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" + integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-block-scoped-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" - integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== +"@babel/plugin-transform-async-to-generator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" + integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.14.5" -"@babel/plugin-transform-block-scoping@^7.12.11": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" - integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== +"@babel/plugin-transform-block-scoped-functions@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" + integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-classes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" - integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== +"@babel/plugin-transform-block-scoping@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz#8cc63e61e50f42e078e6f09be775a75f23ef9939" + integrity sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-classes@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz#0e98e82097b38550b03b483f9b51a78de0acb2cf" + integrity sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" - integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== +"@babel/plugin-transform-computed-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" + integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-destructuring@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" - integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== +"@babel/plugin-transform-destructuring@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" + integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" - integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== +"@babel/plugin-transform-dotall-regex@^7.14.5", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" + integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-duplicate-keys@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" - integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== +"@babel/plugin-transform-duplicate-keys@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" + integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-exponentiation-operator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" - integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== +"@babel/plugin-transform-exponentiation-operator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" + integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-for-of@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" - integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== +"@babel/plugin-transform-for-of@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz#dae384613de8f77c196a8869cbf602a44f7fc0eb" + integrity sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-function-name@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" - integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== +"@babel/plugin-transform-function-name@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" + integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" - integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== +"@babel/plugin-transform-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" + integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-member-expression-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" - integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== +"@babel/plugin-transform-member-expression-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" + integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-modules-amd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" - integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== +"@babel/plugin-transform-modules-amd@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" + integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" - integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== +"@babel/plugin-transform-modules-commonjs@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz#7aaee0ea98283de94da98b28f8c35701429dad97" + integrity sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-simple-access" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" - integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== +"@babel/plugin-transform-modules-systemjs@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz#c75342ef8b30dcde4295d3401aae24e65638ed29" + integrity sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA== dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" - integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== +"@babel/plugin-transform-modules-umd@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" + integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== dependencies: - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" - integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== +"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz#60c06892acf9df231e256c24464bfecb0908fd4e" + integrity sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" -"@babel/plugin-transform-new-target@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" - integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== +"@babel/plugin-transform-new-target@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" + integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-object-super@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" - integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== +"@babel/plugin-transform-object-super@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" + integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.14.5" -"@babel/plugin-transform-parameters@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" - integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== +"@babel/plugin-transform-parameters@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3" + integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" - integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== +"@babel/plugin-transform-property-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" + integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-regenerator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" - integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== +"@babel/plugin-transform-regenerator@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" + integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" - integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== +"@babel/plugin-transform-reserved-words@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" + integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-transform-runtime@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz#af0fded4e846c4b37078e8e5d06deac6cd848562" - integrity sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz#30491dad49c6059f8f8fa5ee8896a0089e987523" + integrity sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg== dependencies: - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" - semver "^5.5.1" + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + babel-plugin-polyfill-corejs2 "^0.2.2" + babel-plugin-polyfill-corejs3 "^0.2.2" + babel-plugin-polyfill-regenerator "^0.2.2" + semver "^6.3.0" -"@babel/plugin-transform-shorthand-properties@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" - integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== +"@babel/plugin-transform-shorthand-properties@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" + integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-spread@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" - integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== +"@babel/plugin-transform-spread@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" + integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" -"@babel/plugin-transform-sticky-regex@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" - integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== +"@babel/plugin-transform-sticky-regex@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" + integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-template-literals@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" - integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== +"@babel/plugin-transform-template-literals@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" + integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typeof-symbol@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b" - integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA== +"@babel/plugin-transform-typeof-symbol@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" + integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" - integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== +"@babel/plugin-transform-typescript@^7.14.5": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c" + integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-typescript" "^7.12.1" + "@babel/helper-create-class-features-plugin" "^7.14.6" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-typescript" "^7.14.5" -"@babel/plugin-transform-unicode-escapes@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" - integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== +"@babel/plugin-transform-unicode-escapes@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" + integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-unicode-regex@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" - integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== +"@babel/plugin-transform-unicode-regex@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" + integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" "@babel/polyfill@^7.4.4": version "7.12.1" @@ -772,78 +822,85 @@ regenerator-runtime "^0.13.4" "@babel/preset-env@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" - integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.8.tgz#254942f5ca80ccabcfbb2a9f524c74bca574005b" + integrity sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg== dependencies: - "@babel/compat-data" "^7.12.7" - "@babel/helper-compilation-targets" "^7.12.5" - "@babel/helper-module-imports" "^7.12.5" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.11" - "@babel/plugin-proposal-async-generator-functions" "^7.12.1" - "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-dynamic-import" "^7.12.1" - "@babel/plugin-proposal-export-namespace-from" "^7.12.1" - "@babel/plugin-proposal-json-strings" "^7.12.1" - "@babel/plugin-proposal-logical-assignment-operators" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-numeric-separator" "^7.12.7" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-catch-binding" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.12.1" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.12.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/compat-data" "^7.14.7" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" + "@babel/plugin-proposal-async-generator-functions" "^7.14.7" + "@babel/plugin-proposal-class-properties" "^7.14.5" + "@babel/plugin-proposal-class-static-block" "^7.14.5" + "@babel/plugin-proposal-dynamic-import" "^7.14.5" + "@babel/plugin-proposal-export-namespace-from" "^7.14.5" + "@babel/plugin-proposal-json-strings" "^7.14.5" + "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" + "@babel/plugin-proposal-numeric-separator" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" + "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" + "@babel/plugin-proposal-optional-chaining" "^7.14.5" + "@babel/plugin-proposal-private-methods" "^7.14.5" + "@babel/plugin-proposal-private-property-in-object" "^7.14.5" + "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.12.1" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-async-to-generator" "^7.12.1" - "@babel/plugin-transform-block-scoped-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.11" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-computed-properties" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-dotall-regex" "^7.12.1" - "@babel/plugin-transform-duplicate-keys" "^7.12.1" - "@babel/plugin-transform-exponentiation-operator" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-function-name" "^7.12.1" - "@babel/plugin-transform-literals" "^7.12.1" - "@babel/plugin-transform-member-expression-literals" "^7.12.1" - "@babel/plugin-transform-modules-amd" "^7.12.1" - "@babel/plugin-transform-modules-commonjs" "^7.12.1" - "@babel/plugin-transform-modules-systemjs" "^7.12.1" - "@babel/plugin-transform-modules-umd" "^7.12.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.1" - "@babel/plugin-transform-new-target" "^7.12.1" - "@babel/plugin-transform-object-super" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-property-literals" "^7.12.1" - "@babel/plugin-transform-regenerator" "^7.12.1" - "@babel/plugin-transform-reserved-words" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/plugin-transform-sticky-regex" "^7.12.7" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/plugin-transform-typeof-symbol" "^7.12.10" - "@babel/plugin-transform-unicode-escapes" "^7.12.1" - "@babel/plugin-transform-unicode-regex" "^7.12.1" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.11" - core-js-compat "^3.8.0" - semver "^5.5.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.14.5" + "@babel/plugin-transform-async-to-generator" "^7.14.5" + "@babel/plugin-transform-block-scoped-functions" "^7.14.5" + "@babel/plugin-transform-block-scoping" "^7.14.5" + "@babel/plugin-transform-classes" "^7.14.5" + "@babel/plugin-transform-computed-properties" "^7.14.5" + "@babel/plugin-transform-destructuring" "^7.14.7" + "@babel/plugin-transform-dotall-regex" "^7.14.5" + "@babel/plugin-transform-duplicate-keys" "^7.14.5" + "@babel/plugin-transform-exponentiation-operator" "^7.14.5" + "@babel/plugin-transform-for-of" "^7.14.5" + "@babel/plugin-transform-function-name" "^7.14.5" + "@babel/plugin-transform-literals" "^7.14.5" + "@babel/plugin-transform-member-expression-literals" "^7.14.5" + "@babel/plugin-transform-modules-amd" "^7.14.5" + "@babel/plugin-transform-modules-commonjs" "^7.14.5" + "@babel/plugin-transform-modules-systemjs" "^7.14.5" + "@babel/plugin-transform-modules-umd" "^7.14.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7" + "@babel/plugin-transform-new-target" "^7.14.5" + "@babel/plugin-transform-object-super" "^7.14.5" + "@babel/plugin-transform-parameters" "^7.14.5" + "@babel/plugin-transform-property-literals" "^7.14.5" + "@babel/plugin-transform-regenerator" "^7.14.5" + "@babel/plugin-transform-reserved-words" "^7.14.5" + "@babel/plugin-transform-shorthand-properties" "^7.14.5" + "@babel/plugin-transform-spread" "^7.14.6" + "@babel/plugin-transform-sticky-regex" "^7.14.5" + "@babel/plugin-transform-template-literals" "^7.14.5" + "@babel/plugin-transform-typeof-symbol" "^7.14.5" + "@babel/plugin-transform-unicode-escapes" "^7.14.5" + "@babel/plugin-transform-unicode-regex" "^7.14.5" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.14.8" + babel-plugin-polyfill-corejs2 "^0.2.2" + babel-plugin-polyfill-corejs3 "^0.2.2" + babel-plugin-polyfill-regenerator "^0.2.2" + core-js-compat "^3.15.0" + semver "^6.3.0" -"@babel/preset-modules@^0.1.3": +"@babel/preset-modules@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== @@ -855,63 +912,62 @@ esutils "^2.0.2" "@babel/preset-typescript@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.12.7.tgz#fc7df8199d6aae747896f1e6c61fc872056632a3" - integrity sha512-nOoIqIqBmHBSEgBXWR4Dv/XBehtIFcw9PqZw6rFYuKrzsZmOQm3PR5siLBnKZFEsDb03IegG8nSjU/iXXXYRmw== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz#aa98de119cf9852b79511f19e7f44a2d379bcce0" + integrity sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-validator-option" "^7.12.1" - "@babel/plugin-transform-typescript" "^7.12.1" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-transform-typescript" "^7.14.5" "@babel/register@^7.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.12.10.tgz#19b87143f17128af4dbe7af54c735663b3999f60" - integrity sha512-EvX/BvMMJRAA3jZgILWgbsrHwBQvllC5T8B29McyME8DvkdOxk4ujESfrMvME8IHSDvWXrmMXxPvA/lx2gqPLQ== + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.14.5.tgz#d0eac615065d9c2f1995842f85d6e56c345f3233" + integrity sha512-TjJpGz/aDjFGWsItRBQMOFTrmTI9tr79CHOK+KIvLeCkbxuOAk2M5QHjvruIMGoo9OuccMh5euplPzc5FjAKGg== dependencies: + clone-deep "^4.0.1" find-cache-dir "^2.0.0" - lodash "^4.17.19" make-dir "^2.1.0" pirates "^4.0.0" source-map-support "^0.5.16" "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446" + integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" - integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== +"@babel/template@^7.14.5", "@babel/template@^7.3.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" + integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.12.7" - "@babel/types" "^7.12.7" + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.14.5" + "@babel/types" "^7.14.5" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" - integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.8.tgz#c0253f02677c5de1a8ff9df6b0aacbec7da1a8ce" + integrity sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg== dependencies: - "@babel/code-frame" "^7.12.11" - "@babel/generator" "^7.12.11" - "@babel/helper-function-name" "^7.12.11" - "@babel/helper-split-export-declaration" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/types" "^7.12.12" + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.8" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.14.8" + "@babel/types" "^7.14.8" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.12.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" - integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== +"@babel/types@^7.0.0", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.8.tgz#38109de8fcadc06415fbd9b74df0065d4d41c728" + integrity sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q== dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" + "@babel/helper-validator-identifier" "^7.14.8" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -955,9 +1011,9 @@ resolve-from "^5.0.0" "@istanbuljs/schema@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" - integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== "@jest/console@^26.6.2": version "26.6.2" @@ -1134,15 +1190,15 @@ version "3.2.3" resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz#cc332fdd25c08ef0e40f4d33fc3f822a0f98b6f4" -"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents": - version "2.1.8-no-fsevents" - resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz#da7c3996b8e6e19ebd14d82eaced2313e7769f9b" - integrity sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w== +"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.2": + version "2.1.8-no-fsevents.2" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz#e324c0a247a5567192dd7180647709d7e2faf94b" + integrity sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg== dependencies: anymatch "^2.0.0" async-each "^1.0.1" braces "^2.3.2" - glob-parent "^3.1.0" + glob-parent "^5.1.2" inherits "^2.0.3" is-binary-path "^1.0.0" is-glob "^4.0.0" @@ -1151,31 +1207,31 @@ readdirp "^2.2.1" upath "^1.1.1" -"@nodelib/fs.scandir@2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" - integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@nodelib/fs.stat" "2.0.4" + "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" - integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" - integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - "@nodelib/fs.scandir" "2.1.4" + "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" "@sinonjs/commons@^1.7.0": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.2.tgz#858f5c4b48d80778fde4b9d541f27edc0d56488b" - integrity sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw== + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: type-detect "4.0.8" @@ -1186,15 +1242,20 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.9.tgz#01d7b86949f455402a94c788883fe4ba574cad41" - integrity sha512-qZLoYeXSTgQuK1h7QQS16hqLGdmqtRmN8w/rl3Au/l5x/zkHx+a4VHrHyBsi1I1vtK2oBHxSzKIu0R5p6spdOA== + version "7.0.10" + resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.10.tgz#c12a182ecf326c26acc7b18a301827594bab6df9" + integrity sha512-g7zrcqL4MiRu3jZzdZZYk0g0KcKk2fddXazSdP1PacEpmjihRsNGU50aaEKnPFuKzfN7WkRktUiCXvs4zU9XXQ== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": - version "7.1.12" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d" - integrity sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ== + version "7.1.15" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024" + integrity sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -1203,31 +1264,31 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.2.tgz#f3d71178e187858f7c45e30380f8f1b7415a12d8" - integrity sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ== + version "7.6.3" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.3.tgz#f456b4b2ce79137f768aa130d2423d2f0ccfaba5" + integrity sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.0.tgz#0c888dd70b3ee9eebb6e4f200e809da0076262be" - integrity sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A== + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.0.tgz#b9a1efa635201ba9bc850323a8793ee2d36c04a0" - integrity sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== dependencies: "@babel/types" "^7.3.0" "@types/babylon@^6.16.2": - version "6.16.5" - resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.5.tgz#1c5641db69eb8cdf378edd25b4be7754beeb48b4" - integrity sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w== + version "6.16.6" + resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.6.tgz#a1e7e01567b26a5ebad321a74d10299189d8d932" + integrity sha512-G4yqdVlhr6YhzLXFKy5F7HtRBU8Y23+iWy7UKthMq/OSQnL1hbsoeXESQ2LY8zEDlknipDG3nRGhUC9tkwvy/w== dependencies: "@types/babel-types" "*" @@ -1244,9 +1305,9 @@ integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== "@types/graceful-fs@^4.1.2": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" - integrity sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg== + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== dependencies: "@types/node" "*" @@ -1263,49 +1324,49 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" - integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^26.0.20": - version "26.0.20" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307" - integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA== + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/json-schema@^7.0.3": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" - integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== +"@types/json-schema@^7.0.7": + version "7.0.8" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.8.tgz#edf1bf1dbf4e04413ca8e5b17b3b7d7d54b59818" + integrity sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg== "@types/node@*": - version "14.14.22" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18" - integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw== + version "16.4.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.0.tgz#2c219eaa3b8d1e4d04f4dd6e40bc68c7467d5272" + integrity sha512-HrJuE7Mlqcjj+00JqMWpZ3tY8w7EUd+S0U3L1+PQSWiXZbOgyQDvi+ogoUxaHApPJq5diKxYBQwA3iIlNcPqOg== "@types/node@12": - version "12.19.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.14.tgz#59e5029a3c2aea34f68b717955381692fd47cafb" - integrity sha512-2U9uLN46+7dv9PiS8VQJcHhuoOjiDPZOLAt0WuA1EanEknIMae+2QbMhayF7cgGqjvRVIfNpt+6jLPczJZFiRw== + version "12.20.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.16.tgz#1acf34f6456208f495dac0434dd540488d17f991" + integrity sha512-6CLxw83vQf6DKqXxMPwl8qpF8I7THFZuIwLt4TnNsumxkp1VsRZWT8txQxncT/Rl2UojTsFzWgDG4FRMwafrlA== "@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== "@types/prettier@^2.0.0": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.6.tgz#f4b1efa784e8db479cdb8b14403e2144b1e9ff03" - integrity sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA== + version "2.3.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" + integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== "@types/request@^2.48.5": - version "2.48.5" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" - integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== + version "2.48.6" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.6.tgz#2300e7fc443108f79efa90e3bdf34c6d60fa89d8" + integrity sha512-vrZaV3Ij7j/l/3hz6OttZFtpRCu7zlq7XgkYHJP6FwVEAZkGQ095WqyJV08/GlW9eyXKVcp/xmtruHm8eHpw1g== dependencies: "@types/caseless" "*" "@types/node" "*" @@ -1313,100 +1374,99 @@ form-data "^2.5.0" "@types/retry@^0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== "@types/stack-utils@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" - integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/tough-cookie@*": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" - integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" + integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== "@types/yargs-parser@*": - version "20.2.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" - integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + version "20.2.1" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" + integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== "@types/yargs@^15.0.0": - version "15.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74" - integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.17.0.tgz#6f856eca4e6a52ce9cf127dfd349096ad936aa2d" - integrity sha512-/fKFDcoHg8oNan39IKFOb5WmV7oWhQe1K6CDaAVfJaNWEhmfqlA24g+u1lqU5bMH7zuNasfMId4LaYWC5ijRLw== + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz#e73c8cabbf3f08dee0e1bda65ed4e622ae8f8921" + integrity sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw== dependencies: - "@typescript-eslint/experimental-utils" "4.17.0" - "@typescript-eslint/scope-manager" "4.17.0" - debug "^4.1.1" + "@typescript-eslint/experimental-utils" "4.28.4" + "@typescript-eslint/scope-manager" "4.28.4" + debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.15" - regexpp "^3.0.0" - semver "^7.3.2" - tsutils "^3.17.1" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.17.0.tgz#762c44aaa1a6a3c05b6d63a8648fb89b89f84c80" - integrity sha512-ZR2NIUbnIBj+LGqCFGQ9yk2EBQrpVVFOh9/Kd0Lm6gLpSAcCuLLe5lUCibKGCqyH9HPwYC0GIJce2O1i8VYmWA== +"@typescript-eslint/experimental-utils@4.28.4": + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz#9c70c35ebed087a5c70fb0ecd90979547b7fec96" + integrity sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA== dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.17.0" - "@typescript-eslint/types" "4.17.0" - "@typescript-eslint/typescript-estree" "4.17.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.28.4" + "@typescript-eslint/types" "4.28.4" + "@typescript-eslint/typescript-estree" "4.28.4" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" "@typescript-eslint/parser@^4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.17.0.tgz#141b647ffc72ebebcbf9b0fe6087f65b706d3215" - integrity sha512-KYdksiZQ0N1t+6qpnl6JeK9ycCFprS9xBAiIrw4gSphqONt8wydBw4BXJi3C11ywZmyHulvMaLjWsxDjUSDwAw== + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.4.tgz#bc462dc2779afeefdcf49082516afdc3e7b96fab" + integrity sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA== dependencies: - "@typescript-eslint/scope-manager" "4.17.0" - "@typescript-eslint/types" "4.17.0" - "@typescript-eslint/typescript-estree" "4.17.0" - debug "^4.1.1" + "@typescript-eslint/scope-manager" "4.28.4" + "@typescript-eslint/types" "4.28.4" + "@typescript-eslint/typescript-estree" "4.28.4" + debug "^4.3.1" -"@typescript-eslint/scope-manager@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.17.0.tgz#f4edf94eff3b52a863180f7f89581bf963e3d37d" - integrity sha512-OJ+CeTliuW+UZ9qgULrnGpPQ1bhrZNFpfT/Bc0pzNeyZwMik7/ykJ0JHnQ7krHanFN9wcnPK89pwn84cRUmYjw== +"@typescript-eslint/scope-manager@4.28.4": + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz#bdbce9b6a644e34f767bd68bc17bb14353b9fe7f" + integrity sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w== dependencies: - "@typescript-eslint/types" "4.17.0" - "@typescript-eslint/visitor-keys" "4.17.0" + "@typescript-eslint/types" "4.28.4" + "@typescript-eslint/visitor-keys" "4.28.4" -"@typescript-eslint/types@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.17.0.tgz#f57d8fc7f31b348db946498a43050083d25f40ad" - integrity sha512-RN5z8qYpJ+kXwnLlyzZkiJwfW2AY458Bf8WqllkondQIcN2ZxQowAToGSd9BlAUZDB5Ea8I6mqL2quGYCLT+2g== +"@typescript-eslint/types@4.28.4": + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.4.tgz#41acbd79b5816b7c0dd7530a43d97d020d3aeb42" + integrity sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww== -"@typescript-eslint/typescript-estree@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.17.0.tgz#b835d152804f0972b80dbda92477f9070a72ded1" - integrity sha512-lRhSFIZKUEPPWpWfwuZBH9trYIEJSI0vYsrxbvVvNyIUDoKWaklOAelsSkeh3E2VBSZiNe9BZ4E5tYBZbUczVQ== +"@typescript-eslint/typescript-estree@4.28.4": + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz#252e6863278dc0727244be9e371eb35241c46d00" + integrity sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ== dependencies: - "@typescript-eslint/types" "4.17.0" - "@typescript-eslint/visitor-keys" "4.17.0" - debug "^4.1.1" - globby "^11.0.1" + "@typescript-eslint/types" "4.28.4" + "@typescript-eslint/visitor-keys" "4.28.4" + debug "^4.3.1" + globby "^11.0.3" is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.17.0": - version "4.17.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.17.0.tgz#9c304cfd20287c14a31d573195a709111849b14d" - integrity sha512-WfuMN8mm5SSqXuAr9NM+fItJ0SVVphobWYkWOwQ1odsfC014Vdxk/92t4JwS1Q6fCA/ABfCKpa3AVtpUKTNKGQ== +"@typescript-eslint/visitor-keys@4.28.4": + version "4.28.4" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz#92dacfefccd6751cbb0a964f06683bfd72d0c4d3" + integrity sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg== dependencies: - "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/types" "4.28.4" eslint-visitor-keys "^2.0.0" JSONStream@^1.0.3: @@ -1417,7 +1477,7 @@ JSONStream@^1.0.3: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.3: +abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== @@ -1438,9 +1498,9 @@ acorn-globals@^6.0.0: acorn-walk "^7.1.1" acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2, acorn-node@^1.6.1: version "1.8.2" @@ -1471,6 +1531,18 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.2.4: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -1481,10 +1553,10 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.0.3.tgz#13ae747eff125cafb230ac504b2406cf371eece2" - integrity sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ== +ajv@^8.0.1: + version "8.6.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" + integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1511,11 +1583,11 @@ ansi-colors@^4.1.1: integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: - type-fest "^0.11.0" + type-fest "^0.21.3" ansi-regex@^5.0.0: version "5.0.0" @@ -1549,10 +1621,10 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1579,11 +1651,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" - integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1667,11 +1734,9 @@ atob@^2.1.2: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== available-typed-arrays@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" - integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== - dependencies: - array-filter "^1.0.0" + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== aws-sign2@~0.7.0: version "0.7.0" @@ -1725,6 +1790,30 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-polyfill-corejs2@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" + integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.2" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.2.2: + version "0.2.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz#72add68cf08a8bf139ba6e6dfc0b1d504098e57b" + integrity sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.2" + core-js-compat "^3.14.0" + +babel-plugin-polyfill-regenerator@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" + integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.2.2" + babel-preset-current-node-syntax@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" @@ -1780,9 +1869,9 @@ babylon@^6.18.0: integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2, base-x@^3.0.6: version "3.0.8" @@ -1791,10 +1880,10 @@ base-x@^3.0.2, base-x@^3.0.6: dependencies: safe-buffer "^5.0.1" -base64-arraybuffer-es6@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.6.0.tgz#036f79f57588dca0018de7792ddf149299382007" - integrity sha512-57nLqKj4ShsDwFJWJsM4sZx6u60WbCge35rWRSevUwqxDtRwwxiKAO800zD2upPv4CfdWjQp//wSLar35nDKvA== +base64-arraybuffer-es6@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.7.0.tgz#dbe1e6c87b1bf1ca2875904461a7de40f21abc86" + integrity sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw== base64-js@^1.0.2: version "1.5.1" @@ -1856,9 +1945,9 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== brace-expansion@^1.1.7: version "1.1.11" @@ -2045,7 +2134,7 @@ browserify@^17.0.0: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.14.5, browserslist@^4.16.1: +browserslist@^4.16.6: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -2093,6 +2182,24 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +c8@^7.6.0: + version "7.7.3" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.7.3.tgz#5af8f83b55dace03b353375e7a2ba85e2c13b17f" + integrity sha512-ZyA7n3w8i4ETV25tVYMHwJxCSnaOf/LfA8vOcuZOPbonuQfD7tBT/gMWZy7eczRpCDuHcvMXwoqAemg6R0p3+A== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@istanbuljs/schema" "^0.1.2" + find-up "^5.0.0" + foreground-child "^2.0.0" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-report "^3.0.0" + istanbul-reports "^3.0.2" + rimraf "^3.0.0" + test-exclude "^6.0.0" + v8-to-istanbul "^8.0.0" + yargs "^16.2.0" + yargs-parser "^20.2.7" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2142,9 +2249,9 @@ camelcase@^6.0.0: integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== caniuse-lite@^1.0.30001219: - version "1.0.30001230" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" - integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== + version "1.0.30001246" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001246.tgz#fe17d9919f87124d6bb416ef7b325356d69dc76c" + integrity sha512-Tc+ff0Co/nFNbLOrziBXmMVtpt9S2c2Y+Z9Nk9Khj09J+0zR9ejvIW5qkZAErCbOrVODCx/MN+GpB5FNBs5GFA== capture-exit@^2.0.0: version "2.0.0" @@ -2158,12 +2265,12 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -catharsis@^0.8.11: - version "0.8.11" - resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.11.tgz#d0eb3d2b82b7da7a3ce2efb1a7b00becc6643468" - integrity sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g== +catharsis@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.9.0.tgz#40382a168be0e6da308c277d3a2b3eb40c7d2121" + integrity sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A== dependencies: - lodash "^4.17.14" + lodash "^4.17.15" center-align@^0.1.1: version "0.1.3" @@ -2183,9 +2290,9 @@ chalk@^2.0.0: supports-color "^5.3.0" chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -2203,19 +2310,19 @@ character-parser@^2.1.1: is-regex "^1.0.3" chokidar@^3.4.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.5.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.3.1" + fsevents "~2.3.2" ci-info@^2.0.0: version "2.0.0" @@ -2270,6 +2377,24 @@ cliui@^6.0.0: strip-ansi "^6.0.0" wrap-ansi "^6.2.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -2327,7 +2452,7 @@ combine-source-map@^0.8.0, combine-source-map@~0.8.0: lodash.memoize "~3.0.3" source-map "~0.5.3" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2395,9 +2520,9 @@ content-type@^1.0.4: integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" @@ -2411,12 +2536,12 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.8.0: - version "3.8.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.3.tgz#9123fb6b9cad30f0651332dc77deba48ef9b0b3f" - integrity sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog== +core-js-compat@^3.14.0, core-js-compat@^3.15.0: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.2.tgz#47272fbb479880de14b4e6081f71f3492f5bd3cb" + integrity sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ== dependencies: - browserslist "^4.16.1" + browserslist "^4.16.6" semver "7.0.0" core-js@^2.4.0, core-js@^2.5.3, core-js@^2.6.5: @@ -2507,7 +2632,7 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.2.0: +cssstyle@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== @@ -2540,6 +2665,13 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0= +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2547,22 +2679,15 @@ debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - decamelize@^1.0.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -decimal.js@^10.2.0: - version "10.2.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" - integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== +decimal.js@^10.2.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== decode-uri-component@^0.2.0: version "0.2.0" @@ -2728,9 +2853,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.3.723: - version "1.3.738" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.738.tgz#aec24b091c82acbfabbdcce08076a703941d17ca" - integrity sha512-vCMf4gDOpEylPSLPLSwAEsz+R3ShP02Y3cAKMZvTqule3XcPp7tgc/0ESI7IS6ZeyBlGClE50N53fIOkcIVnpw== + version "1.3.782" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.782.tgz#522740fe6b4b5255ca754c68d9c406a17b0998e2" + integrity sha512-6AI2se1NqWA1SBf/tlD6tQD/6ZOt+yAhqmrTlh4XZw4/g0Mt3p6JhTQPZxRPxPZiOg0o7ss1EBP/CpYejfnoIA== elliptic@^6.5.3: version "6.5.4" @@ -2781,37 +2906,39 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.18.0-next.1: - version "1.18.0-next.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" - integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" - get-intrinsic "^1.0.2" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" + has-symbols "^1.0.2" + is-callable "^1.2.3" is-negative-zero "^2.0.1" - is-regex "^1.1.1" - object-inspect "^1.9.0" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" object-keys "^1.1.1" object.assign "^4.1.2" - string.prototype.trimend "^1.0.3" - string.prototype.trimstart "^1.0.3" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" -es-get-iterator@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.1.tgz#b93ddd867af16d5118e00881396533c1c6647ad9" - integrity sha512-qorBw8Y7B15DVLaJWy6WdEV/ZkieBcu6QCq/xzWzGOKJqgG1j754vXRfZ3NY7HSShneqU43mPB4OkQBTkvHhFw== +es-get-iterator@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.1" + call-bind "^1.0.2" + get-intrinsic "^1.1.0" has-symbols "^1.0.1" - is-arguments "^1.0.4" - is-map "^2.0.1" - is-set "^2.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" is-string "^1.0.5" isarray "^2.0.5" @@ -2839,13 +2966,13 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escodegen@^1.14.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== dependencies: esprima "^4.0.1" - estraverse "^4.2.0" + estraverse "^5.2.0" esutils "^2.0.2" optionator "^0.8.1" optionalDependencies: @@ -2865,15 +2992,7 @@ eslint-rule-composer@^0.3.0: resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== -eslint-scope@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2881,22 +3000,29 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^2.0.0, eslint-utils@^2.1.0: +eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== -eslint-visitor-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" - integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== +eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint@7.18.0: version "7.18.0" @@ -2956,20 +3082,20 @@ esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" - integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0, esrecurse@^4.3.0: +esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -2979,15 +3105,24 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estree-to-babel@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" + integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== + dependencies: + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.2.0" + c8 "^7.6.0" + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== events@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" - integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -2998,9 +3133,9 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: safe-buffer "^5.1.1" exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== execa@^1.0.0: version "1.0.0" @@ -3128,9 +3263,9 @@ extsprintf@^1.2.0: integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= fake-indexeddb@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-3.1.2.tgz#8073a12ed3b254f7afc064f3cc2629f0110a5303" - integrity sha512-W60eRBrE8r9o/EePyyUc63sr2I/MI9p3zVwLlC1WI1xdmQVqqM6+wec9KDWDz2EZyvJKhrDvy3cGC6hK8L1pfg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-3.1.3.tgz#76d59146a6b994b9bb50ac9949cbd96ad6cca760" + integrity sha512-kpWYPIUGmxW8Q7xG7ampGL63fU/kYNukrIyy9KFj3+KVlFbE/SmvWebzWXBiCMeR0cPK6ufDoGC7MFkPhPLH9w== dependencies: realistic-structured-clone "^2.0.1" setimmediate "^1.0.5" @@ -3141,16 +3276,15 @@ fast-deep-equal@^3.1.1: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + version "3.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" + integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -3163,14 +3297,14 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fast-safe-stringify@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== + version "2.0.8" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f" + integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag== fastq@^1.6.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" - integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + version "1.11.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.1.tgz#5d8175aae17db61947f8b162cfc7f63264d22807" + integrity sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw== dependencies: reusify "^1.0.4" @@ -3182,9 +3316,9 @@ fb-watchman@^2.0.0: bser "2.1.1" file-entry-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.0.tgz#7921a89c391c6d93efec2169ac6bf300c527ea0a" - integrity sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA== + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" @@ -3229,6 +3363,14 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -3238,9 +3380,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" - integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + version "3.2.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.1.tgz#bbef080d95fca6709362c73044a1634f7c6e7d05" + integrity sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg== for-in@^1.0.2: version "1.0.2" @@ -3252,6 +3394,14 @@ foreach@^2.0.5: resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= +foreground-child@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" + integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^3.0.2" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -3266,6 +3416,15 @@ form-data@^2.5.0: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -3292,27 +3451,37 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2, fsevents@~2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" - integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== +fsevents@^2.1.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function.prototype.name@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.4.tgz#e4ea839b9d3672ae99d0efd9f38d9191c5eaac83" + integrity sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + functions-have-names "^1.2.2" + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -functions-have-names@^1.2.0: +functions-have-names@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== -gensync@^1.0.0-beta.1: +gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -3322,15 +3491,15 @@ get-assigned-identifiers@^1.2.0: resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" integrity sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.1, get-intrinsic@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" - integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -3367,22 +3536,7 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.0.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - -glob-parent@^5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -3390,9 +3544,9 @@ glob-parent@^5.1.0: is-glob "^4.0.1" glob@^7.0.0, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3413,10 +3567,10 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" -globby@^11.0.1: - version "11.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83" - integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -3426,9 +3580,9 @@ globby@^11.0.1: slash "^3.0.0" graceful-fs@^4.1.11, graceful-fs@^4.1.9, graceful-fs@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== growly@^1.3.0: version "1.3.0" @@ -3448,6 +3602,11 @@ har-validator@~5.1.3: ajv "^6.12.3" har-schema "^2.0.0" +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3458,10 +3617,10 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has-value@^0.3.1: version "0.3.1" @@ -3559,6 +3718,15 @@ htmlescape@^1.1.0: resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" integrity sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3573,6 +3741,14 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -3662,11 +3838,6 @@ insert-module-globals@^7.2.1: undeclared-identifiers "^1.1.2" xtend "^4.0.0" -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -3681,7 +3852,7 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: +is-arguments@^1.0.4, is-arguments@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== @@ -3700,10 +3871,15 @@ is-arrow-function@^2.0.3: dependencies: is-callable "^1.0.4" -is-bigint@^1.0.0, is-bigint@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== +is-async-fn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-async-fn/-/is-async-fn-1.1.0.tgz#a1a15b11d4a1155cc23b11e91b301b45a3caad16" + integrity sha1-oaFbEdShFVzCOxHpGzAbRaPKrRY= + +is-bigint@^1.0.1, is-bigint@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== is-binary-path@^1.0.0: version "1.0.1" @@ -3719,22 +3895,22 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.0.0, is-boolean-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== +is-boolean-object@^1.1.0, is-boolean-object@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.0.4, is-callable@^1.1.4, is-callable@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" - integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== +is-callable@^1.0.4, is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== is-ci@^2.0.0: version "2.0.0" @@ -3743,10 +3919,10 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== +is-core-module@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491" + integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg== dependencies: has "^1.0.3" @@ -3764,10 +3940,10 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-date-object@^1.0.1, is-date-object@^1.0.2, is-date-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-descriptor@^0.1.0: version "0.1.6" @@ -3788,33 +3964,34 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: kind-of "^6.0.2" is-docker@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" - integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-equal@^1.5.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/is-equal/-/is-equal-1.6.1.tgz#74fafde5060fcaf187041c05f11f0b9f020bb9b3" - integrity sha512-3/79QTolnfNFrxQAvqH8M+O01uGWsVq54BUPG2mXQH7zi4BE/0TY+fmA444t8xSBvIwyNMvsTmCZ5ViVDlqPJg== + version "1.6.2" + resolved "https://registry.yarnpkg.com/is-equal/-/is-equal-1.6.2.tgz#9de9a33fee63c310372e401d2a6ef86dc2668615" + integrity sha512-paNlhukQqphbdiILWvU4Sl3Q1wvJNDqpZUQdnFKbL6XEvSIUemV8BVCOVuElqnYeWN+fG3nLDlv3Mgh3/ehTMA== dependencies: - es-get-iterator "^1.0.1" - functions-have-names "^1.2.0" + es-get-iterator "^1.1.2" + functions-have-names "^1.2.2" has "^1.0.3" is-arrow-function "^2.0.3" - is-bigint "^1.0.0" - is-boolean-object "^1.0.0" - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-generator-function "^1.0.7" - is-number-object "^1.0.3" - is-regex "^1.0.4" - is-string "^1.0.4" + is-bigint "^1.0.2" + is-boolean-object "^1.1.1" + is-callable "^1.2.3" + is-date-object "^1.0.4" + is-generator-function "^1.0.9" + is-number-object "^1.0.5" + is-regex "^1.1.3" + is-string "^1.0.6" is-symbol "^1.0.3" isarray "^2.0.5" - object-inspect "^1.7.0" - object.entries "^1.1.0" - which-boxed-primitive "^1.0.1" - which-collection "^1.0.0" + object-inspect "^1.10.3" + object.entries "^1.1.3" + object.getprototypeof "^1.0.1" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" is-expression@^3.0.0: version "3.0.0" @@ -3836,11 +4013,16 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-finalizationregistry@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.1.tgz#4c8a8d4a72c49ea4b0f7e4f82203373abd4b8e38" + integrity sha512-7ljq3NfRoVd2mwe9CvvU6Io1ZtdLf8x9MUMYC6vATTKTciKVS6c0ZOAHf2YAD9woY7afIhv+rchAYXxkCn0ubg== + is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -3851,17 +4033,10 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-generator-function@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" - integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" +is-generator-function@^1.0.7, is-generator-function@^1.0.8, is-generator-function@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" + integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" @@ -3870,7 +4045,7 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-map@^2.0.1: +is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== @@ -3880,10 +4055,10 @@ is-negative-zero@^2.0.1: resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== -is-number-object@^1.0.3, is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== +is-number-object@^1.0.4, is-number-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== is-number@^3.0.0: version "3.0.0" @@ -3904,24 +4079,25 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" - integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== is-promise@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.0.3, is-regex@^1.0.4, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== +is-regex@^1.0.3, is-regex@^1.1.2, is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: - has-symbols "^1.0.1" + call-bind "^1.0.2" + has-symbols "^1.0.2" -is-set@^2.0.1: +is-set@^2.0.1, is-set@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== @@ -3936,26 +4112,26 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.4, is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== dependencies: - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-typed-array@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.4.tgz#1f66f34a283a3c94a4335434661ca53fff801120" - integrity sha512-ILaRgn4zaSrVNXNGtON6iFNotXW3hAPF3+0fB1usg2jFlWqo5fEDdmJkz0zBfoi7Dgskr8Khi2xZ8cXqZEfXNA== + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== dependencies: available-typed-arrays "^1.0.2" - call-bind "^1.0.0" - es-abstract "^1.18.0-next.1" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" foreach "^2.0.5" has-symbols "^1.0.1" @@ -3974,6 +4150,13 @@ is-weakmap@^2.0.1: resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + is-weakset@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83" @@ -4228,9 +4411,9 @@ jest-leak-detector@^26.6.2: pretty-format "^26.6.2" jest-localstorage-mock@^2.4.6: - version "2.4.6" - resolved "https://registry.yarnpkg.com/jest-localstorage-mock/-/jest-localstorage-mock-2.4.6.tgz#ebb9481943bf52e0f8c864ae4858eb791d68149d" - integrity sha512-8n6tuqscEShpvC7vkq3BPabOGGszD1cdLAKTtTtCRqH2bWJIVfpV4aIhrDJstV7xLOjo56wSVZkoMbT7dWLIVg== + version "2.4.14" + resolved "https://registry.yarnpkg.com/jest-localstorage-mock/-/jest-localstorage-mock-2.4.14.tgz#f42f2ce66ac2675955d537c99f93cff807967d0f" + integrity sha512-B+Y0y3J4wBOHdmcFSicWmVYMFAZFbJvjs1EfRIzUJRg2UAK+YVVUgTn7/MdjENey5xbBKmraBmKY5EX+x1NJXA== jest-matcher-utils@^26.6.2: version "26.6.2" @@ -4473,55 +4656,56 @@ jsbn@~0.1.0: integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsdoc@^3.6.6: - version "3.6.6" - resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.6.tgz#9fe162bbdb13ee7988bf74352b5147565bcfd8e1" - integrity sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ== + version "3.6.7" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.7.tgz#00431e376bed7f9de4716c6f15caa80e64492b89" + integrity sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw== dependencies: "@babel/parser" "^7.9.4" bluebird "^3.7.2" - catharsis "^0.8.11" + catharsis "^0.9.0" escape-string-regexp "^2.0.0" js2xmlparser "^4.0.1" klaw "^3.0.0" markdown-it "^10.0.0" markdown-it-anchor "^5.2.7" - marked "^0.8.2" + marked "^2.0.3" mkdirp "^1.0.4" requizzle "^0.2.3" strip-json-comments "^3.1.0" taffydb "2.6.2" - underscore "~1.10.2" + underscore "~1.13.1" jsdom@^16.4.0: - version "16.4.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb" - integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w== + version "16.6.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" + integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== dependencies: - abab "^2.0.3" - acorn "^7.1.1" + abab "^2.0.5" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" - cssstyle "^2.2.0" + cssstyle "^2.3.0" data-urls "^2.0.0" - decimal.js "^10.2.0" + decimal.js "^10.2.1" domexception "^2.0.1" - escodegen "^1.14.1" + escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" - parse5 "5.1.1" - request "^2.88.2" - request-promise-native "^1.0.8" - saxes "^5.0.0" + parse5 "6.0.1" + saxes "^5.0.1" symbol-tree "^3.2.4" - tough-cookie "^3.0.1" + tough-cookie "^4.0.0" w3c-hr-time "^1.0.2" w3c-xmlserializer "^2.0.0" webidl-conversions "^6.1.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - ws "^7.2.3" + whatwg-url "^8.5.0" + ws "^7.4.5" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -4565,9 +4749,9 @@ json-stringify-safe@~5.0.1: integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" @@ -4691,6 +4875,23 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -4706,12 +4907,12 @@ lodash.memoize@~3.0.3: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8= -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4: +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4798,10 +4999,10 @@ markdown-it@^10.0.0: mdurl "^1.0.1" uc.micro "^1.0.5" -marked@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355" - integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== +marked@^2.0.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" + integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== matrix-mock-request@^1.2.3: version "1.2.3" @@ -4854,13 +5055,13 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== dependencies: braces "^3.0.1" - picomatch "^2.0.5" + picomatch "^2.2.3" miller-rabin@^4.0.0: version "4.0.1" @@ -4870,17 +5071,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.45.0: - version "1.45.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" - integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.28" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" - integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== dependencies: - mime-db "1.45.0" + mime-db "1.48.0" mimic-fn@^2.1.0: version "2.1.0" @@ -5033,9 +5234,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" - integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== + version "8.0.2" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.2.tgz#f3167a38ef0d2c8a866a83e318c1ba0efeb702c5" + integrity sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg== dependencies: growly "^1.3.0" is-wsl "^2.2.0" @@ -5045,9 +5246,9 @@ node-notifier@^8.0.0: which "^2.0.2" node-releases@^1.1.71: - version "1.1.72" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" - integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== normalize-package-data@^2.5.0: version "2.5.0" @@ -5109,10 +5310,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.1.0, object-inspect@^1.7.0, object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== +object-inspect@^1.1.0, object-inspect@^1.10.3, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== object-keys@^1.0.12, object-keys@^1.0.9, object-keys@^1.1.1: version "1.1.1" @@ -5136,15 +5337,24 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" - integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== +object.entries@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" + integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.2" + +object.getprototypeof@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.getprototypeof/-/object.getprototypeof-1.0.1.tgz#dce7a9e6335b04db2e218afc5f423352a8ee3ada" + integrity sha512-orf7CoEkZKn1HYzA5KIt6G3Z2G4LKi1CiIK73c2PA2OK7ZASYp+rlIymYSs09qyrMm2o14U00z3VeD7MSsdvNw== + dependencies: + call-bind "^1.0.2" define-properties "^1.1.3" es-abstract "^1.18.0-next.1" - has "^1.0.3" + reflect.getprototypeof "^1.0.0" object.pick@^1.3.0: version "1.3.0" @@ -5213,6 +5423,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -5227,13 +5444,20 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-retry@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.5.0.tgz#6685336b3672f9ee8174d3769a660cb5e488521d" - integrity sha512-5Hwh4aVQSu6BEP+w2zKlVXtFAaYQe1qWuVADSgoeVlLjwe/Q/AMSoRR4MDeaAfu8llT+YNbEijWu/YF3m6avkg== + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== dependencies: "@types/retry" "^0.12.0" - retry "^0.12.0" + retry "^0.13.1" p-try@^2.0.0: version "2.2.0" @@ -5287,10 +5511,10 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse5@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== pascalcase@^0.1.1: version "0.1.1" @@ -5302,11 +5526,6 @@ path-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -5333,9 +5552,9 @@ path-key@^3.0.0, path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-platform@~0.11.15: version "0.11.15" @@ -5348,9 +5567,9 @@ path-type@^4.0.0: integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -5363,10 +5582,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== pify@^4.0.1: version "4.0.1" @@ -5447,9 +5666,9 @@ promise@^7.0.1: asap "~2.0.3" prompts@^2.0.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7" - integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== + version "2.4.1" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" + integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== dependencies: kleur "^3.0.3" sisteransi "^1.0.5" @@ -5468,7 +5687,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -5614,9 +5833,11 @@ punycode@^2.1.0, punycode@^2.1.1: integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@^6.9.6: - version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" - integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + version "6.10.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + dependencies: + side-channel "^1.0.4" qs@~6.5.2: version "6.5.2" @@ -5634,9 +5855,9 @@ querystring@0.2.0: integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= queue-microtask@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3" - integrity sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg== + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" @@ -5666,15 +5887,17 @@ react-ace@^6.5.0: prop-types "^15.7.2" react-docgen@^5.3.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.3.1.tgz#940b519646a6c285c2950b96512aed59e8f90934" - integrity sha512-YG7YujVTwlLslr2Ny8nQiUfbBuEwKsLHJdQTSdEga1eY/nRFh/7LjCWUn6ogYhu2WDKg4z+6W/BJtUi+DPUIlA== + version "5.4.0" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.0.tgz#2cd7236720ec2769252ef0421f23250b39a153a1" + integrity sha512-JBjVQ9cahmNlfjMGxWUxJg919xBBKAoy3hgDgKERbR+BcF4ANpDuzWAScC7j27hZfd8sJNmMPOLWo9+vB/XJEQ== dependencies: "@babel/core" "^7.7.5" + "@babel/generator" "^7.12.11" "@babel/runtime" "^7.7.6" ast-types "^0.14.2" commander "^2.19.0" doctrine "^3.0.0" + estree-to-babel "^3.1.0" neo-async "^2.6.1" node-dir "^0.1.10" strip-indent "^3.0.0" @@ -5690,9 +5913,9 @@ react-is@^16.8.1: integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== read-only-stream@^2.0.0: version "2.0.0" @@ -5751,10 +5974,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" @@ -5778,6 +6001,17 @@ recast@^0.17.3: private "^0.1.8" source-map "~0.6.1" +reflect.getprototypeof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.0.tgz#e54220a9bb67ec810c1916fc206ba6039509cb53" + integrity sha512-+0EPfQjXK+0X35YbfoXm6SKonJYwD1seJiS170Hl7MVLp5eGAKOGqbnLVtvC9boQ5qV5UpDNop+p0beVYbSI+Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + get-intrinsic "^1.0.2" + which-builtin-type "^1.0.1" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -5815,10 +6049,10 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== regexpu-core@^4.7.1: version "4.7.1" @@ -5838,9 +6072,9 @@ regjsgen@^0.5.1: integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.6.4: - version "0.6.6" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.6.tgz#6d8c939d1a654f78859b08ddcc4aa777f3fa800a" - integrity sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ== + version "0.6.9" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6" + integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ== dependencies: jsesc "~0.5.0" @@ -5850,31 +6084,15 @@ remove-trailing-separator@^1.0.1: integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" @@ -5945,12 +6163,12 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.1.4, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.4.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== +resolve@^1.1.4, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.4.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: - is-core-module "^2.1.0" + is-core-module "^2.2.0" path-parse "^1.0.6" ret@~0.1.10: @@ -5958,10 +6176,10 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== reusify@^1.0.4: version "1.0.4" @@ -6039,14 +6257,14 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -saxes@^5.0.0: +saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: xmlchars "^2.2.0" -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -6056,15 +6274,15 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== +semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" @@ -6096,6 +6314,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + shasum-object@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shasum-object/-/shasum-object-1.0.0.tgz#0b7b74ff5b66ecf9035475522fa05090ac47e29e" @@ -6137,6 +6362,15 @@ shellwords@^0.1.1: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -6221,9 +6455,9 @@ source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.1 source-map "^0.6.0" source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== source-map@^0.5.0, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.7" @@ -6262,9 +6496,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + version "3.0.9" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" + integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -6308,11 +6542,6 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-browserify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" @@ -6330,9 +6559,9 @@ stream-combiner2@^1.1.1: readable-stream "^2.0.2" stream-http@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" - integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" + integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== dependencies: builtin-status-codes "^3.0.0" inherits "^2.0.4" @@ -6348,36 +6577,36 @@ stream-splicer@^2.0.0: readable-stream "^2.0.2" string-length@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" - integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" strip-ansi "^6.0.0" string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" - integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" string_decoder@^1.1.1: @@ -6462,9 +6691,9 @@ supports-color@^7.0.0, supports-color@^7.1.0: has-flag "^4.0.0" supports-hyperlinks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" - integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== dependencies: has-flag "^4.0.0" supports-color "^7.0.0" @@ -6482,14 +6711,16 @@ syntax-error@^1.1.1: acorn-node "^1.2.0" table@^6.0.4: - version "6.0.7" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" - integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: - ajv "^7.0.2" - lodash "^4.17.20" + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.0" + strip-ansi "^6.0.0" taffydb@2.6.2: version "2.6.2" @@ -6505,9 +6736,9 @@ terminal-link@^2.0.0: supports-hyperlinks "^2.0.0" terser@^5.5.1: - version "5.5.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" - integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== + version "5.7.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" + integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== dependencies: commander "^2.20.0" source-map "~0.7.2" @@ -6614,7 +6845,16 @@ token-stream@0.0.1: resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a" integrity sha1-zu78cXp2xDFvEm0LnbqlXX598Bo= -tough-cookie@^2.3.3, tough-cookie@~2.5.0: +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -6622,19 +6862,10 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - -tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== +tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" @@ -6654,9 +6885,9 @@ tsconfig@^5.0.3: strip-json-comments "^2.0.0" tsify@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/tsify/-/tsify-5.0.2.tgz#ba3c9f8de239e89ba3aab6b83d65b569ef8b68c3" - integrity sha512-Pdo3ZO8CAgbQgNcFRBmfbgsPP+4TsD0itbSF5YgTnxKBXfg6WkQ79e4/bqBaq/7cEYa7vIOM1pHxnux8rJJnzg== + version "5.0.4" + resolved "https://registry.yarnpkg.com/tsify/-/tsify-5.0.4.tgz#22163648d04c0c90bdb15704fb14947df2328547" + integrity sha512-XAZtQ5OMPsJFclkZ9xMZWkSNyMhMxEPsz3D2zu79yoKorH9j/DT4xCloJeXk5+cDhosEibu4bseMVjyPOAyLJA== dependencies: convert-source-map "^1.1.0" fs.realpath "^1.0.0" @@ -6671,11 +6902,11 @@ tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== -tsutils@^3.17.1: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== @@ -6718,10 +6949,10 @@ type-detect@4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.6.0: version "0.6.0" @@ -6746,29 +6977,34 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.2.2, typescript@^3.7.5: - version "3.9.7" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" - integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== typescript@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" - integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== typeson-registry@^1.0.0-alpha.20: - version "1.0.0-alpha.38" - resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.38.tgz#42b19c21997ab80e38b3c67d6c1aad1499fea5b9" - integrity sha512-6lt2IhbNT9hyow5hljZqjWtVDXBIaC1X8bBGlBva0Pod2f42g23bVqww09ruquwSC48I8BSSCPi+B2dFHM5ihQ== + version "1.0.0-alpha.39" + resolved "https://registry.yarnpkg.com/typeson-registry/-/typeson-registry-1.0.0-alpha.39.tgz#9e0f5aabd5eebfcffd65a796487541196f4b1211" + integrity sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw== dependencies: - base64-arraybuffer-es6 "^0.6.0" - typeson "^5.18.2" - whatwg-url "^8.1.0" + base64-arraybuffer-es6 "^0.7.0" + typeson "^6.0.0" + whatwg-url "^8.4.0" -typeson@^5.18.2, typeson@^5.8.2: +typeson@^5.8.2: version "5.18.2" resolved "https://registry.yarnpkg.com/typeson/-/typeson-5.18.2.tgz#0d217fc0e11184a66aa7ca0076d9aa7707eb7bc2" integrity sha512-Vetd+OGX05P4qHyHiSLdHZ5Z5GuQDrHHwSdjkqho9NSCYVSLSfRMjklD/unpHH8tXBR9Z/R05rwJSuMpMFrdsw== +typeson@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/typeson/-/typeson-6.1.0.tgz#5b2a53705a5f58ff4d6f82f965917cabd0d7448b" + integrity sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA== + uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" @@ -6794,6 +7030,16 @@ umd@^3.0.0: resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf" integrity sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow== +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + undeclared-identifiers@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz#9254c1d37bdac0ac2b52de4b6722792d2a91e30f" @@ -6805,15 +7051,10 @@ undeclared-identifiers@^1.1.2: simple-concat "^1.0.0" xtend "^4.0.1" -underscore@^1.9.1: - version "1.12.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.0.tgz#4814940551fc80587cef7840d1ebb0f16453be97" - integrity sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ== - -underscore@~1.10.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" - integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== +underscore@^1.9.1, underscore@~1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" + integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g== unhomoglyph@^1.0.6: version "1.0.6" @@ -6853,6 +7094,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -6904,9 +7150,9 @@ util@0.10.3: inherits "2.0.1" util@~0.12.0: - version "0.12.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" - integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== dependencies: inherits "^2.0.3" is-arguments "^1.0.4" @@ -6926,14 +7172,23 @@ uuid@^8.3.0: integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== v8-compile-cache@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" - integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8-to-istanbul@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz#5b95cef45c0f83217ec79f8fc7ee1c8b486aee07" - integrity sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g== + version "7.1.2" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" + integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + +v8-to-istanbul@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" + integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -6983,9 +7238,9 @@ vue-docgen-api@^3.22.0: vue-template-compiler "^2.0.0" vue-template-compiler@^2.0.0: - version "2.6.12" - resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e" - integrity sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg== + version "2.6.14" + resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz#a2f0e7d985670d42c9c9ee0d044fed7690f4f763" + integrity sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g== dependencies: de-indent "^1.0.2" he "^1.1.0" @@ -7045,16 +7300,16 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^8.0.0, whatwg-url@^8.1.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" - integrity sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw== +whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== dependencies: - lodash.sortby "^4.7.0" - tr46 "^2.0.2" + lodash "^4.7.0" + tr46 "^2.1.0" webidl-conversions "^6.1.0" -which-boxed-primitive@^1.0.1: +which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== @@ -7065,7 +7320,24 @@ which-boxed-primitive@^1.0.1: is-string "^1.0.5" is-symbol "^1.0.3" -which-collection@^1.0.0: +which-builtin-type@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.0.tgz#0295cbda3fa75837bf4ab6cc56c4b33af1e99454" + integrity sha512-KOX/VAdpOLOahMo64rn+tPK8IHc8TY12r2iCM/Lvlgk6JMzShmxz751C5HEHP55zBAQe2eJeltmfyGbe3ggw4Q== + dependencies: + function.prototype.name "^1.1.4" + is-async-fn "^1.1.0" + is-date-object "^1.0.2" + is-finalizationregistry "^1.0.1" + is-generator-function "^1.0.8" + is-regex "^1.1.2" + is-weakref "^1.0.1" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.4" + +which-collection@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== @@ -7080,7 +7352,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-typed-array@^1.1.2: +which-typed-array@^1.1.2, which-typed-array@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== @@ -7139,6 +7411,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -7154,10 +7435,10 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^7.2.3: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^7.4.5: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== xml-name-validator@^3.0.0: version "3.0.0" @@ -7180,9 +7461,14 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^2.1.2: version "2.1.2" @@ -7202,6 +7488,11 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.2, yargs-parser@^20.2.7: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs@^15.4.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -7219,6 +7510,19 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" @@ -7228,3 +7532,8 @@ yargs@~3.10.0: cliui "^2.1.0" decamelize "^1.0.0" window-size "0.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 05d0755b6ab8b818b4c192ddba2a4d3b985bd085 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 23 Jul 2021 16:07:49 +0100 Subject: [PATCH 129/129] Update matrix-org-eslint-plugin and tighten max warning limit Whilst it is down, make the most of it! --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 93f2a74a2..854021a71 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "build:minify-browser": "terser dist/browser-matrix.js --compress --mangle --source-map --output dist/browser-matrix.min.js", "gendoc": "jsdoc -c jsdoc.json -P package.json", "lint": "yarn lint:types && yarn lint:js", - "lint:js": "eslint --max-warnings 57 src spec", + "lint:js": "eslint --max-warnings 7 src spec", "lint:js-fix": "eslint --fix src spec", "lint:types": "tsc --noEmit", "test": "jest", diff --git a/yarn.lock b/yarn.lock index 2a60c66a1..563a8e3ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2984,8 +2984,8 @@ eslint-config-google@^0.14.0: integrity sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw== "eslint-plugin-matrix-org@github:matrix-org/eslint-plugin-matrix-org#main": - version "0.3.2" - resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/8529f1d77863db6327cf1a1a4fa65d06cc26f91b" + version "0.3.3" + resolved "https://codeload.github.com/matrix-org/eslint-plugin-matrix-org/tar.gz/50d6bdf6704dd95016d5f1f824f00cac6eaa64e1" eslint-rule-composer@^0.3.0: version "0.3.0"