Files
prowler/ui/eslint.config.ts
Pablo Fernandez Guerra (PFE) cb31856025 chore(ui): migrate ESLint to flat eslint.config.ts with typescript-eslint and import-x (#11352)
Co-authored-by: Pablo F.G <pablo.fernandez@prowler.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 10:17:54 +02:00

150 lines
4.0 KiB
TypeScript

import nextPlugin from "@next/eslint-plugin-next";
import prettierConfig from "eslint-config-prettier/flat";
import { createTypeScriptImportResolver } from "eslint-import-resolver-typescript";
import importX, { createNodeResolver } from "eslint-plugin-import-x";
import jsxA11y from "eslint-plugin-jsx-a11y";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";
import security from "eslint-plugin-security";
import globals from "globals";
import tseslint from "typescript-eslint";
export default tseslint.config(
{
ignores: [
".now/**",
"**/*.css",
".changeset/**",
"dist/**",
"esm/**",
"public/**",
"tests/**",
"scripts/**",
"*.config.js",
"*.config.mjs",
"auth.config.ts",
"eslint.config.ts",
"knip.config.ts",
"playwright.config.ts",
"vitest.config.ts",
".DS_Store",
"node_modules/**",
"coverage/**",
".next/**",
"build/**",
"next-env.d.ts",
],
},
importX.flatConfigs.recommended,
importX.flatConfigs.typescript,
{
files: ["**/*.{ts,tsx,js,jsx}"],
linterOptions: {
reportUnusedDisableDirectives: "error",
},
plugins: {
"@typescript-eslint": tseslint.plugin,
"@next/next": nextPlugin,
react: reactPlugin,
"react-hooks": reactHooksPlugin,
"jsx-a11y": jsxA11y,
security,
},
languageOptions: {
parser: tseslint.parser,
parserOptions: {
projectService: {
allowDefaultProject: [
// Duplicate of events-timeline.test.ts in the same folder;
// TypeScript only picks the .ts sibling, so this .tsx file is
// outside the project graph. Tracked for follow-up cleanup.
"components/shared/events-timeline/events-timeline.test.tsx",
],
},
tsconfigRootDir: import.meta.dirname,
ecmaVersion: "latest",
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
globals: {
...globals.browser,
...globals.node,
...globals.es2021,
React: "readonly",
},
},
settings: {
react: {
version: "detect",
},
"import-x/resolver-next": [
createTypeScriptImportResolver({
alwaysTryTypes: true,
project: "./tsconfig.json",
}),
createNodeResolver(),
],
},
rules: {
"no-console": ["error", { allow: ["error"] }],
eqeqeq: "error",
quotes: ["error", "double", { avoidEscape: true }],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
enableAutofixRemoval: { imports: true },
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
"security/detect-object-injection": "off",
"eol-last": ["error", "always"],
"import-x/order": [
"error",
{
groups: [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
],
"newlines-between": "always",
alphabetize: { order: "asc", caseInsensitive: true },
},
],
// Pre-existing duplicate exports and re-export shape mismatches are
// tracked separately; the migration keeps behavior parity with the
// legacy config until the rule is enforced in the canonical Base layer.
"import-x/export": "off",
"jsx-a11y/anchor-is-valid": [
"error",
{
components: ["Link"],
specialLink: ["hrefLeft", "hrefRight"],
aspects: ["invalidHref", "preferButton"],
},
],
"jsx-a11y/alt-text": "error",
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"@next/next/no-html-link-for-pages": "error",
"@next/next/no-img-element": "warn",
"@next/next/no-sync-scripts": "error",
},
},
prettierConfig,
);