montana/Russian/Site/messenger/eslint.config.js
2026-05-18 18:05:32 +03:00

229 lines
7.5 KiB
JavaScript

import eslint from '@eslint/js';
import eslintReact from '@eslint-react/eslint-plugin';
import stylisticJs from '@stylistic/eslint-plugin';
import { defineConfig, globalIgnores } from 'eslint/config';
import { importX } from 'eslint-plugin-import-x';
import jestPlugin from 'eslint-plugin-jest';
import noNullPlugin from 'eslint-plugin-no-null';
import reactHooksStaticDeps from 'eslint-plugin-react-hooks-static-deps';
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
import ttMultitabPlugin from 'eslint-plugin-tt-multitab';
import unusedImports from 'eslint-plugin-unused-imports';
import tseslint from 'typescript-eslint';
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
tseslint.configs.stylistic,
eslintReact.configs['recommended-typescript'],
importX.flatConfigs.recommended,
importX.flatConfigs.typescript,
ttMultitabPlugin.configs.recommended,
stylisticJs.configs.customize({
semi: true,
arrowParens: 'always',
braceStyle: '1tbs',
quoteProps: 'as-needed',
}),
globalIgnores([
'src/lib/rlottie/**',
'src/lib/video-preview/polyfill',
'src/lib/fasttextweb/**',
'src/lib/gramjs/tl/',
'src/lib/lovely-chart/**',
'src/lib/music-metadata-browser',
'src/lib/fastBlur.js',
'src/types/language.d.ts',
'dist/',
'public/',
'deploy/update_version.js',
'tauri/target/',
]),
{
name: 'teact-config',
files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'],
settings: {
react: {
version: '19',
},
},
rules: {
'no-null/no-null': 'error',
'no-console': 'error',
'no-template-curly-in-string': 'error',
'object-shorthand': 'error',
curly: ['error', 'multi-line'],
eqeqeq: ['error', 'always'],
'no-implicit-coercion': [
'error',
{
boolean: true,
disallowTemplateShorthand: true,
},
],
'no-prototype-builtins': 'off',
'no-undef': 'off',
'no-unused-vars': 'off',
'@stylistic/comma-dangle': ['error', {
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
exports: 'always-multiline',
functions: 'always-multiline',
enums: 'always-multiline',
tuples: 'always-multiline',
generics: 'ignore',
}],
'@stylistic/multiline-ternary': 'off',
'@stylistic/operator-linebreak': 'off',
'@stylistic/max-len': ['error', {
code: 120,
ignoreComments: true,
ignorePattern: '\\sd=".+"', // Ignore lines with "d" attribute
}],
'@stylistic/indent': ['error', 2, {
SwitchCase: 1,
flatTernaryExpressions: false,
}],
'simple-import-sort/imports': [
'error',
{
groups: [
// Side effect imports
['^\\u0000'],
// Lib and global imports
[
'^react',
'^@?\\w',
'dist(/.*|$)',
'^(\\.+/)+(lib/(teact|gramjs))(/.*|$)',
'^(\\.+/)+global$',
],
// Type imports
[
'^(\\.+/)+.+\\u0000$',
'^(\\.+/|\\w+/)+(types)(/.*|$)',
'^(\\.+/|\\w+/)+(types)\\u0000',
],
// Config, utils, helpers
[
'^(\\.+/)+config',
'^(\\.+/)+(lib)(?!/(gramjs|teact))(/.*|$)',
'^(\\.+/)+global/.+',
'^(\\.+/)+(util)(/.*|$)',
'^\\.\\.(?!/?$)',
'^\\.\\./?$',
'^\\./(?=.*/)(?!/?$)',
'^\\.(?!/?$)',
'^\\./?$',
],
// Hooks
[
'.+(/hooks/)(.*|$)',
],
// Components
[
'/[A-Z](([a-z]+[A-Z]?)*)',
],
// Styles and CSS modules
[
'^.+\\.s?css$',
],
// Assets: images, stickers, etc
[
'^(\\.+/)+(assets)(/.*|$)',
],
],
},
],
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
disallowTypeAnnotations: false,
},
],
'@typescript-eslint/no-shadow': 'error',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-floating-promises': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-inferrable-types': 'off',
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/prefer-for-of': 'off',
'@typescript-eslint/array-type': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{
checksVoidReturn: false,
},
],
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'none',
caughtErrors: 'none',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off',
'@typescript-eslint/unbound-method': 'off',
'unused-imports/no-unused-imports': 'error',
'import-x/namespace': ['error', { allowComputed: true }],
'import-x/no-named-as-default-member': 'off',
'react-hooks/exhaustive-deps': 'off',
'react-hooks-static-deps/exhaustive-deps': [
'error',
{
// eslint-disable-next-line @stylistic/max-len
additionalHooks: '(useSyncEffect|useAsync|useDebouncedCallback|useThrottledCallback|useEffectWithPrevDeps|useLayoutEffectWithPrevDeps|useDerivedState|useDerivedSignal|useThrottledResolver|useDebouncedResolver|useThrottleForHeavyAnimation)$',
staticHooks: {
getActions: true,
useFlag: [false, true, true],
useForceUpdate: true,
useReducer: [false, true],
useLastCallback: true,
},
},
],
'@eslint-react/exhaustive-deps': 'off',
'@eslint-react/set-state-in-effect': 'off',
'@eslint-react/unsupported-syntax': 'off',
'@eslint-react/no-clone-element': 'off',
'@eslint-react/component-hook-factories': 'off',
'@eslint-react/no-use-context': 'off',
'@eslint-react/no-context-provider': 'off',
'@eslint-react/no-array-index-key': 'off',
'@eslint-react/web-api/no-leaked-timeout': 'off',
'@eslint-react/no-missing-key': 'off',
'@eslint-react/no-nested-component-definitions': 'off',
'@eslint-react/no-unused-props': 'off',
'@eslint-react/dom-no-unsafe-iframe-sandbox': 'off',
'@eslint-react/dom/no-unsafe-iframe-sandbox': 'off',
'@eslint-react/no-leaked-conditional-rendering': 'error',
},
plugins: {
'no-null': noNullPlugin,
'simple-import-sort': simpleImportSortPlugin,
'unused-imports': unusedImports,
'react-hooks-static-deps': reactHooksStaticDeps,
jest: jestPlugin,
'tt-multitab': ttMultitabPlugin,
},
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
globals: jestPlugin.environments.globals.globals,
},
},
);