229 lines
7.5 KiB
JavaScript
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,
|
|
},
|
|
},
|
|
);
|