Enable oxlint restriction ruleset (#34307)

* Remove stale max-len disablements

* Remove stale camelCase & naming-convention disablements

* Remove stale ban-ts-comment disablements

* Remove stale no-var disablements

* Remove stale no-empty-property disablements

* Remove stale react rule disablements

* Remove stale no-constant-condition disablements

* Remove stale no-unused-vars disablements

* Remove stale disablements for disabled rules

* fixup camelcase

* Remove dead code

* Tidy code

* Tweak oxlint config

* Use oxlint to apply jsx/tsx extension consistently

* Fix import

* Fix imports

* Rename affected snapshots

* Update more imports

* Enable restriction ruleset

* Make code comply with new rules

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

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

* Comply with node/no-process-env

* Comply with unicorn/prefer-node-protocol

* Comply with unicorn/import-style

* Comply with unicorn/no-process-exit

* Comply with no-proto

* Comply with node/handle-callback-err

* Comply with import/no-commonjs

* Comply with node/no-path-concat

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

* Comply with unicorn/no-document-cookie

* Comply with unicorn/prefer-module

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

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

* Tweak oxlint config

* Fix resolves

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate

* Iterate
This commit is contained in:
Michael Telatynski
2026-08-04 09:15:07 +00:00
committed by GitHub
parent c091ebec6e
commit 4aa1a3549e
167 changed files with 526 additions and 346 deletions
+4 -5
View File
@@ -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"), "../.."),
},
},
}),
@@ -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;
}
@@ -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.
@@ -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<string, string> = {};
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 {
@@ -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);
@@ -143,7 +143,7 @@ export function UserMenuView({ vm, className }: UserMenuViewProps): JSX.Element
} = useViewModel(vm);
const { translate: _t } = useI18n();
const trigger = (
<button className={styles.triggerButton} aria-label={_t("menus|user_menu|title")}>
<button className={styles.triggerButton} aria-label={_t("menus|user_menu|title")} type="button">
<div className={styles.avatarWrapper}>
<Avatar id={userId} name={displayName} type="round" size="36px" src={avatarUrl} />
{userStatus && (
@@ -169,6 +169,7 @@ export function ThreadSummaryView({
.join(" ");
return (
// oxlint-disable-next-line react/button-has-type
<button {...props} type={type} className={buttonClassName} onClick={vm.onClick} aria-label={openThreadLabel}>
<IndicatorIcon size="24px" indicator={notificationIndicator} className={styles.threadIcon}>
<ThreadsSolidIcon />
@@ -178,6 +178,7 @@ export function LinkPreviewExpanded(preview: LinkPreviewProps): JSX.Element {
className={styles.preview}
onClick={createImageClickHandler(preview)}
aria-label={_t("timeline|url_preview|view_image")}
type="button"
/>
);
}
@@ -72,6 +72,7 @@ exports[`LinkPreview > renders a preview 1`] = `
aria-label="View image"
class="LinkPreview-module_preview"
style="background-image: url("/static/element.png");"
type="button"
/>
<div
class="LinkPreview-module_textContent"
@@ -46,6 +46,7 @@ exports[`UrlPreviewGroupView > renders a single preview 1`] = `
aria-label="View image"
class="LinkPreview-module_preview"
style="background-image: url("/static/element.png");"
type="button"
/>
<div
class="LinkPreview-module_textContent"
@@ -125,6 +126,7 @@ exports[`UrlPreviewGroupView > renders multiple previews 1`] = `
aria-label="View image"
class="LinkPreview-module_preview"
style="background-image: url("/static/element.png");"
type="button"
/>
<div
class="LinkPreview-module_textContent"
@@ -281,6 +283,7 @@ exports[`UrlPreviewGroupView > renders multiple previews which are hidden 1`] =
aria-label="View image"
class="LinkPreview-module_preview"
style="background-image: url("/static/element.png");"
type="button"
/>
<div
class="LinkPreview-module_textContent"
@@ -369,6 +372,7 @@ exports[`UrlPreviewGroupView > renders with compact density 1`] = `
aria-label="View image"
class="LinkPreview-module_preview"
style="background-image: url("/static/element.png");"
type="button"
/>
<div
class="LinkPreview-module_textContent"
+8 -8
View File
@@ -7,13 +7,12 @@
*/
import { existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig, esmExternalRequirePlugin, type Plugin } from "vite";
import dts from "unplugin-dts/vite";
import react from "@vitejs/plugin-react";
import path from "node:path";
const __dirname = dirname(fileURLToPath(import.meta.url));
const cssLayerOrder = "@layer compound-tokens, compound-web, shared-components, app-web;";
const sharedComponentsLayer = "shared-components";
@@ -27,9 +26,9 @@ function layerCssAssets(): Plugin {
// the `element-` prefix), so we rename on disk to keep the path stable for
// consumers importing `@element-hq/web-shared-components/.../*.css`.
writeBundle(options): void {
const outDir = options.dir ?? resolve(__dirname, "dist");
const expectedPath = resolve(outDir, cssAssetFileName);
const renamedFromPath = resolve(outDir, "web-shared-components.css");
const outDir = options.dir ?? fileURLToPath(import.meta.resolve("./dist"));
const expectedPath = path.resolve(outDir, cssAssetFileName);
const renamedFromPath = path.resolve(outDir, "web-shared-components.css");
if (existsSync(renamedFromPath)) {
renameSync(renamedFromPath, expectedPath);
@@ -54,8 +53,8 @@ export default defineConfig({
// pulling in the rest of the package — which transitively loads dnd-kit and
// other window/document-dependent code.
entry: {
"element-web-shared-components": resolve(__dirname, "src/index.ts"),
"numbers": resolve(__dirname, "src/core/utils/numbers.ts"),
"element-web-shared-components": fileURLToPath(import.meta.resolve("./src/index.ts")),
"numbers": fileURLToPath(import.meta.resolve("./src/core/utils/numbers.ts")),
},
name: "Element Web Shared Components",
// Multi-entry mode needs both formats explicit; UMD doesn't support multi-entry
@@ -99,7 +98,8 @@ export default defineConfig({
bundleTypes: {
invokeOptions: {
localBuild: !!process.env.CI,
typescriptCompilerFolder: resolve(require.resolve("@typescript/old"), "../.."),
// oxlint-disable-next-line unicorn/prefer-module
typescriptCompilerFolder: path.resolve(require.resolve("@typescript/old"), "../.."),
},
},
include: ["src/**/*.{ts,tsx}"],
+2 -5
View File
@@ -6,7 +6,6 @@ Please see LICENSE files in the repository root for full details.
*/
import { defineConfig } from "vitest/config";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { storybookTest } from "@storybook/addon-vitest/vitest-plugin";
import { storybookVis } from "storybook-addon-vis/vitest-plugin";
@@ -16,8 +15,6 @@ import { nodePolyfills } from "vite-plugin-node-polyfills";
import rootConfig from "../../vitest.config";
import react from "@vitejs/plugin-react";
const dirname = typeof __dirname !== "undefined" ? __dirname : path.dirname(fileURLToPath(import.meta.url));
const commonContextOptions: PlaywrightProviderOptions["contextOptions"] = {
reducedMotion: "reduce",
// Force consistent font rendering
@@ -55,7 +52,7 @@ export default defineConfig({
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
storybookTest({
configDir: path.join(dirname, ".storybook"),
configDir: "./.storybook",
storybookScript: "storybook --ci",
tags: {
exclude: ["skip-test"],
@@ -135,7 +132,7 @@ export default defineConfig({
},
resolve: {
alias: {
"@test-utils": path.resolve(__dirname, "./src/test/utils/index.tsx"),
"@test-utils": fileURLToPath(import.meta.resolve("./src/test/utils/index.tsx")),
},
},
plugins: [react()],