1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-10 21:23:02 +03:00

Merge remote-tracking branch 'origin/develop' into dbkr/gcmerge_20221104

This commit is contained in:
David Baker
2022-11-04 14:05:48 +00:00
32 changed files with 584 additions and 247 deletions

View File

@@ -5,6 +5,11 @@ on:
secrets: secrets:
SONAR_TOKEN: SONAR_TOKEN:
required: true required: true
inputs:
extra_args:
type: string
required: false
description: "Extra args to pass to SonarCloud"
jobs: jobs:
sonarqube: sonarqube:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -22,7 +27,7 @@ jobs:
- name: "🩻 SonarCloud Scan" - name: "🩻 SonarCloud Scan"
id: sonarcloud id: sonarcloud
uses: matrix-org/sonarcloud-workflow-action@v2.2 uses: matrix-org/sonarcloud-workflow-action@v2.3
with: with:
repository: ${{ github.event.workflow_run.head_repository.full_name }} repository: ${{ github.event.workflow_run.head_repository.full_name }}
is_pr: ${{ github.event.workflow_run.event == 'pull_request' }} is_pr: ${{ github.event.workflow_run.event == 'pull_request' }}
@@ -33,8 +38,8 @@ jobs:
coverage_run_id: ${{ github.event.workflow_run.id }} coverage_run_id: ${{ github.event.workflow_run.id }}
coverage_workflow_name: tests.yml coverage_workflow_name: tests.yml
coverage_extract_path: coverage coverage_extract_path: coverage
extra_args: ${{ inputs.extra_args }}
- uses: Sibz/github-status-action@v1 - uses: Sibz/github-status-action@v1
if: always() if: always()
with: with:

View File

@@ -8,8 +8,36 @@ concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }} group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
# This is a workaround for https://github.com/SonarSource/SonarJS/issues/578
prepare:
name: Prepare
runs-on: ubuntu-latest
outputs:
reportPaths: ${{ steps.extra_args.outputs.reportPaths }}
testExecutionReportPaths: ${{ steps.extra_args.outputs.testExecutionReportPaths }}
steps:
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
- name: 📥 Download artifact
uses: dawidd6/action-download-artifact@v2
with:
workflow: tests.yaml
run_id: ${{ github.event.workflow_run.id }}
name: coverage
path: coverage
- id: extra_args
run: |
coverage=$(find coverage -type f -name '*lcov.info' | tr '\n' ',' | sed 's/,$//g')
echo "reportPaths=$coverage" >> $GITHUB_OUTPUT
reports=$(find coverage -type f -name 'jest-sonar-report*.xml' | tr '\n' ',' | sed 's/,$//g')
echo "testExecutionReportPaths=$reports" >> $GITHUB_OUTPUT
sonarqube: sonarqube:
name: 🩻 SonarQube name: 🩻 SonarQube
needs: prepare
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
secrets: secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
extra_args: -Dsonar.javascript.lcov.reportPaths=${{ needs.prepare.outputs.reportPaths }} -Dsonar.testExecutionReportPaths=${{ needs.prepare.outputs.testExecutionReportPaths }}

View File

@@ -64,38 +64,3 @@ jobs:
- name: Generate Docs - name: Generate Docs
run: "yarn run gendoc" run: "yarn run gendoc"
tsc-strict:
name: Typescript Strict Error Checker
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
pull-requests: read
checks: write
steps:
- uses: actions/checkout@v3
- name: Get diff lines
id: diff
uses: Equip-Collaboration/diff-line-numbers@v1.0.0
with:
include: '["\\.tsx?$"]'
- name: Detecting files changed
id: files
uses: futuratrepadeira/changed-files@v4.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pattern: '^.*\.tsx?$'
- uses: t3chguy/typescript-check-action@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
use-check: false
check-fail-mode: added
output-behaviour: annotate
ts-extra-args: '--strict'
files-changed: ${{ steps.files.outputs.files_updated }}
files-added: ${{ steps.files.outputs.files_created }}
files-deleted: ${{ steps.files.outputs.files_deleted }}
line-numbers: ${{ steps.diff.outputs.lineNumbers }}

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
/.jsdocbuild /.jsdocbuild
/.jsdoc /.jsdoc
.DS_Store
node_modules node_modules
/.npmrc /.npmrc

View File

@@ -7,6 +7,7 @@
}, },
"scripts": { "scripts": {
"prepublishOnly": "yarn build", "prepublishOnly": "yarn build",
"postinstall": "patch-package",
"start": "echo THIS IS FOR LEGACY PURPOSES ONLY. && babel src -w -s -d lib --verbose --extensions \".ts,.js\"", "start": "echo THIS IS FOR LEGACY PURPOSES ONLY. && babel src -w -s -d lib --verbose --extensions \".ts,.js\"",
"dist": "echo 'This is for the release script so it can make assets (browser bundle).' && yarn build", "dist": "echo 'This is for the release script so it can make assets (browser bundle).' && yarn build",
"clean": "rimraf lib dist", "clean": "rimraf lib dist",
@@ -59,7 +60,7 @@
"bs58": "^5.0.0", "bs58": "^5.0.0",
"content-type": "^1.0.4", "content-type": "^1.0.4",
"loglevel": "^1.7.1", "loglevel": "^1.7.1",
"matrix-events-sdk": "^0.0.1-beta.7", "matrix-events-sdk": "0.0.1-beta.7",
"matrix-widget-api": "^1.0.0", "matrix-widget-api": "^1.0.0",
"p-retry": "4", "p-retry": "4",
"qs": "^6.9.6", "qs": "^6.9.6",
@@ -79,6 +80,7 @@
"@babel/preset-env": "^7.12.11", "@babel/preset-env": "^7.12.11",
"@babel/preset-typescript": "^7.12.7", "@babel/preset-typescript": "^7.12.7",
"@babel/register": "^7.12.10", "@babel/register": "^7.12.10",
"@casualbot/jest-sonar-reporter": "^2.2.5",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.13.tgz", "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.13.tgz",
"@types/bs58": "^4.0.1", "@types/bs58": "^4.0.1",
"@types/content-type": "^1.1.5", "@types/content-type": "^1.1.5",
@@ -106,9 +108,10 @@
"jest-environment-jsdom": "^28.1.3", "jest-environment-jsdom": "^28.1.3",
"jest-localstorage-mock": "^2.4.6", "jest-localstorage-mock": "^2.4.6",
"jest-mock": "^29.0.0", "jest-mock": "^29.0.0",
"jest-sonar-reporter": "^2.0.0",
"jsdoc": "^3.6.6", "jsdoc": "^3.6.6",
"matrix-mock-request": "^2.5.0", "matrix-mock-request": "^2.5.0",
"patch-package": "^6.5.0",
"postinstall-postinstall": "^2.1.0",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"terser": "^5.5.1", "terser": "^5.5.1",
"tsify": "^5.0.2", "tsify": "^5.0.2",
@@ -129,10 +132,11 @@
"text-summary", "text-summary",
"lcov" "lcov"
], ],
"testResultsProcessor": "jest-sonar-reporter" "testResultsProcessor": "@casualbot/jest-sonar-reporter"
}, },
"jestSonar": { "@casualbot/jest-sonar-reporter": {
"reportPath": "coverage", "outputDirectory": "coverage",
"sonar56x": true "outputName": "jest-sonar-report.xml",
"relativePaths": true
} }
} }

View File

@@ -0,0 +1,12 @@
diff --git a/node_modules/matrix-events-sdk/lib/NamespacedMap.d.ts b/node_modules/matrix-events-sdk/lib/NamespacedMap.d.ts
index c141b11..461f528 100644
--- a/node_modules/matrix-events-sdk/lib/NamespacedMap.d.ts
+++ b/node_modules/matrix-events-sdk/lib/NamespacedMap.d.ts
@@ -1,6 +1,6 @@
import { NamespacedValue } from "./NamespacedValue";
import { Optional } from "./types";
-declare type NS = NamespacedValue<Optional<string>, Optional<string>>;
+declare type NS = NamespacedValue<string, string>;
/**
* A `Map` implementation which accepts a NamespacedValue as a key, and arbitrary value. The
* namespaced value must be a string type.

View File

@@ -11,6 +11,6 @@ sonar.exclusions=docs,examples,git-hooks
sonar.typescript.tsconfigPath=./tsconfig.json sonar.typescript.tsconfigPath=./tsconfig.json
sonar.javascript.lcov.reportPaths=coverage/lcov.info sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.coverage.exclusions=spec/**/* sonar.coverage.exclusions=spec/**/*
sonar.testExecutionReportPaths=coverage/test-report.xml sonar.testExecutionReportPaths=coverage/jest-sonar-report.xml
sonar.lang.patterns.ts=**/*.ts,**/*.tsx sonar.lang.patterns.ts=**/*.ts,**/*.tsx

View File

@@ -707,15 +707,11 @@ describe("MatrixClient syncing", () => {
awaitSyncEvent(2), awaitSyncEvent(2),
]).then(() => { ]).then(() => {
const room = client!.getRoom(roomOne)!; const room = client!.getRoom(roomOne)!;
const stateAtStart = room.getLiveTimeline().getState( const stateAtStart = room.getLiveTimeline().getState(EventTimeline.BACKWARDS)!;
EventTimeline.BACKWARDS,
);
const startRoomNameEvent = stateAtStart.getStateEvents('m.room.name', ''); const startRoomNameEvent = stateAtStart.getStateEvents('m.room.name', '');
expect(startRoomNameEvent.getContent().name).toEqual('Old room name'); expect(startRoomNameEvent.getContent().name).toEqual('Old room name');
const stateAtEnd = room.getLiveTimeline().getState( const stateAtEnd = room.getLiveTimeline().getState(EventTimeline.FORWARDS)!;
EventTimeline.FORWARDS,
);
const endRoomNameEvent = stateAtEnd.getStateEvents('m.room.name', ''); const endRoomNameEvent = stateAtEnd.getStateEvents('m.room.name', '');
expect(endRoomNameEvent.getContent().name).toEqual('A new room name'); expect(endRoomNameEvent.getContent().name).toEqual('A new room name');
}); });

View File

@@ -0,0 +1,143 @@
/*
Copyright 2022 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 '../../olm-loader';
import { TestClient } from '../../TestClient';
import { logger } from '../../../src/logger';
import { DEHYDRATION_ALGORITHM } from '../../../src/crypto/dehydration';
const Olm = global.Olm;
describe("Dehydration", () => {
if (!global.Olm) {
logger.warn('Not running dehydration unit tests: libolm not present');
return;
}
beforeAll(function() {
return global.Olm.init();
});
it("should rehydrate a dehydrated device", async () => {
const key = new Uint8Array([1, 2, 3]);
const alice = new TestClient(
"@alice:example.com", "Osborne2", undefined, undefined,
{
cryptoCallbacks: {
getDehydrationKey: async t => key,
},
},
);
const dehydratedDevice = new Olm.Account();
dehydratedDevice.create();
alice.httpBackend.when("GET", "/dehydrated_device").respond(200, {
device_id: "ABCDEFG",
device_data: {
algorithm: DEHYDRATION_ALGORITHM,
account: dehydratedDevice.pickle(new Uint8Array(key)),
},
});
alice.httpBackend.when("POST", "/dehydrated_device/claim").respond(200, {
success: true,
});
expect((await Promise.all([
alice.client.rehydrateDevice(),
alice.httpBackend.flushAllExpected(),
]))[0])
.toEqual("ABCDEFG");
expect(alice.client.getDeviceId()).toEqual("ABCDEFG");
});
it("should dehydrate a device", async () => {
const key = new Uint8Array([1, 2, 3]);
const alice = new TestClient(
"@alice:example.com", "Osborne2", undefined, undefined,
{
cryptoCallbacks: {
getDehydrationKey: async t => key,
},
},
);
await alice.client.initCrypto();
alice.httpBackend.when("GET", "/room_keys/version").respond(404, {
errcode: "M_NOT_FOUND",
});
let pickledAccount = "";
alice.httpBackend.when("PUT", "/dehydrated_device")
.check((req) => {
expect(req.data.device_data).toMatchObject({
algorithm: DEHYDRATION_ALGORITHM,
account: expect.any(String),
});
pickledAccount = req.data.device_data.account;
})
.respond(200, {
device_id: "ABCDEFG",
});
alice.httpBackend.when("POST", "/keys/upload/ABCDEFG")
.check((req) => {
expect(req.data).toMatchObject({
"device_keys": expect.objectContaining({
algorithms: expect.any(Array),
device_id: "ABCDEFG",
user_id: "@alice:example.com",
keys: expect.objectContaining({
"ed25519:ABCDEFG": expect.any(String),
"curve25519:ABCDEFG": expect.any(String),
}),
signatures: expect.objectContaining({
"@alice:example.com": expect.objectContaining({
"ed25519:ABCDEFG": expect.any(String),
}),
}),
}),
"one_time_keys": expect.any(Object),
"org.matrix.msc2732.fallback_keys": expect.any(Object),
});
})
.respond(200, {});
try {
const deviceId =
(await Promise.all([
alice.client.createDehydratedDevice(new Uint8Array(key), {}),
alice.httpBackend.flushAllExpected(),
]))[0];
expect(deviceId).toEqual("ABCDEFG");
expect(deviceId).not.toEqual("");
// try to rehydrate the dehydrated device
const rehydrated = new Olm.Account();
try {
rehydrated.unpickle(new Uint8Array(key), pickledAccount);
} finally {
rehydrated.free();
}
} finally {
alice.client?.crypto?.dehydrationManager?.stop();
alice.client?.crypto?.deviceList.stop();
}
});
});

View File

@@ -55,13 +55,13 @@ describe("EventTimeline", function() {
]; ];
timeline.initialiseState(events); timeline.initialiseState(events);
// @ts-ignore private prop // @ts-ignore private prop
const timelineStartState = timeline.startState; const timelineStartState = timeline.startState!;
expect(mocked(timelineStartState).setStateEvents).toHaveBeenCalledWith( expect(mocked(timelineStartState).setStateEvents).toHaveBeenCalledWith(
events, events,
{ timelineWasEmpty: undefined }, { timelineWasEmpty: undefined },
); );
// @ts-ignore private prop // @ts-ignore private prop
const timelineEndState = timeline.endState; const timelineEndState = timeline.endState!;
expect(mocked(timelineEndState).setStateEvents).toHaveBeenCalledWith( expect(mocked(timelineEndState).setStateEvents).toHaveBeenCalledWith(
events, events,
{ timelineWasEmpty: undefined }, { timelineWasEmpty: undefined },
@@ -185,14 +185,14 @@ describe("EventTimeline", function() {
sentinel.name = "Old Alice"; sentinel.name = "Old Alice";
sentinel.membership = "join"; sentinel.membership = "join";
mocked(timeline.getState(EventTimeline.FORWARDS)).getSentinelMember mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember
.mockImplementation(function(uid) { .mockImplementation(function(uid) {
if (uid === userA) { if (uid === userA) {
return sentinel; return sentinel;
} }
return null; return null;
}); });
mocked(timeline.getState(EventTimeline.BACKWARDS)).getSentinelMember mocked(timeline.getState(EventTimeline.BACKWARDS)!).getSentinelMember
.mockImplementation(function(uid) { .mockImplementation(function(uid) {
if (uid === userA) { if (uid === userA) {
return oldSentinel; return oldSentinel;
@@ -225,14 +225,14 @@ describe("EventTimeline", function() {
sentinel.name = "Old Alice"; sentinel.name = "Old Alice";
sentinel.membership = "join"; sentinel.membership = "join";
mocked(timeline.getState(EventTimeline.FORWARDS)).getSentinelMember mocked(timeline.getState(EventTimeline.FORWARDS)!).getSentinelMember
.mockImplementation(function(uid) { .mockImplementation(function(uid) {
if (uid === userA) { if (uid === userA) {
return sentinel; return sentinel;
} }
return null; return null;
}); });
mocked(timeline.getState(EventTimeline.BACKWARDS)).getSentinelMember mocked(timeline.getState(EventTimeline.BACKWARDS)!).getSentinelMember
.mockImplementation(function(uid) { .mockImplementation(function(uid) {
if (uid === userA) { if (uid === userA) {
return oldSentinel; return oldSentinel;
@@ -269,15 +269,15 @@ describe("EventTimeline", function() {
timeline.addEvent(events[0], { toStartOfTimeline: false }); timeline.addEvent(events[0], { toStartOfTimeline: false });
timeline.addEvent(events[1], { toStartOfTimeline: false }); timeline.addEvent(events[1], { toStartOfTimeline: false });
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents). expect(timeline.getState(EventTimeline.FORWARDS)!.setStateEvents).
toHaveBeenCalledWith([events[0]], { timelineWasEmpty: undefined }); toHaveBeenCalledWith([events[0]], { timelineWasEmpty: undefined });
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents). expect(timeline.getState(EventTimeline.FORWARDS)!.setStateEvents).
toHaveBeenCalledWith([events[1]], { timelineWasEmpty: undefined }); toHaveBeenCalledWith([events[1]], { timelineWasEmpty: undefined });
expect(events[0].forwardLooking).toBe(true); expect(events[0].forwardLooking).toBe(true);
expect(events[1].forwardLooking).toBe(true); expect(events[1].forwardLooking).toBe(true);
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents). expect(timeline.getState(EventTimeline.BACKWARDS)!.setStateEvents).
not.toHaveBeenCalled(); not.toHaveBeenCalled();
}); });
@@ -298,15 +298,15 @@ describe("EventTimeline", function() {
timeline.addEvent(events[0], { toStartOfTimeline: true }); timeline.addEvent(events[0], { toStartOfTimeline: true });
timeline.addEvent(events[1], { toStartOfTimeline: true }); timeline.addEvent(events[1], { toStartOfTimeline: true });
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents). expect(timeline.getState(EventTimeline.BACKWARDS)!.setStateEvents).
toHaveBeenCalledWith([events[0]], { timelineWasEmpty: undefined }); toHaveBeenCalledWith([events[0]], { timelineWasEmpty: undefined });
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents). expect(timeline.getState(EventTimeline.BACKWARDS)!.setStateEvents).
toHaveBeenCalledWith([events[1]], { timelineWasEmpty: undefined }); toHaveBeenCalledWith([events[1]], { timelineWasEmpty: undefined });
expect(events[0].forwardLooking).toBe(false); expect(events[0].forwardLooking).toBe(false);
expect(events[1].forwardLooking).toBe(false); expect(events[1].forwardLooking).toBe(false);
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents). expect(timeline.getState(EventTimeline.FORWARDS)!.setStateEvents).
not.toHaveBeenCalled(); not.toHaveBeenCalled();
}); });

View File

@@ -23,6 +23,7 @@ import { ToDeviceBatch } from '../../src/models/ToDeviceMessage';
import { logger } from '../../src/logger'; import { logger } from '../../src/logger';
import { IStore } from '../../src/store'; import { IStore } from '../../src/store';
import { flushPromises } from '../test-utils/flushPromises'; import { flushPromises } from '../test-utils/flushPromises';
import { removeElement } from "../../src/utils";
const FAKE_USER = "@alice:example.org"; const FAKE_USER = "@alice:example.org";
const FAKE_DEVICE_ID = "AAAAAAAA"; const FAKE_DEVICE_ID = "AAAAAAAA";
@@ -63,6 +64,8 @@ describe.each([
let client: MatrixClient; let client: MatrixClient;
beforeEach(async function() { beforeEach(async function() {
jest.runOnlyPendingTimers();
jest.useRealTimers();
httpBackend = new MockHttpBackend(); httpBackend = new MockHttpBackend();
let store: IStore; let store: IStore;
@@ -288,7 +291,7 @@ describe.each([
], ],
}); });
expect(await httpBackend.flush(undefined, 1, 1)).toEqual(1); expect(await httpBackend.flush(undefined, 1, 20)).toEqual(1);
await flushPromises(); await flushPromises();
const dummyEvent = new MatrixEvent({ const dummyEvent = new MatrixEvent({
@@ -316,12 +319,12 @@ describe.each([
}); });
} }
const expectedCounts = [20, 1];
httpBackend.when( httpBackend.when(
"PUT", "/sendToDevice/org.example.foo/", "PUT", "/sendToDevice/org.example.foo/",
).check((request) => { ).check((request) => {
expect(Object.keys(request.data.messages).length).toEqual(20); expect(removeElement(expectedCounts, c => c === Object.keys(request.data.messages).length)).toBeTruthy();
}).respond(200, {}); }).respond(200, {});
httpBackend.when( httpBackend.when(
"PUT", "/sendToDevice/org.example.foo/", "PUT", "/sendToDevice/org.example.foo/",
).check((request) => { ).check((request) => {

View File

@@ -768,6 +768,19 @@ describe('Call', function() {
}); });
}); });
describe("transferToCall", () => {
it("should send the required events", async () => {
const targetCall = new MatrixCall({ client: client.client, roomId: "!roomId:server" });
const sendEvent = jest.spyOn(client.client, "sendEvent");
await call.transferToCall(targetCall);
const newCallId = (sendEvent.mock.calls[0][2] as any)!.await_call;
expect(sendEvent).toHaveBeenCalledWith(call.roomId, EventType.CallReplaces, expect.objectContaining({
create_call: newCallId,
}));
});
});
describe("muting", () => { describe("muting", () => {
let mockSendVoipEvent: jest.Mock<Promise<void>, [string, object]>; let mockSendVoipEvent: jest.Mock<Promise<void>, [string, object]>;
beforeEach(async () => { beforeEach(async () => {

View File

@@ -30,7 +30,7 @@ export enum TweakName {
export type Tweak<N extends TweakName, V> = { export type Tweak<N extends TweakName, V> = {
set_tweak: N; set_tweak: N;
value: V; value?: V;
}; };
export type TweakHighlight = Tweak<TweakName.Highlight, boolean>; export type TweakHighlight = Tweak<TweakName.Highlight, boolean>;
@@ -76,7 +76,8 @@ export interface IPushRuleCondition<N extends ConditionKind | string> {
export interface IEventMatchCondition extends IPushRuleCondition<ConditionKind.EventMatch> { export interface IEventMatchCondition extends IPushRuleCondition<ConditionKind.EventMatch> {
key: string; key: string;
pattern: string; pattern?: string;
value?: string;
} }
export interface IContainsDisplayNameCondition extends IPushRuleCondition<ConditionKind.ContainsDisplayName> { export interface IContainsDisplayNameCondition extends IPushRuleCondition<ConditionKind.ContainsDisplayName> {

View File

@@ -32,6 +32,28 @@ export enum AutoDiscoveryAction {
FAIL_ERROR = "FAIL_ERROR", FAIL_ERROR = "FAIL_ERROR",
} }
enum AutoDiscoveryError {
Invalid = "Invalid homeserver discovery response",
GenericFailure = "Failed to get autodiscovery configuration from server",
InvalidHsBaseUrl = "Invalid base_url for m.homeserver",
InvalidHomeserver = "Homeserver URL does not appear to be a valid Matrix homeserver",
InvalidIsBaseUrl = "Invalid base_url for m.identity_server",
InvalidIdentityServer = "Identity server URL does not appear to be a valid identity server",
InvalidIs = "Invalid identity server discovery response",
MissingWellknown = "No .well-known JSON file found",
InvalidJson = "Invalid JSON",
}
interface WellKnownConfig extends Omit<IWellKnownConfig, "error"> {
state: AutoDiscoveryAction;
error?: IWellKnownConfig["error"] | null;
}
interface ClientConfig {
"m.homeserver": WellKnownConfig;
"m.identity_server": WellKnownConfig;
}
/** /**
* Utilities for automatically discovery resources, such as homeservers * Utilities for automatically discovery resources, such as homeservers
* for users to log in to. * for users to log in to.
@@ -42,36 +64,25 @@ export class AutoDiscovery {
// translate the meaning of the states in the spec, but also // translate the meaning of the states in the spec, but also
// support our own if needed. // support our own if needed.
public static readonly ERROR_INVALID = "Invalid homeserver discovery response"; public static readonly ERROR_INVALID = AutoDiscoveryError.Invalid;
public static readonly ERROR_GENERIC_FAILURE = "Failed to get autodiscovery configuration from server"; public static readonly ERROR_GENERIC_FAILURE = AutoDiscoveryError.GenericFailure;
public static readonly ERROR_INVALID_HS_BASE_URL = "Invalid base_url for m.homeserver"; public static readonly ERROR_INVALID_HS_BASE_URL = AutoDiscoveryError.InvalidHsBaseUrl;
public static readonly ERROR_INVALID_HOMESERVER = "Homeserver URL does not appear to be a valid Matrix homeserver"; public static readonly ERROR_INVALID_HOMESERVER = AutoDiscoveryError.InvalidHomeserver;
public static readonly ERROR_INVALID_IS_BASE_URL = "Invalid base_url for m.identity_server"; public static readonly ERROR_INVALID_IS_BASE_URL = AutoDiscoveryError.InvalidIsBaseUrl;
// eslint-disable-next-line public static readonly ERROR_INVALID_IDENTITY_SERVER = AutoDiscoveryError.InvalidIdentityServer;
public static readonly ERROR_INVALID_IDENTITY_SERVER = "Identity server URL does not appear to be a valid identity server";
public static readonly ERROR_INVALID_IS = "Invalid identity server discovery response"; public static readonly ERROR_INVALID_IS = AutoDiscoveryError.InvalidIs;
public static readonly ERROR_MISSING_WELLKNOWN = "No .well-known JSON file found"; public static readonly ERROR_MISSING_WELLKNOWN = AutoDiscoveryError.MissingWellknown;
public static readonly ERROR_INVALID_JSON = "Invalid JSON"; public static readonly ERROR_INVALID_JSON = AutoDiscoveryError.InvalidJson;
public static readonly ALL_ERRORS = [ public static readonly ALL_ERRORS = Object.keys(AutoDiscoveryError);
AutoDiscovery.ERROR_INVALID,
AutoDiscovery.ERROR_GENERIC_FAILURE,
AutoDiscovery.ERROR_INVALID_HS_BASE_URL,
AutoDiscovery.ERROR_INVALID_HOMESERVER,
AutoDiscovery.ERROR_INVALID_IS_BASE_URL,
AutoDiscovery.ERROR_INVALID_IDENTITY_SERVER,
AutoDiscovery.ERROR_INVALID_IS,
AutoDiscovery.ERROR_MISSING_WELLKNOWN,
AutoDiscovery.ERROR_INVALID_JSON,
];
/** /**
* The auto discovery failed. The client is expected to communicate * The auto discovery failed. The client is expected to communicate
@@ -120,13 +131,13 @@ export class AutoDiscovery {
* configuration, which may include error states. Rejects on unexpected * configuration, which may include error states. Rejects on unexpected
* failure, not when verification fails. * failure, not when verification fails.
*/ */
public static async fromDiscoveryConfig(wellknown: any): Promise<IClientWellKnown> { public static async fromDiscoveryConfig(wellknown: any): Promise<ClientConfig> {
// Step 1 is to get the config, which is provided to us here. // Step 1 is to get the config, which is provided to us here.
// We default to an error state to make the first few checks easier to // We default to an error state to make the first few checks easier to
// write. We'll update the properties of this object over the duration // write. We'll update the properties of this object over the duration
// of this function. // of this function.
const clientConfig = { const clientConfig: ClientConfig = {
"m.homeserver": { "m.homeserver": {
state: AutoDiscovery.FAIL_ERROR, state: AutoDiscovery.FAIL_ERROR,
error: AutoDiscovery.ERROR_INVALID, error: AutoDiscovery.ERROR_INVALID,
@@ -197,7 +208,7 @@ export class AutoDiscovery {
if (wellknown["m.identity_server"]) { if (wellknown["m.identity_server"]) {
// We prepare a failing identity server response to save lines later // We prepare a failing identity server response to save lines later
// in this branch. // in this branch.
const failingClientConfig = { const failingClientConfig: ClientConfig = {
"m.homeserver": clientConfig["m.homeserver"], "m.homeserver": clientConfig["m.homeserver"],
"m.identity_server": { "m.identity_server": {
state: AutoDiscovery.FAIL_PROMPT, state: AutoDiscovery.FAIL_PROMPT,
@@ -279,7 +290,7 @@ export class AutoDiscovery {
* configuration, which may include error states. Rejects on unexpected * configuration, which may include error states. Rejects on unexpected
* failure, not when discovery fails. * failure, not when discovery fails.
*/ */
public static async findClientConfig(domain: string): Promise<IClientWellKnown> { public static async findClientConfig(domain: string): Promise<ClientConfig> {
if (!domain || typeof(domain) !== "string" || domain.length === 0) { if (!domain || typeof(domain) !== "string" || domain.length === 0) {
throw new Error("'domain' must be a string of non-zero length"); throw new Error("'domain' must be a string of non-zero length");
} }
@@ -298,7 +309,7 @@ export class AutoDiscovery {
// We default to an error state to make the first few checks easier to // We default to an error state to make the first few checks easier to
// write. We'll update the properties of this object over the duration // write. We'll update the properties of this object over the duration
// of this function. // of this function.
const clientConfig = { const clientConfig: ClientConfig = {
"m.homeserver": { "m.homeserver": {
state: AutoDiscovery.FAIL_ERROR, state: AutoDiscovery.FAIL_ERROR,
error: AutoDiscovery.ERROR_INVALID, error: AutoDiscovery.ERROR_INVALID,
@@ -367,18 +378,18 @@ export class AutoDiscovery {
* @return {string|boolean} The sanitized URL or a falsey value if the URL is invalid. * @return {string|boolean} The sanitized URL or a falsey value if the URL is invalid.
* @private * @private
*/ */
private static sanitizeWellKnownUrl(url: string): string | boolean { private static sanitizeWellKnownUrl(url: string): string | false {
if (!url) return false; if (!url) return false;
try { try {
let parsed = null; let parsed: URL | undefined;
try { try {
parsed = new URL(url); parsed = new URL(url);
} catch (e) { } catch (e) {
logger.error("Could not parse url", e); logger.error("Could not parse url", e);
} }
if (!parsed || !parsed.hostname) return false; if (!parsed?.hostname) return false;
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return false; if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return false;
const port = parsed.port ? `:${parsed.port}` : ""; const port = parsed.port ? `:${parsed.port}` : "";
@@ -448,12 +459,17 @@ export class AutoDiscovery {
}; };
} }
} catch (err) { } catch (err) {
const error = err as Error | string | undefined; const error = err as AutoDiscoveryError | string | undefined;
let reason = "";
if (typeof error === "object") {
reason = (<Error>error)?.message;
}
return { return {
error, error,
raw: {}, raw: {},
action: AutoDiscoveryAction.FAIL_PROMPT, action: AutoDiscoveryAction.FAIL_PROMPT,
reason: (<Error>error)?.message || "General failure", reason: reason || "General failure",
}; };
} }
@@ -463,7 +479,7 @@ export class AutoDiscovery {
action: AutoDiscoveryAction.SUCCESS, action: AutoDiscoveryAction.SUCCESS,
}; };
} catch (err) { } catch (err) {
const error = err as Error | string | undefined; const error = err as Error;
return { return {
error, error,
raw: {}, raw: {},

View File

@@ -518,7 +518,7 @@ export interface IUploadKeySignaturesResponse {
} }
export interface IPreviewUrlResponse { export interface IPreviewUrlResponse {
[key: string]: string | number; [key: string]: undefined | string | number;
"og:title": string; "og:title": string;
"og:type": string; "og:type": string;
"og:url": string; "og:url": string;
@@ -716,8 +716,9 @@ export interface IMyDevice {
display_name?: string; display_name?: string;
last_seen_ip?: string; last_seen_ip?: string;
last_seen_ts?: number; last_seen_ts?: number;
[UNSTABLE_MSC3852_LAST_SEEN_UA.stable]?: string; // UNSTABLE_MSC3852_LAST_SEEN_UA
[UNSTABLE_MSC3852_LAST_SEEN_UA.unstable]?: string; last_seen_user_agent?: string;
"org.matrix.msc3852.last_seen_user_agent"?: string;
} }
export interface Keys { export interface Keys {
@@ -3225,7 +3226,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
opts: IKeyBackupRestoreOpts, opts: IKeyBackupRestoreOpts,
): Promise<IKeyBackupRestoreResult> { ): Promise<IKeyBackupRestoreResult> {
const privKey = decodeRecoveryKey(recoveryKey); const privKey = decodeRecoveryKey(recoveryKey);
return this.restoreKeyBackup(privKey, targetRoomId, targetSessionId, backupInfo, opts); return this.restoreKeyBackup(privKey, targetRoomId!, targetSessionId!, backupInfo, opts);
} }
public async restoreKeyBackupWithCache( public async restoreKeyBackupWithCache(
@@ -3387,7 +3388,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
const path = this.makeKeyBackupPath(roomId, sessionId, version); const path = this.makeKeyBackupPath(roomId!, sessionId!, version!);
await this.http.authedRequest( await this.http.authedRequest(
Method.Delete, path.path, path.queryData, undefined, Method.Delete, path.path, path.queryData, undefined,
{ prefix: ClientPrefix.V3 }, { prefix: ClientPrefix.V3 },
@@ -3879,7 +3880,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
roomId: string, roomId: string,
threadId: string | null, threadId: string | null,
eventType: string | IContent, eventType: string | IContent,
content: IContent | string, content?: IContent | string,
txnId?: string, txnId?: string,
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
if (!threadId?.startsWith(EVENT_ID_PREFIX) && threadId !== null) { if (!threadId?.startsWith(EVENT_ID_PREFIX) && threadId !== null) {
@@ -3891,10 +3892,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// If we expect that an event is part of a thread but is missing the relation // If we expect that an event is part of a thread but is missing the relation
// we need to add it manually, as well as the reply fallback // we need to add it manually, as well as the reply fallback
if (threadId && !content["m.relates_to"]?.rel_type) { if (threadId && !content!["m.relates_to"]?.rel_type) {
const isReply = !!content["m.relates_to"]?.["m.in_reply_to"]; const isReply = !!content!["m.relates_to"]?.["m.in_reply_to"];
content["m.relates_to"] = { content!["m.relates_to"] = {
...content["m.relates_to"], ...content!["m.relates_to"],
"rel_type": THREAD_RELATION_TYPE.name, "rel_type": THREAD_RELATION_TYPE.name,
"event_id": threadId, "event_id": threadId,
// Set is_falling_back to true unless this is actually intended to be a reply // Set is_falling_back to true unless this is actually intended to be a reply
@@ -3902,7 +3903,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
}; };
const thread = this.getRoom(roomId)?.getThread(threadId); const thread = this.getRoom(roomId)?.getThread(threadId);
if (thread && !isReply) { if (thread && !isReply) {
content["m.relates_to"]["m.in_reply_to"] = { content!["m.relates_to"]["m.in_reply_to"] = {
"event_id": thread.lastReply((ev: MatrixEvent) => { "event_id": thread.lastReply((ev: MatrixEvent) => {
return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status; return ev.isRelation(THREAD_RELATION_TYPE.name) && !ev.status;
})?.getId() ?? threadId, })?.getId() ?? threadId,
@@ -4200,7 +4201,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
if (!eventId?.startsWith(EVENT_ID_PREFIX)) { if (!eventId?.startsWith(EVENT_ID_PREFIX)) {
opts = txnId as IRedactOpts; opts = txnId as IRedactOpts;
txnId = eventId; txnId = eventId;
eventId = threadId; eventId = threadId!;
threadId = null; threadId = null;
} }
const reason = opts?.reason; const reason = opts?.reason;
@@ -4233,7 +4234,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public sendMessage( public sendMessage(
roomId: string, roomId: string,
threadId: string | null | IContent, threadId: string | null | IContent,
content: IContent | string, content?: IContent | string,
txnId?: string, txnId?: string,
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
if (typeof threadId !== "string" && threadId !== null) { if (typeof threadId !== "string" && threadId !== null) {
@@ -4417,7 +4418,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public sendImageMessage( public sendImageMessage(
roomId: string, roomId: string,
threadId: string | null, threadId: string | null,
url: string | IImageInfo, url?: string | IImageInfo,
info?: IImageInfo | string, info?: IImageInfo | string,
text = "Image", text = "Image",
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
@@ -4461,7 +4462,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public sendStickerMessage( public sendStickerMessage(
roomId: string, roomId: string,
threadId: string | null, threadId: string | null,
url: string | IImageInfo, url?: string | IImageInfo,
info?: IImageInfo | string, info?: IImageInfo | string,
text = "Sticker", text = "Sticker",
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
@@ -5329,11 +5330,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// Here we handle non-thread timelines only, but still process any thread events to populate thread summaries. // Here we handle non-thread timelines only, but still process any thread events to populate thread summaries.
let timeline = timelineSet.getTimelineForEvent(events[0].getId()!); let timeline = timelineSet.getTimelineForEvent(events[0].getId()!);
if (timeline) { if (timeline) {
timeline.getState(EventTimeline.BACKWARDS).setUnknownStateEvents(res.state.map(mapper)); timeline.getState(EventTimeline.BACKWARDS)!.setUnknownStateEvents(res.state.map(mapper));
} else { } else {
timeline = timelineSet.addTimeline(); timeline = timelineSet.addTimeline();
timeline.initialiseState(res.state.map(mapper)); timeline.initialiseState(res.state.map(mapper));
timeline.getState(EventTimeline.FORWARDS).paginationToken = res.end; timeline.getState(EventTimeline.FORWARDS)!.paginationToken = res.end;
} }
const [timelineEvents, threadedEvents] = timelineSet.room.partitionThreadedEvents(events); const [timelineEvents, threadedEvents] = timelineSet.room.partitionThreadedEvents(events);
@@ -5422,7 +5423,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// Here we handle non-thread timelines only, but still process any thread events to populate thread summaries. // Here we handle non-thread timelines only, but still process any thread events to populate thread summaries.
let timeline = timelineSet.getTimelineForEvent(event.getId()); let timeline = timelineSet.getTimelineForEvent(event.getId());
if (timeline) { if (timeline) {
timeline.getState(EventTimeline.BACKWARDS).setUnknownStateEvents(res.state.map(mapper)); timeline.getState(EventTimeline.BACKWARDS)!.setUnknownStateEvents(res.state.map(mapper));
} else { } else {
timeline = timelineSet.addTimeline(); timeline = timelineSet.addTimeline();
timeline.initialiseState(res.state.map(mapper)); timeline.initialiseState(res.state.map(mapper));
@@ -5483,7 +5484,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
// Here we handle non-thread timelines only, but still process any thread events to populate thread // Here we handle non-thread timelines only, but still process any thread events to populate thread
// summaries. // summaries.
const timeline = timelineSet.getLiveTimeline(); const timeline = timelineSet.getLiveTimeline();
timeline.getState(EventTimeline.BACKWARDS).setUnknownStateEvents(res.state.map(mapper)); timeline.getState(EventTimeline.BACKWARDS)!.setUnknownStateEvents(res.state.map(mapper));
timelineSet.addEventsToTimeline(events, true, timeline, null); timelineSet.addEventsToTimeline(events, true, timeline, null);
if (!resOlder.next_batch) { if (!resOlder.next_batch) {
@@ -5786,7 +5787,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
eventTimeline.getFilter(), eventTimeline.getFilter(),
).then((res) => { ).then((res) => {
if (res.state) { if (res.state) {
const roomState = eventTimeline.getState(dir); const roomState = eventTimeline.getState(dir)!;
const stateEvents = res.state.map(this.getEventMapper()); const stateEvents = res.state.map(this.getEventMapper());
roomState.setUnknownStateEvents(stateEvents); roomState.setUnknownStateEvents(stateEvents);
} }
@@ -5861,7 +5862,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
eventTimeline.getFilter(), eventTimeline.getFilter(),
).then((res) => { ).then((res) => {
if (res.state) { if (res.state) {
const roomState = eventTimeline.getState(dir); const roomState = eventTimeline.getState(dir)!;
const stateEvents = res.state.map(this.getEventMapper()); const stateEvents = res.state.map(this.getEventMapper());
roomState.setUnknownStateEvents(stateEvents); roomState.setUnknownStateEvents(stateEvents);
} }

View File

@@ -118,12 +118,12 @@ export function makeEmoteMessage(body: string) {
/** Location content helpers */ /** Location content helpers */
export const getTextForLocationEvent = ( export const getTextForLocationEvent = (
uri: string, uri: string | undefined,
assetType: LocationAssetType, assetType: LocationAssetType,
timestamp: number, timestamp?: number,
description?: string, description?: string | null,
): string => { ): string => {
const date = `at ${new Date(timestamp).toISOString()}`; const date = `at ${new Date(timestamp!).toISOString()}`;
const assetName = assetType === LocationAssetType.Self ? 'User' : undefined; const assetName = assetType === LocationAssetType.Self ? 'User' : undefined;
const quotedDescription = description ? `"${description}"` : undefined; const quotedDescription = description ? `"${description}"` : undefined;
@@ -147,10 +147,10 @@ export const getTextForLocationEvent = (
export const makeLocationContent = ( export const makeLocationContent = (
// this is first but optional // this is first but optional
// to avoid a breaking change // to avoid a breaking change
text: string | undefined, text?: string,
uri: string, uri?: string,
timestamp: number, timestamp?: number,
description?: string, description?: string | null,
assetType?: LocationAssetType, assetType?: LocationAssetType,
): LegacyLocationEventContent & MLocationEventContent => { ): LegacyLocationEventContent & MLocationEventContent => {
const defaultedText = text ?? const defaultedText = text ??
@@ -187,7 +187,7 @@ export const parseLocationEvent = (wireEventContent: LocationEventWireContent):
const assetType = asset?.type ?? LocationAssetType.Self; const assetType = asset?.type ?? LocationAssetType.Self;
const fallbackText = text ?? wireEventContent.body; const fallbackText = text ?? wireEventContent.body;
return makeLocationContent(fallbackText, geoUri, timestamp, description, assetType); return makeLocationContent(fallbackText, geoUri, timestamp ?? undefined, description, assetType);
}; };
/** /**
@@ -201,7 +201,7 @@ export type MakeTopicContent = (
export const makeTopicContent: MakeTopicContent = (topic, htmlTopic) => { export const makeTopicContent: MakeTopicContent = (topic, htmlTopic) => {
const renderings = [{ body: topic, mimetype: "text/plain" }]; const renderings = [{ body: topic, mimetype: "text/plain" }];
if (isProvided(htmlTopic)) { if (isProvided(htmlTopic)) {
renderings.push({ body: htmlTopic, mimetype: "text/html" }); renderings.push({ body: htmlTopic!, mimetype: "text/html" });
} }
return { topic, [M_TOPIC.name]: renderings }; return { topic, [M_TOPIC.name]: renderings };
}; };
@@ -247,14 +247,14 @@ export const makeBeaconInfoContent: MakeBeaconInfoContent = (
export type BeaconInfoState = MBeaconInfoContent & { export type BeaconInfoState = MBeaconInfoContent & {
assetType?: LocationAssetType; assetType?: LocationAssetType;
timestamp: number; timestamp?: number;
}; };
/** /**
* Flatten beacon info event content * Flatten beacon info event content
*/ */
export const parseBeaconInfoContent = (content: MBeaconInfoEventContent): BeaconInfoState => { export const parseBeaconInfoContent = (content: MBeaconInfoEventContent): BeaconInfoState => {
const { description, timeout, live } = content; const { description, timeout, live } = content;
const timestamp = M_TIMESTAMP.findIn<number>(content); const timestamp = M_TIMESTAMP.findIn<number>(content) ?? undefined;
const asset = M_ASSET.findIn<MAssetContent>(content); const asset = M_ASSET.findIn<MAssetContent>(content);
return { return {
@@ -290,14 +290,14 @@ export const makeBeaconContent: MakeBeaconContent = (
}, },
}); });
export type BeaconLocationState = MLocationContent & { export type BeaconLocationState = Omit<MLocationContent, "uri"> & {
uri?: string; // override from MLocationContent to allow optionals uri?: string; // override from MLocationContent to allow optionals
timestamp?: number; timestamp?: number;
}; };
export const parseBeaconContent = (content: MBeaconEventContent): BeaconLocationState => { export const parseBeaconContent = (content: MBeaconEventContent): BeaconLocationState => {
const location = M_LOCATION.findIn<MLocationContent>(content); const location = M_LOCATION.findIn<MLocationContent>(content);
const timestamp = M_TIMESTAMP.findIn<number>(content); const timestamp = M_TIMESTAMP.findIn<number>(content) ?? undefined;
return { return {
description: location?.description, description: location?.description,

View File

@@ -302,7 +302,7 @@ export class BackupManager {
|| now - this.sessionLastCheckAttemptedTime[targetSessionId!] > KEY_BACKUP_CHECK_RATE_LIMIT || now - this.sessionLastCheckAttemptedTime[targetSessionId!] > KEY_BACKUP_CHECK_RATE_LIMIT
) { ) {
this.sessionLastCheckAttemptedTime[targetSessionId!] = now; this.sessionLastCheckAttemptedTime[targetSessionId!] = now;
await this.baseApis.restoreKeyBackupWithCache(targetRoomId, targetSessionId, this.backupInfo, {}); await this.baseApis.restoreKeyBackupWithCache(targetRoomId!, targetSessionId!, this.backupInfo, {});
} }
} }

View File

@@ -201,7 +201,7 @@ export class Backend implements CryptoStore {
let stateIndex = 0; let stateIndex = 0;
let result: OutgoingRoomKeyRequest; let result: OutgoingRoomKeyRequest;
function onsuccess(this: IDBRequest<IDBCursorWithValue>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) {
const cursor = this.result; const cursor = this.result;
if (cursor) { if (cursor) {
// got a match // got a match
@@ -256,7 +256,7 @@ export class Backend implements CryptoStore {
let stateIndex = 0; let stateIndex = 0;
const results: OutgoingRoomKeyRequest[] = []; const results: OutgoingRoomKeyRequest[] = [];
function onsuccess(this: IDBRequest<IDBCursorWithValue>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) {
const cursor = this.result; const cursor = this.result;
if (cursor) { if (cursor) {
const keyReq = cursor.value; const keyReq = cursor.value;
@@ -309,7 +309,7 @@ export class Backend implements CryptoStore {
): Promise<OutgoingRoomKeyRequest | null> { ): Promise<OutgoingRoomKeyRequest | null> {
let result: OutgoingRoomKeyRequest | null = null; let result: OutgoingRoomKeyRequest | null = null;
function onsuccess(this: IDBRequest<IDBCursorWithValue>) { function onsuccess(this: IDBRequest<IDBCursorWithValue | null>) {
const cursor = this.result; const cursor = this.result;
if (!cursor) { if (!cursor) {
return; return;

View File

@@ -49,7 +49,7 @@ export class HTTPError extends Error {
*/ */
export class MatrixError extends HTTPError { export class MatrixError extends HTTPError {
public readonly errcode?: string; public readonly errcode?: string;
public readonly data: IErrorJson; public data: IErrorJson;
constructor( constructor(
errorJson: IErrorJson = {}, errorJson: IErrorJson = {},

View File

@@ -21,6 +21,7 @@ limitations under the License.
import { logger } from './logger'; import { logger } from './logger';
import { MatrixClient } from "./client"; import { MatrixClient } from "./client";
import { defer, IDeferred } from "./utils"; import { defer, IDeferred } from "./utils";
import { MatrixError } from "./http-api";
const EMAIL_STAGE_TYPE = "m.login.email.identity"; const EMAIL_STAGE_TYPE = "m.login.email.identity";
const MSISDN_STAGE_TYPE = "m.login.msisdn"; const MSISDN_STAGE_TYPE = "m.login.msisdn";
@@ -111,7 +112,7 @@ interface IOpts {
sessionId?: string; sessionId?: string;
clientSecret?: string; clientSecret?: string;
emailSid?: string; emailSid?: string;
doRequest(auth: IAuthData, background: boolean): Promise<IAuthData>; doRequest(auth: IAuthData | null, background: boolean): Promise<IAuthData>;
stateUpdated(nextStage: AuthType, status: IStageStatus): void; stateUpdated(nextStage: AuthType, status: IStageStatus): void;
requestEmailToken(email: string, secret: string, attempt: number, session: string): Promise<{ sid: string }>; requestEmailToken(email: string, secret: string, attempt: number, session: string): Promise<{ sid: string }>;
busyChanged?(busy: boolean): void; busyChanged?(busy: boolean): void;
@@ -328,7 +329,7 @@ export class InteractiveAuth {
* @param {string} loginType login type for the stage * @param {string} loginType login type for the stage
* @return {object?} any parameters from the server for this stage * @return {object?} any parameters from the server for this stage
*/ */
public getStageParams(loginType: string): Record<string, any> { public getStageParams(loginType: string): Record<string, any> | undefined {
return this.data.params?.[loginType]; return this.data.params?.[loginType];
} }
@@ -428,10 +429,10 @@ export class InteractiveAuth {
this.requestingEmailToken = true; this.requestingEmailToken = true;
try { try {
const requestTokenResult = await this.requestEmailTokenCallback( const requestTokenResult = await this.requestEmailTokenCallback(
this.inputs.emailAddress, this.inputs.emailAddress!,
this.clientSecret, this.clientSecret,
this.emailAttempt++, this.emailAttempt++,
this.data.session, this.data.session!,
); );
this.emailSid = requestTokenResult.sid; this.emailSid = requestTokenResult.sid;
logger.trace("Email token request succeeded"); logger.trace("Email token request succeeded");
@@ -454,16 +455,16 @@ export class InteractiveAuth {
* This can be set to true for requests that just poll to see if auth has * This can be set to true for requests that just poll to see if auth has
* been completed elsewhere. * been completed elsewhere.
*/ */
private async doRequest(auth: IAuthData, background = false): Promise<void> { private async doRequest(auth: IAuthData | null, background = false): Promise<void> {
try { try {
const result = await this.requestCallback(auth, background); const result = await this.requestCallback(auth, background);
this.attemptAuthDeferred!.resolve(result); this.attemptAuthDeferred!.resolve(result);
this.attemptAuthDeferred = null; this.attemptAuthDeferred = null;
} catch (error) { } catch (error) {
// sometimes UI auth errors don't come with flows // sometimes UI auth errors don't come with flows
const errorFlows = error.data?.flows ?? null; const errorFlows = (<MatrixError>error).data?.flows ?? null;
const haveFlows = this.data.flows || Boolean(errorFlows); const haveFlows = this.data.flows || Boolean(errorFlows);
if (error.httpStatus !== 401 || !error.data || !haveFlows) { if ((<MatrixError>error).httpStatus !== 401 || !(<MatrixError>error).data || !haveFlows) {
// doesn't look like an interactive-auth failure. // doesn't look like an interactive-auth failure.
if (!background) { if (!background) {
this.attemptAuthDeferred?.reject(error); this.attemptAuthDeferred?.reject(error);
@@ -474,20 +475,23 @@ export class InteractiveAuth {
logger.log("Background poll request failed doing UI auth: ignoring", error); logger.log("Background poll request failed doing UI auth: ignoring", error);
} }
} }
if (!error.data) { if (!(<MatrixError>error).data) {
error.data = {}; (<MatrixError>error).data = {};
} }
// if the error didn't come with flows, completed flows or session ID, // if the error didn't come with flows, completed flows or session ID,
// copy over the ones we have. Synapse sometimes sends responses without // copy over the ones we have. Synapse sometimes sends responses without
// any UI auth data (eg. when polling for email validation, if the email // any UI auth data (eg. when polling for email validation, if the email
// has not yet been validated). This appears to be a Synapse bug, which // has not yet been validated). This appears to be a Synapse bug, which
// we workaround here. // we workaround here.
if (!error.data.flows && !error.data.completed && !error.data.session) { if (!(<MatrixError>error).data.flows &&
error.data.flows = this.data.flows; !(<MatrixError>error).data.completed &&
error.data.completed = this.data.completed; !(<MatrixError>error).data.session
error.data.session = this.data.session; ) {
(<MatrixError>error).data.flows = this.data.flows;
(<MatrixError>error).data.completed = this.data.completed;
(<MatrixError>error).data.session = this.data.session;
} }
this.data = error.data; this.data = (<MatrixError>error).data;
try { try {
this.startNextAuthStage(); this.startNextAuthStage();
} catch (e) { } catch (e) {

View File

@@ -145,7 +145,7 @@ export class MSC3089Branch {
let event: MatrixEvent | undefined = room.getUnfilteredTimelineSet().findEventById(this.id); let event: MatrixEvent | undefined = room.getUnfilteredTimelineSet().findEventById(this.id);
// keep scrolling back if needed until we find the event or reach the start of the room: // keep scrolling back if needed until we find the event or reach the start of the room:
while (!event && room.getLiveTimeline().getState(EventTimeline.BACKWARDS).paginationToken) { while (!event && room.getLiveTimeline().getState(EventTimeline.BACKWARDS)!.paginationToken) {
await this.client.scrollback(room, 100); await this.client.scrollback(room, 100);
event = room.getUnfilteredTimelineSet().findEventById(this.id); event = room.getUnfilteredTimelineSet().findEventById(this.id);
} }

View File

@@ -132,19 +132,19 @@ export class Beacon extends TypedEventEmitter<Exclude<BeaconEvent, BeaconEvent.N
this.checkLiveness(); this.checkLiveness();
if (!this.beaconInfo) return; if (!this.beaconInfo) return;
if (this.isLive) { if (this.isLive) {
const expiryInMs = (this.beaconInfo.timestamp + this.beaconInfo.timeout) - Date.now(); const expiryInMs = (this.beaconInfo.timestamp! + this.beaconInfo.timeout) - Date.now();
if (expiryInMs > 1) { if (expiryInMs > 1) {
this.livenessWatchTimeout = setTimeout( this.livenessWatchTimeout = setTimeout(
() => { this.monitorLiveness(); }, () => { this.monitorLiveness(); },
expiryInMs, expiryInMs,
); );
} }
} else if (this.beaconInfo.timestamp > Date.now()) { } else if (this.beaconInfo.timestamp! > Date.now()) {
// beacon start timestamp is in the future // beacon start timestamp is in the future
// check liveness again then // check liveness again then
this.livenessWatchTimeout = setTimeout( this.livenessWatchTimeout = setTimeout(
() => { this.monitorLiveness(); }, () => { this.monitorLiveness(); },
this.beaconInfo.timestamp - Date.now(), this.beaconInfo.timestamp! - Date.now(),
); );
} }
} }
@@ -165,6 +165,7 @@ export class Beacon extends TypedEventEmitter<Exclude<BeaconEvent, BeaconEvent.N
if (!parsed.uri || !parsed.timestamp) return false; // we won't be able to process these if (!parsed.uri || !parsed.timestamp) return false; // we won't be able to process these
const { timestamp } = parsed; const { timestamp } = parsed;
return ( return (
this._beaconInfo!.timestamp &&
// only include positions that were taken inside the beacon's live period // only include positions that were taken inside the beacon's live period
isTimestampInDuration(this._beaconInfo!.timestamp, this._beaconInfo!.timeout, timestamp) && isTimestampInDuration(this._beaconInfo!.timestamp, this._beaconInfo!.timeout, timestamp) &&
// ignore positions older than our current latest location // ignore positions older than our current latest location
@@ -197,10 +198,10 @@ export class Beacon extends TypedEventEmitter<Exclude<BeaconEvent, BeaconEvent.N
// may have a start timestamp in the future from Bob's POV // may have a start timestamp in the future from Bob's POV
// handle this by adding 6min of leniency to the start timestamp when it is in the future // handle this by adding 6min of leniency to the start timestamp when it is in the future
if (!this.beaconInfo) return; if (!this.beaconInfo) return;
const startTimestamp = this.beaconInfo.timestamp > Date.now() ? const startTimestamp = this.beaconInfo.timestamp! > Date.now() ?
this.beaconInfo.timestamp - 360000 /* 6min */ : this.beaconInfo.timestamp! - 360000 /* 6min */ :
this.beaconInfo.timestamp; this.beaconInfo.timestamp;
this._isLive = !!this._beaconInfo?.live && this._isLive = !!this._beaconInfo?.live && !!startTimestamp &&
isTimestampInDuration(startTimestamp, this._beaconInfo?.timeout, Date.now()); isTimestampInDuration(startTimestamp, this._beaconInfo?.timeout, Date.now());
if (prevLiveness !== this.isLive) { if (prevLiveness !== this.isLive) {

View File

@@ -625,7 +625,7 @@ export class EventTimelineSet extends TypedEventEmitter<EmittedEvents, EventTime
} }
EventTimeline.setEventMetadata( EventTimeline.setEventMetadata(
event, event,
roomState, roomState!,
false, false,
); );
tlEvents[j] = event; tlEvents[j] = event;

View File

@@ -19,7 +19,7 @@ limitations under the License.
*/ */
import { logger } from '../logger'; import { logger } from '../logger';
import { RoomState, IMarkerFoundOptions } from "./room-state"; import { IMarkerFoundOptions, RoomState } from "./room-state";
import { EventTimelineSet } from "./event-timeline-set"; import { EventTimelineSet } from "./event-timeline-set";
import { MatrixEvent } from "./event"; import { MatrixEvent } from "./event";
import { Filter } from "../filter"; import { Filter } from "../filter";
@@ -95,8 +95,8 @@ export class EventTimeline {
private readonly name: string; private readonly name: string;
private events: MatrixEvent[] = []; private events: MatrixEvent[] = [];
private baseIndex = 0; private baseIndex = 0;
private startState: RoomState; private startState?: RoomState;
private endState: RoomState; private endState?: RoomState;
private prevTimeline: EventTimeline | null = null; private prevTimeline: EventTimeline | null = null;
private nextTimeline: EventTimeline | null = null; private nextTimeline: EventTimeline | null = null;
public paginationRequests: Record<Direction, Promise<boolean> | null> = { public paginationRequests: Record<Direction, Promise<boolean> | null> = {
@@ -126,10 +126,12 @@ export class EventTimeline {
*/ */
constructor(private readonly eventTimelineSet: EventTimelineSet) { constructor(private readonly eventTimelineSet: EventTimelineSet) {
this.roomId = eventTimelineSet.room?.roomId ?? null; this.roomId = eventTimelineSet.room?.roomId ?? null;
this.startState = new RoomState(this.roomId); if (this.roomId) {
this.startState.paginationToken = null; this.startState = new RoomState(this.roomId);
this.endState = new RoomState(this.roomId); this.startState.paginationToken = null;
this.endState.paginationToken = null; this.endState = new RoomState(this.roomId);
this.endState.paginationToken = null;
}
// this is used by client.js // this is used by client.js
this.paginationRequests = { 'b': null, 'f': null }; this.paginationRequests = { 'b': null, 'f': null };
@@ -167,12 +169,8 @@ export class EventTimeline {
Object.freeze(e); Object.freeze(e);
} }
this.startState.setStateEvents(stateEvents, { this.startState?.setStateEvents(stateEvents, { timelineWasEmpty });
timelineWasEmpty, this.endState?.setStateEvents(stateEvents, { timelineWasEmpty });
});
this.endState.setStateEvents(stateEvents, {
timelineWasEmpty,
});
} }
/** /**
@@ -190,7 +188,7 @@ export class EventTimeline {
public forkLive(direction: Direction): EventTimeline { public forkLive(direction: Direction): EventTimeline {
const forkState = this.getState(direction); const forkState = this.getState(direction);
const timeline = new EventTimeline(this.eventTimelineSet); const timeline = new EventTimeline(this.eventTimelineSet);
timeline.startState = forkState.clone(); timeline.startState = forkState?.clone();
// Now clobber the end state of the new live timeline with that from the // Now clobber the end state of the new live timeline with that from the
// previous live timeline. It will be identical except that we'll keep // previous live timeline. It will be identical except that we'll keep
// using the same RoomMember objects for the 'live' set of members with any // using the same RoomMember objects for the 'live' set of members with any
@@ -198,7 +196,7 @@ export class EventTimeline {
timeline.endState = forkState; timeline.endState = forkState;
// Firstly, we just stole the current timeline's end state, so it needs a new one. // Firstly, we just stole the current timeline's end state, so it needs a new one.
// Make an immutable copy of the state so back pagination will get the correct sentinels. // Make an immutable copy of the state so back pagination will get the correct sentinels.
this.endState = forkState.clone(); this.endState = forkState?.clone();
return timeline; return timeline;
} }
@@ -214,8 +212,8 @@ export class EventTimeline {
public fork(direction: Direction): EventTimeline { public fork(direction: Direction): EventTimeline {
const forkState = this.getState(direction); const forkState = this.getState(direction);
const timeline = new EventTimeline(this.eventTimelineSet); const timeline = new EventTimeline(this.eventTimelineSet);
timeline.startState = forkState.clone(); timeline.startState = forkState?.clone();
timeline.endState = forkState.clone(); timeline.endState = forkState?.clone();
return timeline; return timeline;
} }
@@ -276,7 +274,7 @@ export class EventTimeline {
* *
* @return {RoomState} state at the start/end of the timeline * @return {RoomState} state at the start/end of the timeline
*/ */
public getState(direction: Direction): RoomState { public getState(direction: Direction): RoomState | undefined {
if (direction == EventTimeline.BACKWARDS) { if (direction == EventTimeline.BACKWARDS) {
return this.startState; return this.startState;
} else if (direction == EventTimeline.FORWARDS) { } else if (direction == EventTimeline.FORWARDS) {
@@ -296,7 +294,7 @@ export class EventTimeline {
* @return {?string} pagination token * @return {?string} pagination token
*/ */
public getPaginationToken(direction: Direction): string | null { public getPaginationToken(direction: Direction): string | null {
return this.getState(direction).paginationToken; return this.getState(direction)?.paginationToken ?? null;
} }
/** /**
@@ -304,12 +302,15 @@ export class EventTimeline {
* *
* @param {?string} token pagination token * @param {?string} token pagination token
* *
* @param {string} direction EventTimeline.BACKWARDS to set the paginatio * @param {string} direction EventTimeline.BACKWARDS to set the pagination
* token for going backwards in time; EventTimeline.FORWARDS to set the * token for going backwards in time; EventTimeline.FORWARDS to set the
* pagination token for going forwards in time. * pagination token for going forwards in time.
*/ */
public setPaginationToken(token: string | null, direction: Direction): void { public setPaginationToken(token: string | null, direction: Direction): void {
this.getState(direction).paginationToken = token; const state = this.getState(direction);
if (state) {
state.paginationToken = token;
}
} }
/** /**
@@ -408,16 +409,14 @@ export class EventTimeline {
const timelineSet = this.getTimelineSet(); const timelineSet = this.getTimelineSet();
if (timelineSet.room) { if (timelineSet.room) {
EventTimeline.setEventMetadata(event, roomState, toStartOfTimeline); EventTimeline.setEventMetadata(event, roomState!, toStartOfTimeline);
// modify state but only on unfiltered timelineSets // modify state but only on unfiltered timelineSets
if ( if (
event.isState() && event.isState() &&
timelineSet.room.getUnfilteredTimelineSet() === timelineSet timelineSet.room.getUnfilteredTimelineSet() === timelineSet
) { ) {
roomState.setStateEvents([event], { roomState?.setStateEvents([event], { timelineWasEmpty });
timelineWasEmpty,
});
// it is possible that the act of setting the state event means we // it is possible that the act of setting the state event means we
// can set more metadata (specifically sender/target props), so try // can set more metadata (specifically sender/target props), so try
// it again if the prop wasn't previously set. It may also mean that // it again if the prop wasn't previously set. It may also mean that
@@ -428,8 +427,8 @@ export class EventTimeline {
// back in time, else we'll set the .sender value for BEFORE the given // back in time, else we'll set the .sender value for BEFORE the given
// member event, whereas we want to set the .sender value for the ACTUAL // member event, whereas we want to set the .sender value for the ACTUAL
// member event itself. // member event itself.
if (!event.sender || (event.getType() === "m.room.member" && !toStartOfTimeline)) { if (!event.sender || (event.getType() === EventType.RoomMember && !toStartOfTimeline)) {
EventTimeline.setEventMetadata(event, roomState, toStartOfTimeline); EventTimeline.setEventMetadata(event, roomState!, toStartOfTimeline);
} }
} }
} }

View File

@@ -413,7 +413,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
if (this.clearEvent) { if (this.clearEvent) {
return this.clearEvent.type; return this.clearEvent.type;
} }
return this.event.type; return this.event.type!;
} }
/** /**
@@ -423,7 +423,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* @return {string} The event type. * @return {string} The event type.
*/ */
public getWireType(): EventType | string { public getWireType(): EventType | string {
return this.event.type; return this.event.type!;
} }
/** /**
@@ -441,7 +441,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
* @return {Number} The event timestamp, e.g. <code>1433502692297</code> * @return {Number} The event timestamp, e.g. <code>1433502692297</code>
*/ */
public getTs(): number { public getTs(): number {
return this.event.origin_server_ts; return this.event.origin_server_ts!;
} }
/** /**
@@ -625,8 +625,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
): void { ): void {
// keep the plain-text data for 'view source' // keep the plain-text data for 'view source'
this.clearEvent = { this.clearEvent = {
type: this.event.type, type: this.event.type!,
content: this.event.content, content: this.event.content!,
}; };
this.event.type = cryptoType; this.event.type = cryptoType;
this.event.content = cryptoContent; this.event.content = cryptoContent;
@@ -730,7 +730,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
const wireContent = this.getWireContent(); const wireContent = this.getWireContent();
return crypto.requestRoomKey({ return crypto.requestRoomKey({
algorithm: wireContent.algorithm, algorithm: wireContent.algorithm,
room_id: this.getRoomId(), room_id: this.getRoomId()!,
session_id: wireContent.session_id, session_id: wireContent.session_id,
sender_key: wireContent.sender_key, sender_key: wireContent.sender_key,
}, this.getKeyRequestRecipients(userId), true); }, this.getKeyRequestRecipients(userId), true);
@@ -790,10 +790,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
const re = options.isRetry ? 're' : ''; const re = options.isRetry ? 're' : '';
// For find results: this can produce "Error decrypting event (id=$ev)" and // For find results: this can produce "Error decrypting event (id=$ev)" and
// "Error redecrypting event (id=$ev)". // "Error redecrypting event (id=$ev)".
logger.error( logger.error(`Error ${re}decrypting event (id=${this.getId()})`, e);
`Error ${re}decrypting event ` +
`(id=${this.getId()}): ${e.stack || e}`,
);
this.decryptionPromise = null; this.decryptionPromise = null;
this.retryDecryption = false; this.retryDecryption = false;
return; return;
@@ -1007,7 +1004,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
const value = this._localRedactionEvent; const value = this._localRedactionEvent;
this._localRedactionEvent = null; this._localRedactionEvent = null;
if (this.event.unsigned) { if (this.event.unsigned) {
this.event.unsigned.redacted_because = null; this.event.unsigned.redacted_because = undefined;
} }
return !!value; return !!value;
} }
@@ -1194,8 +1191,8 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
if (!this.isRedacted()) return null; if (!this.isRedacted()) return null;
if (this.clearEvent?.unsigned) { if (this.clearEvent?.unsigned) {
return this.clearEvent?.unsigned.redacted_because; return this.clearEvent?.unsigned.redacted_because ?? null;
} else if (this.event.unsigned.redacted_because) { } else if (this.event.unsigned?.redacted_because) {
return this.event.unsigned.redacted_because; return this.event.unsigned.redacted_because;
} else { } else {
return {}; return {};
@@ -1246,7 +1243,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
this.emit(MatrixEventEvent.LocalEventIdReplaced, this); this.emit(MatrixEventEvent.LocalEventIdReplaced, this);
} }
this.localTimestamp = Date.now() - this.getAge(); this.localTimestamp = Date.now() - this.getAge()!;
} }
/** /**
@@ -1290,7 +1287,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
// State events cannot be m.replace relations // State events cannot be m.replace relations
return false; return false;
} }
return relation?.rel_type && relation.event_id && (relType ? relation.rel_type === relType : true); return !!(relation?.rel_type && relation.event_id && (relType ? relation.rel_type === relType : true));
} }
/** /**
@@ -1302,7 +1299,7 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
if (!this.isRelation()) { if (!this.isRelation()) {
return null; return null;
} }
return this.getWireContent()["m.relates_to"]; return this.getWireContent()["m.relates_to"] ?? null;
} }
/** /**

View File

@@ -164,7 +164,7 @@ export class IgnoredInvites {
const senderServer = sender.split(":")[1]; const senderServer = sender.split(":")[1];
const roomServer = roomId.split(":")[1]; const roomServer = roomId.split(":")[1];
for (const room of policyRooms) { for (const room of policyRooms) {
const state = room.getUnfilteredTimelineSet().getLiveTimeline().getState(EventTimeline.FORWARDS); const state = room.getUnfilteredTimelineSet().getLiveTimeline().getState(EventTimeline.FORWARDS)!;
for (const { scope, entities } of [ for (const { scope, entities } of [
{ scope: PolicyScope.Room, entities: [roomId] }, { scope: PolicyScope.Room, entities: [roomId] },

View File

@@ -1032,10 +1032,8 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
// state at the start and end of that timeline. These are more // state at the start and end of that timeline. These are more
// for backwards-compatibility than anything else. // for backwards-compatibility than anything else.
this.timeline = this.getLiveTimeline().getEvents(); this.timeline = this.getLiveTimeline().getEvents();
this.oldState = this.getLiveTimeline() this.oldState = this.getLiveTimeline().getState(EventTimeline.BACKWARDS)!;
.getState(EventTimeline.BACKWARDS); this.currentState = this.getLiveTimeline().getState(EventTimeline.FORWARDS)!;
this.currentState = this.getLiveTimeline()
.getState(EventTimeline.FORWARDS);
// Let people know to register new listeners for the new state // Let people know to register new listeners for the new state
// references. The reference won't necessarily change every time so only // references. The reference won't necessarily change every time so only
@@ -1564,8 +1562,8 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
pendingEvents = true, pendingEvents = true,
}: ICreateFilterOpts = {}, }: ICreateFilterOpts = {},
): EventTimelineSet { ): EventTimelineSet {
if (this.filteredTimelineSets[filter.filterId]) { if (this.filteredTimelineSets[filter.filterId!]) {
return this.filteredTimelineSets[filter.filterId]; return this.filteredTimelineSets[filter.filterId!];
} }
const opts = Object.assign({ filter, pendingEvents }, this.opts); const opts = Object.assign({ filter, pendingEvents }, this.opts);
const timelineSet = new EventTimelineSet(this, opts); const timelineSet = new EventTimelineSet(this, opts);
@@ -1574,7 +1572,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
RoomEvent.TimelineReset, RoomEvent.TimelineReset,
]); ]);
if (useSyncEvents) { if (useSyncEvents) {
this.filteredTimelineSets[filter.filterId] = timelineSet; this.filteredTimelineSets[filter.filterId!] = timelineSet;
this.timelineSets.push(timelineSet); this.timelineSets.push(timelineSet);
} }
@@ -1623,7 +1621,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
} }
private async getThreadListFilter(filterType = ThreadFilterType.All): Promise<Filter> { private async getThreadListFilter(filterType = ThreadFilterType.All): Promise<Filter> {
const myUserId = this.client.getUserId(); const myUserId = this.client.getUserId()!;
const filter = new Filter(myUserId); const filter = new Filter(myUserId);
const definition: IFilterDefinition = { const definition: IFilterDefinition = {
@@ -1635,7 +1633,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
}; };
if (filterType === ThreadFilterType.My) { if (filterType === ThreadFilterType.My) {
definition.room.timeline[FILTER_RELATED_BY_SENDERS.name] = [myUserId]; definition!.room!.timeline![FILTER_RELATED_BY_SENDERS.name] = [myUserId];
} }
filter.setDefinition(definition); filter.setDefinition(definition);
@@ -1681,7 +1679,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
return event.getSender() === this.client.getUserId(); return event.getSender() === this.client.getUserId();
}); });
if (filterType !== ThreadFilterType.My || currentUserParticipated) { if (filterType !== ThreadFilterType.My || currentUserParticipated) {
timelineSet.getLiveTimeline().addEvent(thread.rootEvent, { timelineSet.getLiveTimeline().addEvent(thread.rootEvent!, {
toStartOfTimeline: false, toStartOfTimeline: false,
}); });
} }
@@ -1851,8 +1849,8 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
* @param {Filter} filter the filter whose timelineSet is to be forgotten * @param {Filter} filter the filter whose timelineSet is to be forgotten
*/ */
public removeFilteredTimelineSet(filter: Filter): void { public removeFilteredTimelineSet(filter: Filter): void {
const timelineSet = this.filteredTimelineSets[filter.filterId]; const timelineSet = this.filteredTimelineSets[filter.filterId!];
delete this.filteredTimelineSets[filter.filterId]; delete this.filteredTimelineSets[filter.filterId!];
const i = this.timelineSets.indexOf(timelineSet); const i = this.timelineSets.indexOf(timelineSet);
if (i > -1) { if (i > -1) {
this.timelineSets.splice(i, 1); this.timelineSets.splice(i, 1);
@@ -2187,7 +2185,7 @@ export class Room extends ReadReceipt<RoomEmittedEvents, RoomEventHandlerMap> {
// call setEventMetadata to set up event.sender etc // call setEventMetadata to set up event.sender etc
// as event is shared over all timelineSets, we set up its metadata based // as event is shared over all timelineSets, we set up its metadata based
// on the unfiltered timelineSet. // on the unfiltered timelineSet.
EventTimeline.setEventMetadata(event, this.getLiveTimeline().getState(EventTimeline.FORWARDS), false); EventTimeline.setEventMetadata(event, this.getLiveTimeline().getState(EventTimeline.FORWARDS)!, false);
this.txnToEvent[txnId] = event; this.txnToEvent[txnId] = event;
if (this.pendingEventList) { if (this.pendingEventList) {

View File

@@ -201,7 +201,7 @@ export class Thread extends ReadReceipt<EmittedEvents, EventHandlerMap> {
}; };
public get roomState(): RoomState { public get roomState(): RoomState {
return this.room.getLiveTimeline().getState(EventTimeline.FORWARDS); return this.room.getLiveTimeline().getState(EventTimeline.FORWARDS)!;
} }
private addEventToTimeline(event: MatrixEvent, toStartOfTimeline: boolean): void { private addEventToTimeline(event: MatrixEvent, toStartOfTimeline: boolean): void {

View File

@@ -219,8 +219,11 @@ export class PushProcessor {
return null; return null;
} }
private templateRuleToRaw(kind: PushRuleKind, tprule: any): any { private templateRuleToRaw(
const rawrule = { kind: PushRuleKind,
tprule: IPushRule,
): Pick<IPushRule, "rule_id" | "actions" | "conditions"> | null {
const rawrule: Pick<IPushRule, "rule_id" | "actions" | "conditions"> = {
'rule_id': tprule.rule_id, 'rule_id': tprule.rule_id,
'actions': tprule.actions, 'actions': tprule.actions,
'conditions': [], 'conditions': [],
@@ -234,7 +237,7 @@ export class PushProcessor {
if (!tprule.rule_id) { if (!tprule.rule_id) {
return null; return null;
} }
rawrule.conditions.push({ rawrule.conditions!.push({
'kind': ConditionKind.EventMatch, 'kind': ConditionKind.EventMatch,
'key': 'room_id', 'key': 'room_id',
'value': tprule.rule_id, 'value': tprule.rule_id,
@@ -244,7 +247,7 @@ export class PushProcessor {
if (!tprule.rule_id) { if (!tprule.rule_id) {
return null; return null;
} }
rawrule.conditions.push({ rawrule.conditions!.push({
'kind': ConditionKind.EventMatch, 'kind': ConditionKind.EventMatch,
'key': 'user_id', 'key': 'user_id',
'value': tprule.rule_id, 'value': tprule.rule_id,
@@ -254,7 +257,7 @@ export class PushProcessor {
if (!tprule.pattern) { if (!tprule.pattern) {
return null; return null;
} }
rawrule.conditions.push({ rawrule.conditions!.push({
'kind': ConditionKind.EventMatch, 'kind': ConditionKind.EventMatch,
'key': 'content.body', 'key': 'content.body',
'pattern': tprule.pattern, 'pattern': tprule.pattern,
@@ -474,7 +477,7 @@ export class PushProcessor {
return actionObj; return actionObj;
} }
public ruleMatchesEvent(rule: IPushRule, ev: MatrixEvent): boolean { public ruleMatchesEvent(rule: Partial<IPushRule> & Pick<IPushRule, "conditions">, ev: MatrixEvent): boolean {
if (!rule.conditions?.length) return true; if (!rule.conditions?.length) return true;
let ret = true; let ret = true;

View File

@@ -347,7 +347,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
public isPtt = false; public isPtt = false;
private readonly client: MatrixClient; private readonly client: MatrixClient;
private readonly forceTURN: boolean; private readonly forceTURN?: boolean;
private readonly turnServers: Array<TurnServer>; private readonly turnServers: Array<TurnServer>;
// A queue for candidates waiting to go out. // A queue for candidates waiting to go out.
// We try to amalgamate candidates into a single candidate message where // We try to amalgamate candidates into a single candidate message where
@@ -979,9 +979,9 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
wantedValue} because the other side doesn't support it. Answering with ${ wantedValue} because the other side doesn't support it. Answering with ${
type}=${valueOfTheOtherSide}.`, type}=${valueOfTheOtherSide}.`,
); );
return valueOfTheOtherSide; return valueOfTheOtherSide!;
} }
return wantedValue ?? valueOfTheOtherSide; return wantedValue ?? valueOfTheOtherSide!;
} }
/** /**

View File

@@ -8,7 +8,8 @@
"noImplicitAny": false, "noImplicitAny": false,
"noUnusedLocals": true, "noUnusedLocals": true,
"noEmit": true, "noEmit": true,
"declaration": true "declaration": true,
"strict": true
}, },
"include": [ "include": [
"./src/**/*.ts", "./src/**/*.ts",

180
yarn.lock
View File

@@ -1092,6 +1092,15 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@casualbot/jest-sonar-reporter@^2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@casualbot/jest-sonar-reporter/-/jest-sonar-reporter-2.2.5.tgz#23d187ddb8d65129a3c8d8239b0540a52c4dc82a"
integrity sha512-Pmb4aEtJudz9G0VsmEUzuDm5iWGOCDsmulzi6AP/RgAXEcmsSxVdxjcgA+2SHC005diU4mXnPLiQyiiMIAtUjA==
dependencies:
mkdirp "1.0.4"
uuid "8.3.2"
xml "1.0.1"
"@eslint/eslintrc@^1.3.3": "@eslint/eslintrc@^1.3.3":
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95"
@@ -1894,6 +1903,11 @@
"@typescript-eslint/types" "5.42.0" "@typescript-eslint/types" "5.42.0"
eslint-visitor-keys "^3.3.0" eslint-visitor-keys "^3.3.0"
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
JSONStream@^1.0.3: JSONStream@^1.0.3:
version "1.3.5" version "1.3.5"
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
@@ -2612,7 +2626,7 @@ chalk@^2.0.0:
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
supports-color "^5.3.0" supports-color "^5.3.0"
chalk@^4.0.0: chalk@^4.0.0, chalk@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@@ -2647,6 +2661,11 @@ chokidar@^3.4.0:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
ci-info@^3.2.0, ci-info@^3.4.0: ci-info@^3.2.0, ci-info@^3.4.0:
version "3.5.0" version "3.5.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.5.0.tgz#bfac2a29263de4c829d806b1ab478e35091e171f"
@@ -2890,6 +2909,17 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
sha.js "^2.4.8" sha.js "^2.4.8"
cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
semver "^5.5.0"
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -3699,6 +3729,13 @@ find-up@^5.0.0:
locate-path "^6.0.0" locate-path "^6.0.0"
path-exists "^4.0.0" path-exists "^4.0.0"
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
dependencies:
micromatch "^4.0.2"
flat-cache@^3.0.4: flat-cache@^3.0.4:
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
@@ -3736,6 +3773,15 @@ form-data@^4.0.0:
combined-stream "^1.0.8" combined-stream "^1.0.8"
mime-types "^2.1.12" mime-types "^2.1.12"
fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-readdir-recursive@^1.1.0: fs-readdir-recursive@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
@@ -3889,7 +3935,7 @@ globrex@^0.1.2:
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
graceful-fs@^4.1.9, graceful-fs@^4.2.4, graceful-fs@^4.2.9: graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
version "4.2.10" version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -4170,6 +4216,13 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-ci@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
dependencies:
ci-info "^2.0.0"
is-core-module@^2.10.0, is-core-module@^2.8.1, is-core-module@^2.9.0: is-core-module@^2.10.0, is-core-module@^2.8.1, is-core-module@^2.9.0:
version "2.11.0" version "2.11.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
@@ -4327,7 +4380,7 @@ is-weakref@^1.0.2:
dependencies: dependencies:
call-bind "^1.0.2" call-bind "^1.0.2"
is-wsl@^2.2.0: is-wsl@^2.1.1, is-wsl@^2.2.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
@@ -4761,13 +4814,6 @@ jest-snapshot@^29.2.2:
pretty-format "^29.2.1" pretty-format "^29.2.1"
semver "^7.3.5" semver "^7.3.5"
jest-sonar-reporter@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz#faa54a7d2af7198767ee246a82b78c576789cf08"
integrity sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==
dependencies:
xml "^1.0.1"
jest-util@^28.1.3: jest-util@^28.1.3:
version "28.1.3" version "28.1.3"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0"
@@ -4966,6 +5012,13 @@ json5@^2.2.1:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==
optionalDependencies:
graceful-fs "^4.1.6"
jsonparse@^1.2.0: jsonparse@^1.2.0:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@@ -4991,6 +5044,13 @@ kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klaw-sync@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
dependencies:
graceful-fs "^4.1.11"
klaw@^3.0.0: klaw@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146"
@@ -5183,7 +5243,7 @@ marked@^4.0.10:
resolved "https://registry.yarnpkg.com/marked/-/marked-4.1.1.tgz#2f709a4462abf65a283f2453dc1c42ab177d302e" resolved "https://registry.yarnpkg.com/marked/-/marked-4.1.1.tgz#2f709a4462abf65a283f2453dc1c42ab177d302e"
integrity sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw== integrity sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==
matrix-events-sdk@^0.0.1-beta.7: matrix-events-sdk@0.0.1-beta.7:
version "0.0.1-beta.7" version "0.0.1-beta.7"
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934" resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934"
integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA== integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA==
@@ -5241,7 +5301,7 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4: micromatch@^4.0.2, micromatch@^4.0.4:
version "4.0.5" version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
@@ -5306,7 +5366,7 @@ mkdirp-classic@^0.5.2:
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mkdirp@^1.0.4: mkdirp@1.0.4, mkdirp@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -5375,6 +5435,11 @@ next-tick@1, next-tick@^1.1.0:
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-dir@^0.1.10: node-dir@^0.1.10:
version "0.1.17" version "0.1.17"
resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5"
@@ -5474,6 +5539,14 @@ onetime@^5.1.2:
dependencies: dependencies:
mimic-fn "^2.1.0" mimic-fn "^2.1.0"
open@^7.4.2:
version "7.4.2"
resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
open@^8.4.0: open@^8.4.0:
version "8.4.0" version "8.4.0"
resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8"
@@ -5512,6 +5585,11 @@ os-browserify@~0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
p-limit@^2.0.0, p-limit@^2.2.0: p-limit@^2.0.0, p-limit@^2.2.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@@ -5612,6 +5690,26 @@ parse5@6.0.1:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
patch-package@^6.5.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.5.0.tgz#feb058db56f0005da59cfa316488321de585e88a"
integrity sha512-tC3EqJmo74yKqfsMzELaFwxOAu6FH6t+FzFOsnWAuARm7/n2xB5AOeOueE221eM9gtMuIKMKpF9tBy/X2mNP0Q==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^4.1.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^2.0.0"
fs-extra "^7.0.1"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.6"
open "^7.4.2"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
yaml "^1.10.2"
path-browserify@^1.0.0: path-browserify@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
@@ -5632,6 +5730,11 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
path-key@^3.0.0, path-key@^3.1.0: path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
@@ -5702,6 +5805,11 @@ pluralize@^8.0.0:
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1"
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
postinstall-postinstall@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3"
integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==
prelude-ls@^1.2.1: prelude-ls@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -6202,6 +6310,13 @@ right-align@^0.1.1:
dependencies: dependencies:
align-text "^0.1.1" align-text "^0.1.1"
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
rimraf@^3.0.2: rimraf@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@@ -6267,7 +6382,7 @@ sdp-transform@^2.14.1:
resolved "https://registry.yarnpkg.com/sdp-transform/-/sdp-transform-2.14.1.tgz#2bb443583d478dee217df4caa284c46b870d5827" resolved "https://registry.yarnpkg.com/sdp-transform/-/sdp-transform-2.14.1.tgz#2bb443583d478dee217df4caa284c46b870d5827"
integrity sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw== integrity sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw==
"semver@2 || 3 || 4 || 5", semver@^5.6.0: "semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0:
version "5.7.1" version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -6306,6 +6421,13 @@ shasum-object@^1.0.0:
dependencies: dependencies:
fast-safe-stringify "^2.0.7" fast-safe-stringify "^2.0.7"
shebang-command@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
dependencies:
shebang-regex "^1.0.0"
shebang-command@^2.0.0: shebang-command@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -6313,6 +6435,11 @@ shebang-command@^2.0.0:
dependencies: dependencies:
shebang-regex "^3.0.0" shebang-regex "^3.0.0"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
shebang-regex@^3.0.0: shebang-regex@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
@@ -6683,6 +6810,13 @@ tiny-glob@^0.2.9:
globalyzer "0.1.0" globalyzer "0.1.0"
globrex "^0.1.2" globrex "^0.1.2"
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
dependencies:
os-tmpdir "~1.0.2"
tmpl@1.0.5: tmpl@1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
@@ -6964,7 +7098,7 @@ universal-user-agent@^6.0.0:
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
universalify@^0.1.2: universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
@@ -7015,7 +7149,7 @@ util@~0.12.0:
is-typed-array "^1.1.3" is-typed-array "^1.1.3"
which-typed-array "^1.1.2" which-typed-array "^1.1.2"
uuid@^8.3.2: uuid@8.3.2, uuid@^8.3.2:
version "8.3.2" version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
@@ -7187,6 +7321,13 @@ which-typed-array@^1.1.2:
has-tostringtag "^1.0.0" has-tostringtag "^1.0.0"
is-typed-array "^1.1.9" is-typed-array "^1.1.9"
which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
which@^2.0.1: which@^2.0.1:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
@@ -7249,7 +7390,7 @@ xml-name-validator@^4.0.0:
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
xml@^1.0.1: xml@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw== integrity sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==
@@ -7284,6 +7425,11 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@^20.2.2, yargs-parser@^20.2.9: yargs-parser@^20.2.2, yargs-parser@^20.2.9:
version "20.2.9" version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"