Enable more oxlint rules (#34189)

* Fix type imports

* Fix jsdoc

* Fixup types

* Fix stray awaits on non-thenables

* Fixup imports

* Fix splats

* Fix this-context on callbacks

* Memoise react contexts

* Prefer find/flatMap

* Make oxlint happier about our React keys

* Avoid unsafe default function params

* Fixup jsdoc

* Fixup contexts

* Switch from eslint to oxlint

* Some oxlint-related tweaks

* Iterate

* Partial revert to defer some changes and shrink diff

* Iterate

* Add eslint-plugin-element-call and enable the copyright rule

* Set strictStorePkgContentCheck

* Iterate

* Enable forwardRef oxlint rule

* Enable no-unused-vars oxlint rule

* Enable no-implied-eval oxlint rule

* Enable no-duplicate-type-constituents oxlint rule

* Enable explicit-length-check oxlint rule

* Enable prefer-number-properties oxlint rule

* Enable no-callback-in-promise oxlint rule

* Enable no-require-imports oxlint rule

* Remove disablement of most unicorn oxlint rules

* Enable no-conditional-tests oxlint rule

* Enable promise-valid-params oxlint rule

* Enable require-unicode-regexp oxlint rule

* Remove max-len comments as we use oxfmt for formatting

* Enable majority of oxlint `suspicious` rules

* Iterate

* Fix oxlint type-aware lint running without dependencies built
This commit is contained in:
Michael Telatynski
2026-07-29 08:26:07 +00:00
committed by GitHub
parent e8848e4746
commit bbec915fb0
178 changed files with 405 additions and 403 deletions
@@ -64,6 +64,7 @@ const mapAutoDiscoveryErrorTranslation = (err: AutoDiscoveryError): TranslationK
}
};
// oxlint-disable-next-line typescript/no-extraneous-class
export default class AutoDiscoveryUtils {
/**
* Checks if a given error or error message is considered an error
+1 -1
View File
@@ -165,7 +165,7 @@ const getMsc3531Enabled = (): boolean => {
if (msc3531Enabled === null) {
msc3531Enabled = SettingsStore.getValue("feature_msc3531_hide_messages_pending_moderation");
}
return msc3531Enabled!;
return msc3531Enabled;
};
/**
+1 -1
View File
@@ -95,7 +95,7 @@ export function formatList(items: ReactNode[], itemLimit = items.length, include
}
if (items.every((e) => typeof e === "string")) {
return formatter.format(items as string[]);
return formatter.format(items);
}
const parts = formatter.formatToParts(items.map((_, i) => `${i}`));
+1 -1
View File
@@ -75,7 +75,7 @@ export class MediaEventHelper implements IDestroyable {
private fetchSource = (): Promise<Blob> => {
const content = this.event.getContent<MediaEventContent>();
if (this.media.isEncrypted) {
return decryptFile(content.file!, content.info);
return decryptFile(content.file, content.info);
}
return (
+4 -4
View File
@@ -68,7 +68,7 @@ function findRefNodes(
const end = isAddition ? route.length - 1 : route.length;
for (let i = 0; i < end; ++i) {
refParentNode = refNode;
refNode = refNode?.childNodes[route[i]!];
refNode = refNode?.childNodes[route[i]];
}
return { refNode, refParentNode };
}
@@ -117,7 +117,7 @@ function isRouteOfNextSibling(route1: number[], route2: number[]): boolean {
// last element of route1 being larger
// (e.g. coming behind route1 at that level)
const lastD1Idx = route1.length - 1;
return route2[lastD1Idx]! >= route1[lastD1Idx]!;
return route2[lastD1Idx] >= route1[lastD1Idx];
}
function adjustRoutes(diff: IDiff, remainingDiffs: IDiff[]): void {
@@ -261,9 +261,9 @@ export function editBodyDiffToHtml(originalContent: IContent, editContent: ICont
const diffMathPatch = new DiffMatchPatch();
// parse the base html message as a DOM tree, to which we'll apply the differences found.
// fish out the div in which we wrapped the messages above with children[0].
const originalRootNode = new DOMParser().parseFromString(originalBody, "text/html").body.children[0]!;
const originalRootNode = new DOMParser().parseFromString(originalBody, "text/html").body.children[0];
for (let i = 0; i < diffActions.length; ++i) {
const diff = diffActions[i]!;
const diff = diffActions[i];
renderDifferenceInDOM(originalRootNode, diff, diffMathPatch);
// DiffDOM assumes in subsequent diffs route path that
// the action was applied (e.g. that a removeElement action removed the element).
+1
View File
@@ -19,6 +19,7 @@ import {
import { isContentActionable } from "./EventUtils";
import { ReadPinsEventId } from "../components/views/right_panel/types";
// oxlint-disable-next-line typescript/no-extraneous-class
export default class PinningUtils {
/**
* Event types that may be pinned.
+1 -1
View File
@@ -47,7 +47,7 @@ async function idbInit(): Promise<void> {
async function idbTransaction(
table: string,
mode: IDBTransactionMode,
fn: (objectStore: IDBObjectStore) => IDBRequest<any>,
fn: (objectStore: IDBObjectStore) => IDBRequest,
): Promise<any> {
if (!idb) {
await idbInit();
+1 -1
View File
@@ -59,7 +59,7 @@ export function getTileServerWellKnown(matrixClient: MatrixClient): ITileServerW
return tileServerFromWellKnown(matrixClient.getClientWellKnown());
}
export function tileServerFromWellKnown(clientWellKnown?: IClientWellKnown | undefined): ITileServerWellKnown {
export function tileServerFromWellKnown(clientWellKnown?: IClientWellKnown): ITileServerWellKnown {
return clientWellKnown?.[TILE_SERVER_WK_KEY.name] ?? clientWellKnown?.[TILE_SERVER_WK_KEY.altName];
}
+1
View File
@@ -38,6 +38,7 @@ const WIDGET_WAIT_TIME = 20000;
export type { IWidgetEvent, UserWidget };
// oxlint-disable-next-line typescript/no-extraneous-class
export default class WidgetUtils {
/**
* Returns true if user is able to send state events to modify widgets in this room
+4 -4
View File
@@ -46,9 +46,9 @@ export const getBeaconBounds = (beacons: Beacon[]): Bounds | undefined => {
if (sortedByLat.length < 1 || sortedByLong.length < 1) return;
return {
north: sortedByLat[0]!.latitude,
south: sortedByLat[sortedByLat.length - 1]!.latitude,
east: sortedByLong[0]!.longitude,
west: sortedByLong[sortedByLong.length - 1]!.longitude,
north: sortedByLat[0].latitude,
south: sortedByLat[sortedByLat.length - 1].latitude,
east: sortedByLong[0].longitude,
west: sortedByLong[sortedByLong.length - 1].longitude,
};
};
@@ -362,9 +362,9 @@ export default class HTMLExporter extends Exporter {
protected createModifiedEvent(text: string, mxEv: MatrixEvent, italic = true): MatrixEvent {
const modifiedContent = {
msgtype: MsgType.Text,
body: `${text}`,
body: text,
format: "org.matrix.custom.html",
formatted_body: `${text}`,
formatted_body: text,
};
if (italic) {
modifiedContent.formatted_body = "<em>" + modifiedContent.formatted_body + "</em>";
+2 -2
View File
@@ -28,7 +28,7 @@ describe("createMapSiteLinkFromEvent", () => {
it("returns OpenStreetMap link if event contains m.location with valid uri", () => {
expect(createMapSiteLinkFromEvent(makeLocationEvent("geo:51.5076,-0.1276"))).toEqual(
"https://www.openstreetmap.org/" + "?mlat=51.5076&mlon=-0.1276" + "#map=16/51.5076/-0.1276",
"https://www.openstreetmap.org/?mlat=51.5076&mlon=-0.1276#map=16/51.5076/-0.1276",
);
});
@@ -38,7 +38,7 @@ describe("createMapSiteLinkFromEvent", () => {
it("returns OpenStreetMap link if event contains geo_uri", () => {
expect(createMapSiteLinkFromEvent(makeLegacyLocationEvent("geo:51.5076,-0.1276"))).toEqual(
"https://www.openstreetmap.org/" + "?mlat=51.5076&mlon=-0.1276" + "#map=16/51.5076/-0.1276",
"https://www.openstreetmap.org/?mlat=51.5076&mlon=-0.1276#map=16/51.5076/-0.1276",
);
});
+2 -2
View File
@@ -33,8 +33,8 @@ export const parseGeoUri = (uri: string): GeolocationCoordinates | undefined =>
}
const geoCoords = {
latitude: latitude!,
longitude: longitude!,
latitude: latitude,
longitude: longitude,
altitude: parse(coords[2]),
accuracy: uncertainty!,
altitudeAccuracy: null,
+1 -1
View File
@@ -83,7 +83,7 @@ export function attachMentions(
// mentioned users.
const prevMentions = editedContent["m.mentions"];
if (Array.isArray(prevMentions?.user_ids)) {
prevMentions!.user_ids.forEach((userId) => userMentions.delete(userId));
prevMentions.user_ids.forEach((userId) => userMentions.delete(userId));
}
// If the original event mentioned the room, nothing to do here.
+2 -2
View File
@@ -59,7 +59,7 @@ export async function createLocalNotificationSettingsIfNeeded(cli: MatrixClient)
if (cli.isGuest()) {
return;
}
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId!);
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId);
const event = cli.getAccountData(eventType);
// New sessions will create an account data event to signify they support
// remote toggling of push notifications on this device. Default `is_silenced=true`
@@ -77,7 +77,7 @@ export async function createLocalNotificationSettingsIfNeeded(cli: MatrixClient)
}
export function localNotificationsAreSilenced(cli: MatrixClient): boolean {
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId!);
const eventType = getLocalNotificationAccountDataEventType(cli.deviceId);
const event = cli.getAccountData(eventType);
return event?.getContent<LocalNotificationSettings>()?.is_silenced ?? false;
}
@@ -437,7 +437,7 @@ describe("Permalinks", function () {
it("should correctly parse event permalink via arguments", () => {
const result = parsePermalink(
"https://matrix.to/#/!room_id:server/$event_id/some_thing_here/foobar" + "?via=m1.org&via=m2.org",
"https://matrix.to/#/!room_id:server/$event_id/some_thing_here/foobar?via=m1.org&via=m2.org",
);
expect(result?.eventId).toBe("$event_id/some_thing_here/foobar");
expect(result?.roomIdOrAlias).toBe("!room_id:server");
+1 -1
View File
@@ -17,7 +17,7 @@ import { DirectoryMember, type Member, ThreepidMember } from "./direct-messages"
* @returns {Promise<Member[]>} Same list with ThreepidMembers replaced by DirectoryMembers if succesfully resolved
*/
export const resolveThreePids = async (members: Member[], client: MatrixClient): Promise<Member[]> => {
const threePidMembers = members.filter((m) => m instanceof ThreepidMember) as ThreepidMember[];
const threePidMembers = members.filter((m) => m instanceof ThreepidMember);
// Nothing to do here
if (threePidMembers.length === 0) return members;