Enable oxlint restriction ruleset (#34307)

* Remove stale max-len disablements

* Remove stale camelCase & naming-convention disablements

* Remove stale ban-ts-comment disablements

* Remove stale no-var disablements

* Remove stale no-empty-property disablements

* Remove stale react rule disablements

* Remove stale no-constant-condition disablements

* Remove stale no-unused-vars disablements

* Remove stale disablements for disabled rules

* fixup camelcase

* Remove dead code

* Tidy code

* Tweak oxlint config

* Use oxlint to apply jsx/tsx extension consistently

* Fix import

* Fix imports

* Rename affected snapshots

* Update more imports

* Enable restriction ruleset

* Make code comply with new rules

* Make code comply with react/button-has-type

* Make code comply with typescript/non-nullable-type-assertion-style

* Comply with node/no-process-env

* Comply with unicorn/prefer-node-protocol

* Comply with unicorn/import-style

* Comply with unicorn/no-process-exit

* Comply with no-proto

* Comply with node/handle-callback-err

* Comply with import/no-commonjs

* Comply with node/no-path-concat

* Comply with unicorn/no-length-as-slice-end

* Comply with unicorn/no-document-cookie

* Comply with unicorn/prefer-module

* Comply with typescript/prefer-literal-enum-member

* Comply with jsx-a11y/anchor-ambiguous-text

* Tweak oxlint config

* Fix resolves

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate
This commit is contained in:
Michael Telatynski
2026-08-04 09:15:07 +00:00
committed by GitHub
parent c091ebec6e
commit 4aa1a3549e
167 changed files with 526 additions and 346 deletions
@@ -18,8 +18,7 @@ import dispatcher from "../../../../../src/dispatcher/dispatcher";
import { Action } from "../../../../../src/dispatcher/actions";
jest.mock("../../../../../src/stores/OwnBeaconStore", () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const EventEmitter = require("events");
const EventEmitter = jest.requireActual("events");
class MockOwnBeaconStore extends EventEmitter {
public getLiveBeaconIdsWithLocationPublishError = jest.fn().mockReturnValue([]);
public getBeaconById = jest.fn();
@@ -18,7 +18,7 @@ describe("BaseDialog", () => {
// Autolock's autofocus in the empty dialog is focusing on the close button and bringing up the tooltip
// So we either need to call escape twice(one for the tooltip and one for the dialog) or focus
// on the dialog first.
const dialog = container.querySelector('[role="dialog"]') as HTMLElement;
const dialog = container.querySelector<HTMLElement>('[role="dialog"]')!;
dialog?.focus();
await userEvent.keyboard("{Escape}");
expect(onFinished).toHaveBeenCalled();
@@ -76,41 +76,49 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
</h2>
<button
class="mx_DevTools_button"
type="button"
>
Send custom timeline event
</button>
<button
class="mx_DevTools_button"
type="button"
>
Explore room state
</button>
<button
class="mx_DevTools_button"
type="button"
>
Explore room account data
</button>
<button
class="mx_DevTools_button"
type="button"
>
View servers in room
</button>
<button
class="mx_DevTools_button"
type="button"
>
Notifications debug
</button>
<button
class="mx_DevTools_button"
type="button"
>
Active Widgets
</button>
<button
class="mx_DevTools_button"
type="button"
>
Users
</button>
<button
class="mx_DevTools_button"
type="button"
>
Explore sticky state
</button>
@@ -123,21 +131,25 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
</h2>
<button
class="mx_DevTools_button"
type="button"
>
Explore account data
</button>
<button
class="mx_DevTools_button"
type="button"
>
Settings explorer
</button>
<button
class="mx_DevTools_button"
type="button"
>
Server info
</button>
<button
class="mx_DevTools_button"
type="button"
>
End-to-end encryption
</button>
@@ -317,7 +329,9 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -51,10 +51,14 @@ exports[`<EventEditor /> should render 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
<button>
<button
type="button"
>
Send
</button>
</div>
@@ -115,10 +119,14 @@ exports[`<EventEditor /> thread context should pre-populate a thread relationshi
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
<button>
<button
type="button"
>
Send
</button>
</div>
@@ -64,7 +64,9 @@ exports[`<RoomNotifications /> should render 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -185,7 +185,9 @@ exports[`<Users /> should render a single device - signed by owner 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -377,7 +379,9 @@ exports[`<Users /> should render a single device - unsigned 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -571,7 +575,9 @@ exports[`<Users /> should render a single device - verified by cross-signing 1`]
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -672,6 +678,7 @@ exports[`<Users /> should render a single user 1`] = `
<li>
<button
class="mx_DevTools_button"
type="button"
>
<div
class="mx_E2EIcon mx_E2EIcon_inline"
@@ -698,6 +705,7 @@ exports[`<Users /> should render a single user 1`] = `
<li>
<button
class="mx_DevTools_button"
type="button"
>
<div
class="mx_E2EIcon mx_E2EIcon_inline"
@@ -722,6 +730,7 @@ exports[`<Users /> should render a single user 1`] = `
<li>
<button
class="mx_DevTools_button"
type="button"
>
<div
class="mx_E2EIcon mx_E2EIcon_inline"
@@ -757,7 +766,9 @@ exports[`<Users /> should render a single user 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -828,7 +839,9 @@ exports[`<Users /> should render a user list 1`] = `
<div
class="mx_Dialog_buttons"
>
<button>
<button
type="button"
>
Back
</button>
</div>
@@ -92,7 +92,9 @@ exports[`ExportE2eKeysDialog renders 1`] = `
type="submit"
value="Export"
/>
<button>
<button
type="button"
>
Cancel
</button>
</div>
@@ -93,7 +93,9 @@ exports[`ImportE2eKeysDialog renders 1`] = `
type="submit"
value="Import"
/>
<button>
<button
type="button"
>
Cancel
</button>
</div>
@@ -33,7 +33,7 @@ describe("<FilterDropdown />", () => {
await act(async () => {
const button = container.querySelector('[role="button"]');
expect(button).toBeTruthy();
fireEvent.click(button as Element);
fireEvent.click(button!);
await flushPromises();
});
@@ -85,7 +85,7 @@ describe("<ImageView />", () => {
<ImageView src="https://example.com/image.png" name="filename.png" onFinished={jest.fn()} />,
);
const dialog = container.querySelector('[role="dialog"]') as HTMLElement;
const dialog = container.querySelector<HTMLElement>('[role="dialog"]')!;
dialog?.focus();
fireEvent.keyDown(dialog!, { key: "s", code: "KeyS", ctrlKey: true });
@@ -7,6 +7,7 @@ exports[`EventListSummary correctly identifies transitions 1`] = `
<span>
<button
class="mx_EventTile_spoiler"
type="button"
>
 
<span
@@ -34,6 +35,7 @@ exports[`EventListSummary correctly orders sequences of transitions by the order
<span>
<button
class="mx_EventTile_spoiler"
type="button"
>
 
<span
@@ -131,6 +133,7 @@ exports[`EventListSummary handles many users following the same sequence of memb
<span>
<button
class="mx_EventTile_spoiler"
type="button"
>
 
<span
@@ -155,6 +158,7 @@ exports[`EventListSummary handles multiple users following the same sequence of
<span>
<button
class="mx_EventTile_spoiler"
type="button"
>
 
<span
@@ -257,6 +261,7 @@ exports[`EventListSummary truncates multiple sequences of repetitions with other
<span>
<button
class="mx_EventTile_spoiler"
type="button"
>
 
<span
@@ -422,11 +422,11 @@ describe("EmojiPicker", function () {
});
// Initially, people category should be visible
const peopleTab = container.querySelector('[title*="Smileys"]') as HTMLButtonElement;
const peopleTab = container.querySelector('[title*="Smileys"]')!;
expect(peopleTab).toHaveAttribute("tabindex", "0");
// Click on nature category tab
const natureTab = container.querySelector('[title*="Animals"]') as HTMLButtonElement;
const natureTab = container.querySelector('[title*="Animals"]')!;
await userEvent.click(natureTab);
// Wait for scroll and visibility update
@@ -444,7 +444,7 @@ describe("EmojiPicker", function () {
});
// Focus on the category header
const peopleTab = container.querySelector('[title*="Smileys"]') as HTMLButtonElement;
const peopleTab = container.querySelector<HTMLButtonElement>('[title*="Smileys"]')!;
peopleTab.focus();
expect(peopleTab).toHaveFocus();
@@ -471,14 +471,14 @@ describe("EmojiPicker", function () {
});
// Focus on the category header
const peopleTab = container.querySelector('[title*="Smileys"]') as HTMLButtonElement;
const peopleTab = container.querySelector<HTMLButtonElement>('[title*="Smileys"]')!;
peopleTab.focus();
// Press End to jump to last category
await userEvent.keyboard("[End]");
await waitFor(() => {
const flagsTab = container.querySelector('[title*="Flags"]') as HTMLButtonElement;
const flagsTab = container.querySelector('[title*="Flags"]')!;
expect(flagsTab).toHaveFocus();
});
@@ -227,7 +227,7 @@ describe("<MImageReplyBody />", () => {
it("opens the image viewer with thumbnail geometry", async () => {
const { container } = renderBase();
await waitFor(() => expect(screen.getByRole("img", { name: "demo image" })).toBeInTheDocument());
const image = container.querySelector("img.mx_MImageBody_thumbnail") as HTMLImageElement;
const image = container.querySelector("img.mx_MImageBody_thumbnail")!;
image.getBoundingClientRect = () => ({ width: 100, height: 80, x: 10, y: 20 }) as DOMRect;
jest.spyOn(Modal, "createDialog").mockReturnValue({} as any);
@@ -257,7 +257,7 @@ describe("<MImageReplyBody />", () => {
it("updates load dimensions and toggles hover/focus banner state", async () => {
const { container, ref } = renderBase();
await waitFor(() => expect(screen.getByRole("img", { name: "demo image" })).toBeInTheDocument());
const image = container.querySelector("img.mx_MImageBody_thumbnail") as HTMLImageElement;
const image = container.querySelector("img.mx_MImageBody_thumbnail")!;
Object.defineProperty(image, "naturalWidth", { configurable: true, value: 640 });
Object.defineProperty(image, "naturalHeight", { configurable: true, value: 480 });
@@ -466,7 +466,7 @@ describe("<MImageReplyBody />", () => {
},
});
await waitFor(() => expect(container.querySelector("img[style*='display: none']")).not.toBeNull());
const image = container.querySelector("img[style*='display: none']") as HTMLImageElement;
const image = container.querySelector("img[style*='display: none']")!;
Object.defineProperty(image, "naturalWidth", { configurable: true, value: 640 });
Object.defineProperty(image, "naturalHeight", { configurable: true, value: 480 });
@@ -10,8 +10,8 @@ import React from "react";
import { fireEvent, render, type RenderResult } from "jest-matrix-react";
import { type MatrixClient, type MatrixEvent, EventType, type Room, MsgType } from "matrix-js-sdk/src/matrix";
import fetchMock from "@fetch-mock/jest";
import fs from "fs";
import path from "path";
import fs from "node:fs";
import path from "node:path";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { mkEvent, mkRoom, stubClient } from "../../../../test-utils";
@@ -541,6 +541,7 @@ exports[`<TextualBody /> renders formatted m.text correctly spoilers get injecte
Hey
<button
class="mx_EventTile_spoiler"
type="button"
>
<span
class="mx_EventTile_spoiler_reason"
@@ -19,7 +19,7 @@ import {
ProfileKeyTimezone,
ProfileKeyMSC4175Timezone,
} from "matrix-js-sdk/src/matrix";
import { EventEmitter } from "events";
import { EventEmitter } from "node:events";
import {
UserVerificationStatus,
type VerificationRequest,
@@ -112,11 +112,11 @@ describe("<FilteredDeviceList />", () => {
const setFilter = async (container: HTMLElement, option: DeviceSecurityVariation | string) => {
const dropdown = container.querySelector('[aria-label="Filter devices"]');
fireEvent.click(dropdown as Element);
fireEvent.click(dropdown!);
// tick to let dropdown render
await flushPromises();
fireEvent.click(container.querySelector(`#device-list-filter__${option}`) as Element);
fireEvent.click(container.querySelector(`#device-list-filter__${option}`)!);
};
it("does not display filter description when filter is falsy", () => {
@@ -219,7 +219,7 @@ describe("<FilteredDeviceList />", () => {
act(() => {
const tile = getByTestId(`device-tile-${hundredDaysOld.device_id}`);
const toggle = tile.querySelector('[aria-label="Show details"]');
fireEvent.click(toggle as Element);
fireEvent.click(toggle!);
});
expect(onDeviceExpandToggle).toHaveBeenCalledWith(hundredDaysOld.device_id);
@@ -123,6 +123,7 @@ exports[`<SecurityRoomSettingsTab /> join rule handles error when updating join
>
<button
class="mx_Dialog_primary"
type="button"
>
OK
</button>
@@ -948,18 +948,16 @@ describe("<SessionManagerTab />", () => {
toggleDeviceDetails(getByTestId, alicesMobileDevice.device_id);
const deviceDetails = getByTestId(`device-detail-${alicesMobileDevice.device_id}`);
const signOutButton = deviceDetails.querySelector(
'[data-testid="device-detail-sign-out-cta"]',
) as Element;
const signOutButton = deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]')!;
fireEvent.click(signOutButton);
await confirmSignout(getByTestId, false);
// doesnt enter loading state
expect(
(deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]') as Element).getAttribute(
"aria-disabled",
),
deviceDetails
.querySelector('[data-testid="device-detail-sign-out-cta"]')!
.getAttribute("aria-disabled"),
).toEqual(null);
// delete not called
expect(mockClient.deleteMultipleDevices).not.toHaveBeenCalled();
@@ -991,9 +989,7 @@ describe("<SessionManagerTab />", () => {
toggleDeviceDetails(getByTestId, alicesMobileDevice.device_id);
const deviceDetails = getByTestId(`device-detail-${alicesMobileDevice.device_id}`);
const signOutButton = deviceDetails.querySelector(
'[data-testid="device-detail-sign-out-cta"]',
) as Element;
const signOutButton = deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]')!;
fireEvent.click(signOutButton);
await confirmSignout(getByTestId);
@@ -1052,17 +1048,15 @@ describe("<SessionManagerTab />", () => {
toggleDeviceDetails(getByTestId, alicesMobileDevice.device_id);
const deviceDetails = getByTestId(`device-detail-${alicesMobileDevice.device_id}`);
const signOutButton = deviceDetails.querySelector(
'[data-testid="device-detail-sign-out-cta"]',
) as Element;
const signOutButton = deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]')!;
fireEvent.click(signOutButton);
await confirmSignout(getByTestId);
// button is loading
expect(
(deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]') as Element).getAttribute(
"aria-disabled",
),
deviceDetails
.querySelector('[data-testid="device-detail-sign-out-cta"]')!
.getAttribute("aria-disabled"),
).toEqual("true");
await flushPromises();
@@ -1094,9 +1088,9 @@ describe("<SessionManagerTab />", () => {
// loading state cleared
expect(
(deviceDetails.querySelector('[data-testid="device-detail-sign-out-cta"]') as Element).getAttribute(
"aria-disabled",
),
deviceDetails
.querySelector('[data-testid="device-detail-sign-out-cta"]')!
.getAttribute("aria-disabled"),
).toEqual(null);
});
@@ -1241,7 +1235,7 @@ describe("<SessionManagerTab />", () => {
const deviceDetails = getByTestId(`device-detail-${alicesMobileDevice.device_id}`);
const manageDeviceButton = deviceDetails.querySelector(
'[data-testid="device-detail-sign-out-cta"]',
) as Element;
)!;
expect(manageDeviceButton).toHaveAttribute(
"href",
`https://issuer.org/account?action=org.matrix.session_view&device_id=${alicesMobileDevice.device_id}`,
@@ -35,12 +35,14 @@ enum Keys {
ARROW_DOWN = 40,
}
/* oxlint-disable typescript/prefer-literal-enum-member */
enum DragDirection {
LEFT = Keys.ARROW_LEFT,
UP = Keys.ARROW_UP,
RIGHT = Keys.ARROW_RIGHT,
DOWN = Keys.ARROW_DOWN,
}
/* oxlint-enable typescript/prefer-literal-enum-member */
// taken from https://github.com/hello-pangea/dnd/blob/main/test/unit/integration/util/controls.ts#L20
const createTransitionEndEvent = (): Event => {
@@ -86,8 +88,7 @@ const drop = async (element: HTMLElement) => {
};
jest.mock("../../../../../src/stores/spaces/SpaceStore", () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const EventEmitter = require("events");
const EventEmitter = jest.requireActual("events");
class MockSpaceStore extends EventEmitter {
invitedSpaces: SpaceKey[] = [];
enabledMetaSpaces: MetaSpace[] = [];
@@ -21,8 +21,7 @@ import { NotificationLevel } from "../../../../../src/stores/notifications/Notif
import { SDKContextClass } from "../../../../../src/contexts/SDKContextClass";
jest.mock("../../../../../src/stores/spaces/SpaceStore", () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
const EventEmitter = require("events");
const EventEmitter = jest.requireActual("events");
class MockSpaceStore extends EventEmitter {
activeSpace: SpaceKey = "!space1";
setActiveSpace = jest.fn();