shoc-frontend-new/eslint.config.js
2026-07-24 11:36:30 -03:00

101 lines
3.1 KiB
JavaScript

import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import pluginReactHooks from "eslint-plugin-react-hooks";
import pluginReactRefresh from "eslint-plugin-react-refresh";
import globals from "globals";
import tseslint from "typescript-eslint";
import noNonBooleanJsxAnd from "./eslint-rules/no-non-boolean-jsx-and.js";
import noVpErrorOutsideText from "./eslint-rules/no-vp-error-outside-text.js";
const localRules = {
rules: {
"no-non-boolean-jsx-and": noNonBooleanJsxAnd,
"no-vp-error-outside-text": noVpErrorOutsideText,
},
};
const legacyIgnores = [
"src/pages/**",
"src/app/store.js",
"src/app/slices/**",
"src/lib/queryClient.js",
"src/hooks/**/*.js",
"src/components/*.{js,css}",
"src/constants/**",
"src/layouts/**",
"src/**/*.js",
"src/**/*.jsx",
];
export default tseslint.config(
{
ignores: [
"dist/**",
"build/**",
"node_modules/**",
"coverage/**",
"infra/cdk/cdk.out/**",
"infra/cdk/bin/**/*.d.ts",
"infra/cdk/bin/**/*.js",
"infra/cdk/lib/**/*.d.ts",
"infra/cdk/lib/**/*.js",
...legacyIgnores,
],
},
js.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{
files: [
"src/{api,domain,app,lib,providers,infra,config,hooks,components/auth}/**/*.{ts,tsx}",
"src/**/*.{ts,tsx}",
"vite.config.ts",
],
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
globals: globals.browser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
plugins: {
"react-hooks": pluginReactHooks,
"react-refresh": pluginReactRefresh,
seahaven: localRules,
},
rules: {
...pluginReactHooks.configs.recommended.rules,
"react-hooks/set-state-in-effect": "off",
"react-hooks/exhaustive-deps": "warn",
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
"@typescript-eslint/no-explicit-any": "warn",
"seahaven/no-non-boolean-jsx-and": "error",
"seahaven/no-vp-error-outside-text": "error",
"no-restricted-syntax": [
"error",
{
selector:
"JSXExpressionContainer > ConditionalExpression[alternate.type='Literal'][alternate.value=null]",
message:
"Use logical AND for one-sided JSX rendering instead of `condition ? element : null`.",
},
{
selector:
":matches(JSXOpeningElement[name.name='p'], JSXOpeningElement[name.name='h1'], JSXOpeningElement[name.name='h2'], JSXOpeningElement[name.name='h3'], JSXOpeningElement[name.name='h4'], JSXOpeningElement[name.name='h5'], JSXOpeningElement[name.name='h6'])",
message:
"Use the shared Text component so typography semantics, family, tone, and feedback behavior stay consistent.",
},
],
},
},
{
files: ["vite.config.ts", "scripts/**/*.{js,mjs}"],
languageOptions: {
globals: globals.node,
},
},
);