diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c9d11f02c..a71d86006 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,7 @@ - + - + + + 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/ diff --git a/CHANGELOG.md b/CHANGELOG.md index a7baac3a3..f352afcf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,44 @@ +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) + + * 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) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..d90508302 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,194 @@ +Contributing code to matrix-js-sdk +================================== + +Everyone is welcome to contribute code to matrix-js-sdk, provided that they are +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](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 +into our repo (https://help.github.com/articles/using-pull-requests/) + +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. + +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 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. + +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 (this is +the default for PRs labelled with `T-Task`): + +*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 +element-web notes: Fix a bug where the 'Herd' button only worked on Tuesdays +``` + +This example is for Element Web. You can specify: + * matrix-react-sdk + * element-web + * element-desktop + +If your PR introduces a breaking change, use the `Notes` section in the same +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: + +*Remove legacy class* + +``` +Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead. +``` + +Other metadata can be added using labels. + * `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. + +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: +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. + +Members should not be exported as a default export in general - it causes problems +with the architecture of the SDK (index file becomes less clear) and could +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](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 +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 +description of the area(s) you've worked on. Also, we sometimes have swag to +give away to contributors - if you feel that Matrix-branded apparel is missing +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 +(https://www.kernel.org/doc/Documentation/SubmittingPatches), Docker +(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: + +``` +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 + +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 + +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 + +(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. + +(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: + +``` +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. + +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: + +``` +git rebase --signoff origin/develop +``` diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 532e09aac..000000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,131 +0,0 @@ -Contributing code to matrix-js-sdk -================================== - -Everyone is welcome to contribute code to matrix-js-sdk, provided that they are -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 ``_). - -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 -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 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. - -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 -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. - -Members should not be exported as a default export in general - it causes problems -with the architecture of the SDK (index file becomes less clear) and could -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 -(``_) -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 -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 -description of the area(s) you've worked on. Also, we sometimes have swag to -give away to contributors - if you feel that Matrix-branded apparel is missing -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 -(https://www.kernel.org/doc/Documentation/SubmittingPatches), Docker -(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:: - - 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 - - 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 - - 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 - - (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. - - (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:: - - 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. - -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:: - - git rebase --signoff origin/develop diff --git a/package.json b/package.json index b1c92efe6..854021a71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "12.0.1", + "version": "12.1.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -15,7 +15,8 @@ "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", "test:watch": "jest --watch", 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 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; diff --git a/spec/unit/crypto/backup.spec.js b/spec/unit/crypto/backup.spec.js index ae6b25ddf..bbd2a6d8e 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.msc3270.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.msc3270.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/spec/unit/room.spec.js b/spec/unit/room.spec.js index 7675609d3..be746a237 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,291 @@ 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"); + }); + + 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"); + }); + + 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"); + }); + }); + }); }); diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts new file mode 100644 index 000000000..a4eda1b48 --- /dev/null +++ b/src/@types/PushRules.ts @@ -0,0 +1,164 @@ +/* +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. +*/ + +// allow camelcase as these are things that go onto the wire +/* eslint-disable camelcase */ + +export enum PushRuleActionName { + DontNotify = "dont_notify", + Notify = "notify", + Coalesce = "coalesce", +} + +export enum TweakName { + Highlight = "highlight", + Sound = "sound", +} + +export type Tweak = { + set_tweak: N; + 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 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 enum PushRuleKind { + Override = "override", + ContentSpecific = "content", + RoomSpecific = "room", + SenderSpecific = "sender", + Underride = "underride", +} + +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 type PushRuleSet = { + [k in PushRuleKind]?: IPushRule[]; +}; + +export interface IPushRule { + actions: PushRuleAction[]; + conditions?: PushRuleCondition[]; + default: boolean; + enabled: boolean; + pattern?: string; + rule_id: RuleId | string; +} + +export interface IAnnotatedPushRule extends IPushRule { + kind: PushRuleKind; +} + +export interface IPushRules { + global: PushRuleSet; + device?: PushRuleSet; +} + +export interface IPusher { + app_display_name: string; + app_id: string; + 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 + lang: string; + profile_tag?: string; + pushkey: string; +} + +export interface IPusherRequest extends IPusher { + append?: boolean; +} + +/* eslint-enable camelcase */ diff --git a/src/@types/event.ts b/src/@types/event.ts index f7b22992e..42c7d0529 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -144,6 +144,28 @@ 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. + * + * 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", + "io.element.functional_members"); + export interface IEncryptedFile { url: string; mimetype?: string; 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/@types/partials.ts b/src/@types/partials.ts index ecdc6525a..19c11d153 100644 --- a/src/@types/partials.ts +++ b/src/@types/partials.ts @@ -39,3 +39,38 @@ 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"; + +// Knock and private are reserved keywords which are not yet implemented. +export enum JoinRule { + Public = "public", + Invite = "invite", + /** + * @deprecated Reserved keyword. Should not be used. Not yet implemented. + */ + Private = "private", + 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 RestrictedAllowType { + RoomMembership = "m.room_membership", // 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", +} diff --git a/src/@types/requests.ts b/src/@types/requests.ts index eaf682831..d8dbcda2e 100644 --- a/src/@types/requests.ts +++ b/src/@types/requests.ts @@ -15,9 +15,12 @@ limitations under the License. */ import { Callback } from "../client"; +import { IContent } from "../models/event"; import { Preset, Visibility } from "./partials"; +import { SearchKey } from "./search"; +import { IRoomEventFilter } from "../filter"; -// 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 { @@ -63,12 +66,12 @@ export interface IGuestAccessOpts { } export interface ISearchOpts { - keys?: string[]; + keys?: SearchKey[]; query: string; } export interface IEventSearchOpts { - filter: any; // TODO: Types + filter?: IRoomEventFilter; term: string; } @@ -82,7 +85,7 @@ export interface IInvite3PID { export interface ICreateRoomStateEvent { type: string; state_key?: string; // defaults to an empty string - content: object; + content: IContent; } export interface ICreateRoomOpts { @@ -104,9 +107,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 +124,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..0aa8a34a4 --- /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/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/@types/spaces.ts b/src/@types/spaces.ts new file mode 100644 index 000000000..da35bc0b9 --- /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 { IPublicRoomsChunkRoom } from "../client"; + +// Types relating to Rooms of type `m.space` and related APIs + +/* eslint-disable camelcase */ +export interface ISpaceSummaryRoom extends IPublicRoomsChunkRoom { + 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/@types/threepids.ts b/src/@types/threepids.ts new file mode 100644 index 000000000..1740dec7a --- /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 IThreepid { + medium: ThreepidMedium; + address: string; + validated_at: number; // eslint-disable-line camelcase + added_at: number; // eslint-disable-line camelcase +} diff --git a/src/client.ts b/src/client.ts index 6acc6c1bd..45d1de013 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, IEvent, 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 { IActionsObject, 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,35 +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, ISecretStorageKeyInfo, NotificationCountType } from "./matrix"; -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, @@ -83,11 +87,21 @@ import { IEncryptedEventInfo, IImportRoomKeysOpts, IRecoveryKey, - ISecretStorageKey, + 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,38 @@ 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"; +import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules"; +import { IThreepid } from "./@types/threepids"; -export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; +export type Store = IStore; export type SessionStore = WebStorageSessionStore; export type CryptoStore = MemoryCryptoStore | LocalStorageCryptoStore | IndexedDBCryptoStore; @@ -132,7 +161,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 +290,7 @@ export interface ICreateClientOpts { */ unstableClientRelationAggregation?: boolean; - verificationMethods?: Array; + verificationMethods?: Array; /** * Whether relaying calls through a TURN server should be forced. Default false. @@ -366,9 +395,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 } export interface IChangePasswordCapability { @@ -404,7 +439,6 @@ export interface ISignedKey { algorithms: string[]; device_id: string; } -/* eslint-enable camelcase */ export type KeySignatures = Record>; interface IUploadKeySignaturesResponse { @@ -414,6 +448,225 @@ 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; +} + +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 { + [key: string]: any; // extensible + "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: Partial; // legacy and undocumented, api is deprecated so this won't get attention +} + +interface IJoinedMembersResponse { + joined: { + [userId: string]: { + display_name: string; + avatar_url: string; + }; + }; +} + +export interface IPublicRoomsChunkRoom { + 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: IPublicRoomsChunkRoom[]; + 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 IMyDevice { + device_id: string; + display_name?: string; + last_seen_ip?: string; + last_seen_ts?: number; +} + +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: https://github.com/matrix-org/matrix-doc/issues/3203 + 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 @@ -432,7 +685,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. @@ -452,10 +705,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; @@ -471,15 +724,15 @@ 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 exportedOlmDeviceToImport: IOlmDevice; @@ -701,7 +954,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(); } @@ -713,7 +966,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) { @@ -725,11 +978,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(); } } @@ -1042,7 +1293,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; } @@ -1492,7 +1743,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"); } @@ -1622,9 +1873,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"); } @@ -1646,7 +1897,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"); } @@ -1841,7 +2096,11 @@ 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 +2116,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 +2169,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"); } @@ -1925,9 +2184,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"); } @@ -2028,7 +2287,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"); } @@ -2050,7 +2309,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; } @@ -2084,7 +2343,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")); } @@ -2125,28 +2384,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; } /** @@ -2327,7 +2584,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", { @@ -2341,11 +2598,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 }; } /** @@ -2357,8 +2611,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"); } @@ -2551,12 +2804,12 @@ 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; }); + 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 @@ -2589,9 +2842,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); @@ -2599,9 +2850,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; } @@ -2624,7 +2873,7 @@ export class MatrixClient extends EventEmitter { await this.importRoomKeys(keys, { progressCallback, - untrusted: true, + untrusted, source: "backup", }); @@ -2703,7 +2952,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, @@ -2743,7 +2992,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']; @@ -2754,7 +3003,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; } @@ -2786,10 +3035,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, @@ -2821,7 +3070,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) { @@ -2861,10 +3110,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); @@ -2907,7 +3156,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( @@ -2924,11 +3173,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 }); @@ -2954,10 +3202,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); } @@ -2991,8 +3239,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); } /** @@ -3002,8 +3250,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); } /** @@ -3027,18 +3275,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); } /** @@ -3064,18 +3310,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); } /** @@ -3085,7 +3334,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( @@ -3094,11 +3343,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; @@ -3107,9 +3356,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); } /** @@ -3118,13 +3365,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 { @@ -3136,7 +3383,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( @@ -3402,15 +3649,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); } /** @@ -3418,7 +3670,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( @@ -3436,7 +3688,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 { @@ -3449,7 +3701,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( @@ -3468,7 +3720,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( @@ -3483,7 +3735,7 @@ export class MatrixClient extends EventEmitter { text = undefined; } const content = { - msgtype: "m.image", + msgtype: MsgType.Image, url: url, info: info, body: text, @@ -3497,7 +3749,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( @@ -3524,7 +3776,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( @@ -3542,7 +3794,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( @@ -3560,7 +3812,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( @@ -3577,12 +3829,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 = {}; @@ -3597,9 +3849,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) { @@ -3616,10 +3866,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 = {}; @@ -3633,7 +3883,7 @@ export class MatrixClient extends EventEmitter { } const addlContent = { - "m.hidden": Boolean(opts.hidden), + "org.matrix.msc2285.hidden": Boolean(opts.hidden), }; return this.sendReceipt(event, "m.read", addlContent, callback); @@ -3659,7 +3909,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})`); @@ -3695,11 +3945,15 @@ 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; + 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. @@ -3729,10 +3983,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. } @@ -3747,9 +4001,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); } /** @@ -3773,7 +4025,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']; @@ -3783,8 +4035,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) { @@ -3794,7 +4045,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; @@ -3802,14 +4053,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']; @@ -3827,7 +4078,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; @@ -4103,17 +4354,18 @@ 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: "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); } /** @@ -4122,10 +4374,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) { @@ -4141,10 +4391,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) { @@ -4184,22 +4432,16 @@ 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((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 } @@ -4297,8 +4539,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()); @@ -4333,7 +4576,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} */ @@ -4439,16 +4682,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, @@ -4670,13 +4911,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(undefined); if (opts.allowRead) { - readPromise = this.sendStateEvent(roomId, "m.room.history_visibility", { + readPromise = this.sendStateEvent(roomId, EventType.RoomHistoryVisibility, { history_visibility: "world_readable", }, ""); } @@ -4703,7 +4944,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink?: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/register/email/requestToken", { @@ -4735,7 +4976,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink?: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/register/msisdn/requestToken", { @@ -4757,7 +4998,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 @@ -4770,7 +5011,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/3pid/email/requestToken", { @@ -4785,7 +5026,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. * @@ -4802,7 +5043,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/3pid/msisdn/requestToken", { @@ -4818,13 +5059,13 @@ 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 - * 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, + * requestEmailToken calls the equivalent API directly on the identity server, * therefore bypassing the password reset specific logic. * * @param {string} email As requestEmailToken @@ -4839,7 +5080,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/password/email/requestToken", { @@ -4854,7 +5095,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 @@ -4870,7 +5111,7 @@ export class MatrixClient extends EventEmitter { clientSecret: string, sendAttempt: number, nextLink: string, - ): Promise { // TODO: Types + ): Promise { return this.requestTokenFromEndpoint( "/account/password/msisdn/requestToken", { @@ -4891,16 +5132,16 @@ 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 // 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 ID server URL: " + this.idBaseUrl); - } + const idServerUrl = new URL(this.idBaseUrl); postParams.id_server = idServerUrl.host; if ( @@ -4915,10 +5156,7 @@ export class MatrixClient extends EventEmitter { } } - return this.http.request( - undefined, "POST", endpoint, undefined, - postParams, - ); + return this.http.request(undefined, "POST", endpoint, undefined, postParams); } /** @@ -4953,7 +5191,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; @@ -4968,20 +5206,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(); @@ -5020,8 +5258,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, }; @@ -5058,7 +5296,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 = { @@ -5066,7 +5304,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, @@ -5076,7 +5314,7 @@ export class MatrixClient extends EventEmitter { }, }; - const searchResults = { + const searchResults: ISearchResults = { _query: body, results: [], highlights: [], @@ -5092,7 +5330,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. @@ -5102,7 +5340,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 = { @@ -5129,8 +5367,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; @@ -5191,7 +5430,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, }); @@ -5211,7 +5450,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 { @@ -5295,13 +5534,13 @@ 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 * @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, }); @@ -5311,7 +5550,7 @@ export class MatrixClient extends EventEmitter { ); } - private startCallEventHandler = () => { + private startCallEventHandler = (): void => { if (this.isInitialSyncComplete()) { this.callEventHandler.start(); this.off("sync", this.startCallEventHandler); @@ -5320,18 +5559,18 @@ 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"); } /** - * 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 + public getTurnServers(): ITurnServer[] { return this.turnServers || []; } @@ -5362,7 +5601,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, @@ -5433,14 +5672,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: '' }); } /** @@ -5449,7 +5686,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 }, @@ -5459,21 +5696,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; } @@ -5484,7 +5719,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]) => { @@ -5503,7 +5738,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'); } @@ -5522,7 +5757,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; } @@ -5722,14 +5957,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 { @@ -5744,7 +5979,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(); } @@ -5798,9 +6033,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://") || @@ -5811,8 +6046,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); @@ -5863,7 +6098,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 @@ -6108,9 +6343,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 = {}; @@ -6121,9 +6354,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); } /** @@ -6154,14 +6385,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 @@ -6181,9 +6411,7 @@ export class MatrixClient extends EventEmitter { } } - return this.http.authedRequest( - callback, "POST", "/createRoom", undefined, options, - ); + return this.http.authedRequest(callback, "POST", "/createRoom", undefined, options); } /** @@ -6228,7 +6456,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); } @@ -6242,7 +6470,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, @@ -6267,7 +6499,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; @@ -6312,7 +6544,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, @@ -6342,7 +6579,7 @@ export class MatrixClient extends EventEmitter { content: any, stateKey = "", callback?: Callback, - ): Promise { // TODO: Types + ): Promise { const pathParams = { $roomId: roomId, $eventType: eventType, @@ -6352,9 +6589,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); } /** @@ -6364,7 +6599,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; @@ -6408,12 +6643,10 @@ export class MatrixClient extends EventEmitter { const content = { "m.fully_read": rmEventId, "m.read": rrEventId, - "m.hidden": Boolean(opts ? opts.hidden : false), + "org.matrix.msc2285.hidden": Boolean(opts ? opts.hidden : false), }; - return this.http.authedRequest( - undefined, "POST", path, undefined, content, - ); + return this.http.authedRequest(undefined, "POST", path, undefined, content); } /** @@ -6432,7 +6665,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, }); @@ -6452,7 +6685,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 = {}; @@ -6470,9 +6703,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); } } @@ -6481,19 +6712,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); } /** @@ -6501,16 +6730,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); } /** @@ -6523,8 +6750,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 }); } /** @@ -6542,18 +6768,17 @@ 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 + // 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 }); return this.http.request(callback, "GET", path); @@ -6566,7 +6791,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, }); @@ -6583,17 +6808,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 }); } /** @@ -6632,7 +6851,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, }; @@ -6641,13 +6860,11 @@ 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); } /** - * 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, @@ -6689,7 +6906,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); } @@ -6698,7 +6915,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); } @@ -6722,7 +6939,12 @@ 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, + // eslint-disable-next-line camelcase + ): Promise<{ avatar_url?: string, displayname?: string }> { if (utils.isFunction(info)) { callback = info as any as Callback; // legacy info = undefined; @@ -6738,14 +6960,12 @@ 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: IThreepid[] }> { const path = "/account/3pid"; - return this.http.authedRequest( - callback, "GET", path, undefined, undefined, - ); + return this.http.authedRequest(callback, "GET", path, undefined, undefined); } /** @@ -6784,13 +7004,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 }); } /** @@ -6807,7 +7024,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; @@ -6827,18 +7044,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 }); } /** @@ -6849,13 +7067,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 }); } /** @@ -6883,10 +7101,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); } /** @@ -6895,13 +7111,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); } /** @@ -6912,7 +7126,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, }); @@ -6968,34 +7183,31 @@ 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); } /** * 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 { // TODO: Types + public setPusher(pusher: IPusherRequest, 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); } /** + * 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); }); @@ -7007,18 +7219,22 @@ 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: PushRuleKind, + ruleId: Exclude, + 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, $ruleId: ruleId, }); - return this.http.authedRequest( - callback, "PUT", path, undefined, body, - ); + return this.http.authedRequest(callback, "PUT", path, undefined, body); } /** @@ -7026,10 +7242,15 @@ 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: PushRuleKind, + ruleId: Exclude, + callback?: Callback, + ): Promise { // TODO: Types // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -7050,11 +7271,11 @@ 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 + ): Promise<{}> { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", { $kind: kind, $ruleId: ruleId, @@ -7076,11 +7297,11 @@ 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 + ): Promise<{}> { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", { $kind: kind, $ruleId: ruleId, @@ -7100,16 +7321,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); } /** @@ -7125,7 +7344,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); } @@ -7151,12 +7374,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 || {}; @@ -7186,7 +7407,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) { @@ -7218,7 +7443,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, @@ -7239,7 +7464,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}. * @@ -7253,7 +7478,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"; @@ -7362,7 +7587,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. * @@ -7375,7 +7600,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, @@ -7528,7 +7753,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 @@ -7613,7 +7838,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. * @@ -7668,15 +7893,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; }); @@ -7690,7 +7913,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, }); @@ -7706,7 +7932,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, }); @@ -7716,9 +7942,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( @@ -7731,9 +7955,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 }); } /** @@ -7744,7 +7966,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, @@ -7770,7 +7992,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/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/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 140c4cadb..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"; @@ -9,10 +25,10 @@ import { CrossSigningKeys, ICrossSigningKey, ICryptoCallbacks, - ISecretStorageKeyInfo, ISignedKey, KeySignatures, } from "../matrix"; +import { ISecretStorageKeyInfo } from "./api"; import { IKeyBackupInfo } from "./keybackup"; interface ICrossSigningKeys { @@ -109,8 +125,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); } /** @@ -246,7 +262,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 +275,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 +283,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 +300,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, @@ -293,6 +309,7 @@ class AccountDataClientAdapter extends EventEmitter { return Promise.resolve().then(() => { const event = new MatrixEvent({ type, content }); this.emit("accountData", event, lastEvent); + return {}; }); } } @@ -337,7 +354,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/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/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.js b/src/crypto/SecretStorage.ts similarity index 62% rename from src/crypto/SecretStorage.js rename to src/crypto/SecretStorage.ts index f57c61cb1..fb5665fa6 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,95 @@ 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, calculateKeyCheck } from './aes'; import { encodeBase64 } from "./olmlib"; +import { ICryptoCallbacks, MatrixClient, MatrixEvent } from '../matrix'; +import { IAddSecretStorageKeyOpts, ISecretStorageKeyInfo } 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"; +// 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; + promise: Promise; + cancel: (reason: string) => void; +} + +export interface IAccountDataClient extends EventEmitter { + // 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 { + name: string; + devices: string[]; + resolve: (reason: string) => void; + reject: (error: Error) => void; +} + +interface IDecryptors { + encrypt: (plaintext: string) => Promise; + decrypt: (ciphertext: 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 requests = new Map(); - async getDefaultKeyId() { - const defaultKey = await this._baseApis.getAccountDataFromServer( + // 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( + private readonly accountDataAdapter: IAccountDataClient, + private readonly cryptoCallbacks: ICryptoCallbacks, + private readonly baseApis?: MatrixClient, + ) {} + + 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) => { - const listener = (ev) => { + public setDefaultKeyId(keyId: string): Promise { + return new Promise((resolve, reject) => { + const listener = (ev: MatrixEvent): void => { 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 +119,14 @@ 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 { + const keyInfo = { algorithm } as ISecretStorageKeyInfo; - if (!opts) opts = {}; + if (!opts) opts = {} as IAddSecretStorageKeyOpts; if (opts.name) { keyInfo.name = opts.name; @@ -99,25 +137,25 @@ 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; } } 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 +172,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,9 +182,9 @@ export class SecretStorage extends EventEmitter { return null; } - const keyInfo = await this._baseApis.getAccountDataFromServer( + const keyInfo = await this.accountDataAdapter.getAccountDataFromServer( "m.secret_storage.key." + keyId, - ); + ) as ISecretStorageKeyInfo; return keyInfo ? [keyId, keyInfo] : null; } @@ -156,8 +195,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,10 +207,10 @@ 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); + 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 +221,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 * @@ -194,7 +229,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?: string[]): Promise { const encrypted = {}; if (!keys) { @@ -211,9 +246,9 @@ 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, - ); + ) as ISecretStorageKeyInfo; if (!keyInfo) { throw new Error("Unknown key: " + keyId); } @@ -221,7 +256,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 +266,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 +276,20 @@ export class SecretStorage extends EventEmitter { * * @return {string} the contents of the secret */ - async get(name) { - let secretInfo = await this._baseApis.getAccountDataFromServer(name); + public 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 +310,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 +335,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) { + public 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 +350,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 +371,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(); + public request(name: string, devices: string[]): 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) => { + + const cancel = (reason: string) => { // 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 +420,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 +443,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 +494,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 +522,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 +564,15 @@ 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 +588,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/aes.ts b/src/crypto/aes.ts index 1c370ecc4..736755b89 100644 --- a/src/crypto/aes.ts +++ b/src/crypto/aes.ts @@ -261,3 +261,16 @@ export function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: strin return subtleCrypto ? decryptBrowser(data, key, name) : decryptNode(data, key, name); } +// 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: Uint8Array, iv?: string): Promise { + return encryptAES(ZERO_STR, key, "", iv); +} 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/algorithms/megolm.ts b/src/crypto/algorithms/megolm.ts index e111703a8..2a1a2d8db 100644 --- a/src/crypto/algorithms/megolm.ts +++ b/src/crypto/algorithms/megolm.ts @@ -1670,7 +1670,7 @@ class MegolmDecryption extends DecryptionAlgorithm { */ public importRoomKey(session: IMegolmSessionData, opts: any = {}): Promise { const extraSessionData: any = {}; - if (opts.untrusted) { + if (opts.untrusted || session.untrusted) { extraSessionData.untrusted = true; } if (session["org.matrix.msc3061.shared_history"]) { diff --git a/src/crypto/api.ts b/src/crypto/api.ts index 8daafb6d7..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 "../matrix"; // TODO: Merge this with crypto.js once converted @@ -107,14 +106,32 @@ 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; } +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/backup.ts b/src/crypto/backup.ts index 533391831..82f90a6c7 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -29,7 +29,10 @@ import { keyFromPassphrase } from './key_passphrase'; import { sleep } from "../utils"; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { encodeRecoveryKey } from './recoverykey'; -import { IKeyBackupInfo } from "./keybackup"; +import { encryptAES, decryptAES, calculateKeyCheck } from './aes'; +import { getCrypto } from '../utils'; +import { ICurve25519AuthData, IAes256AuthData, IKeyBackupInfo, IKeyBackupSession } from "./keybackup"; +import { UnstableValue } from "../NamespacedValue"; const KEY_BACKUP_KEYS_PER_REQUEST = 200; @@ -75,16 +78,29 @@ interface BackupAlgorithmClass { prepare( key: string | Uint8Array | null, ): Promise<[Uint8Array, AuthData]>; + + checkBackupVersion(info: IKeyBackupInfo): void; } 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. */ @@ -102,6 +118,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 {IKeyBackupInfo} info the key backup info + */ + public static checkBackupVersion(info: IKeyBackupInfo): 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: IKeyBackupInfo, getKey: GetKey): Promise { const Algorithm = algorithmsByName[info.algorithm]; if (!Algorithm) { @@ -250,7 +284,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: [ @@ -271,7 +305,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"); @@ -280,7 +313,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; } @@ -441,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( @@ -464,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, @@ -472,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(); @@ -552,7 +582,7 @@ export class Curve25519 implements BackupAlgorithm { public static algorithmName = "m.megolm_backup.v1.curve25519-aes-sha2"; constructor( - public authData: AuthData, + public authData: ICurve25519AuthData, private publicKey: any, // FIXME: PkEncryption private getKey: () => Promise, ) {} @@ -561,12 +591,12 @@ export class Curve25519 implements BackupAlgorithm { 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( @@ -574,7 +604,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) { @@ -597,6 +627,14 @@ export class Curve25519 implements BackupAlgorithm { } } + public static checkBackupVersion(info: IKeyBackupInfo): void { + if (!("public_key" in info.auth_data)) { + throw new Error("Invalid backup data returned"); + } + } + + public get untrusted() { return true; } + public async encryptSession(data: Record): Promise { const plainText: Record = Object.assign({}, data); delete plainText.session_id; @@ -605,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 { @@ -654,8 +694,120 @@ export class Curve25519 implements BackupAlgorithm { } } +function randomBytes(size: number): Uint8Array { + const crypto: {randomBytes: (n: number) => Uint8Array} | undefined = getCrypto() as any; + if (crypto) { + // nodejs version + return crypto.randomBytes(size); + } + if (window?.crypto) { + // browser version + const buf = new Uint8Array(size); + window.crypto.getRandomValues(buf); + return buf; + } + 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 = UNSTABLE_MSC3270_NAME.name; + + constructor( + public readonly authData: IAes256AuthData, + private readonly key: Uint8Array, + ) {} + + public static async init( + authData: IAes256AuthData, + 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: Partial = {}; + 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 as AuthData]; + } + + public static checkBackupVersion(info: IKeyBackupInfo): void { + if (!("iv" in info.auth_data && "mac" in info.auth_data)) { + throw new Error("Invalid backup data returned"); + } + } + + public get untrusted() { return false; } + + 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(await decryptAES(sessionData.session_data, 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/dehydration.ts b/src/crypto/dehydration.ts index 95fb77752..80791b901 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 "./api"; // FIXME: these types should eventually go in a different file type Signatures = Record>; @@ -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 1af4cfcc3..761333f65 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -33,11 +33,18 @@ 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, + SecretStorageKeyTuple, + ISecretRequest, + SecretStorageKeyObject, +} from './SecretStorage'; +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"; @@ -45,8 +52,8 @@ 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 { DehydrationManager } from './dehydration'; +import { decryptAES, encryptAES, calculateKeyCheck } from './aes'; +import { DehydrationManager, IDeviceKeys, IOneTimeKey } from './dehydration'; import { BackupManager } from "./backup"; import { IStore } from "../store"; import { Room } from "../models/room"; @@ -54,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"; @@ -63,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 @@ -75,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); @@ -126,6 +136,7 @@ export interface IMegolmSessionData { session_id: string; session_key: string; algorithm: string; + untrusted?: boolean; } /* eslint-enable camelcase */ @@ -134,6 +145,10 @@ interface IDeviceVerificationUpgrade { crossSigningInfo: CrossSigningInfo; } +export interface ICheckOwnCrossSigningTrustOpts { + allowPrivateKeyRequests?: boolean; +} + /** * @typedef {Object} module:crypto~OlmSessionResult * @property {module:crypto/deviceinfo} device device info @@ -192,7 +207,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. @@ -359,7 +374,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. @@ -789,7 +805,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 calculateKeyCheck(privateKey); keyInfo.iv = iv; keyInfo.mac = mac; @@ -959,6 +975,20 @@ export class Crypto extends EventEmitter { 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(); @@ -970,15 +1000,19 @@ 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 { 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 +1024,14 @@ 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 { if (!devices) { devices = Object.keys(this.deviceList.getRawStoredDevicesForUser(this.userId)); } @@ -1009,7 +1046,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); } @@ -1388,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 @@ -1742,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, }); }); } @@ -1874,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; @@ -2222,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( @@ -2435,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 @@ -2492,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; @@ -2848,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 @@ -2996,9 +3033,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/crypto/key_passphrase.ts b/src/crypto/key_passphrase.ts index ca11e7d2f..474031160 100644 --- a/src/crypto/key_passphrase.ts +++ b/src/crypto/key_passphrase.ts @@ -22,8 +22,8 @@ const DEFAULT_BITSIZE = 256; /* eslint-disable camelcase */ interface IAuthData { - private_key_salt: string; - private_key_iterations: number; + private_key_salt?: string; + private_key_iterations?: number; private_key_bits?: number; } /* eslint-enable camelcase */ diff --git a/src/crypto/keybackup.ts b/src/crypto/keybackup.ts index 123f18f76..4d8981ff8 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 @@ -24,6 +24,7 @@ export interface IKeyBackupSession { ciphertext: string; ephemeral: string; mac: string; + iv: string; }; } @@ -32,15 +33,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; - }; + auth_data: ISigned & (ICurve25519AuthData | IAes256AuthData); count?: number; etag?: string; version?: string; // number contained within 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/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/filter.ts b/src/filter.ts index 859aeb0c7..8cbd2a67e 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; } @@ -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/http-api.js b/src/http-api.js index a48c165d0..92c6e420f 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, @@ -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; 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/interactive-auth.ts b/src/interactive-auth.ts index 3c8b0c168..4ad0f4dd0 100644 --- a/src/interactive-auth.ts +++ b/src/interactive-auth.ts @@ -264,9 +264,7 @@ export class InteractiveAuth { 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 = { @@ -294,7 +292,7 @@ export class InteractiveAuth { /** * get the client secret used for validation sessions - * with the ID server. + * with the identity server. * * @return {string} client secret */ diff --git a/src/matrix.ts b/src/matrix.ts index 2cce6867a..78906a716 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/api"; 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. 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/event-timeline.ts b/src/models/event-timeline.ts index 92a9b9633..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", @@ -49,15 +50,16 @@ export class EventTimeline { * @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false */ static setEventMetadata(event: MatrixEvent, stateContext: RoomState, toStartOfTimeline: boolean): void { - // 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() === EventType.RoomMember) { + 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 @@ -345,15 +347,16 @@ export class EventTimeline { */ public addEvent(event: MatrixEvent, atStart: boolean): void { 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 diff --git a/src/models/event.ts b/src/models/event.ts index 9650f9026..2c5655717 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -263,6 +263,16 @@ export class MatrixEvent extends EventEmitter { this.localTimestamp = Date.now() - this.getAge(); } + /** + * 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 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; + } + /** * Get the event_id for this event. * @return {string} The event ID, e.g. $143350589368169JsLZx:localhost @@ -1231,20 +1241,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(), - }; - - // if this is a redaction then attach the redacts key - if (this.isRedaction()) { - event.redacts = this.event.redacts; - } + const event = this.getEffectiveEvent(); if (!this.isEncrypted()) { return event; diff --git a/src/models/room.ts b/src/models/room.ts index 9970ae595..1f36eaf9d 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -25,13 +25,13 @@ 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'; import { ReEmitter } from '../ReEmitter'; -import { EventType, RoomCreateTypeField, RoomType } from "../@types/event"; -import { IRoomVersionsCapability, MatrixClient, RoomVersionStability } from "../client"; +import { EventType, RoomCreateTypeField, RoomType, UNSTABLE_ELEMENT_FUNCTIONAL_USERS } from "../@types/event"; +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 " + @@ -649,7 +649,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", @@ -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(); @@ -713,7 +712,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; @@ -2037,24 +2036,45 @@ 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(UNSTABLE_ELEMENT_FUNCTIONAL_USERS.name, ""); + if (Array.isArray(mFunctionalMembers?.getContent().service_members)) { + excludedUserIds = mFunctionalMembers.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)); + 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); @@ -2065,7 +2085,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 = diff --git a/src/models/search-result.ts b/src/models/search-result.ts index 7d3cc81c0..486e30abf 100644 --- a/src/models/search-result.ts +++ b/src/models/search-result.ts @@ -20,27 +20,9 @@ limitations under the License. import { EventContext } from "./event-context"; import { EventMapper } from "../event-mapper"; +import { IResultContext, ISearchResult } from "../@types/search"; import { IRoomEvent } from "../sync-accumulator"; -/* eslint-disable camelcase */ -interface IContext { - events_before?: IRoomEvent[]; - events_after?: IRoomEvent[]; - start?: string; - end?: string; - profile_info?: Record; -} -/* eslint-enable camelcase */ - -interface ISearchResult { - rank: number; - result: IRoomEvent; - context: IContext; -} - export class SearchResult { /** * Create a SearchResponse from the response to /search @@ -49,8 +31,9 @@ export class SearchResult { * @param {function} eventMapper * @return {SearchResult} */ + public static fromJson(jsonObj: ISearchResult, eventMapper: EventMapper): SearchResult { - const jsonContext: IContext = jsonObj.context || {}; + const jsonContext = jsonObj.context || {} as IResultContext; const eventsBefore = jsonContext.events_before || []; const eventsAfter = jsonContext.events_after || []; 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/service-types.ts b/src/service-types.ts index 79dc99937..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 - IM = 'SERVICE_TYPE_IM', // An Integration Manager + IS = 'SERVICE_TYPE_IS', // An identity server + IM = 'SERVICE_TYPE_IM', // An integration manager } diff --git a/src/store/index.ts b/src/store/index.ts index 80cdc8a1a..7e52d014e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -18,10 +18,11 @@ 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"; +import { IMinimalEvent, IGroups, IRooms, ISyncResponse } 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; @@ -182,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. @@ -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: IEvent[]): Promise; clearOutOfBandMembers(roomId: string): Promise; - getClientOptions(): Promise; + getClientOptions(): Promise; - storeClientOptions(options: object): Promise; + storeClientOptions(options: IStartClientOpts): Promise; } diff --git a/src/store/indexeddb-backend.ts b/src/store/indexeddb-backend.ts new file mode 100644 index 000000000..4fe309f13 --- /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(): Promise; + 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]; 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..9a7e803bb 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,8 @@ LocalIndexedDBStoreBackend.prototype = { * client state to where it was at the last save, or null if there * is no saved sync data. */ - getSavedSync: function(copy) { - if (copy === undefined) copy = true; - - const data = this._syncAccumulator.getJSON(); + public getSavedSync(copy = true): Promise { + 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 +387,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 +416,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 +441,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 +460,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 +470,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 +480,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 +539,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 +549,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..14ddee82d --- /dev/null +++ b/src/store/indexeddb-remote-backend.ts @@ -0,0 +1,192 @@ +/* +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 {Function} workerFactory Factory which produces a Worker + * @param {string=} dbName Optional database name. The same name must be used + * to open the same database. + */ + constructor( + private readonly workerFactory: () => Worker, + private readonly dbName: string, + ) {} + + /** + * 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 = this.workerFactory(); + 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 f7f9fb8b9..f41a898c6 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 { MatrixEvent } from "../models/event"; +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. @@ -41,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 { @@ -50,8 +51,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; @@ -110,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); } @@ -222,7 +214,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 +228,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"); @@ -247,7 +239,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 +251,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 452eb0c9a..656bd1808 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 { ISyncResponse } from "../sync-accumulator"; function isValidFilterId(filterId: string): boolean { const isValidStr = typeof filterId === "string" && @@ -59,9 +60,9 @@ 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 oobMembers: Record = {}; // roomId: [member events] private clientOptions = {}; constructor(opts: IOpts = {}) { @@ -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(); } @@ -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 1a136d1d1..c2b4ea933 100644 --- a/src/store/stub.ts +++ b/src/store/stub.ts @@ -23,19 +23,21 @@ 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"; +import { ISyncResponse } from "../sync-accumulator"; /** * Construct a stub store. This does no-ops on most store methods. * @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); } @@ -212,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(); } @@ -264,11 +266,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(); } 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/sync.ts b/src/sync.ts index 8049d03f6..c2534387f 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -136,7 +136,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 @@ -319,7 +319,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 || []; @@ -330,8 +330,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( @@ -644,12 +643,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 @@ -755,7 +754,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) { @@ -852,7 +851,7 @@ export class SyncApi { } // Begin next sync - this._sync(syncOptions); + this.doSync(syncOptions); } private doSyncRequest(syncOptions: ISyncOptions, syncToken: string): IRequestPromise { @@ -957,7 +956,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 003aa6986..e5734bd0c 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; } /** @@ -116,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]); } } } @@ -464,7 +477,7 @@ export async function promiseMapSeries( } } -export function promiseTry(fn: () => T): Promise { +export function promiseTry(fn: () => T | Promise): Promise { return new Promise((resolve) => resolve(fn())); } @@ -670,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); +} 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 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()) { diff --git a/yarn.lock b/yarn.lock index 076bd2252..563a8e3ba 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: @@ -2857,23 +2984,15 @@ 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/e8197938dca66849ffdac4baca7c05275df12835" + 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" 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==