1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-25 05:23:13 +03:00

Improve types (#3589)

* Improve types

* Improve coverage
This commit is contained in:
Michael Telatynski
2023-07-12 11:39:33 +01:00
committed by GitHub
parent 01226e41d9
commit 1cb5fff5a1
8 changed files with 319 additions and 246 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -71,6 +71,7 @@ import {
UploadResponse, UploadResponse,
HTTPError, HTTPError,
IRequestOpts, IRequestOpts,
Body,
} from "./http-api"; } from "./http-api";
import { import {
Crypto, Crypto,
@@ -2012,12 +2013,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Set whether this client is a guest account. <b>This method is experimental * Set whether this client is a guest account. <b>This method is experimental
* and may change without warning.</b> * and may change without warning.</b>
* @param guest - True if this is a guest account. * @param guest - True if this is a guest account.
* @experimental if the token is a macaroon, it should be encoded in it that it is a 'guest'
* access token, which means that the SDK can determine this entirely without
* the dev manually flipping this flag.
*/ */
public setGuest(guest: boolean): void { public setGuest(guest: boolean): void {
// EXPERIMENTAL:
// If the token is a macaroon, it should be encoded in it that it is a 'guest'
// access token, which means that the SDK can determine this entirely without
// the dev manually flipping this flag.
this.isGuestAccount = guest; this.isGuestAccount = guest;
} }
@@ -4405,7 +4405,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
private sendCompleteEvent( private sendCompleteEvent(
roomId: string, roomId: string,
threadId: string | null, threadId: string | null,
eventObject: any, eventObject: Partial<IEvent>,
txnId?: string, txnId?: string,
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
if (!txnId) { if (!txnId) {
@@ -4982,7 +4982,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Promise which resolves: to an empty object `{}` * @returns Promise which resolves: to an empty object `{}`
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public async sendReceipt(event: MatrixEvent, receiptType: ReceiptType, body: any, unthreaded = false): Promise<{}> { public async sendReceipt(
event: MatrixEvent,
receiptType: ReceiptType,
body?: Record<string, any>,
unthreaded = false,
): Promise<{}> {
if (this.isGuest()) { if (this.isGuest()) {
return Promise.resolve({}); // guests cannot send receipts so don't bother. return Promise.resolve({}); // guests cannot send receipts so don't bother.
} }
@@ -5140,7 +5145,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
$roomId: roomId, $roomId: roomId,
$userId: this.getUserId()!, $userId: this.getUserId()!,
}); });
const data: any = { const data: QueryDict = {
typing: isTyping, typing: isTyping,
}; };
if (isTyping) { if (isTyping) {
@@ -5332,7 +5337,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
} }
const populationResults: { [roomId: string]: Error } = {}; const populationResults: { [roomId: string]: Error } = {};
const promises: Promise<any>[] = []; const promises: Promise<unknown>[] = [];
const doLeave = (roomId: string): Promise<void> => { const doLeave = (roomId: string): Promise<void> => {
return this.leave(roomId) return this.leave(roomId)
@@ -5935,7 +5940,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
throw new Error("getLatestTimeline only supports room timelines"); throw new Error("getLatestTimeline only supports room timelines");
} }
let event; let event: IRoomEvent | undefined;
if (timelineSet.threadListType !== null) { if (timelineSet.threadListType !== null) {
const res = await this.createThreadListMessagesRequest( const res = await this.createThreadListMessagesRequest(
timelineSet.room.roomId, timelineSet.room.roomId,
@@ -6394,7 +6399,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
"", "",
); );
let readPromise: Promise<any> = Promise.resolve<any>(undefined); let readPromise: Promise<unknown> = Promise.resolve();
if (opts.allowRead) { if (opts.allowRead) {
readPromise = this.sendStateEvent( readPromise = this.sendStateEvent(
roomId, roomId,
@@ -6599,7 +6604,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
*/ */
private async requestTokenFromEndpoint<T extends IRequestTokenResponse>( private async requestTokenFromEndpoint<T extends IRequestTokenResponse>(
endpoint: string, endpoint: string,
params: Record<string, any>, params: QueryDict,
): Promise<T> { ): Promise<T> {
const postParams = Object.assign({}, params); const postParams = Object.assign({}, params);
@@ -7949,8 +7954,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* to false. * to false.
* @returns Promise which resolves: On success, the empty object * @returns Promise which resolves: On success, the empty object
*/ */
public deactivateAccount(auth?: any, erase?: boolean): Promise<{ id_server_unbind_result: IdServerUnbindResult }> { public deactivateAccount(
const body: any = {}; auth?: AuthDict,
erase?: boolean,
): Promise<{ id_server_unbind_result: IdServerUnbindResult }> {
const body: Body = {};
if (auth) { if (auth) {
body.auth = auth; body.auth = auth;
} }
@@ -8188,7 +8196,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
public sendStateEvent( public sendStateEvent(
roomId: string, roomId: string,
eventType: string, eventType: string,
content: any, content: IContent,
stateKey = "", stateKey = "",
opts: IRequestOpts = {}, opts: IRequestOpts = {},
): Promise<ISendEventResponse> { ): Promise<ISendEventResponse> {
@@ -8406,13 +8414,13 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* it invisible. * it invisible.
* @returns Promise which resolves: result object * @returns Promise which resolves: result object
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
* @deprecated missing from the spec
*/ */
public setRoomDirectoryVisibilityAppService( public setRoomDirectoryVisibilityAppService(
networkId: string, networkId: string,
roomId: string, roomId: string,
visibility: "public" | "private", visibility: "public" | "private",
): Promise<any> { ): Promise<any> {
// TODO: Types
const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", { const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", {
$networkId: networkId, $networkId: networkId,
$roomId: roomId, $roomId: roomId,
@@ -8428,7 +8436,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Promise which resolves: an array of results. * @returns Promise which resolves: an array of results.
*/ */
public searchUserDirectory({ term, limit }: { term: string; limit?: number }): Promise<IUserDirectoryResponse> { public searchUserDirectory({ term, limit }: { term: string; limit?: number }): Promise<IUserDirectoryResponse> {
const body: any = { const body: Body = {
search_term: term, search_term: term,
}; };
@@ -8506,14 +8514,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* Add a 3PID to your homeserver account and optionally bind it to an identity * Add a 3PID to your homeserver account and optionally bind it to an identity
* server as well. An identity server is required as part of the `creds` object. * server as well. An identity server is required as part of the `creds` object.
* *
* This API is deprecated, and you should instead use `addThreePidOnly` * @deprecated this API is deprecated, and you should instead use `addThreePidOnly` for homeservers that support it.
* for homeservers that support it.
* *
* @returns Promise which resolves: on success * @returns Promise which resolves: on success
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public addThreePid(creds: any, bind: boolean): Promise<any> { public addThreePid(creds: IBindThreePidBody, bind: boolean): Promise<{ submit_url?: string }> {
// TODO: Types
const path = "/account/3pid"; const path = "/account/3pid";
const data = { const data = {
threePidCreds: creds, threePidCreds: creds,
@@ -8673,7 +8679,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
$device_id: deviceId, $device_id: deviceId,
}); });
const body: any = {}; const body: Body = {};
if (auth) { if (auth) {
body.auth = auth; body.auth = auth;
@@ -8691,7 +8697,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* @returns Rejects: with an error response. * @returns Rejects: with an error response.
*/ */
public deleteMultipleDevices(devices: string[], auth?: AuthDict): Promise<{}> { public deleteMultipleDevices(devices: string[], auth?: AuthDict): Promise<{}> {
const body: any = { devices }; const body: Body = { devices };
if (auth) { if (auth) {
body.auth = auth; body.auth = auth;
@@ -8868,7 +8874,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
{ body, next_batch: nextBatch }: { body: ISearchRequestBody; next_batch?: string }, { body, next_batch: nextBatch }: { body: ISearchRequestBody; next_batch?: string },
abortSignal?: AbortSignal, abortSignal?: AbortSignal,
): Promise<ISearchResponse> { ): Promise<ISearchResponse> {
const queryParams: any = {}; const queryParams: QueryDict = {};
if (nextBatch) { if (nextBatch) {
queryParams.next_batch = nextBatch; queryParams.next_batch = nextBatch;
} }
@@ -9488,7 +9494,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
* response to getThirdpartyProtocols() * response to getThirdpartyProtocols()
* @returns Promise which resolves to the result object * @returns Promise which resolves to the result object
*/ */
public getThirdpartyUser(protocol: string, params: any): Promise<IThirdPartyUser[]> { public getThirdpartyUser(protocol: string, params?: QueryDict): Promise<IThirdPartyUser[]> {
const path = utils.encodeUri("/thirdparty/user/$protocol", { const path = utils.encodeUri("/thirdparty/user/$protocol", {
$protocol: protocol, $protocol: protocol,
}); });
@@ -9664,7 +9670,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
proxyBaseUrl?: string, proxyBaseUrl?: string,
abortSignal?: AbortSignal, abortSignal?: AbortSignal,
): Promise<MSC3575SlidingSyncResponse> { ): Promise<MSC3575SlidingSyncResponse> {
const qps: Record<string, any> = {}; const qps: QueryDict = {};
if (req.pos) { if (req.pos) {
qps.pos = req.pos; qps.pos = req.pos;
delete req.pos; delete req.pos;

View File

@@ -18,8 +18,7 @@ limitations under the License.
* Cross signing methods * Cross signing methods
*/ */
import { PkSigning } from "@matrix-org/olm"; import type { PkSigning } from "@matrix-org/olm";
import { decodeBase64, encodeBase64, IObject, pkSign, pkVerify } from "./olmlib"; import { decodeBase64, encodeBase64, IObject, pkSign, pkVerify } from "./olmlib";
import { logger } from "../logger"; import { logger } from "../logger";
import { IndexedDBCryptoStore } from "../crypto/store/indexeddb-crypto-store"; import { IndexedDBCryptoStore } from "../crypto/store/indexeddb-crypto-store";
@@ -245,7 +244,7 @@ export class CrossSigningInfo {
* @returns A map from key type (string) to private key (Uint8Array) * @returns A map from key type (string) to private key (Uint8Array)
*/ */
public async getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>> { public async getCrossSigningKeysFromCache(): Promise<Map<string, Uint8Array>> {
const keys = new Map(); const keys = new Map<string, Uint8Array>();
const cacheCallbacks = this.cacheCallbacks; const cacheCallbacks = this.cacheCallbacks;
if (!cacheCallbacks) return keys; if (!cacheCallbacks) return keys;
for (const type of ["master", "self_signing", "user_signing"]) { for (const type of ["master", "self_signing", "user_signing"]) {
@@ -294,8 +293,8 @@ export class CrossSigningInfo {
const privateKeys: Record<string, Uint8Array> = {}; const privateKeys: Record<string, Uint8Array> = {};
const keys: Record<string, ICrossSigningKey> = {}; const keys: Record<string, ICrossSigningKey> = {};
let masterSigning; let masterSigning: PkSigning | undefined;
let masterPub; let masterPub: string | undefined;
try { try {
if (level & CrossSigningLevel.MASTER) { if (level & CrossSigningLevel.MASTER) {

View File

@@ -48,7 +48,7 @@ import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChan
import { Request, ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel"; import { Request, ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel";
import { IllegalMethod } from "./verification/IllegalMethod"; import { IllegalMethod } from "./verification/IllegalMethod";
import { KeySignatureUploadError } from "../errors"; import { KeySignatureUploadError } from "../errors";
import { calculateKeyCheck, decryptAES, encryptAES } from "./aes"; import { calculateKeyCheck, decryptAES, encryptAES, IEncryptedPayload } from "./aes";
import { DehydrationManager } from "./dehydration"; import { DehydrationManager } from "./dehydration";
import { BackupManager } from "./backup"; import { BackupManager } from "./backup";
import { IStore } from "../store"; import { IStore } from "../store";
@@ -1242,8 +1242,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
* @returns the key, if any, or null * @returns the key, if any, or null
*/ */
public async getSessionBackupPrivateKey(): Promise<Uint8Array | null> { public async getSessionBackupPrivateKey(): Promise<Uint8Array | null> {
let key = await new Promise<any>((resolve) => { let key = await new Promise<Uint8Array | IEncryptedPayload | null>((resolve) => {
// TODO types
this.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => { this.cryptoStore.doTxn("readonly", [IndexedDBCryptoStore.STORE_ACCOUNT], (txn) => {
this.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1"); this.cryptoStore.getSecretStorePrivateKey(txn, resolve, "m.megolm_backup.v1");
}); });
@@ -1254,7 +1253,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(key) || key)); key = new Uint8Array(olmlib.decodeBase64(fixBackupKey(key) || key));
await this.storeSessionBackupPrivateKey(key); await this.storeSessionBackupPrivateKey(key);
} }
if (key && key.ciphertext) { if (key && typeof key === "object" && "ciphertext" in key) {
const pickleKey = Buffer.from(this.olmDevice.pickleKey); const pickleKey = Buffer.from(this.olmDevice.pickleKey);
const decrypted = await decryptAES(key, pickleKey, "m.megolm_backup.v1"); const decrypted = await decryptAES(key, pickleKey, "m.megolm_backup.v1");
key = olmlib.decodeBase64(decrypted); key = olmlib.decodeBase64(decrypted);
@@ -2202,12 +2201,12 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
blocked: boolean | null = null, blocked: boolean | null = null,
known: boolean | null = null, known: boolean | null = null,
keys?: Record<string, string>, keys?: Record<string, string>,
): Promise<DeviceInfo | CrossSigningInfo> { ): Promise<DeviceInfo | CrossSigningInfo | ICrossSigningKey | undefined> {
// Check if the 'device' is actually a cross signing key // Check if the 'device' is actually a cross signing key
// The js-sdk's verification treats cross-signing keys as devices // The js-sdk's verification treats cross-signing keys as devices
// and so uses this method to mark them verified. // and so uses this method to mark them verified.
const xsk = this.deviceList.getStoredCrossSigningForUser(userId); const xsk = this.deviceList.getStoredCrossSigningForUser(userId);
if (xsk && xsk.getId() === deviceId) { if (xsk?.getId() === deviceId) {
if (blocked !== null || known !== null) { if (blocked !== null || known !== null) {
throw new Error("Cannot set blocked or known for a cross-signing key"); throw new Error("Cannot set blocked or known for a cross-signing key");
} }
@@ -2257,7 +2256,7 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
// This will emit events when it comes back down the sync // This will emit events when it comes back down the sync
// (we could do local echo to speed things up) // (we could do local echo to speed things up)
} }
return device as any; // TODO types return device!;
} else { } else {
return xsk; return xsk;
} }

View File

@@ -22,13 +22,11 @@ import { checkObjectHasKeys, encodeParams } from "../utils";
import { TypedEventEmitter } from "../models/typed-event-emitter"; import { TypedEventEmitter } from "../models/typed-event-emitter";
import { Method } from "./method"; import { Method } from "./method";
import { ConnectionError, MatrixError } from "./errors"; import { ConnectionError, MatrixError } from "./errors";
import { HttpApiEvent, HttpApiEventHandlerMap, IHttpOpts, IRequestOpts } from "./interface"; import { HttpApiEvent, HttpApiEventHandlerMap, IHttpOpts, IRequestOpts, Body } from "./interface";
import { anySignal, parseErrorResponse, timeoutSignal } from "./utils"; import { anySignal, parseErrorResponse, timeoutSignal } from "./utils";
import { QueryDict } from "../utils"; import { QueryDict } from "../utils";
import { logger } from "../logger"; import { logger } from "../logger";
type Body = Record<string, any> | BodyInit;
interface TypedResponse<T> extends Response { interface TypedResponse<T> extends Response {
json(): Promise<T>; json(): Promise<T>;
} }

View File

@@ -16,6 +16,8 @@ limitations under the License.
import { MatrixError } from "./errors"; import { MatrixError } from "./errors";
export type Body = Record<string, any> | BodyInit;
export interface IHttpOpts { export interface IHttpOpts {
fetchFn?: typeof global.fetch; fetchFn?: typeof global.fetch;

View File

@@ -17,7 +17,12 @@ limitations under the License.
import { UnstableValue } from "matrix-events-sdk"; import { UnstableValue } from "matrix-events-sdk";
import { RendezvousChannel, RendezvousFailureListener, RendezvousFailureReason, RendezvousIntent } from "."; import { RendezvousChannel, RendezvousFailureListener, RendezvousFailureReason, RendezvousIntent } from ".";
import { IMSC3882GetLoginTokenCapability, MatrixClient, UNSTABLE_MSC3882_CAPABILITY } from "../client"; import {
ICrossSigningKey,
IMSC3882GetLoginTokenCapability,
MatrixClient,
UNSTABLE_MSC3882_CAPABILITY,
} from "../client";
import { CrossSigningInfo } from "../crypto/CrossSigning"; import { CrossSigningInfo } from "../crypto/CrossSigning";
import { DeviceInfo } from "../crypto/deviceinfo"; import { DeviceInfo } from "../crypto/deviceinfo";
import { buildFeatureSupportMap, Feature, ServerSupport } from "../feature"; import { buildFeatureSupportMap, Feature, ServerSupport } from "../feature";
@@ -178,7 +183,9 @@ export class MSC3906Rendezvous {
return deviceId; return deviceId;
} }
private async verifyAndCrossSignDevice(deviceInfo: DeviceInfo): Promise<CrossSigningInfo | DeviceInfo> { private async verifyAndCrossSignDevice(
deviceInfo: DeviceInfo,
): Promise<CrossSigningInfo | DeviceInfo | ICrossSigningKey | undefined> {
if (!this.client.crypto) { if (!this.client.crypto) {
throw new Error("Crypto not available on client"); throw new Error("Crypto not available on client");
} }
@@ -223,7 +230,7 @@ export class MSC3906Rendezvous {
*/ */
public async verifyNewDeviceOnExistingDevice( public async verifyNewDeviceOnExistingDevice(
timeout = 10 * 1000, timeout = 10 * 1000,
): Promise<DeviceInfo | CrossSigningInfo | undefined> { ): Promise<DeviceInfo | CrossSigningInfo | ICrossSigningKey | undefined> {
if (!this.newDeviceId) { if (!this.newDeviceId) {
throw new Error("No new device to sign"); throw new Error("No new device to sign");
} }

View File

@@ -23,14 +23,13 @@ export class MediaTrackHandler {
const isNotNullAndKind = (track: MediaStreamTrack | null): boolean => { const isNotNullAndKind = (track: MediaStreamTrack | null): boolean => {
return track !== null && track.kind === kind; return track !== null && track.kind === kind;
}; };
// @ts-ignore The linter don't get it
return this.pc return this.pc
.getTransceivers() .getTransceivers()
.filter((t) => t.currentDirection === "sendonly" || t.currentDirection === "sendrecv") .filter((t) => t.currentDirection === "sendonly" || t.currentDirection === "sendrecv")
.filter((t) => t.sender !== null) .filter((t) => t.sender !== null)
.map((t) => t.sender) .map((t) => t.sender)
.map((s) => s.track) .map((s) => s.track)
.filter(isNotNullAndKind); .filter(isNotNullAndKind) as MediaStreamTrack[];
} }
public getTackById(trackId: string): MediaStreamTrack | undefined { public getTackById(trackId: string): MediaStreamTrack | undefined {