From ea34cce00ae0d799402dba8c7b172e3f4c024153 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 4 Feb 2025 13:41:32 +0000 Subject: [PATCH] Apply lint rule @typescript-eslint/no-empty-object-type (#4679) --- .eslintrc.cjs | 10 +- spec/test-utils/webrtc.ts | 3 +- spec/unit/rust-crypto/rust-crypto.spec.ts | 3 +- src/@types/common.ts | 2 + src/@types/event.ts | 14 +-- src/@types/extensible_events.ts | 4 +- src/@types/global.d.ts | 1 + src/@types/polls.ts | 3 +- src/client.ts | 105 ++++++++++---------- src/crypto-api/CryptoEventHandlerMap.ts | 3 +- src/crypto/EncryptionSetup.ts | 3 +- src/crypto/OutgoingRoomKeyRequestManager.ts | 3 +- src/embedded.ts | 9 +- src/http-api/fetch.ts | 2 +- src/interactive-auth.ts | 11 +- src/matrixrtc/MembershipManager.ts | 5 +- src/models/MSC3089TreeSpace.ts | 3 +- src/models/event.ts | 3 +- src/secret-storage.ts | 3 +- src/sliding-sync.ts | 2 +- 20 files changed, 108 insertions(+), 84 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7bad5c817..0f781215c 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -112,8 +112,13 @@ module.exports = { "@typescript-eslint/ban-ts-comment": "off", // We're okay with assertion errors when we ask for them "@typescript-eslint/no-non-null-assertion": "off", - // We do this sometimes to brand interfaces - "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-empty-object-type": [ + "error", + { + // We do this sometimes to brand interfaces + allowInterfaces: "with-single-extends", + }, + ], "quotes": "off", // We use a `logger` intermediary module @@ -147,6 +152,7 @@ module.exports = { // We don't need super strict typing in test utilities "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-member-accessibility": "off", + "@typescript-eslint/no-empty-object-type": "off", }, }, ], diff --git a/spec/test-utils/webrtc.ts b/spec/test-utils/webrtc.ts index 924d024ca..066bb09bc 100644 --- a/spec/test-utils/webrtc.ts +++ b/spec/test-utils/webrtc.ts @@ -17,6 +17,7 @@ limitations under the License. import { ClientEvent, ClientEventHandlerMap, + EmptyObject, EventType, GroupCall, GroupCallIntent, @@ -466,7 +467,7 @@ export class MockCallMatrixClient extends TypedEventEmitter(); public sendToDevice = jest.fn< - Promise<{}>, + Promise, [eventType: string, contentMap: SendToDeviceContentMap, txnId?: string] >(); diff --git a/spec/unit/rust-crypto/rust-crypto.spec.ts b/spec/unit/rust-crypto/rust-crypto.spec.ts index dec85b167..de87b52d6 100644 --- a/spec/unit/rust-crypto/rust-crypto.spec.ts +++ b/spec/unit/rust-crypto/rust-crypto.spec.ts @@ -33,6 +33,7 @@ import { AccountDataEvents, Device, DeviceVerification, + EmptyObject, encodeBase64, HttpApiEvent, HttpApiEventHandlerMap, @@ -2348,7 +2349,7 @@ class DummyAccountDataClient } } - public async setAccountData(eventType: string, content: any): Promise<{}> { + public async setAccountData(eventType: string, content: any): Promise { this.storage.set(eventType, content); this.emit( ClientEvent.AccountData, diff --git a/src/@types/common.ts b/src/@types/common.ts index fc8e7af73..bc5575b95 100644 --- a/src/@types/common.ts +++ b/src/@types/common.ts @@ -20,3 +20,5 @@ export type NonEmptyArray = [T, ...T[]]; export type Without = { [P in Exclude]?: never }; export type XOR = T | U extends object ? (Without & U) | (Without & T) : T | U; export type Writeable = { -readonly [P in keyof T]: T[P] }; + +export type EmptyObject = Record; diff --git a/src/@types/event.ts b/src/@types/event.ts index 2f4d1e950..edbb3b79b 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -38,7 +38,7 @@ import { import { IGroupCallRoomMemberState, IGroupCallRoomState } from "../webrtc/groupCall.ts"; import { MSC3089EventContent } from "../models/MSC3089Branch.ts"; import { M_BEACON, M_BEACON_INFO, MBeaconEventContent, MBeaconInfoEventContent } from "./beacon.ts"; -import { XOR } from "./common.ts"; +import { EmptyObject } from "./common.ts"; import { ReactionEventContent, RoomMessageEventContent, StickerEventContent } from "./events.ts"; import { MCallAnswer, @@ -337,7 +337,7 @@ export interface StateEvents { [EventType.RoomJoinRules]: RoomJoinRulesEventContent; [EventType.RoomMember]: RoomMemberEventContent; // XXX: Spec says this event has 3 required fields but kicking such an invitation requires sending `{}` - [EventType.RoomThirdPartyInvite]: XOR; + [EventType.RoomThirdPartyInvite]: RoomThirdPartyInviteEventContent | EmptyObject; [EventType.RoomPowerLevels]: RoomPowerLevelsEventContent; [EventType.RoomName]: RoomNameEventContent; [EventType.RoomTopic]: RoomTopicEventContent; @@ -351,13 +351,13 @@ export interface StateEvents { [EventType.SpaceChild]: SpaceChildEventContent; [EventType.SpaceParent]: SpaceParentEventContent; - [EventType.PolicyRuleUser]: XOR; - [EventType.PolicyRuleRoom]: XOR; - [EventType.PolicyRuleServer]: XOR; + [EventType.PolicyRuleUser]: PolicyRuleEventContent | EmptyObject; + [EventType.PolicyRuleRoom]: PolicyRuleEventContent | EmptyObject; + [EventType.PolicyRuleServer]: PolicyRuleEventContent | EmptyObject; // MSC3401 [EventType.GroupCallPrefix]: IGroupCallRoomState; - [EventType.GroupCallMemberPrefix]: XOR>; + [EventType.GroupCallMemberPrefix]: IGroupCallRoomMemberState | SessionMembershipData | EmptyObject; // MSC3089 [UNSTABLE_MSC3089_BRANCH.name]: MSC3089EventContent; @@ -372,7 +372,7 @@ export interface StateEvents { export interface AccountDataEvents extends SecretStorageAccountDataEvents { [EventType.PushRules]: IPushRules; [EventType.Direct]: { [userId: string]: string[] }; - [EventType.IgnoredUserList]: { [userId: string]: {} }; + [EventType.IgnoredUserList]: { ignored_users: { [userId: string]: EmptyObject } }; "m.secret_storage.default_key": { key: string }; // Flag set by the rust SDK (Element X) and also used by us to mark that the user opted out of backup // (I don't know why it's m.org.matrix...) diff --git a/src/@types/extensible_events.ts b/src/@types/extensible_events.ts index 27095c271..d6d4f0cb8 100644 --- a/src/@types/extensible_events.ts +++ b/src/@types/extensible_events.ts @@ -97,12 +97,12 @@ export type AnyRelation = TSNamespace | string; /** * An m.relates_to relationship */ -export type RelatesToRelationship = { +export type RelatesToRelationship = { "m.relates_to": { // See https://github.com/microsoft/TypeScript/issues/23182#issuecomment-379091887 for array syntax rel_type: [R] extends [never] ? AnyRelation : TSNamespace; event_id: string; - } & DefaultNever; + }; }; /** diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index c9103dbeb..c679e3cae 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -60,6 +60,7 @@ declare global { }; } + // eslint-disable-next-line @typescript-eslint/no-empty-object-type interface DummyInterfaceWeShouldntBeUsingThis {} interface Navigator { diff --git a/src/@types/polls.ts b/src/@types/polls.ts index 1a602dc0c..fecd434b4 100644 --- a/src/@types/polls.ts +++ b/src/@types/polls.ts @@ -22,6 +22,7 @@ import { RelatesToRelationship, TSNamespace, } from "./extensible_events.ts"; +import { EmptyObject } from "./common.ts"; /** * Identifier for a disclosed poll. @@ -109,7 +110,7 @@ export const M_POLL_END = new UnstableValue("m.poll.end", "org.matrix.msc3381.po /** * The event definition for an m.poll.end event (in content) */ -export type PollEndEvent = EitherAnd<{ [M_POLL_END.name]: {} }, { [M_POLL_END.altName]: {} }>; +export type PollEndEvent = EitherAnd<{ [M_POLL_END.name]: EmptyObject }, { [M_POLL_END.altName]: EmptyObject }>; /** * The content for an m.poll.end event diff --git a/src/client.ts b/src/client.ts index d2ed331cf..26addedb0 100644 --- a/src/client.ts +++ b/src/client.ts @@ -249,6 +249,7 @@ import { Capabilities, ServerCapabilities } from "./serverCapabilities.ts"; import { sha256 } from "./digest.ts"; import { keyFromAuthData } from "./common-crypto/key-passphrase.ts"; import { discoverAndValidateOIDCIssuerWellKnown, OidcClientConfig, validateAuthMetadataAndKeys } from "./oidc/index.ts"; +import { EmptyObject } from "./@types/common.ts"; export type Store = IStore; @@ -4251,7 +4252,7 @@ export class MatrixClient extends TypedEventEmitter( eventType: K, content: AccountDataEvents[K] | Record, - ): Promise<{}> { + ): Promise { const path = utils.encodeUri("/user/$userId/account_data/$type", { $userId: this.credentials.userId!, $type: eventType, @@ -4338,8 +4339,8 @@ export class MatrixClient extends TypedEventEmitter { - const content = { ignored_users: {} as Record }; + public setIgnoredUsers(userIds: string[]): Promise { + const content = { ignored_users: {} as Record }; userIds.forEach((u) => { content.ignored_users[u] = {}; }); @@ -4520,7 +4521,7 @@ export class MatrixClient extends TypedEventEmitter { + public setRoomTag(roomId: string, tagName: string, metadata: ITagMetadata = {}): Promise { const path = utils.encodeUri("/user/$userId/rooms/$roomId/tags/$tag", { $userId: this.credentials.userId!, $roomId: roomId, @@ -4534,7 +4535,7 @@ export class MatrixClient extends TypedEventEmitter { + public deleteRoomTag(roomId: string, tagName: string): Promise { const path = utils.encodeUri("/user/$userId/rooms/$roomId/tags/$tag", { $userId: this.credentials.userId!, $roomId: roomId, @@ -4549,7 +4550,7 @@ export class MatrixClient extends TypedEventEmitter): Promise<{}> { + public setRoomAccountData(roomId: string, eventType: string, content: Record): Promise { const path = utils.encodeUri("/user/$userId/rooms/$roomId/account_data/$type", { $userId: this.credentials.userId!, $roomId: roomId, @@ -5449,7 +5450,7 @@ export class MatrixClient extends TypedEventEmitter { + public async _unstable_updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise { if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) { throw Error("Server does not support the delayed events API"); } @@ -5480,7 +5481,7 @@ export class MatrixClient extends TypedEventEmitter, unthreaded = false, - ): Promise<{}> { + ): Promise { if (this.isGuest()) { return Promise.resolve({}); // guests cannot send receipts so don't bother. } @@ -5496,7 +5497,7 @@ export class MatrixClient extends TypedEventEmitter(Method.Post, path, undefined, fullBody || {}); + const promise = this.http.authedRequest(Method.Post, path, undefined, fullBody || {}); const room = this.getRoom(event.getRoomId()); if (room && this.credentials.userId) { @@ -5516,7 +5517,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { if (!event) return; const eventId = event.getId()!; const room = this.getRoom(event.getRoomId()); @@ -5546,7 +5547,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const room = this.getRoom(roomId); if (room?.hasPendingEvent(rmEventId)) { throw new Error(`Cannot set read marker to a pending event (${rmEventId})`); @@ -5627,7 +5628,7 @@ export class MatrixClient extends TypedEventEmitter { + public sendTyping(roomId: string, isTyping: boolean, timeoutMs: number): Promise { if (this.isGuest()) { return Promise.resolve({}); // guests cannot send typing notifications so don't bother. } @@ -5745,7 +5746,7 @@ export class MatrixClient extends TypedEventEmitter { + public invite(roomId: string, userId: string, reason?: string): Promise { return this.membershipChange(roomId, userId, KnownMembership.Invite, reason); } @@ -5756,7 +5757,7 @@ export class MatrixClient extends TypedEventEmitter { + public inviteByEmail(roomId: string, email: string): Promise { return this.inviteByThreePid(roomId, "email", email); } @@ -5768,7 +5769,7 @@ export class MatrixClient extends TypedEventEmitter { + public async inviteByThreePid(roomId: string, medium: string, address: string): Promise { const path = utils.encodeUri("/rooms/$roomId/invite", { $roomId: roomId }); const identityServerUrl = this.getIdentityServerUrl(true); @@ -5800,7 +5801,7 @@ export class MatrixClient extends TypedEventEmitter { + public leave(roomId: string): Promise { return this.membershipChange(roomId, undefined, KnownMembership.Leave); } @@ -5858,7 +5859,7 @@ export class MatrixClient extends TypedEventEmitter { + public ban(roomId: string, userId: string, reason?: string): Promise { return this.membershipChange(roomId, userId, KnownMembership.Ban, reason); } @@ -5868,12 +5869,12 @@ export class MatrixClient extends TypedEventEmitter { + public async forget(roomId: string, deleteRoom = true): Promise { // API returns an empty object const path = utils.encodeUri("/rooms/$room_id/forget", { $room_id: roomId, }); - const response = await this.http.authedRequest<{}>(Method.Post, path); + const response = await this.http.authedRequest(Method.Post, path); if (deleteRoom) { this.store.removeRoom(roomId); this.emit(ClientEvent.DeleteRoom, roomId); @@ -5885,7 +5886,7 @@ export class MatrixClient extends TypedEventEmitter { + public unban(roomId: string, userId: string): Promise { // unbanning != set their state to leave: this used to be // the case, but was then changed so that leaving was always // a revoking of privilege, otherwise two people racing to @@ -5905,7 +5906,7 @@ export class MatrixClient extends TypedEventEmitter { + public kick(roomId: string, userId: string, reason?: string): Promise { const path = utils.encodeUri("/rooms/$roomId/kick", { $roomId: roomId, }); @@ -5921,7 +5922,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { // API returns an empty object const path = utils.encodeUri("/rooms/$room_id/$membership", { $room_id: roomId, @@ -5972,9 +5973,9 @@ export class MatrixClient extends TypedEventEmitter; - public setProfileInfo(info: "displayname", data: { displayname: string }): Promise<{}>; - public setProfileInfo(info: "avatar_url" | "displayname", data: object): Promise<{}> { + public setProfileInfo(info: "avatar_url", data: { avatar_url: string }): Promise; + public setProfileInfo(info: "displayname", data: { displayname: string }): Promise; + public setProfileInfo(info: "avatar_url" | "displayname", data: object): Promise { const path = utils.encodeUri("/profile/$userId/$info", { $userId: this.credentials.userId!, $info: info, @@ -5986,7 +5987,7 @@ export class MatrixClient extends TypedEventEmitter { + public async setDisplayName(name: string): Promise { const prom = await this.setProfileInfo("displayname", { displayname: name }); // XXX: synthesise a profile update for ourselves because Synapse is broken and won't const user = this.getUser(this.getUserId()!); @@ -6001,7 +6002,7 @@ export class MatrixClient extends TypedEventEmitter { + public async setAvatarUrl(url: string): Promise { const prom = await this.setProfileInfo("avatar_url", { avatar_url: url }); // XXX: synthesise a profile update for ourselves because Synapse is broken and won't const user = this.getUser(this.getUserId()!); @@ -8363,7 +8364,7 @@ export class MatrixClient extends TypedEventEmitter { + public async logout(stopClient = false): Promise { if (this.crypto?.backupManager?.getKeyBackupEnabled()) { try { while ((await this.crypto.backupManager.backupPendingKeys(200)) > 0); @@ -8421,7 +8422,7 @@ export class MatrixClient extends TypedEventEmitter> { - const body: UIARequest<{}> = { auth }; + const body: UIARequest = { auth }; return this.http.authedRequest>( Method.Post, "/login/get_token", @@ -8662,7 +8663,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const path = utils.encodeUri("/rooms/$roomId/read_markers", { $roomId: roomId, }); @@ -8737,7 +8738,7 @@ export class MatrixClient extends TypedEventEmitter { + public createAlias(alias: string, roomId: string): Promise { const path = utils.encodeUri("/directory/room/$alias", { $alias: alias, }); @@ -8754,7 +8755,7 @@ export class MatrixClient extends TypedEventEmitter { + public deleteAlias(alias: string): Promise { const path = utils.encodeUri("/directory/room/$alias", { $alias: alias, }); @@ -8808,7 +8809,7 @@ export class MatrixClient extends TypedEventEmitter { + public setRoomDirectoryVisibility(roomId: string, visibility: Visibility): Promise { const path = utils.encodeUri("/directory/list/room/$roomId", { $roomId: roomId, }); @@ -9083,7 +9084,7 @@ export class MatrixClient extends TypedEventEmitter { + public async addThreePidOnly(data: IAddThreePidOnlyBody): Promise { const path = "/account/3pid/add"; return this.http.authedRequest(Method.Post, path, undefined, data); } @@ -9099,7 +9100,7 @@ export class MatrixClient extends TypedEventEmitter { + public async bindThreePid(data: IBindThreePidBody): Promise { const path = "/account/3pid/bind"; return this.http.authedRequest(Method.Post, path, undefined, data); } @@ -9153,7 +9154,7 @@ export class MatrixClient extends TypedEventEmitter { + public setPassword(authDict: AuthDict, newPassword: string, logoutDevices?: boolean): Promise { const path = "/account/password"; const data = { auth: authDict, @@ -9161,7 +9162,7 @@ export class MatrixClient extends TypedEventEmitter(Method.Post, path, undefined, data); + return this.http.authedRequest(Method.Post, path, undefined, data); } /** @@ -9195,7 +9196,7 @@ export class MatrixClient extends TypedEventEmitter { + public setDeviceDetails(deviceId: string, body: { display_name: string }): Promise { const path = utils.encodeUri("/devices/$device_id", { $device_id: deviceId, }); @@ -9211,7 +9212,7 @@ export class MatrixClient extends TypedEventEmitter { + public deleteDevice(deviceId: string, auth?: AuthDict): Promise { const path = utils.encodeUri("/devices/$device_id", { $device_id: deviceId, }); @@ -9233,7 +9234,7 @@ export class MatrixClient extends TypedEventEmitter { + public deleteMultipleDevices(devices: string[], auth?: AuthDict): Promise { const body: Body = { devices }; if (auth) { @@ -9274,7 +9275,7 @@ export class MatrixClient extends TypedEventEmitter { + public setPusher(pusher: IPusherRequest): Promise { const path = "/pushers/set"; return this.http.authedRequest(Method.Post, path, undefined, pusher); } @@ -9286,7 +9287,7 @@ export class MatrixClient extends TypedEventEmitter { + public removePusher(pushKey: string, appId: string): Promise { const path = "/pushers/set"; const body = { pushkey: pushKey, @@ -9304,7 +9305,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const key = `${LOCAL_NOTIFICATION_SETTINGS_PREFIX.name}.${deviceId}` as const; return this.setAccountData(key, notificationSettings); } @@ -9341,7 +9342,7 @@ export class MatrixClient extends TypedEventEmitter, body: Pick, - ): Promise<{}> { + ): Promise { // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -9354,7 +9355,7 @@ export class MatrixClient extends TypedEventEmitter): Promise<{}> { + public deletePushRule(scope: string, kind: PushRuleKind, ruleId: Exclude): Promise { // NB. Scope not uri encoded because devices need the '/' const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", { $kind: kind, @@ -9373,7 +9374,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", { $kind: kind, $ruleId: ruleId, @@ -9391,7 +9392,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", { $kind: kind, $ruleId: ruleId, @@ -9517,7 +9518,7 @@ export class MatrixClient extends TypedEventEmitter { + public uploadDeviceSigningKeys(auth?: AuthDict, keys?: CrossSigningKeys): Promise { // API returns empty object const data = Object.assign({}, keys); if (auth) Object.assign(data, { auth }); @@ -9857,7 +9858,7 @@ export class MatrixClient extends TypedEventEmitter { // Note: we're using the V2 API by calling this function, but our // function contract requires a V1 response. We therefore have to @@ -9953,7 +9954,7 @@ export class MatrixClient extends TypedEventEmitter { + public sendToDevice(eventType: string, contentMap: SendToDeviceContentMap, txnId?: string): Promise { const path = utils.encodeUri("/sendToDevice/$eventType/$txnId", { $eventType: eventType, $txnId: txnId ? txnId : this.makeTxnId(), @@ -10047,7 +10048,7 @@ export class MatrixClient extends TypedEventEmitter { + ): Promise { const url = this.termsUrlForService(serviceType, baseUrl); const headers = { Authorization: "Bearer " + accessToken, @@ -10070,7 +10071,7 @@ export class MatrixClient extends TypedEventEmitter { + public reportEvent(roomId: string, eventId: string, score: number, reason: string): Promise { const path = utils.encodeUri("/rooms/$roomId/report/$eventId", { $roomId: roomId, $eventId: eventId, diff --git a/src/crypto-api/CryptoEventHandlerMap.ts b/src/crypto-api/CryptoEventHandlerMap.ts index 12ffe0828..73b5f1eae 100644 --- a/src/crypto-api/CryptoEventHandlerMap.ts +++ b/src/crypto-api/CryptoEventHandlerMap.ts @@ -18,6 +18,7 @@ import { CryptoEvent } from "./CryptoEvent.ts"; import { VerificationRequest } from "./verification.ts"; import { UserVerificationStatus } from "./index.ts"; import { RustBackupCryptoEventMap } from "../rust-crypto/backup.ts"; +import { EmptyObject } from "../@types/common.ts"; /** * A map of the {@link CryptoEvent} fired by the {@link CryptoApi} and their payloads. @@ -26,7 +27,7 @@ export type CryptoEventHandlerMap = { [CryptoEvent.VerificationRequestReceived]: (request: VerificationRequest) => void; [CryptoEvent.UserTrustStatusChanged]: (userId: string, userTrustLevel: UserVerificationStatus) => void; [CryptoEvent.KeyBackupDecryptionKeyCached]: (version: string) => void; - [CryptoEvent.KeysChanged]: (data: {}) => void; + [CryptoEvent.KeysChanged]: (data: EmptyObject) => void; [CryptoEvent.WillUpdateDevices]: (users: string[], initialFetch: boolean) => void; [CryptoEvent.DevicesUpdated]: (users: string[], initialFetch: boolean) => void; [CryptoEvent.LegacyCryptoStoreMigrationProgress]: (progress: number, total: number) => void; diff --git a/src/crypto/EncryptionSetup.ts b/src/crypto/EncryptionSetup.ts index 96f892cf9..226d0e638 100644 --- a/src/crypto/EncryptionSetup.ts +++ b/src/crypto/EncryptionSetup.ts @@ -26,6 +26,7 @@ import { TypedEventEmitter } from "../models/typed-event-emitter.ts"; import { AccountDataClient, SecretStorageKeyDescription } from "../secret-storage.ts"; import { BootstrapCrossSigningOpts, CrossSigningKeyInfo } from "../crypto-api/index.ts"; import { AccountDataEvents } from "../@types/event.ts"; +import { EmptyObject } from "../@types/common.ts"; interface ICrossSigningKeys { authUpload: BootstrapCrossSigningOpts["authUploadDeviceSigningKeys"]; @@ -267,7 +268,7 @@ class AccountDataClientAdapter public setAccountData( type: K, content: AccountDataEvents[K] | Record, - ): Promise<{}> { + ): Promise { const event = new MatrixEvent({ type, content }); const lastEvent = this.values.get(type); this.values.set(type, event); diff --git a/src/crypto/OutgoingRoomKeyRequestManager.ts b/src/crypto/OutgoingRoomKeyRequestManager.ts index 4f3cf2534..dc1b59a9b 100644 --- a/src/crypto/OutgoingRoomKeyRequestManager.ts +++ b/src/crypto/OutgoingRoomKeyRequestManager.ts @@ -22,6 +22,7 @@ import { IRoomKeyRequestBody, IRoomKeyRequestRecipient } from "./index.ts"; import { CryptoStore, OutgoingRoomKeyRequest } from "./store/base.ts"; import { EventType, ToDeviceMessageId } from "../@types/event.ts"; import { MapWithDefault } from "../utils.ts"; +import { EmptyObject } from "../@types/common.ts"; /** * Internal module. Management of outgoing room key requests. @@ -460,7 +461,7 @@ export class OutgoingRoomKeyRequestManager { message: RequestMessage, recipients: IRoomKeyRequestRecipient[], txnId?: string, - ): Promise<{}> { + ): Promise { const contentMap = new MapWithDefault>>(() => new Map()); for (const recip of recipients) { const userDeviceMap = contentMap.getOrCreate(recip.userId); diff --git a/src/embedded.ts b/src/embedded.ts index b0cc4c158..efa6ffbf7 100644 --- a/src/embedded.ts +++ b/src/embedded.ts @@ -57,7 +57,7 @@ import { ToDeviceBatch, ToDevicePayload } from "./models/ToDeviceMessage.ts"; import { DeviceInfo } from "./crypto/deviceinfo.ts"; import { IOlmDevice } from "./crypto/algorithms/megolm.ts"; import { MapWithDefault, recursiveMapToObject } from "./utils.ts"; -import { TypedEventEmitter } from "./matrix.ts"; +import { EmptyObject, TypedEventEmitter } from "./matrix.ts"; interface IStateEventRequest { eventType: string; @@ -431,15 +431,16 @@ export class RoomWidgetClient extends MatrixClient { * @experimental This currently relies on an unstable MSC (MSC4140). */ // eslint-disable-next-line - public async _unstable_updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise<{}> { + public async _unstable_updateDelayedEvent(delayId: string, action: UpdateDelayedEventAction): Promise { if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) { throw Error("Server does not support the delayed events API"); } - return await this.widgetApi.updateDelayedEvent(delayId, action); + await this.widgetApi.updateDelayedEvent(delayId, action); + return {}; } - public async sendToDevice(eventType: string, contentMap: SendToDeviceContentMap): Promise<{}> { + public async sendToDevice(eventType: string, contentMap: SendToDeviceContentMap): Promise { await this.widgetApi.sendToDevice(eventType, false, recursiveMapToObject(contentMap)); return {}; } diff --git a/src/http-api/fetch.ts b/src/http-api/fetch.ts index bdf9cb153..3a8255a15 100644 --- a/src/http-api/fetch.ts +++ b/src/http-api/fetch.ts @@ -68,7 +68,7 @@ export class FetchHttpApi { this.opts.idBaseUrl = url; } - public idServerRequest>( + public idServerRequest>( method: Method, path: string, params: Record | undefined, diff --git a/src/interactive-auth.ts b/src/interactive-auth.ts index e98ed64a4..57aec75cf 100644 --- a/src/interactive-auth.ts +++ b/src/interactive-auth.ts @@ -134,6 +134,7 @@ export type AuthDict = | RecaptchaDict | EmailIdentityDict | { type: Exclude; [key: string]: any } + // eslint-disable-next-line @typescript-eslint/no-empty-object-type | {}; export class NoAuthFlowFoundError extends Error { @@ -421,10 +422,12 @@ export class InteractiveAuth { // use the sessionid from the last request, if one is present. let auth: AuthDict; if ((this.data as IAuthData)?.session) { - auth = { - session: (this.data as IAuthData).session, - }; - Object.assign(auth, authData); + auth = Object.assign( + { + session: (this.data as IAuthData).session, + }, + authData, + ); } else { auth = authData; } diff --git a/src/matrixrtc/MembershipManager.ts b/src/matrixrtc/MembershipManager.ts index 47b892d0d..ed4288a6c 100644 --- a/src/matrixrtc/MembershipManager.ts +++ b/src/matrixrtc/MembershipManager.ts @@ -10,6 +10,7 @@ import { CallMembership, DEFAULT_EXPIRE_DURATION, SessionMembershipData } from " import { Focus } from "./focus.ts"; import { isLivekitFocusActive } from "./LivekitFocus.ts"; import { MembershipConfig } from "./MatrixRTCSession.ts"; +import { EmptyObject } from "../@types/common.ts"; /** * This interface defines what a MembershipManager uses and exposes. * This interface is what we use to write tests and allows to change the actual implementation @@ -203,7 +204,7 @@ export class LegacyMembershipManager implements IMembershipManager { this.updateCallMembershipRunning = false; } }; - private makeNewMembership(deviceId: string): SessionMembershipData | {} { + private makeNewMembership(deviceId: string): SessionMembershipData | EmptyObject { // If we're joined, add our own if (this.isJoined()) { return this.makeMyMembership(deviceId); @@ -239,7 +240,7 @@ export class LegacyMembershipManager implements IMembershipManager { const localDeviceId = this.client.getDeviceId(); if (!localUserId || !localDeviceId) throw new Error("User ID or device ID was null!"); - let newContent: {} | SessionMembershipData = {}; + let newContent: EmptyObject | SessionMembershipData = {}; // TODO: add back expiary logic to non-legacy events // previously we checked here if the event is timed out and scheduled a check if not. // maybe there is a better way. diff --git a/src/models/MSC3089TreeSpace.ts b/src/models/MSC3089TreeSpace.ts index 6de3a05fd..9968c8833 100644 --- a/src/models/MSC3089TreeSpace.ts +++ b/src/models/MSC3089TreeSpace.ts @@ -35,6 +35,7 @@ import { FileType } from "../http-api/index.ts"; import { KnownMembership } from "../@types/membership.ts"; import { RoomPowerLevelsEventContent, SpaceChildEventContent } from "../@types/state_events.ts"; import type { EncryptedFile, FileContent } from "../@types/media.ts"; +import { EmptyObject } from "../@types/common.ts"; /** * The recommended defaults for a tree space's power levels. Note that this @@ -81,7 +82,7 @@ export enum TreePermissions { declare module "../@types/media" { interface FileContent { - [UNSTABLE_MSC3089_LEAF.name]?: {}; + [UNSTABLE_MSC3089_LEAF.name]?: EmptyObject; } } diff --git a/src/models/event.ts b/src/models/event.ts index 6aea68d5e..5a5d2af14 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -49,6 +49,7 @@ import { EventTimeline } from "./event-timeline.ts"; import { Membership } from "../@types/membership.ts"; import { DecryptionFailureCode } from "../crypto-api/index.ts"; import { RoomState } from "./room-state.ts"; +import { EmptyObject } from "../@types/common.ts"; export { EventStatus } from "./event-status.ts"; @@ -1376,7 +1377,7 @@ export class MatrixEvent extends TypedEventEmitter( eventType: K, content: AccountDataEvents[K] | Record, - ) => Promise<{}>; + ) => Promise; } /** diff --git a/src/sliding-sync.ts b/src/sliding-sync.ts index 4e93d8f21..7d6042c69 100644 --- a/src/sliding-sync.ts +++ b/src/sliding-sync.ts @@ -265,7 +265,7 @@ export enum ExtensionState { /** * An interface that must be satisfied to register extensions */ -export interface Extension { +export interface Extension { /** * The extension name to go under 'extensions' in the request body. * @returns The JSON key.