diff --git a/apps/desktop/electron-builder.ts b/apps/desktop/electron-builder.ts index 830b68dfca..a1e7f94d18 100644 --- a/apps/desktop/electron-builder.ts +++ b/apps/desktop/electron-builder.ts @@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details. import * as os from "node:os"; import * as fs from "node:fs"; -import * as path from "node:path"; +import path from "node:path"; import { type Configuration as BaseConfiguration } from "electron-builder"; /** diff --git a/apps/desktop/playwright/e2e/launch/config-options.spec.ts b/apps/desktop/playwright/e2e/launch/config-options.spec.ts index 39d7c1d584..db5e91711c 100644 --- a/apps/desktop/playwright/e2e/launch/config-options.spec.ts +++ b/apps/desktop/playwright/e2e/launch/config-options.spec.ts @@ -5,19 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { resolve, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { test, expect } from "../../element-desktop-test.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); - test.describe("App config options", () => { test.describe("Should load custom config via env", () => { test.slow(); test.use({ extraEnv: { - ELEMENT_DESKTOP_CONFIG_JSON: resolve(__dirname, "../..", "fixtures/custom-config.json"), + ELEMENT_DESKTOP_CONFIG_JSON: fileURLToPath(import.meta.resolve("../../fixtures/custom-config.json")), }, }); test("should launch and use configured homeserver", async ({ page }) => { @@ -31,7 +28,7 @@ test.describe("App config options", () => { test.describe("Should load custom config via argument", () => { test.slow(); test.use({ - extraArgs: ["--config", resolve(__dirname, "../..", "fixtures/custom-config.json")], + extraArgs: ["--config", fileURLToPath(import.meta.resolve("../../fixtures/custom-config.json"))], }); test("should launch and use configured homeserver", async ({ page }) => { await page.locator("#matrixchat").waitFor(); diff --git a/apps/desktop/playwright/element-desktop-test.ts b/apps/desktop/playwright/element-desktop-test.ts index c3a7570cbb..86ca5d1a72 100644 --- a/apps/desktop/playwright/element-desktop-test.ts +++ b/apps/desktop/playwright/element-desktop-test.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { _electron as electron, test as base, expect as baseExpect, type ElectronApplication } from "@playwright/test"; import fs from "node:fs/promises"; -import path, { dirname } from "node:path"; +import path from "node:path"; import os from "node:os"; import { fileURLToPath } from "node:url"; import { PassThrough } from "node:stream"; @@ -44,7 +44,7 @@ interface Fixtures { stderr: CapturedPassThrough; } -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export const test = base.extend({ extraEnv: {}, diff --git a/apps/desktop/scripts/copy-res.ts b/apps/desktop/scripts/copy-res.ts index 39b8169cdd..e8ac13b60f 100755 --- a/apps/desktop/scripts/copy-res.ts +++ b/apps/desktop/scripts/copy-res.ts @@ -11,7 +11,7 @@ Please see LICENSE in the repository root for full details. import parseArgs from "minimist"; import * as chokidar from "chokidar"; -import * as path from "node:path"; +import path from "node:path"; import * as fs from "node:fs"; const argv = parseArgs(process.argv.slice(2), {}); diff --git a/apps/desktop/scripts/fetch-package.ts b/apps/desktop/scripts/fetch-package.ts index c5eb76cf95..2d882f29f1 100644 --- a/apps/desktop/scripts/fetch-package.ts +++ b/apps/desktop/scripts/fetch-package.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE in the repository root for full details. */ -import * as path from "node:path"; +import path from "node:path"; import { createWriteStream, promises as fs } from "node:fs"; import * as childProcess from "node:child_process"; import * as tar from "tar"; diff --git a/apps/desktop/scripts/hak/index.ts b/apps/desktop/scripts/hak/index.ts index db6ecd4da9..a48ac96f6b 100644 --- a/apps/desktop/scripts/hak/index.ts +++ b/apps/desktop/scripts/hak/index.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import HakEnv from "./hakEnv.ts"; @@ -28,7 +28,7 @@ const METACOMMANDS: Record = { // Scripts valid in a hak.json 'scripts' section const HAKSCRIPTS = ["check", "fetch", "build"]; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); async function main(): Promise { const prefix = path.join(__dirname, "..", ".."); diff --git a/apps/desktop/src/asar.ts b/apps/desktop/src/asar.ts index ba9e9800da..0fc371b47b 100644 --- a/apps/desktop/src/asar.ts +++ b/apps/desktop/src/asar.ts @@ -6,11 +6,11 @@ Please see LICENSE files in the repository root for full details. */ import { fileURLToPath } from "node:url"; -import { dirname } from "node:path"; +import path from "node:path"; import { tryPaths } from "./utils.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); let asarPathPromise: Promise | undefined; // Get the webapp resource file path, memoizes result diff --git a/apps/desktop/src/build-config.test.ts b/apps/desktop/src/build-config.test.ts index 856d91d5fc..24db7f0d3f 100644 --- a/apps/desktop/src/build-config.test.ts +++ b/apps/desktop/src/build-config.test.ts @@ -7,12 +7,12 @@ Please see LICENSE files in the repository root for full details. import { expect, describe, it, beforeEach, vi } from "vitest"; import { fs as memfs, vol } from "memfs"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { getBuildConfig } from "./build-config.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); vi.mock("node:fs", () => ({ default: memfs })); diff --git a/apps/desktop/src/build-config.ts b/apps/desktop/src/build-config.ts index 5533e0b774..ff04a79e24 100644 --- a/apps/desktop/src/build-config.ts +++ b/apps/desktop/src/build-config.ts @@ -5,13 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { type JsonObject } from "shared-types"; import { loadJsonFile } from "./utils.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); let buildConfig: BuildConfig; diff --git a/apps/desktop/src/config.test.ts b/apps/desktop/src/config.test.ts index 36d0b07711..275b1f3e28 100644 --- a/apps/desktop/src/config.test.ts +++ b/apps/desktop/src/config.test.ts @@ -7,13 +7,13 @@ Please see LICENSE files in the repository root for full details. import { expect, describe, it, beforeEach, vi } from "vitest"; import { fs as memfs, vol } from "memfs"; -import { dirname, resolve } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { dialog } from "electron"; import { type ConfigOptions } from "./config.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); vi.mock("node:fs", () => ({ default: memfs })); vi.mock("node:fs/promises", () => ({ default: memfs.promises })); @@ -52,7 +52,7 @@ describe("loadConfig", () => { }); it("should ignore localConfigPath if does not exist", async () => { - const config = await loadConfig(resolve(__dirname, "../custom-config.json")); + const config = await loadConfig("/invalid-path/custom-config.json"); expect(config.brand).toBe("Element"); expect(config.web_base_url).toBe("https://chat.org.com"); expect(config.default_hs_url).toBe("https://matrix.org.com"); diff --git a/apps/desktop/src/electron-main.ts b/apps/desktop/src/electron-main.ts index 3af1da6f57..7bb269baca 100644 --- a/apps/desktop/src/electron-main.ts +++ b/apps/desktop/src/electron-main.ts @@ -23,7 +23,7 @@ import { desktopCapturer, } from "electron"; import * as Sentry from "@sentry/electron/main"; -import path, { dirname } from "node:path"; +import path from "node:path"; import windowStateKeeper from "electron-window-state"; import { URL, fileURLToPath } from "node:url"; @@ -48,7 +48,7 @@ import { getIconPath } from "./icon.js"; import { getArgs } from "./args.js"; import { type ConfigOptions, loadConfig } from "./config.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const buildConfig = getBuildConfig(); const protocolHandler = new ProtocolHandler(buildConfig.protocol); diff --git a/apps/desktop/src/icon.test.ts b/apps/desktop/src/icon.test.ts index 11e3ae6bd1..a8886be9b5 100644 --- a/apps/desktop/src/icon.test.ts +++ b/apps/desktop/src/icon.test.ts @@ -7,12 +7,9 @@ Please see LICENSE files in the repository root for full details. import { expect, describe, it, beforeEach, vi } from "vitest"; import { fs as memfs, vol } from "memfs"; -import { dirname, resolve } from "node:path"; -import { fileURLToPath } from "node:url"; import { getIconPath } from "./icon.js"; - -const __dirname = dirname(fileURLToPath(import.meta.url)); +import { fileURLToPath } from "node:url"; vi.mock("node:fs/promises", () => ({ default: memfs.promises })); @@ -28,20 +25,20 @@ describe("getIconPath", () => { "build/icon.png": "png", "build/icon.ico": "ico", }, - resolve(__dirname, "../webapp"), + fileURLToPath(import.meta.resolve("../webapp")), ); }); it("should use .ico on Windows", async () => { vi.spyOn(process, "platform", "get").mockReturnValue("win32"); - await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.ico")); + await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.ico"))); }); it("should use .png on macOS", async () => { vi.spyOn(process, "platform", "get").mockReturnValue("darwin"); - await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.png")); + await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.png"))); }); it("should use .png on Linux", async () => { vi.spyOn(process, "platform", "get").mockReturnValue("linux"); - await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.png")); + await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.png"))); }); }); diff --git a/apps/desktop/src/language-helper.ts b/apps/desktop/src/language-helper.ts index 33cf9c9f11..1194810902 100644 --- a/apps/desktop/src/language-helper.ts +++ b/apps/desktop/src/language-helper.ts @@ -7,14 +7,14 @@ Please see LICENSE files in the repository root for full details. import counterpart from "counterpart"; import { type TranslationKey as TKey } from "matrix-web-i18n"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type EN from "./i18n/strings/en_EN.json"; import { loadJsonFile } from "./utils.js"; import type Store from "./store.js"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const FALLBACK_LOCALE = "en"; diff --git a/apps/web/I18nWebpackPlugin.ts b/apps/web/I18nWebpackPlugin.ts index f0892a7029..10649e47f6 100644 --- a/apps/web/I18nWebpackPlugin.ts +++ b/apps/web/I18nWebpackPlugin.ts @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. import webpack from "webpack"; import * as fs from "node:fs/promises"; -import * as path from "node:path"; +import path from "node:path"; import _ from "lodash"; import { type Translations } from "matrix-web-i18n"; diff --git a/apps/web/__mocks__/maplibre-gl.js b/apps/web/__mocks__/maplibre-gl.js index 475648e774..a76c529e2f 100644 --- a/apps/web/__mocks__/maplibre-gl.js +++ b/apps/web/__mocks__/maplibre-gl.js @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -const EventEmitter = require("events"); +const EventEmitter = require("node:events"); const { LngLat, NavigationControl, LngLatBounds } = require("maplibre-gl"); class MockMap extends EventEmitter { diff --git a/apps/web/jest.config.ts b/apps/web/jest.config.ts index 35f0541da5..83b3cf7479 100644 --- a/apps/web/jest.config.ts +++ b/apps/web/jest.config.ts @@ -7,12 +7,12 @@ Please see LICENSE files in the repository root for full details. */ import { env } from "node:process"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { Config } from "jest"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const config: Config = { testEnvironment: "jest-fixed-jsdom", diff --git a/apps/web/playwright/e2e/crypto/migration.spec.ts b/apps/web/playwright/e2e/crypto/migration.spec.ts index 7fb00ef41c..59c68f7336 100644 --- a/apps/web/playwright/e2e/crypto/migration.spec.ts +++ b/apps/web/playwright/e2e/crypto/migration.spec.ts @@ -6,14 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import path from "path"; +import path from "node:path"; import { readFile } from "node:fs/promises"; -import { dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { expect, test } from "../../element-web-test"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); test.describe("migration", { tag: "@no-webkit" }, function () { test.use({ diff --git a/apps/web/playwright/pages/ElementAppPage.ts b/apps/web/playwright/pages/ElementAppPage.ts index 3c7d66a950..3618f0ffc3 100644 --- a/apps/web/playwright/pages/ElementAppPage.ts +++ b/apps/web/playwright/pages/ElementAppPage.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { type Locator, type Page, expect } from "@playwright/test"; import { readFile } from "node:fs/promises"; -import { basename } from "node:path"; +import path from "node:path"; import { rejectToast, rejectToastIfExists } from "@element-hq/element-web-playwright-common"; import { Settings } from "./settings"; @@ -197,15 +197,19 @@ export class ElementAppPage { /** * Drags a "file" into the specified composer and automatically uploads it. * @param location Should the drop target the main room or the thread. - * @param path The path to the sample file so it can be read. + * @param samplePath The path to the sample file so it can be read. * @param type The mimetype of the file. */ - public async composerDragAndUploadFiles(location: "room" | "thread", path: string, type: string): Promise { + public async composerDragAndUploadFiles( + location: "room" | "thread", + samplePath: string, + type: string, + ): Promise { // Based on https://github.com/microsoft/playwright/issues/10667#issuecomment-2742123424 // This read a file, encodes it into base64 and then sends it along to the page to be treated // as a DataTransfer (the mechanism for drag and dropped files). - const buffer = await readFile(path); - const name = basename(path); + const buffer = await readFile(samplePath); + const name = path.basename(samplePath); const dataTransfer = await this.page.evaluateHandle( async ([buffer, name, type]) => { @@ -227,15 +231,19 @@ export class ElementAppPage { /** * Paste a "file" into the specified locator and automatically uploads it. * @param location Should the drop target the main room or the thread. - * @param path The path to the sample file so it can be read. + * @param samplePath The path to the sample file so it can be read. * @param type The mimetype of the file. */ - public async composerDragAndPasteFile(location: "room" | "thread", path: string, type: string): Promise { + public async composerDragAndPasteFile( + location: "room" | "thread", + samplePath: string, + type: string, + ): Promise { // Based on https://github.com/microsoft/playwright/issues/10667#issuecomment-2742123424 // This read a file, encodes it into base64 and then sends it along to the page to be treated // as a DataTransfer (the mechanism for drag and dropped files). - const buffer = await readFile(path); - const name = basename(path); + const buffer = await readFile(samplePath); + const name = path.basename(samplePath); const composer = this.getComposerField(location === "thread"); await composer.evaluate( diff --git a/apps/web/playwright/plugins/homeserver/synapse/consentHomeserver.ts b/apps/web/playwright/plugins/homeserver/synapse/consentHomeserver.ts index 97bfd60d4e..8ef2681bfe 100644 --- a/apps/web/playwright/plugins/homeserver/synapse/consentHomeserver.ts +++ b/apps/web/playwright/plugins/homeserver/synapse/consentHomeserver.ts @@ -7,18 +7,18 @@ Please see LICENSE files in the repository root for full details. */ import { type SynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers/index.js"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { type Fixtures } from "../../../element-web-test.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export const consentHomeserver: Fixtures = { _homeserver: [ async ({ _homeserver: container, mailpit }, use) => { (container as SynapseContainer) - .withCopyDirectoriesToContainer([{ source: join(__dirname, "res"), target: "/data/res" }]) + .withCopyDirectoriesToContainer([{ source: path.join(__dirname, "res"), target: "/data/res" }]) .withSmtpServer(mailpit) .withConfig({ user_consent: { diff --git a/apps/web/playwright/plugins/oauth_server/index.ts b/apps/web/playwright/plugins/oauth_server/index.ts index 274973810b..02f3cdfc9a 100644 --- a/apps/web/playwright/plugins/oauth_server/index.ts +++ b/apps/web/playwright/plugins/oauth_server/index.ts @@ -6,15 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import http from "http"; +import http from "node:http"; import express from "express"; -import { type AddressInfo } from "net"; +import { type AddressInfo } from "node:net"; import { type TestInfo } from "@playwright/test"; import { randB64Bytes } from "@element-hq/element-web-playwright-common/lib/utils/rand.js"; -import { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export class OAuthServer { private server?: http.Server; diff --git a/apps/web/playwright/sample-files/example-module.js b/apps/web/playwright/sample-files/example-module.js index 561dea5fd3..57f3c64ad2 100644 --- a/apps/web/playwright/sample-files/example-module.js +++ b/apps/web/playwright/sample-files/example-module.js @@ -19,6 +19,7 @@ export default class ExampleModule { } async load() { const brand = this.api.config.get("brand"); + // oxlint-disable-next-line no-alert alert(this.api.i18n.translate("key", { brand })); } } diff --git a/apps/web/playwright/sample-files/index.ts b/apps/web/playwright/sample-files/index.ts index bef5fb197c..5d3475da8a 100644 --- a/apps/web/playwright/sample-files/index.ts +++ b/apps/web/playwright/sample-files/index.ts @@ -5,15 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { readFile } from "node:fs/promises"; import { readFileSync } from "node:fs"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export function getSampleFilePath(file: string): string { - return join(__dirname, file); + return path.join(__dirname, file); } export function readSampleFile(file: string, encoding: null): Promise; diff --git a/apps/web/playwright/sample-files/settings-module.js b/apps/web/playwright/sample-files/settings-module.js index 7bf1d787c3..950be72a8f 100644 --- a/apps/web/playwright/sample-files/settings-module.js +++ b/apps/web/playwright/sample-files/settings-module.js @@ -11,6 +11,7 @@ export default class SettingsModule { this.api = api; } async load() { + // oxlint-disable-next-line no-alert alert(this.api.settings.getValue("language")); } } diff --git a/apps/web/src/CallStatusListener.test.ts b/apps/web/src/CallStatusListener.test.ts index 9d7295a454..abe320229f 100644 --- a/apps/web/src/CallStatusListener.test.ts +++ b/apps/web/src/CallStatusListener.test.ts @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. // @vitest-environment happy-dom -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; import type { MatrixClient } from "matrix-js-sdk/src/matrix"; diff --git a/apps/web/src/MediaDeviceHandler.ts b/apps/web/src/MediaDeviceHandler.ts index c77fd87377..461813c0b6 100644 --- a/apps/web/src/MediaDeviceHandler.ts +++ b/apps/web/src/MediaDeviceHandler.ts @@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { logger } from "matrix-js-sdk/src/logger"; diff --git a/apps/web/src/Registration.tsx b/apps/web/src/Registration.tsx index 098d25ca6c..e580047acc 100644 --- a/apps/web/src/Registration.tsx +++ b/apps/web/src/Registration.tsx @@ -56,6 +56,7 @@ export async function startAnyRegistrationFlow( modal.close(); dis.dispatch({ action: "start_registration", screenAfterLogin: options.screen_after }); }} + type="button" > {_t("auth|register_action")} , diff --git a/apps/web/src/ScalarMessaging.ts b/apps/web/src/ScalarMessaging.ts index 20858b5d1c..4971a80671 100644 --- a/apps/web/src/ScalarMessaging.ts +++ b/apps/web/src/ScalarMessaging.ts @@ -827,7 +827,7 @@ async function readEvents( const effectiveStateKey = stateKey === true ? undefined : stateKey; let events: MatrixEvent[] = []; - events = events.concat(room.currentState.getStateEvents(eventType, effectiveStateKey as string) || []); + events = events.concat(room.currentState.getStateEvents(eventType, effectiveStateKey!) || []); events = events.slice(0, effectiveLimit); sendResponse(event, { diff --git a/apps/web/src/SlidingSyncManager.test.ts b/apps/web/src/SlidingSyncManager.test.ts index b66ecc5806..5e7b278389 100644 --- a/apps/web/src/SlidingSyncManager.test.ts +++ b/apps/web/src/SlidingSyncManager.test.ts @@ -12,7 +12,7 @@ import { vi, describe, it, expect, beforeEach } from "vitest"; import { type SlidingSync, SlidingSyncEvent, SlidingSyncState } from "matrix-js-sdk/src/sliding-sync"; import { ClientEvent, type MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import fetchMock from "@fetch-mock/vitest"; -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { waitFor } from "test-utils-rtl"; import { mkStubRoom, stubClient } from "test-utils"; diff --git a/apps/web/src/UserActivity.ts b/apps/web/src/UserActivity.ts index 61f786e861..faf231ecdc 100644 --- a/apps/web/src/UserActivity.ts +++ b/apps/web/src/UserActivity.ts @@ -101,7 +101,9 @@ export default class UserActivity { // as we fork the promise here, // avoid unhandled rejection warnings }) - .catch((err) => {}); + .catch(() => { + // Do nothing + }); } } diff --git a/apps/web/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx b/apps/web/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx index 31c7c7ca8d..15c9bd918a 100644 --- a/apps/web/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx +++ b/apps/web/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx @@ -211,7 +211,7 @@ export default class ExportE2eKeysDialog extends React.Component value={_t("action|export")} disabled={disableForm} /> - diff --git a/apps/web/src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx b/apps/web/src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx index fff841d8a6..26ef2eec4d 100644 --- a/apps/web/src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx +++ b/apps/web/src/async-components/views/dialogs/security/ImportE2eKeysDialog.tsx @@ -180,7 +180,7 @@ export default class ImportE2eKeysDialog extends React.Component value={_t("action|import")} disabled={!this.state.enableSubmit || disableForm} /> - diff --git a/apps/web/src/audio/Playback.ts b/apps/web/src/audio/Playback.ts index fa0bceffdf..d94e4593a2 100644 --- a/apps/web/src/audio/Playback.ts +++ b/apps/web/src/audio/Playback.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { SimpleObservable } from "matrix-widget-api"; import { logger } from "matrix-js-sdk/src/logger"; diff --git a/apps/web/src/audio/VoiceRecording.ts b/apps/web/src/audio/VoiceRecording.ts index ea8ca96e4e..48a624d49b 100644 --- a/apps/web/src/audio/VoiceRecording.ts +++ b/apps/web/src/audio/VoiceRecording.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import Recorder from "opus-recorder/dist/recorder.min.js"; import encoderPath from "opus-recorder/dist/encoderWorker.min.js"; import { SimpleObservable } from "matrix-widget-api"; +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { logger } from "matrix-js-sdk/src/logger"; import { clamp } from "@element-hq/web-shared-components"; diff --git a/apps/web/src/components/structures/LegacyCallEventGrouper.ts b/apps/web/src/components/structures/LegacyCallEventGrouper.ts index 28b44ea8a0..9390fd6400 100644 --- a/apps/web/src/components/structures/LegacyCallEventGrouper.ts +++ b/apps/web/src/components/structures/LegacyCallEventGrouper.ts @@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details. import { EventType, type MatrixEvent } from "matrix-js-sdk/src/matrix"; import { CallEvent, CallState, CallType, type MatrixCall } from "matrix-js-sdk/src/webrtc/call"; +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import { LegacyCallHandlerEvent } from "../../LegacyCallHandler"; diff --git a/apps/web/src/components/structures/RoomView.tsx b/apps/web/src/components/structures/RoomView.tsx index 57fb721265..42f2d87808 100644 --- a/apps/web/src/components/structures/RoomView.tsx +++ b/apps/web/src/components/structures/RoomView.tsx @@ -712,19 +712,19 @@ export class RoomView extends React.Component { // Add watchers for each of the settings we just looked up this.settingWatchers = this.settingWatchers.concat([ SettingsStore.watchSetting("showReadReceipts", roomId, (...[, , , value]) => - this.setState({ showReadReceipts: value as boolean }), + this.setState({ showReadReceipts: value! }), ), SettingsStore.watchSetting("showRedactions", roomId, (...[, , , value]) => - this.setState({ showRedactions: value as boolean }), + this.setState({ showRedactions: value! }), ), SettingsStore.watchSetting("showJoinLeaves", roomId, (...[, , , value]) => - this.setState({ showJoinLeaves: value as boolean }), + this.setState({ showJoinLeaves: value! }), ), SettingsStore.watchSetting("showAvatarChanges", roomId, (...[, , , value]) => - this.setState({ showAvatarChanges: value as boolean }), + this.setState({ showAvatarChanges: value! }), ), SettingsStore.watchSetting("showDisplaynameChanges", roomId, (...[, , , value]) => - this.setState({ showDisplaynameChanges: value as boolean }), + this.setState({ showDisplaynameChanges: value! }), ), ]); @@ -985,34 +985,32 @@ export class RoomView extends React.Component { this.context.resizeNotifier.on("isResizing", this.onIsResizing); this.settingWatchers = [ - SettingsStore.watchSetting("layout", null, (...[, , , value]) => - this.setState({ layout: value as Layout }), - ), + SettingsStore.watchSetting("layout", null, (...[, , , value]) => this.setState({ layout: value! })), SettingsStore.watchSetting("lowBandwidth", null, (...[, , , value]) => - this.setState({ lowBandwidth: value as boolean }), + this.setState({ lowBandwidth: value! }), ), SettingsStore.watchSetting("alwaysShowTimestamps", null, (...[, , , value]) => - this.setState({ alwaysShowTimestamps: value as boolean }), + this.setState({ alwaysShowTimestamps: value! }), ), SettingsStore.watchSetting("showTwelveHourTimestamps", null, (...[, , , value]) => - this.setState({ showTwelveHourTimestamps: value as boolean }), + this.setState({ showTwelveHourTimestamps: value! }), ), SettingsStore.watchSetting(TimezoneHandler.USER_TIMEZONE_KEY, null, (...[, , , value]) => - this.setState({ userTimezone: value as string }), + this.setState({ userTimezone: value! }), ), SettingsStore.watchSetting("readMarkerInViewThresholdMs", null, (...[, , , value]) => - this.setState({ readMarkerInViewThresholdMs: value as number }), + this.setState({ readMarkerInViewThresholdMs: value! }), ), SettingsStore.watchSetting("readMarkerOutOfViewThresholdMs", null, (...[, , , value]) => - this.setState({ readMarkerOutOfViewThresholdMs: value as number }), + this.setState({ readMarkerOutOfViewThresholdMs: value! }), ), SettingsStore.watchSetting("showHiddenEventsInTimeline", null, (...[, , , value]) => - this.setState({ showHiddenEvents: value as boolean }), + this.setState({ showHiddenEvents: value! }), ), SettingsStore.watchSetting("urlPreviewsEnabled", null, this.onUrlPreviewsEnabledChange), SettingsStore.watchSetting("urlPreviewsEnabled_e2ee", null, this.onUrlPreviewsEnabledChange), SettingsStore.watchSetting("feature_dynamic_room_predecessors", null, (...[, , , value]) => - this.setState({ msc3946ProcessDynamicPredecessor: value as boolean }), + this.setState({ msc3946ProcessDynamicPredecessor: value! }), ), ]; diff --git a/apps/web/src/components/structures/ScrollPanel.tsx b/apps/web/src/components/structures/ScrollPanel.tsx index da77abe5e6..3be253a8e5 100644 --- a/apps/web/src/components/structures/ScrollPanel.tsx +++ b/apps/web/src/components/structures/ScrollPanel.tsx @@ -158,7 +158,7 @@ export default class ScrollPanel extends React.Component { return Promise.resolve(false); }, onUnfillRequest: function (backwards: boolean, scrollToken: string) {}, - onScroll: function () {}, + onScroll: function (): void {}, }; private readonly pendingFillRequests: Record<"b" | "f", boolean | null> = { diff --git a/apps/web/src/components/structures/TabbedView.tsx b/apps/web/src/components/structures/TabbedView.tsx index 99b43e7bbb..a48538e871 100644 --- a/apps/web/src/components/structures/TabbedView.tsx +++ b/apps/web/src/components/structures/TabbedView.tsx @@ -102,8 +102,6 @@ function TabLabel({ tab, isActive, showToolip, onClick }: ITab const label = _t(tab.label); return ( - // The RovingAccessibleComponent correctly sets the tabIndex based on roving context - // oxlint-disable-next-line jsx-a11y/interactive-supports-focus { this.setupThreadListeners(this.state.thread); this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, (...[, , , value]) => - this.setState({ layout: value as Layout }), + this.setState({ layout: value! }), ); if (this.state.thread) { diff --git a/apps/web/src/components/structures/ViewSource.tsx b/apps/web/src/components/structures/ViewSource.tsx index 2d3b716839..cbb6ed4f4e 100644 --- a/apps/web/src/components/structures/ViewSource.tsx +++ b/apps/web/src/components/structures/ViewSource.tsx @@ -172,7 +172,9 @@ export default class ViewSource extends React.Component { {isEditing ? this.editSourceContent() : this.viewSourceContent()} {!isEditing && canEdit && (
- +
)} diff --git a/apps/web/src/components/structures/auth/CompleteSecurity.test.tsx b/apps/web/src/components/structures/auth/CompleteSecurity.test.tsx index b334d88e30..156c4015bd 100644 --- a/apps/web/src/components/structures/auth/CompleteSecurity.test.tsx +++ b/apps/web/src/components/structures/auth/CompleteSecurity.test.tsx @@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details. import { vi, describe, it, expect, beforeEach, afterEach } from "vitest"; import React from "react"; import { act, render, screen } from "test-utils-rtl"; -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { stubClient } from "test-utils"; import CompleteSecurity from "./CompleteSecurity"; diff --git a/apps/web/src/components/structures/auth/LoginSplashView.test.tsx b/apps/web/src/components/structures/auth/LoginSplashView.test.tsx index e81db88031..870233371a 100644 --- a/apps/web/src/components/structures/auth/LoginSplashView.test.tsx +++ b/apps/web/src/components/structures/auth/LoginSplashView.test.tsx @@ -11,7 +11,7 @@ Please see LICENSE files in the repository root for full details. import { vi, describe, it, expect, beforeEach } from "vitest"; import { act, render, type RenderResult } from "test-utils-rtl"; import React, { type ComponentProps } from "react"; -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { CryptoEvent } from "matrix-js-sdk/src/crypto-api"; import { sleep } from "matrix-js-sdk/src/utils"; diff --git a/apps/web/src/components/views/auth/PasswordLogin.tsx b/apps/web/src/components/views/auth/PasswordLogin.tsx index 97978cb4e2..6898846a64 100644 --- a/apps/web/src/components/views/auth/PasswordLogin.tsx +++ b/apps/web/src/components/views/auth/PasswordLogin.tsx @@ -64,10 +64,10 @@ export default class PasswordLogin extends React.PureComponent { private [LoginField.Password]: Field | null = null; public static defaultProps = { - onUsernameChanged: function () {}, - onUsernameBlur: function () {}, - onPhoneCountryChanged: function () {}, - onPhoneNumberChanged: function () {}, + onUsernameChanged: function (): void {}, + onUsernameBlur: function (): void {}, + onPhoneCountryChanged: function (): void {}, + onPhoneNumberChanged: function (): void {}, loginIncorrect: false, disableSubmit: false, }; diff --git a/apps/web/src/components/views/dialogs/AskInviteAnywayDialog.tsx b/apps/web/src/components/views/dialogs/AskInviteAnywayDialog.tsx index ddc4c04d4a..fb6161f72c 100644 --- a/apps/web/src/components/views/dialogs/AskInviteAnywayDialog.tsx +++ b/apps/web/src/components/views/dialogs/AskInviteAnywayDialog.tsx @@ -77,11 +77,13 @@ export default function AskInviteAnywayDialog({
- - + -
diff --git a/apps/web/src/components/views/dialogs/DevtoolsDialog.tsx b/apps/web/src/components/views/dialogs/DevtoolsDialog.tsx index d9074f8449..24aea999bf 100644 --- a/apps/web/src/components/views/dialogs/DevtoolsDialog.tsx +++ b/apps/web/src/components/views/dialogs/DevtoolsDialog.tsx @@ -97,7 +97,7 @@ const DevtoolsDialog: React.FC = ({ roomId, threadRootId, onFinished }) setTool([label, tool]); }; return ( - ); diff --git a/apps/web/src/components/views/dialogs/ErrorDialog.tsx b/apps/web/src/components/views/dialogs/ErrorDialog.tsx index 5f800e53df..8ac9484eef 100644 --- a/apps/web/src/components/views/dialogs/ErrorDialog.tsx +++ b/apps/web/src/components/views/dialogs/ErrorDialog.tsx @@ -74,7 +74,12 @@ export default class ErrorDialog extends React.Component { {this.props.description || _t("error|dialog_description_default")}
-
diff --git a/apps/web/src/components/views/dialogs/SessionRestoreErrorDialog.tsx b/apps/web/src/components/views/dialogs/SessionRestoreErrorDialog.tsx index edf93558ff..1bb6ed7f6d 100644 --- a/apps/web/src/components/views/dialogs/SessionRestoreErrorDialog.tsx +++ b/apps/web/src/components/views/dialogs/SessionRestoreErrorDialog.tsx @@ -50,7 +50,7 @@ export default class SessionRestoreErrorDialog extends React.Component { const brand = SdkConfig.get().brand; const clearStorageButton = ( - ); diff --git a/apps/web/src/components/views/dialogs/UploadConfirmDialog.tsx b/apps/web/src/components/views/dialogs/UploadConfirmDialog.tsx index 820b047c38..9f7ac23f1f 100644 --- a/apps/web/src/components/views/dialogs/UploadConfirmDialog.tsx +++ b/apps/web/src/components/views/dialogs/UploadConfirmDialog.tsx @@ -104,7 +104,11 @@ export default class UploadConfirmDialog extends React.Component let uploadAllButton: JSX.Element | undefined; if (this.props.currentIndex + 1 < this.props.totalFiles) { - uploadAllButton = ; + uploadAllButton = ( + + ); } return ( diff --git a/apps/web/src/components/views/dialogs/devtools/AccountData.tsx b/apps/web/src/components/views/dialogs/devtools/AccountData.tsx index e4e1ffe769..6631675d4f 100644 --- a/apps/web/src/components/views/dialogs/devtools/AccountData.tsx +++ b/apps/web/src/components/views/dialogs/devtools/AccountData.tsx @@ -78,7 +78,7 @@ const BaseAccountDataExplorer: React.FC = ({ events, Editor, actionLabel }; return ( - ); diff --git a/apps/web/src/components/views/dialogs/devtools/BaseTool.tsx b/apps/web/src/components/views/dialogs/devtools/BaseTool.tsx index 09120ecde2..6a2ce75d5c 100644 --- a/apps/web/src/components/views/dialogs/devtools/BaseTool.tsx +++ b/apps/web/src/components/views/dialogs/devtools/BaseTool.tsx @@ -61,7 +61,11 @@ const BaseTool: React.FC> = ({ }); }; - actionButton = ; + actionButton = ( + + ); } return ( @@ -69,7 +73,9 @@ const BaseTool: React.FC> = ({
{children}
{extraButton} - + {actionButton}
diff --git a/apps/web/src/components/views/dialogs/devtools/FilteredList.tsx b/apps/web/src/components/views/dialogs/devtools/FilteredList.tsx index e59059722a..14419b79e4 100644 --- a/apps/web/src/components/views/dialogs/devtools/FilteredList.tsx +++ b/apps/web/src/components/views/dialogs/devtools/FilteredList.tsx @@ -50,7 +50,7 @@ const FilteredList: React.FC = ({ children, query, onChange }) => { }; return ( - ); diff --git a/apps/web/src/components/views/dialogs/devtools/RoomState.tsx b/apps/web/src/components/views/dialogs/devtools/RoomState.tsx index 0d7041355a..01b666c9c5 100644 --- a/apps/web/src/components/views/dialogs/devtools/RoomState.tsx +++ b/apps/web/src/components/views/dialogs/devtools/RoomState.tsx @@ -100,6 +100,7 @@ const StateEventButton: React.FC = ({ label, onClick }) = mx_DevTools_RoomStateExplorer_button_emptyString: !trimmed, })} onClick={onClick} + type="button" > {content} @@ -148,7 +149,11 @@ const RoomStateExplorerEventType: React.FC = ({ eventType, onBa const onHistoryClick = (): void => { setHistory(true); }; - const extraButton = ; + const extraButton = ( + + ); return ; } diff --git a/apps/web/src/components/views/dialogs/devtools/StickyEventState.tsx b/apps/web/src/components/views/dialogs/devtools/StickyEventState.tsx index e531ddebe2..8f36788441 100644 --- a/apps/web/src/components/views/dialogs/devtools/StickyEventState.tsx +++ b/apps/web/src/components/views/dialogs/devtools/StickyEventState.tsx @@ -56,7 +56,11 @@ export const StickyStateExplorer: React.FC = ({ onBack, setTool {_t("action|back")}} + actions={ + + } > {_t("devtools|sticky_events_not_supported")} @@ -107,7 +111,12 @@ export const StickyStateExplorer: React.FC = ({ onBack, setTool

{uniqueEventTypes.map((eventType) => ( - ))} diff --git a/apps/web/src/components/views/dialogs/devtools/Users.tsx b/apps/web/src/components/views/dialogs/devtools/Users.tsx index bcd54a612f..a0ba101dd8 100644 --- a/apps/web/src/components/views/dialogs/devtools/Users.tsx +++ b/apps/web/src/components/views/dialogs/devtools/Users.tsx @@ -88,7 +88,7 @@ interface UserButtonProps { */ const UserButton: React.FC = ({ member, onClick }) => { return ( - ); @@ -273,7 +273,7 @@ const DeviceButton: React.FC = ({ crypto, device, onClick }) null, ); return ( - diff --git a/apps/web/src/components/views/dialogs/devtools/WidgetExplorer.tsx b/apps/web/src/components/views/dialogs/devtools/WidgetExplorer.tsx index d899c46c7c..284a80de1d 100644 --- a/apps/web/src/components/views/dialogs/devtools/WidgetExplorer.tsx +++ b/apps/web/src/components/views/dialogs/devtools/WidgetExplorer.tsx @@ -53,7 +53,12 @@ const WidgetExplorer: React.FC = ({ onBack }) => { {widgets.map((w) => ( - ))} diff --git a/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index b987e04aea..59d0f2f560 100644 --- a/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -538,7 +538,7 @@ const SpotlightDialog: React.FC = ({ initialText = "", initialFilter = n }); // we intentionally ignore changes to the rovingContext for the purpose of this hook // we only want to reset the focus whenever the results or filters change - // eslint-disable-next-line + // oxlint-disable-next-line react-hooks/exhaustive-deps }, [results, filter]); const viewRoom = ( diff --git a/apps/web/src/components/views/elements/Dropdown.tsx b/apps/web/src/components/views/elements/Dropdown.tsx index fb245a7e3e..00c9970533 100644 --- a/apps/web/src/components/views/elements/Dropdown.tsx +++ b/apps/web/src/components/views/elements/Dropdown.tsx @@ -238,9 +238,7 @@ export default class Dropdown extends React.Component { highlightedOption: nextKey, }); - ( - this.dropdownRootElement?.querySelector(`#${this.props.id}__${nextKey}`) as HTMLLIElement - )?.focus(); + this.dropdownRootElement?.querySelector(`#${this.props.id}__${nextKey}`)?.focus(); } else { this.setState({ expanded: true }); } @@ -251,9 +249,7 @@ export default class Dropdown extends React.Component { this.setState({ highlightedOption: prevKey, }); - ( - this.dropdownRootElement?.querySelector(`#${this.props.id}__${prevKey}`) as HTMLLIElement - )?.focus(); + this.dropdownRootElement?.querySelector(`#${this.props.id}__${prevKey}`)?.focus(); } else { this.setState({ expanded: true }); } @@ -319,7 +315,7 @@ export default class Dropdown extends React.Component { { diff --git a/apps/web/src/components/views/emojipicker/Search.tsx b/apps/web/src/components/views/emojipicker/Search.tsx index 4f6ede9c06..cc0b42a411 100644 --- a/apps/web/src/components/views/emojipicker/Search.tsx +++ b/apps/web/src/components/views/emojipicker/Search.tsx @@ -55,6 +55,7 @@ class Search extends React.PureComponent { onClick={() => this.props.onChange("")} className="mx_EmojiPicker_search_clear" title={_t("emoji_picker|cancel_search_label")} + type="button" > diff --git a/apps/web/src/components/views/messages/MBodyFactory.tsx b/apps/web/src/components/views/messages/MBodyFactory.tsx index d6d4baff14..2dc73bf86e 100644 --- a/apps/web/src/components/views/messages/MBodyFactory.tsx +++ b/apps/web/src/components/views/messages/MBodyFactory.tsx @@ -296,7 +296,7 @@ const MESSAGE_BODY_TYPES = new Map([ // Render a body using the picked factory. // Falls back to the provided factory when msgtype has no specific handler. export function renderMBody(props: IBodyProps, fallbackFactory?: MBodyComponent): JSX.Element | null { - const BodyType = MESSAGE_BODY_TYPES.get(props.mxEvent.getContent().msgtype as string) ?? fallbackFactory; + const BodyType = MESSAGE_BODY_TYPES.get(props.mxEvent.getContent().msgtype!) ?? fallbackFactory; if (!BodyType) { return null; } diff --git a/apps/web/src/components/views/right_panel/TimelineCard.tsx b/apps/web/src/components/views/right_panel/TimelineCard.tsx index 3d5cabd1f9..521219c0a7 100644 --- a/apps/web/src/components/views/right_panel/TimelineCard.tsx +++ b/apps/web/src/components/views/right_panel/TimelineCard.tsx @@ -92,10 +92,10 @@ export default class TimelineCard extends React.Component { this.context.roomViewStore.addListener(UPDATE_EVENT, this.onRoomViewStoreUpdate); this.dispatcherRef = dis.register(this.onAction); this.readReceiptsSettingWatcher = SettingsStore.watchSetting("showReadReceipts", null, (...[, , , value]) => - this.setState({ showReadReceipts: value as boolean }), + this.setState({ showReadReceipts: value! }), ); this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, (...[, , , value]) => - this.setState({ layout: value as Layout }), + this.setState({ layout: value! }), ); } diff --git a/apps/web/src/components/views/right_panel/UserInfo.tsx b/apps/web/src/components/views/right_panel/UserInfo.tsx index 9875ebfe15..aced0b6b2f 100644 --- a/apps/web/src/components/views/right_panel/UserInfo.tsx +++ b/apps/web/src/components/views/right_panel/UserInfo.tsx @@ -195,7 +195,7 @@ const UserInfo: React.FC = ({ user, room, onClose, phase = RightPanelPha let content: JSX.Element | undefined; switch (phase) { case RightPanelPhases.MemberInfo: - content = ; + content = ; break; case RightPanelPhases.EncryptionPanel: classes.push("mx_UserInfo_smallAvatar"); diff --git a/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx b/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx index 2aa4e1a0aa..8353d3aa0d 100644 --- a/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx +++ b/apps/web/src/components/views/rooms/RoomHeader/RoomHeader.tsx @@ -485,6 +485,7 @@ export default function RoomHeader({ : () => sdkContext.rightPanelStore.showOrHidePhase(RightPanelPhases.RoomSummary) } className="mx_RoomHeader_infoWrapper" + type="button" > dm > does not show the face pile for DMs 1`] = ` aria-label="Room info" class="mx_RoomHeader_infoWrapper" tabindex="0" + type="button" >

{ - this.setState({ deviceNotificationsEnabled: value as boolean }); + this.setState({ deviceNotificationsEnabled: value! }); }), ]; diff --git a/apps/web/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx b/apps/web/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx index e7cc42397c..3675921ea1 100644 --- a/apps/web/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx +++ b/apps/web/src/components/views/settings/tabs/user/VoiceUserSettingsTab.tsx @@ -78,7 +78,7 @@ export default class VoiceUserSettingsTab extends React.Component this.setState({ enableLegacyCallsVoip: value as boolean }), + (...[, , , , value]) => this.setState({ enableLegacyCallsVoip: value! }), ); const canSeeDeviceLabels = await MediaDeviceHandler.hasAnyLabeledDevices(); diff --git a/apps/web/src/components/views/voip/LegacyCallView.tsx b/apps/web/src/components/views/voip/LegacyCallView.tsx index 51c58fdd70..0dc6955ffb 100644 --- a/apps/web/src/components/views/voip/LegacyCallView.tsx +++ b/apps/web/src/components/views/voip/LegacyCallView.tsx @@ -501,38 +501,20 @@ export default class LegacyCallView extends React.Component { // We've already checked that we have feeds so we cast away the optional when passing the feed return (
- +
); } else if (secondaryFeed) { return (
- + {secondaryFeedElement}
); } else { return (
- + {sidebarShown && ( )} diff --git a/apps/web/src/hooks/useEventEmitter.ts b/apps/web/src/hooks/useEventEmitter.ts index 391232a42a..dc71257a78 100644 --- a/apps/web/src/hooks/useEventEmitter.ts +++ b/apps/web/src/hooks/useEventEmitter.ts @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import { useRef, useEffect, useState, useCallback, type DependencyList } from "react"; import { type ListenerMap, type TypedEventEmitter } from "matrix-js-sdk/src/matrix"; +// oxlint-disable-next-line no-restricted-imports import type { EventEmitter } from "events"; type Handler = (...args: any[]) => void; diff --git a/apps/web/src/i18n/settings.ts b/apps/web/src/i18n/settings.ts index dadeceabc2..10dead6d3e 100644 --- a/apps/web/src/i18n/settings.ts +++ b/apps/web/src/i18n/settings.ts @@ -42,6 +42,7 @@ export async function setLanguage(...preferredLangs: string[]): Promise { await SettingsStore.setValue("language", null, SettingLevel.DEVICE, chosenLanguage); // Adds a lot of noise to test runs, so disable logging there. + // oxlint-disable-next-line node/no-process-env if (process.env.NODE_ENV !== "test") { logger.log("set language to " + chosenLanguage); } diff --git a/apps/web/src/indexing/EventIndex.ts b/apps/web/src/indexing/EventIndex.ts index 0d396bb392..6b6f351012 100644 --- a/apps/web/src/indexing/EventIndex.ts +++ b/apps/web/src/indexing/EventIndex.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import { RoomMember, diff --git a/apps/web/src/models/Call.ts b/apps/web/src/models/Call.ts index 06198289d3..8335a35361 100644 --- a/apps/web/src/models/Call.ts +++ b/apps/web/src/models/Call.ts @@ -26,6 +26,7 @@ import { MatrixRTCSessionManagerEvents, } from "matrix-js-sdk/src/matrixrtc"; +// oxlint-disable-next-line no-restricted-imports import type EventEmitter from "events"; import type { IApp } from "../stores/WidgetStore"; import SettingsStore from "../settings/SettingsStore"; diff --git a/apps/web/src/sentry.ts b/apps/web/src/sentry.ts index db9dd21a14..d705ef7c02 100644 --- a/apps/web/src/sentry.ts +++ b/apps/web/src/sentry.ts @@ -201,6 +201,7 @@ export async function initSentry(sentryConfig: IConfigOptions["sentry"]): Promis Sentry.init({ dsn: sentryConfig.dsn, + // oxlint-disable-next-line node/no-process-env release: process.env.VERSION, environment: sentryConfig.environment, defaultIntegrations: false, diff --git a/apps/web/src/stores/ActiveWidgetStore.ts b/apps/web/src/stores/ActiveWidgetStore.ts index 74497ebf99..270b18628f 100644 --- a/apps/web/src/stores/ActiveWidgetStore.ts +++ b/apps/web/src/stores/ActiveWidgetStore.ts @@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { type MatrixEvent, RoomStateEvent, type RoomState } from "matrix-js-sdk/src/matrix"; diff --git a/apps/web/src/stores/AsyncStore.ts b/apps/web/src/stores/AsyncStore.ts index b6aeb41368..dd9b059604 100644 --- a/apps/web/src/stores/AsyncStore.ts +++ b/apps/web/src/stores/AsyncStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import AwaitLock from "await-lock"; diff --git a/apps/web/src/stores/InitialCryptoSetupStore.ts b/apps/web/src/stores/InitialCryptoSetupStore.ts index 226d3f4b2a..ee646fb53a 100644 --- a/apps/web/src/stores/InitialCryptoSetupStore.ts +++ b/apps/web/src/stores/InitialCryptoSetupStore.ts @@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { type MatrixClient } from "matrix-js-sdk/src/matrix"; import { logger } from "matrix-js-sdk/src/logger"; diff --git a/apps/web/src/stores/LatestRtcNotificationEventStore.test.ts b/apps/web/src/stores/LatestRtcNotificationEventStore.test.ts index 6d2e1a839d..a5c9c7d087 100644 --- a/apps/web/src/stores/LatestRtcNotificationEventStore.test.ts +++ b/apps/web/src/stores/LatestRtcNotificationEventStore.test.ts @@ -9,7 +9,7 @@ import { describe, it, expect, vi } from "vitest"; import { type EventTimeline, EventType, RoomEvent } from "matrix-js-sdk/src/matrix"; -import { EventEmitter } from "stream"; +import { EventEmitter } from "node:events"; import { mkEvent, mkRoom, mkRoomMember, stubClient } from "../../test/test-utils"; import { CallStoreEvent, type CallStore } from "./CallStore"; diff --git a/apps/web/src/stores/NonUrgentToastStore.ts b/apps/web/src/stores/NonUrgentToastStore.ts index 3912fb5788..a1f514a512 100644 --- a/apps/web/src/stores/NonUrgentToastStore.ts +++ b/apps/web/src/stores/NonUrgentToastStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { type ComponentClass } from "../@types/common"; diff --git a/apps/web/src/stores/ReadyWatchingStore.ts b/apps/web/src/stores/ReadyWatchingStore.ts index 1c7b92ade7..e2366c34e8 100644 --- a/apps/web/src/stores/ReadyWatchingStore.ts +++ b/apps/web/src/stores/ReadyWatchingStore.ts @@ -7,6 +7,7 @@ */ import { type MatrixClient, SyncState } from "matrix-js-sdk/src/matrix"; +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import { MatrixClientPeg } from "../MatrixClientPeg"; diff --git a/apps/web/src/stores/RoomViewStore.tsx b/apps/web/src/stores/RoomViewStore.tsx index b2ff60fe09..5604fb3936 100644 --- a/apps/web/src/stores/RoomViewStore.tsx +++ b/apps/web/src/stores/RoomViewStore.tsx @@ -15,6 +15,7 @@ import { KnownMembership } from "matrix-js-sdk/src/types"; import { logger } from "matrix-js-sdk/src/logger"; import { type ViewRoom as ViewRoomEvent } from "@matrix-org/analytics-events/types/typescript/ViewRoom"; import { type JoinedRoom as JoinedRoomEvent } from "@matrix-org/analytics-events/types/typescript/JoinedRoom"; +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { RoomViewLifecycle, diff --git a/apps/web/src/stores/SetupEncryptionStore.ts b/apps/web/src/stores/SetupEncryptionStore.ts index 659a524edd..5815782d8e 100644 --- a/apps/web/src/stores/SetupEncryptionStore.ts +++ b/apps/web/src/stores/SetupEncryptionStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { type KeyBackupInfo, diff --git a/apps/web/src/stores/ThreepidInviteStore.ts b/apps/web/src/stores/ThreepidInviteStore.ts index c9e0a9eb21..a8a282dc09 100644 --- a/apps/web/src/stores/ThreepidInviteStore.ts +++ b/apps/web/src/stores/ThreepidInviteStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { base32 } from "rfc4648"; import { type RoomType } from "matrix-js-sdk/src/matrix"; diff --git a/apps/web/src/stores/ToastStore.ts b/apps/web/src/stores/ToastStore.ts index 971e49be58..04de298340 100644 --- a/apps/web/src/stores/ToastStore.ts +++ b/apps/web/src/stores/ToastStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { logger } from "matrix-js-sdk/src/logger"; import { type JSX } from "react"; diff --git a/apps/web/src/stores/UIStore.ts b/apps/web/src/stores/UIStore.ts index e3e9558bbe..13b59fee46 100644 --- a/apps/web/src/stores/UIStore.ts +++ b/apps/web/src/stores/UIStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; export enum UI_EVENTS { diff --git a/apps/web/src/stores/WidgetEchoStore.ts b/apps/web/src/stores/WidgetEchoStore.ts index 6c41d3d514..3ca206930f 100644 --- a/apps/web/src/stores/WidgetEchoStore.ts +++ b/apps/web/src/stores/WidgetEchoStore.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line no-restricted-imports import EventEmitter from "events"; import { type IWidget } from "matrix-widget-api"; import { type MatrixEvent } from "matrix-js-sdk/src/matrix"; diff --git a/apps/web/src/stores/local-echo/GenericEchoChamber.ts b/apps/web/src/stores/local-echo/GenericEchoChamber.ts index 6dbd7f587b..27ae8f241d 100644 --- a/apps/web/src/stores/local-echo/GenericEchoChamber.ts +++ b/apps/web/src/stores/local-echo/GenericEchoChamber.ts @@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import { type MatrixClient } from "matrix-js-sdk/src/matrix"; +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import { type EchoContext } from "./EchoContext"; diff --git a/apps/web/src/stores/spaces/SpaceStore.test.ts b/apps/web/src/stores/spaces/SpaceStore.test.ts index 148a000755..b890b861af 100644 --- a/apps/web/src/stores/spaces/SpaceStore.test.ts +++ b/apps/web/src/stores/spaces/SpaceStore.test.ts @@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details. // @vitest-environment happy-dom import { vi, describe, it, expect, beforeAll, beforeEach, afterEach } from "vitest"; -import { type EventEmitter } from "events"; +import { type EventEmitter } from "node:events"; import { EventType, RoomMember, diff --git a/apps/web/src/utils/Image.test.ts b/apps/web/src/utils/Image.test.ts index 1c8464db83..7f381bdba7 100644 --- a/apps/web/src/utils/Image.test.ts +++ b/apps/web/src/utils/Image.test.ts @@ -9,10 +9,11 @@ Please see LICENSE files in the repository root for full details. import { describe, it, expect } from "vitest"; import fs from "node:fs"; import path from "node:path"; +import { fileURLToPath } from "node:url"; import { blobIsAnimated, mayBeAnimated } from "./Image"; -const imagesDir = path.resolve(__dirname, "../../test/unit-tests/images"); +const imagesDir = fileURLToPath(import.meta.resolve("../../test/unit-tests/images")); describe("Image", () => { describe("mayBeAnimated", () => { diff --git a/apps/web/src/utils/ResizeNotifier.ts b/apps/web/src/utils/ResizeNotifier.ts index 02b4848c2f..a52db4fc1e 100644 --- a/apps/web/src/utils/ResizeNotifier.ts +++ b/apps/web/src/utils/ResizeNotifier.ts @@ -15,6 +15,7 @@ Please see LICENSE files in the repository root for full details. * @event module:utils~ResizeNotifier#"middlePanelResizedNoisy" */ +// oxlint-disable-next-line no-restricted-imports import { EventEmitter } from "events"; import { throttle } from "lodash"; diff --git a/apps/web/src/utils/UrlPreviewFetcher.ts b/apps/web/src/utils/UrlPreviewFetcher.ts index 708f96d49c..d38d8db1e4 100644 --- a/apps/web/src/utils/UrlPreviewFetcher.ts +++ b/apps/web/src/utils/UrlPreviewFetcher.ts @@ -212,17 +212,6 @@ export class UrlPreviewFetcher { * Convert an MSC4095 URL preview bundle item to a UrlPreview */ public previewFromBundle(single: UnstableBundledUrlPreviewSingle): UrlPreview { - // missing fields from the bundle because backend does provide it: - // - siteName (can be computed) - // - favicon - // - media is a video or audio? - // TODO in next PR: URL previews in encrypted chat? - const hasImage = - typeof single["og:image"] === "string" && - typeof single["og:image:type"] === "string" && - typeof single["og:image:width"] === "number" && - typeof single["og:image:height"] === "number"; - const preview: UrlPreview = { link: single.matched_url, title: single["og:title"] ?? single.matched_url, @@ -232,7 +221,17 @@ export class UrlPreviewFetcher { ogUrl: single["og:url"], }; - if (hasImage) { + // missing fields from the bundle because backend does provide it: + // - siteName (can be computed) + // - favicon + // - media is a video or audio? + // TODO in next PR: URL previews in encrypted chat? + if ( + typeof single["og:image"] === "string" && + typeof single["og:image:type"] === "string" && + typeof single["og:image:width"] === "number" && + typeof single["og:image:height"] === "number" + ) { const media = mediaFromMxc(single["og:image"], this.client); const thumb = media.getThumbnailOfSourceHttp(PREVIEW_WIDTH_PX, PREVIEW_HEIGHT_PX, "scale"); @@ -245,10 +244,10 @@ export class UrlPreviewFetcher { preview.image = { imageThumb: thumb, imageFull: media.srcHttp, - imageType: single["og:image:type"] as string, - mxcImageFull: single["og:image"] as string, - width: single["og:image:width"] as number, - height: single["og:image:height"] as number, + imageType: single["og:image:type"], + mxcImageFull: single["og:image"], + width: single["og:image:width"], + height: single["og:image:height"], playable: false, // TODO: do we know? }; } diff --git a/apps/web/src/utils/arrays.ts b/apps/web/src/utils/arrays.ts index 3056738d3c..ee9ac68943 100644 --- a/apps/web/src/utils/arrays.ts +++ b/apps/web/src/utils/arrays.ts @@ -135,7 +135,7 @@ export function arrayTrimFill(a: T[], len: number, seed: T[]): T[] { * @returns A copy of the array. */ export function arrayFastClone(a: T[]): T[] { - return a.slice(0, a.length); + return a.slice(0); } /** diff --git a/apps/web/src/utils/image-media.ts b/apps/web/src/utils/image-media.ts index 78ba51276c..46b527ac68 100644 --- a/apps/web/src/utils/image-media.ts +++ b/apps/web/src/utils/image-media.ts @@ -63,7 +63,7 @@ export async function createThumbnail( let context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D; try { canvas = new window.OffscreenCanvas(targetWidth, targetHeight); - context = canvas.getContext("2d") as OffscreenCanvasRenderingContext2D; + context = canvas.getContext("2d")!; } catch { // Fallback support for other browsers (Safari and Firefox for now) canvas = document.createElement("canvas"); diff --git a/apps/web/src/utils/permalinks/Permalinks.test.ts b/apps/web/src/utils/permalinks/Permalinks.test.ts index 360fd724f9..eeaa7fe093 100644 --- a/apps/web/src/utils/permalinks/Permalinks.test.ts +++ b/apps/web/src/utils/permalinks/Permalinks.test.ts @@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details. import { vi, describe, it, expect, afterAll, beforeEach } from "vitest"; import { getMockClientWithEventEmitter } from "test-utils/client"; -import { type EventEmitter } from "events"; +import { type EventEmitter } from "node:events"; import { Room, RoomMember, EventType, MatrixEvent } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; diff --git a/apps/web/src/vector/app.tsx b/apps/web/src/vector/app.tsx index 48907eb02d..f1e7f645b8 100644 --- a/apps/web/src/vector/app.tsx +++ b/apps/web/src/vector/app.tsx @@ -36,6 +36,7 @@ import { ModuleNotificationDecoration } from "../modules/components/ModuleNotifi import Login from "../Login.ts"; import { startOAuthLogin } from "../utils/oauth/authorize.ts"; +// oxlint-disable-next-line node/no-process-env logger.log(`Application is running in ${process.env.NODE_ENV} mode`); window.matrixLogger = logger; diff --git a/apps/web/src/vector/index.ts b/apps/web/src/vector/index.ts index d69e74b0eb..586b55a052 100644 --- a/apps/web/src/vector/index.ts +++ b/apps/web/src/vector/index.ts @@ -22,10 +22,10 @@ import "../../res/css/_index.pcss"; // Require common CSS here; this will make webpack process it into bundle.css. // Our own CSS (which is themed) is imported via separate webpack entry points // in webpack.config.js -// eslint-disable-next-line @typescript-eslint/no-require-imports +// eslint-disable-next-line @typescript-eslint/no-require-imports,import/no-commonjs,unicorn/prefer-module require("katex/dist/katex.css"); -// eslint-disable-next-line @typescript-eslint/no-require-imports +// eslint-disable-next-line @typescript-eslint/no-require-imports,import/no-commonjs,unicorn/prefer-module require("./localstorage-fix"); // Patch a fake window.TouchEvent for re-resizable's unguarded `instanceof TouchEvent`. diff --git a/apps/web/src/vector/mobile_guide/mobile-apps.ts b/apps/web/src/vector/mobile_guide/mobile-apps.ts index 574e219ca9..5d6f88439c 100644 --- a/apps/web/src/vector/mobile_guide/mobile-apps.ts +++ b/apps/web/src/vector/mobile_guide/mobile-apps.ts @@ -59,7 +59,7 @@ export const mobileApps: Record = { }; export function updateMobilePage(metadata: MobileAppMetadata, deepLinkUrl: string, server: string | undefined): void { - const appleMeta = document.querySelector('meta[name="apple-itunes-app"]') as Element; + const appleMeta = document.querySelector('meta[name="apple-itunes-app"]')!; appleMeta.setAttribute("content", `app-id=${metadata.appleAppId}`); if (server) { diff --git a/apps/web/src/vector/platform/WebPlatform.test.ts b/apps/web/src/vector/platform/WebPlatform.test.ts index d7576bb1d3..02fa172055 100644 --- a/apps/web/src/vector/platform/WebPlatform.test.ts +++ b/apps/web/src/vector/platform/WebPlatform.test.ts @@ -136,6 +136,7 @@ describe("WebPlatform", () => { }); describe("app version", () => { + // oxlint-disable-next-line node/no-process-env const envVersion = process.env.VERSION; const prodVersion = "1.10.13"; diff --git a/apps/web/src/vector/platform/WebPlatform.ts b/apps/web/src/vector/platform/WebPlatform.ts index 88aa7ee9cc..a546ad5018 100644 --- a/apps/web/src/vector/platform/WebPlatform.ts +++ b/apps/web/src/vector/platform/WebPlatform.ts @@ -35,6 +35,7 @@ function getNormalizedAppVersion(version: string): string { } export default class WebPlatform extends BasePlatform { + // oxlint-disable-next-line node/no-process-env private static readonly VERSION = process.env.VERSION!; // baked in by Webpack private readonly registerServiceWorkerPromise: Promise; diff --git a/apps/web/src/vector/rageshakesetup.test.ts b/apps/web/src/vector/rageshakesetup.test.ts index ba2dad2e58..55f0c25463 100644 --- a/apps/web/src/vector/rageshakesetup.test.ts +++ b/apps/web/src/vector/rageshakesetup.test.ts @@ -48,7 +48,7 @@ describe("mxSendRageshake", () => { }); it.each(["", " ", undefined, null])("Does not send a rageshake if text is '%s'", async (text) => { - await window.mxSendRageshake(text as string); + await window.mxSendRageshake(text!); expect(fetchMock).not.toHaveFetched(); }); diff --git a/apps/web/src/viewmodels/message-body/ImageBodyViewModel.ts b/apps/web/src/viewmodels/message-body/ImageBodyViewModel.ts index b4df1e2f9f..eb3fd5ceac 100644 --- a/apps/web/src/viewmodels/message-body/ImageBodyViewModel.ts +++ b/apps/web/src/viewmodels/message-body/ImageBodyViewModel.ts @@ -122,7 +122,7 @@ export class ImageBodyViewModel this.state = initialState; const imageSizeWatcherRef = SettingsStore.watchSetting("Images.size", null, (_s, _r, _l, _nvl, value) => { - this.setImageSize(value as ImageSize); + this.setImageSize(value!); }); this.disposables.track(() => SettingsStore.unwatchSetting(imageSizeWatcherRef)); } diff --git a/apps/web/src/viewmodels/message-body/VideoBodyViewModel.ts b/apps/web/src/viewmodels/message-body/VideoBodyViewModel.ts index 11fece6954..e320d939c9 100644 --- a/apps/web/src/viewmodels/message-body/VideoBodyViewModel.ts +++ b/apps/web/src/viewmodels/message-body/VideoBodyViewModel.ts @@ -109,7 +109,7 @@ export class VideoBodyViewModel this.state = initialState; const imageSizeWatcherRef = SettingsStore.watchSetting("Images.size", null, (_s, _r, _l, _nvl, value) => { - this.setImageSize(value as ImageSize); + this.setImageSize(value!); }); this.disposables.track(() => SettingsStore.unwatchSetting(imageSizeWatcherRef)); } diff --git a/apps/web/src/viewmodels/room/timeline/event-tile/call/call-mocks.ts b/apps/web/src/viewmodels/room/timeline/event-tile/call/call-mocks.ts index 779fb2ee2e..23cc691d39 100644 --- a/apps/web/src/viewmodels/room/timeline/event-tile/call/call-mocks.ts +++ b/apps/web/src/viewmodels/room/timeline/event-tile/call/call-mocks.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { type RoomMember, type MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; import { mkEvent, mkRoomMember } from "../../../../../../test/test-utils"; diff --git a/apps/web/src/viewmodels/structures/auto-collapse/behaviours/CollapseOnCallResizeBehaviour.test.ts b/apps/web/src/viewmodels/structures/auto-collapse/behaviours/CollapseOnCallResizeBehaviour.test.ts index dc7074bf8c..745938c6a7 100644 --- a/apps/web/src/viewmodels/structures/auto-collapse/behaviours/CollapseOnCallResizeBehaviour.test.ts +++ b/apps/web/src/viewmodels/structures/auto-collapse/behaviours/CollapseOnCallResizeBehaviour.test.ts @@ -7,7 +7,7 @@ // @vitest-environment happy-dom -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { type CallStore, CallStoreEvent } from "../../../../stores/CallStore"; import { CollapseOnCallResizeBehaviour } from "./CollapseOnCallResizeBehaviour"; diff --git a/apps/web/test/globalSetup.ts b/apps/web/test/globalSetup.ts index c00ca3abf8..fd1c3fbb7d 100644 --- a/apps/web/test/globalSetup.ts +++ b/apps/web/test/globalSetup.ts @@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ +// oxlint-disable-next-line import/no-commonjs,unicorn/prefer-module module.exports = async () => { process.env.TZ = "UTC"; }; diff --git a/apps/web/test/setupTests.ts b/apps/web/test/setupTests.ts index beed2e70f9..e5f1881a01 100644 --- a/apps/web/test/setupTests.ts +++ b/apps/web/test/setupTests.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { env } from "process"; +import { env } from "node:process"; import "@testing-library/jest-dom"; import "blob-polyfill"; import { secureRandomString } from "matrix-js-sdk/src/randomstring"; @@ -61,7 +61,7 @@ if (env["GITHUB_ACTIONS"] !== undefined) { // // These are also require() calls to make sure they get called // synchronously. -/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-require-imports,import/no-commonjs,unicorn/prefer-module */ require("./setup/setupManualMocks"); // must be first require("./setup/setupLanguage"); require("./setup/setupConfig"); diff --git a/apps/web/test/test-utils/audio.ts b/apps/web/test/test-utils/audio.ts index eb9f91bcc6..ef775730fa 100644 --- a/apps/web/test/test-utils/audio.ts +++ b/apps/web/test/test-utils/audio.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { SimpleObservable } from "matrix-widget-api"; import { type Playback, PlaybackState } from "../../src/audio/Playback"; diff --git a/apps/web/test/test-utils/client.ts b/apps/web/test/test-utils/client.ts index 8cd204a579..91c3e56238 100644 --- a/apps/web/test/test-utils/client.ts +++ b/apps/web/test/test-utils/client.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { type MockedObject } from "vitest"; import { type MethodLikeKeys, type PropertyLikeKeys } from "jest-mock"; import { type MockedObjectDeep } from "@vitest/spy"; diff --git a/apps/web/test/test-utils/test-utils.ts b/apps/web/test/test-utils/test-utils.ts index 4aa6861010..5a3261ccc5 100644 --- a/apps/web/test/test-utils/test-utils.ts +++ b/apps/web/test/test-utils/test-utils.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { type MockedObject } from "vitest"; import { MatrixEvent, diff --git a/apps/web/test/test-utils/utilities.ts b/apps/web/test/test-utils/utilities.ts index 16fd6c5d39..1abb5479eb 100644 --- a/apps/web/test/test-utils/utilities.ts +++ b/apps/web/test/test-utils/utilities.ts @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. import { act } from "test-utils-rtl"; -import type EventEmitter from "events"; +import type EventEmitter from "node:events"; import { type ActionPayload } from "../../src/dispatcher/payloads"; import defaultDispatcher from "../../src/dispatcher/dispatcher"; import { type DispatcherAction } from "../../src/dispatcher/actions"; diff --git a/apps/web/test/unit-tests/LegacyCallHandler-test.ts b/apps/web/test/unit-tests/LegacyCallHandler-test.ts index 02992d5428..971c5bad2e 100644 --- a/apps/web/test/unit-tests/LegacyCallHandler-test.ts +++ b/apps/web/test/unit-tests/LegacyCallHandler-test.ts @@ -17,7 +17,7 @@ import { } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { CallEvent, CallState, CallType, MatrixCall } from "matrix-js-sdk/src/webrtc/call"; -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { mocked } from "jest-mock"; import { CallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/callEventHandler"; import fetchMock from "@fetch-mock/jest"; diff --git a/apps/web/test/unit-tests/audio/MockedPlayback.ts b/apps/web/test/unit-tests/audio/MockedPlayback.ts index 5c89bfc0d5..cde6e837e7 100644 --- a/apps/web/test/unit-tests/audio/MockedPlayback.ts +++ b/apps/web/test/unit-tests/audio/MockedPlayback.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { SimpleObservable } from "matrix-widget-api"; import { PlaybackState } from "../../../src/audio/Playback"; diff --git a/apps/web/test/unit-tests/audio/VoiceRecording-test.ts b/apps/web/test/unit-tests/audio/VoiceRecording-test.ts index 73329ba566..29d4fae621 100644 --- a/apps/web/test/unit-tests/audio/VoiceRecording-test.ts +++ b/apps/web/test/unit-tests/audio/VoiceRecording-test.ts @@ -136,7 +136,7 @@ describe("VoiceRecording", () => { MediaDeviceHandlerMock.getAudioInput.mockReturnValue("default"); await recording.start(); - const constraints = mocked(navigator.mediaDevices.getUserMedia).mock.calls[0][0] as MediaStreamConstraints; + const constraints = mocked(navigator.mediaDevices.getUserMedia).mock.calls[0][0]!; expect(constraints.audio).toEqual( expect.not.objectContaining({ deviceId: expect.anything(), diff --git a/apps/web/test/unit-tests/components/structures/MessagePanel-test.tsx b/apps/web/test/unit-tests/components/structures/MessagePanel-test.tsx index 4e1508356c..bb75f4fe19 100644 --- a/apps/web/test/unit-tests/components/structures/MessagePanel-test.tsx +++ b/apps/web/test/unit-tests/components/structures/MessagePanel-test.tsx @@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { type MatrixEvent, Room, RoomMember, type Thread, ReceiptType } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; import { render, within } from "jest-matrix-react"; diff --git a/apps/web/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap b/apps/web/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap index 9d12ef1b2e..72faba944c 100644 --- a/apps/web/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap +++ b/apps/web/test/unit-tests/components/structures/__snapshots__/RoomView-test.tsx.snap @@ -25,6 +25,7 @@ exports[`RoomView for a local room in state CREATING should match the snapshot 1 aria-label="Room info" class="mx_RoomHeader_infoWrapper" tabindex="0" + type="button" >
{ - // 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(); diff --git a/apps/web/test/unit-tests/components/views/dialogs/BaseDialog-test.tsx b/apps/web/test/unit-tests/components/views/dialogs/BaseDialog-test.tsx index 41a396c5b6..6a536fb686 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/BaseDialog-test.tsx +++ b/apps/web/test/unit-tests/components/views/dialogs/BaseDialog-test.tsx @@ -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('[role="dialog"]')!; dialog?.focus(); await userEvent.keyboard("{Escape}"); expect(onFinished).toHaveBeenCalled(); diff --git a/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/DevtoolsDialog-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/DevtoolsDialog-test.tsx.snap index c476c1d360..169d0f0f7e 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/DevtoolsDialog-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/DevtoolsDialog-test.tsx.snap @@ -76,41 +76,49 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = ` @@ -123,21 +131,25 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = ` @@ -317,7 +329,9 @@ exports[`DevtoolsDialog renders the devtools dialog 1`] = `
-
diff --git a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Event-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Event-test.tsx.snap index 7fca222e84..992bf96d39 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Event-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Event-test.tsx.snap @@ -51,10 +51,14 @@ exports[` should render 1`] = `
- -
@@ -115,10 +119,14 @@ exports[` thread context should pre-populate a thread relationshi
- -
diff --git a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/RoomNotifications-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/RoomNotifications-test.tsx.snap index 2fc0258c49..09dce1d977 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/RoomNotifications-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/RoomNotifications-test.tsx.snap @@ -64,7 +64,9 @@ exports[` should render 1`] = `
-
diff --git a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap index 1e77b0d218..308354fc83 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/devtools/__snapshots__/Users-test.tsx.snap @@ -185,7 +185,9 @@ exports[` should render a single device - signed by owner 1`] = `
-
@@ -377,7 +379,9 @@ exports[` should render a single device - unsigned 1`] = `
-
@@ -571,7 +575,9 @@ exports[` should render a single device - verified by cross-signing 1`]
-
@@ -672,6 +678,7 @@ exports[` should render a single user 1`] = `
  • @@ -828,7 +839,9 @@ exports[` should render a user list 1`] = `
    -
    diff --git a/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ExportE2eKeysDialog-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ExportE2eKeysDialog-test.tsx.snap index cfee3dd7d7..61a055907d 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ExportE2eKeysDialog-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ExportE2eKeysDialog-test.tsx.snap @@ -92,7 +92,9 @@ exports[`ExportE2eKeysDialog renders 1`] = ` type="submit" value="Export" /> -
    diff --git a/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ImportE2eKeysDialog-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ImportE2eKeysDialog-test.tsx.snap index 37bfb2765f..d54bc4929d 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ImportE2eKeysDialog-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/security/__snapshots__/ImportE2eKeysDialog-test.tsx.snap @@ -93,7 +93,9 @@ exports[`ImportE2eKeysDialog renders 1`] = ` type="submit" value="Import" /> -
    diff --git a/apps/web/test/unit-tests/components/views/elements/FilterDropdown-test.tsx b/apps/web/test/unit-tests/components/views/elements/FilterDropdown-test.tsx index d84cc7d691..44a3a5ec9d 100644 --- a/apps/web/test/unit-tests/components/views/elements/FilterDropdown-test.tsx +++ b/apps/web/test/unit-tests/components/views/elements/FilterDropdown-test.tsx @@ -33,7 +33,7 @@ describe("", () => { await act(async () => { const button = container.querySelector('[role="button"]'); expect(button).toBeTruthy(); - fireEvent.click(button as Element); + fireEvent.click(button!); await flushPromises(); }); diff --git a/apps/web/test/unit-tests/components/views/elements/ImageView-test.tsx b/apps/web/test/unit-tests/components/views/elements/ImageView-test.tsx index 4a5bd83710..3043fbd118 100644 --- a/apps/web/test/unit-tests/components/views/elements/ImageView-test.tsx +++ b/apps/web/test/unit-tests/components/views/elements/ImageView-test.tsx @@ -85,7 +85,7 @@ describe("", () => { , ); - const dialog = container.querySelector('[role="dialog"]') as HTMLElement; + const dialog = container.querySelector('[role="dialog"]')!; dialog?.focus(); fireEvent.keyDown(dialog!, { key: "s", code: "KeyS", ctrlKey: true }); diff --git a/apps/web/test/unit-tests/components/views/elements/__snapshots__/EventListSummary-test.tsx.snap b/apps/web/test/unit-tests/components/views/elements/__snapshots__/EventListSummary-test.tsx.snap index 6c30e0ce87..45ca820208 100644 --- a/apps/web/test/unit-tests/components/views/elements/__snapshots__/EventListSummary-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/elements/__snapshots__/EventListSummary-test.tsx.snap @@ -7,6 +7,7 @@ exports[`EventListSummary correctly identifies transitions 1`] = ` diff --git a/apps/web/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx b/apps/web/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx index 9095f78c7e..e63045354f 100644 --- a/apps/web/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx +++ b/apps/web/test/unit-tests/components/views/settings/tabs/user/SessionManagerTab-test.tsx @@ -948,18 +948,16 @@ describe("", () => { 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("", () => { 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("", () => { 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("", () => { // 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("", () => { 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}`, diff --git a/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx b/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx index 3ad77ec2a2..cd3379fe8f 100644 --- a/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx +++ b/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx @@ -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[] = []; diff --git a/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx b/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx index ea38579a8a..7b3b93c384 100644 --- a/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx +++ b/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx @@ -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(); diff --git a/apps/web/test/unit-tests/models/Call-test.ts b/apps/web/test/unit-tests/models/Call-test.ts index ba3b264b54..dbab94ba4d 100644 --- a/apps/web/test/unit-tests/models/Call-test.ts +++ b/apps/web/test/unit-tests/models/Call-test.ts @@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { mocked } from "jest-mock"; import { waitFor } from "jest-matrix-react"; import { diff --git a/apps/web/test/unit-tests/modules/ExtrasApi-test.tsx b/apps/web/test/unit-tests/modules/ExtrasApi-test.tsx index cb895d2b6a..bb566f86c4 100644 --- a/apps/web/test/unit-tests/modules/ExtrasApi-test.tsx +++ b/apps/web/test/unit-tests/modules/ExtrasApi-test.tsx @@ -8,7 +8,7 @@ import React, { act } from "react"; import { render, type RenderOptions } from "jest-matrix-react"; import { type MatrixClient, PendingEventOrdering, Room } from "matrix-js-sdk/src/matrix"; -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { stubClient } from "../../test-utils"; import DMRoomMap from "../../../src/utils/DMRoomMap"; diff --git a/apps/web/test/unit-tests/stores/RoomViewStore-test.ts b/apps/web/test/unit-tests/stores/RoomViewStore-test.ts index 95bf2e72fb..3b1cca51cc 100644 --- a/apps/web/test/unit-tests/stores/RoomViewStore-test.ts +++ b/apps/web/test/unit-tests/stores/RoomViewStore-test.ts @@ -13,7 +13,7 @@ import { RoomViewLifecycle, type ViewRoomOpts, } from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"; -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { RoomViewStore } from "../../../src/stores/RoomViewStore"; import { Action } from "../../../src/dispatcher/actions"; @@ -98,9 +98,7 @@ jest.mock("../../../src/utils/DMRoomMap", () => { }); jest.mock("../../../src/stores/WidgetStore", () => { - // This mock needs to use a real EventEmitter; require is the only way to import that in a hoisted block - // eslint-disable-next-line @typescript-eslint/no-require-imports - const EventEmitter = require("events"); + const EventEmitter = jest.requireActual("events"); const apps: IApp[] = []; const instance = new (class extends EventEmitter { getApps() { diff --git a/apps/web/test/unit-tests/utils/MegolmExportEncryption-test.ts b/apps/web/test/unit-tests/utils/MegolmExportEncryption-test.ts index 5ce425343b..f86ffe45d0 100644 --- a/apps/web/test/unit-tests/utils/MegolmExportEncryption-test.ts +++ b/apps/web/test/unit-tests/utils/MegolmExportEncryption-test.ts @@ -6,8 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { TextEncoder } from "util"; -import nodeCrypto from "crypto"; +import { TextEncoder } from "node:util"; +import nodeCrypto from "node:crypto"; import { Crypto } from "@peculiar/webcrypto"; import type * as MegolmExportEncryptionExport from "../../../src/utils/MegolmExportEncryption"; @@ -74,8 +74,7 @@ describe("MegolmExportEncryption", function () { subtle: webCrypto.subtle, }, }); - // eslint-disable-next-line @typescript-eslint/no-require-imports - MegolmExportEncryption = require("../../../src/utils/MegolmExportEncryption"); + MegolmExportEncryption = jest.requireActual("../../../src/utils/MegolmExportEncryption"); }); describe("decrypt", function () { diff --git a/apps/web/test/unit-tests/utils/SessionLock-test.ts b/apps/web/test/unit-tests/utils/SessionLock-test.ts index b0125debc5..fc7a2236ed 100644 --- a/apps/web/test/unit-tests/utils/SessionLock-test.ts +++ b/apps/web/test/unit-tests/utils/SessionLock-test.ts @@ -252,7 +252,7 @@ describe("SessionLock", () => { const window2 = createWindow(); // import the dependencies of getSessionLock into the new context - // eslint-disable-next-line @typescript-eslint/no-require-imports + // eslint-disable-next-line typescript/no-require-imports,typescript/no-var-requires window2._logger = require("matrix-js-sdk/src/logger"); window2.SESSION_LOCK_CONSTANTS = SESSION_LOCK_CONSTANTS; diff --git a/apps/web/test/viewmodels/event-tiles/E2eMessageSharedIconViewModel-test.ts b/apps/web/test/viewmodels/event-tiles/E2eMessageSharedIconViewModel-test.ts index 7aa334541f..5f8571a6e4 100644 --- a/apps/web/test/viewmodels/event-tiles/E2eMessageSharedIconViewModel-test.ts +++ b/apps/web/test/viewmodels/event-tiles/E2eMessageSharedIconViewModel-test.ts @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { EventTimeline, RoomStateEvent, diff --git a/apps/web/test/viewmodels/event-tiles/MJitsiWidgetEventViewModel-test.ts b/apps/web/test/viewmodels/event-tiles/MJitsiWidgetEventViewModel-test.ts index 46c41d96a6..1968b50b01 100644 --- a/apps/web/test/viewmodels/event-tiles/MJitsiWidgetEventViewModel-test.ts +++ b/apps/web/test/viewmodels/event-tiles/MJitsiWidgetEventViewModel-test.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { type MatrixClient, type Room } from "matrix-js-sdk/src/matrix"; import { MJitsiWidgetEventViewModel } from "../../../src/viewmodels/room/timeline/event-tile/MJitsiWidgetEventViewModel"; diff --git a/apps/web/test/viewmodels/event-tiles/ThreadSummaryViewModel-test.ts b/apps/web/test/viewmodels/event-tiles/ThreadSummaryViewModel-test.ts index e77a9fdc48..07f51a861b 100644 --- a/apps/web/test/viewmodels/event-tiles/ThreadSummaryViewModel-test.ts +++ b/apps/web/test/viewmodels/event-tiles/ThreadSummaryViewModel-test.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import { EventEmitter } from "events"; +import { EventEmitter } from "node:events"; import { type MouseEvent } from "react"; import { EventType, diff --git a/apps/web/test/viewmodels/room-list/RoomListItemViewModel-test.ts b/apps/web/test/viewmodels/room-list/RoomListItemViewModel-test.ts index 3abd78c1c3..d0bd7ea05d 100644 --- a/apps/web/test/viewmodels/room-list/RoomListItemViewModel-test.ts +++ b/apps/web/test/viewmodels/room-list/RoomListItemViewModel-test.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { type MatrixClient, type MatrixEvent, diff --git a/apps/web/test/viewmodels/room/EventTileActionBarViewModel-test.ts b/apps/web/test/viewmodels/room/EventTileActionBarViewModel-test.ts index 1c7125beb5..10a61b8e58 100644 --- a/apps/web/test/viewmodels/room/EventTileActionBarViewModel-test.ts +++ b/apps/web/test/viewmodels/room/EventTileActionBarViewModel-test.ts @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -import EventEmitter from "events"; +import EventEmitter from "node:events"; import { waitFor } from "@testing-library/dom"; import { mocked } from "jest-mock"; import { diff --git a/apps/web/vitest.config.ts b/apps/web/vitest.config.ts index c2e633271e..7b36f631e8 100644 --- a/apps/web/vitest.config.ts +++ b/apps/web/vitest.config.ts @@ -5,41 +5,45 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ +import { fileURLToPath } from "node:url"; import { defineProject } from "vitest/config"; import svgr from "vite-plugin-svgr"; -import { resolve } from "node:path"; + +function resolve(specifier: string): string { + return fileURLToPath(import.meta.resolve(specifier)); +} export default defineProject({ resolve: { alias: [ - { find: "test-utils-rtl", replacement: resolve(__dirname, "./test/test-utils/vitest-matrix-react") }, - { find: "test-utils", replacement: resolve(__dirname, "./test/test-utils") }, + { find: "test-utils-rtl", replacement: resolve("./test/test-utils/vitest-matrix-react") }, + { find: "test-utils", replacement: resolve("./test/test-utils") }, // Stub out workers as they do not play well under test { find: /.*workers\/(.+)Factory/, - replacement: resolve(__dirname, "./__mocks__/workerFactoryMock.js"), + replacement: resolve("./__mocks__/workerFactoryMock.js"), }, { find: /.*waveWorker\.min\.js$/, - replacement: resolve(__dirname, "./__mocks__/empty.js"), + replacement: resolve("./__mocks__/empty.js"), }, { find: /.*decoderWorker\.min\.js$/, - replacement: resolve(__dirname, "./__mocks__/empty.js"), + replacement: resolve("./__mocks__/empty.js"), }, { find: /.*decoderWorker\.min\.wasm$/, - replacement: resolve(__dirname, "./__mocks__/empty.js"), + replacement: resolve("./__mocks__/empty.js"), }, // Stub this out as we lack AudioWorkletProcessor in the test env { find: "./recorderWorkletFactory", - replacement: resolve(__dirname, "./__mocks__/empty.js"), + replacement: resolve("./__mocks__/empty.js"), }, // Stub out legacy modules so we don't need to build them first { find: "../modules.js", - replacement: resolve(__dirname, "./__mocks__/empty.js"), + replacement: resolve("./__mocks__/empty.js"), }, ], }, @@ -54,7 +58,7 @@ export default defineProject({ url: "http://localhost/", }, }, - snapshotSerializers: [resolve(__dirname, "./src/test/react-use-id-serializer.ts")], + snapshotSerializers: [resolve("./src/test/react-use-id-serializer.ts")], }, plugins: [ svgr({ diff --git a/docs/generated/[id].paths.ts b/docs/generated/[id].paths.ts index acb0715397..e77af1c51d 100644 --- a/docs/generated/[id].paths.ts +++ b/docs/generated/[id].paths.ts @@ -6,19 +6,20 @@ Please see LICENSE in the repository root for full details. */ import genWorkflowMermaid from "../../scripts/gen-workflow-mermaid"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; +import { type ResolvedRouteConfig } from "vitepress"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default { - async paths() { - const root = join(__dirname, "..", ".."); + async paths(): Promise[]> { + const root = path.join(__dirname, "..", ".."); return [ { params: { id: "automations" }, - content: await genWorkflowMermaid([root, join(root, "node_modules", "matrix-js-sdk")]), + content: await genWorkflowMermaid([root, path.join(root, "node_modules", "matrix-js-sdk")]), }, ]; }, diff --git a/modules/banner/vite.config.ts b/modules/banner/vite.config.ts index a5f7d1c139..bbccf424bf 100644 --- a/modules/banner/vite.config.ts +++ b/modules/banner/vite.config.ts @@ -5,7 +5,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { mergeConfig } from "vite"; import react from "@vitejs/plugin-react"; @@ -14,12 +13,10 @@ import svgr from "vite-plugin-svgr"; import { importCSSSheet } from "@arcmantle/vite-plugin-import-css-sheet"; import baseConfig from "@element-hq/element-web-module-api/vite.base.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); - export default mergeConfig(baseConfig, { build: { lib: { - entry: resolve(__dirname, "src/index.tsx"), + entry: fileURLToPath(import.meta.resolve("./src/index.tsx")), name: "element-web-module-banner", fileName: "index", formats: ["es"], diff --git a/modules/playwright.config.ts b/modules/playwright.config.ts index 78aa2af98f..54827761f9 100644 --- a/modules/playwright.config.ts +++ b/modules/playwright.config.ts @@ -7,12 +7,12 @@ Please see LICENSE files in the repository root for full details. import { defineConfig, devices, type Project } from "@playwright/test"; import fs, { globSync } from "node:fs"; -import path, { dirname } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import type { Options } from "./playwright/element-web-test.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const chromeProject = { ...devices["Desktop Chrome"], diff --git a/modules/restricted-guests/vite.config.ts b/modules/restricted-guests/vite.config.ts index 8049efcc95..dd6c5b9681 100644 --- a/modules/restricted-guests/vite.config.ts +++ b/modules/restricted-guests/vite.config.ts @@ -5,7 +5,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { mergeConfig } from "vite"; import react from "@vitejs/plugin-react"; @@ -13,12 +12,10 @@ import { nodePolyfills } from "vite-plugin-node-polyfills"; import { importCSSSheet } from "@arcmantle/vite-plugin-import-css-sheet"; import baseConfig from "@element-hq/element-web-module-api/vite.base.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); - export default mergeConfig(baseConfig, { build: { lib: { - entry: resolve(__dirname, "src/index.tsx"), + entry: fileURLToPath(import.meta.resolve("./src/index.tsx")), name: "element-web-module-restricted-guests", fileName: "index", formats: ["es"], diff --git a/modules/widget-lifecycle/vite.config.ts b/modules/widget-lifecycle/vite.config.ts index 413eed0d8f..6a88b800ca 100644 --- a/modules/widget-lifecycle/vite.config.ts +++ b/modules/widget-lifecycle/vite.config.ts @@ -5,17 +5,14 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import { mergeConfig } from "vitest/config"; import baseConfig from "@element-hq/element-web-module-api/vite.base.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); - export default mergeConfig(baseConfig, { build: { lib: { - entry: resolve(__dirname, "src/index.ts"), + entry: fileURLToPath(import.meta.resolve("./src/index.ts")), name: "element-web-module-widget-lifecycle", fileName: "index", formats: ["es"], diff --git a/modules/widget-toggles/vite.config.ts b/modules/widget-toggles/vite.config.ts index efcb970ec7..ee4a75323b 100644 --- a/modules/widget-toggles/vite.config.ts +++ b/modules/widget-toggles/vite.config.ts @@ -5,7 +5,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; import react from "@vitejs/plugin-react"; import { nodePolyfills } from "vite-plugin-node-polyfills"; @@ -14,12 +13,10 @@ import { importCSSSheet } from "@arcmantle/vite-plugin-import-css-sheet"; import { mergeConfig } from "vitest/config"; import baseConfig from "@element-hq/element-web-module-api/vite.base.ts"; -const __dirname = dirname(fileURLToPath(import.meta.url)); - export default mergeConfig(baseConfig, { build: { lib: { - entry: resolve(__dirname, "src/index.tsx"), + entry: fileURLToPath(import.meta.resolve("./src/index.tsx")), name: "element-web-module-widget-toggles", fileName: "index", formats: ["es"], diff --git a/oxlint.config.ts b/oxlint.config.ts index ba6ebac12d..5387f68b97 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -52,6 +52,7 @@ export default defineConfig({ correctness: "error", perf: "error", suspicious: "error", + restriction: "warn", }, options: { typeAware: true, @@ -82,7 +83,7 @@ export default defineConfig({ "/packages/shared-components/typedoc/", ], settings: { - jsdoc: { + "jsdoc": { tagNamePreference: { remark: "remarks", privateRemarks: "privateRemarks", @@ -96,6 +97,23 @@ export default defineConfig({ resolves: "resolves", }, }, + "vitest": { + typecheck: true, + }, + "jsx-a11y": { + components: { + Button: "button", + IconButton: "button", + AccessibleButton: "button", + RovingAccessibleButton: "button", + ContextMenuButton: "button", + ContextMenuTooltipButton: "button", + }, + // polymorphicPropName: "as", // Would be good to enable in the future + }, + "react": { + componentWrapperFunctions: ["withMatrixClientHOC"], + }, }, rules: { "no-constant-condition": ["error", { checkLoops: "allExceptWhileTrue" }], @@ -108,17 +126,56 @@ export default defineConfig({ ], "prefer-const": ["error", { destructuring: "all" }], "import/first": "error", - "typescript/no-require-imports": "error", "new-cap": "error", - "no-empty-pattern": "error", "typescript/no-unsafe-function-type": "error", "react/rules-of-hooks": "error", "no-extend-native": "error", "no-inner-declarations": "error", - "no-var": "error", "typescript/no-unnecessary-type-constraint": "error", "jsx-filename-extension": ["error", { allow: "as-needed", extensions: ["tsx"] }], + // Tune restriction ruleset + "no-undefined": "off", + "typescript/use-unknown-in-catch-callback-variable": "off", + "typescript/promise-function-async": "off", + "typescript/no-non-null-assertion": "off", + "typescript/no-invalid-void-type": "off", + "typescript/no-explicit-any": "off", + "typescript/no-import-type-side-effects": "off", + "typescript/no-dynamic-delete": "off", + "typescript/explicit-module-boundary-types": "off", + "no-param-reassign": "off", + "no-use-before-define": "off", + "class-methods-use-this": "off", + "no-plusplus": "off", + "no-default-export": "off", + "no-console": "off", + "complexity": "off", + "no-void": "off", + "no-empty-function": "off", + "default-case": "off", + "no-implicit-globals": "off", + "no-bitwise": "off", + "no-empty": "off", + "no-eq-null": "off", + "promise/catch-or-return": "off", + "node/no-process-env": "off", // We enable this for src in overrides + "unicorn/no-array-reduce": "off", + "unicorn/no-anonymous-default-export": "off", + "import/no-relative-parent-imports": "off", + "import/unambiguous": "off", + "import/no-cycle": "off", + "jsdoc/empty-tags": "off", + "vitest/require-test-timeout": "off", + "react/jsx-no-literals": "off", + "react/prefer-function-component": "off", + "react/forbid-component-props": "off", + "react/no-multi-comp": "off", + "react/no-danger": "off", + "react/only-export-components": "off", + "react/no-react-children": "off", + "react/no-clone-element": "off", + "unicorn/no-instanceof-array": "error", "no-restricted-globals": ["error", ...defaultRestrictedGlobals], "no-restricted-properties": ["error", ...defaultRestrictedProperties], @@ -141,10 +198,6 @@ export default defineConfig({ allowExpressions: true, }, ], - "typescript/explicit-member-accessibility": "error", - - // Require us to be more explicit about type conversions to help prevent bugs - "typescript/no-base-to-string": ["error"], // Prevent invalid non-type re-exports of types, these can cause downstream build failures "typescript/consistent-type-exports": ["error"], @@ -232,19 +285,13 @@ export default defineConfig({ message: "Buffer is not available in the web.", }, ], + "node/no-process-env": "error", + "unicorn/prefer-node-protocol": "off", }, }, { files: ["{packages,apps,modules}/*/src/**/*"], rules: { - "no-restricted-imports": [ - "error", - { - name: "events", - message: "Please use TypedEventEmitter instead", - }, - ], - // Enable this in the future, it has a lot of false positives right now // "react/react-compiler": "error", }, @@ -285,6 +332,24 @@ export default defineConfig({ ], }, }, + { + files: [ + "apps/desktop/src/**/*", + "packages/playwright-common/src/**/*", + "**/scripts/**/*", + "apps/web/module_system/**/*", + ], + rules: { + "no-restricted-globals": "off", + "unicorn/prefer-node-protocol": "error", + // These files can use envvars + "node/no-process-env": "off", + // They do not depend on js-sdk for access to TypedEventEmitter so disable this rule + "no-restricted-imports": "off", + // They can use process.exit + "unicorn/no-process-exit": "off", + }, + }, { files: ["apps/web/**/*"], rules: { @@ -307,6 +372,10 @@ export default defineConfig({ "error", { paths: [ + { + name: "events", + message: "Please use TypedEventEmitter instead", + }, { name: "react", importNames: ["forwardRef"], @@ -471,12 +540,16 @@ export default defineConfig({ ], "jsdoc/check-tag-names": "off", "typescript/explicit-function-return-type": "off", + "typescript/explicit-module-boundary-types": "off", "typescript/explicit-member-accessibility": "off", + "no-proto": "off", // Disable a11y rules for components in tests "jsx-a11y/role-has-required-aria-props": "off", + "react/button-has-type": "off", "jsx-a11y/interactive-supports-focus": "off", "jsx-a11y/no-static-element-interactions": "off", + "jsx-a11y/anchor-ambiguous-text": "off", "jsx-a11y/click-events-have-key-events": "off", "jsx-a11y/media-has-caption": "off", "jsx-a11y/no-noninteractive-element-to-interactive-role": "off", @@ -519,6 +592,15 @@ export default defineConfig({ files: ["**/*.{cjs,js}"], rules: { "typescript/no-require-imports": "off", + "import/no-commonjs": "off", + "unicorn/prefer-module": "off", + }, + }, + { + files: ["apps/web/test/**/*-test.*"], + rules: { + // Jest is still CommonJS + "unicorn/prefer-module": "off", }, }, { diff --git a/packages/module-api/vite.config.ts b/packages/module-api/vite.config.ts index 85e24c4a8e..e465f9319e 100644 --- a/packages/module-api/vite.config.ts +++ b/packages/module-api/vite.config.ts @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial Please see LICENSE files in the repository root for full details. */ -import { dirname, resolve } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; import { defineConfig } from "vitest/config"; import dts from "unplugin-dts/vite"; @@ -13,12 +13,10 @@ import externalGlobals from "rollup-plugin-external-globals"; import packageJson from "./package.json" with { type: "json" }; -const __dirname = dirname(fileURLToPath(import.meta.url)); - export default defineConfig({ build: { lib: { - entry: resolve(__dirname, "src/index.ts"), + entry: fileURLToPath(import.meta.resolve("./src/index.ts")), name: "element-web-plugin-engine", fileName: "element-web-plugin-engine", }, @@ -33,7 +31,8 @@ export default defineConfig({ invokeOptions: { // Always overwrite element-web-module-api.api.md localBuild: true, - typescriptCompilerFolder: resolve(require.resolve("@typescript/old"), "../.."), + // oxlint-disable-next-line unicorn/prefer-module + typescriptCompilerFolder: path.resolve(require.resolve("@typescript/old"), "../.."), }, }, }), diff --git a/packages/playwright-common/src/expect/screenshot.ts b/packages/playwright-common/src/expect/screenshot.ts index ad8dc1a7b7..55eb21518c 100644 --- a/packages/playwright-common/src/expect/screenshot.ts +++ b/packages/playwright-common/src/expect/screenshot.ts @@ -16,7 +16,7 @@ import { type PageAssertionsToHaveScreenshotOptions, type MatcherReturnType, } from "@playwright/test"; -import { extname } from "node:path"; +import path from "node:path"; import { ANNOTATION } from "../stale-screenshot-reporter.js"; @@ -28,7 +28,7 @@ function sanitizeForFilePath(s: string): string { // Based on https://github.com/microsoft/playwright/blob/2b77ed4d7aafa85a600caa0b0d101b72c8437eeb/packages/playwright/src/util.ts#L206C8-L210C2 function sanitizeFilePathBeforeExtension(filePath: string): string { - const ext = extname(filePath); + const ext = path.extname(filePath); const base = filePath.substring(0, filePath.length - ext.length); return sanitizeForFilePath(base) + ext; } diff --git a/packages/playwright-common/src/testcontainers/mas-config.ts b/packages/playwright-common/src/testcontainers/mas-config.ts index 1f3a911ecd..b21481d190 100644 --- a/packages/playwright-common/src/testcontainers/mas-config.ts +++ b/packages/playwright-common/src/testcontainers/mas-config.ts @@ -1,3 +1,4 @@ +// oxlint-disable-next-line unicorn/no-abusive-eslint-disable /* eslint-disable */ /** * This file was automatically generated by json-schema-to-typescript. diff --git a/packages/shared-components/.storybook/main.ts b/packages/shared-components/.storybook/main.ts index 60fb388507..990f5b51f7 100644 --- a/packages/shared-components/.storybook/main.ts +++ b/packages/shared-components/.storybook/main.ts @@ -9,15 +9,15 @@ import type { StorybookConfig } from "@storybook/react-vite"; import fs from "node:fs"; import { nodePolyfills } from "vite-plugin-node-polyfills"; import { mergeConfig, normalizePath, type Plugin } from "vite"; -import { dirname, join } from "node:path"; +import path from "node:path"; import { fileURLToPath } from "node:url"; -const __dirname = dirname(fileURLToPath(import.meta.url)); -const srcRoot = normalizePath(join(__dirname, "..", "src")); +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const srcRoot = normalizePath(path.join(__dirname, "..", "src")); const sharedComponentsLayer = "shared-components"; // Get a list of available languages so the language selector can display them at runtime -const languageFiles = fs.readdirSync(join(__dirname, "..", "src", "i18n", "strings")).map((f) => f.slice(0, -5)); +const languageFiles = fs.readdirSync(path.join(__dirname, "..", "src", "i18n", "strings")).map((f) => f.slice(0, -5)); const languages: Record = {}; for (const lang of languageFiles) { @@ -35,7 +35,7 @@ for (const lang of languageFiles) { * It is needed in projects that use Yarn PnP or are set up within a monorepo. */ function getAbsolutePath(value: string): any { - return dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); + return path.dirname(fileURLToPath(import.meta.resolve(`${value}/package.json`))); } function layerSharedComponentCssModules(): Plugin { diff --git a/packages/shared-components/src/core/i18n/I18nApi.ts b/packages/shared-components/src/core/i18n/I18nApi.ts index 348570c4cd..c2d3691791 100644 --- a/packages/shared-components/src/core/i18n/I18nApi.ts +++ b/packages/shared-components/src/core/i18n/I18nApi.ts @@ -53,7 +53,7 @@ export class I18nApi implements II18nApi { public translate(this: void, key: TranslationKey, variables: Variables | undefined, tags: Tags): React.ReactNode; public translate(this: void, key: TranslationKey, variables?: Variables, tags?: Tags): React.ReactNode | string { if (tags) return _t(key, variables, tags); - return _t(key, variables as Variables); + return _t(key, variables!); } public humanizeTime = (timeMillis: number): string => humanizeTime(timeMillis, this); diff --git a/packages/shared-components/src/menus/UserMenu/UserMenu.tsx b/packages/shared-components/src/menus/UserMenu/UserMenu.tsx index b5872a5bef..b3375a9e5a 100644 --- a/packages/shared-components/src/menus/UserMenu/UserMenu.tsx +++ b/packages/shared-components/src/menus/UserMenu/UserMenu.tsx @@ -143,7 +143,7 @@ export function UserMenuView({ vm, className }: UserMenuViewProps): JSX.Element } = useViewModel(vm); const { translate: _t } = useI18n(); const trigger = ( -