import js from '@eslint/js';
import globals from 'globals';
import tseslint from 'typescript-eslint';
import pluginVue from 'eslint-plugin-vue';
import eslintPrettier from 'eslint-config-prettier';
import { defineConfig } from 'eslint/config';
import type { Linter } from 'eslint';
import { cumulativeComplexityRule } from './eslint-rules/cumulative-complexity.ts';
const localPlugin = {
rules: { 'cumulative-complexity': cumulativeComplexityRule },
};
const rules: Linter.RulesRecord = {
'no-debugger': 'warn',
'no-console': 'warn',
quotes: ['error', 'single', { avoidEscape: true }],
'quote-props': ['warn', 'as-needed'],
'comma-dangle': ['error', 'only-multiline'],
camelcase: ['error', { properties: 'never' }],
'array-bracket-spacing': 'warn',
'arrow-spacing': 'warn',
'block-spacing': 'warn',
'comma-spacing': 'warn',
'computed-property-spacing': 'warn',
'generator-star-spacing': 'warn',
'key-spacing': 'warn',
'keyword-spacing': 'warn',
'object-curly-spacing': ['warn', 'always'],
'rest-spread-spacing': 'warn',
'switch-colon-spacing': 'error',
'func-call-spacing': 'off',
'semi-spacing': 'warn',
'template-curly-spacing': 'warn',
'template-tag-spacing': 'warn',
'yield-star-spacing': 'warn',
'space-unary-ops': 'warn',
'no-multi-spaces': 'warn',
'no-mixed-spaces-and-tabs': 'warn',
'no-trailing-spaces': 'warn',
'spaced-comment': 'warn',
'space-infix-ops': 'warn',
'space-in-parens': 'warn',
'eol-last': 'warn',
indent: ['warn', 2, { SwitchCase: 1 }],
semi: ['warn', 'always'],
'prefer-template': 'error',
'prefer-spread': 'error',
'no-var': 'error',
'max-lines-per-function': [
'warn',
{
max: 100,
skipComments: true,
skipBlankLines: true,
},
],
'local/cumulative-complexity': ['warn', 8, '^use[A-Z]'],
'max-depth': ['warn', 4],
'max-len': [
'warn',
{
code: 160,
ignoreTemplateLiterals: true,
ignoreStrings: true,
ignorePattern: 'd="([\\s\\S]*?)"',
ignoreComments: true,
},
],
'default-param-last': 'off',
'no-param-reassign': ['error', { props: false }],
'no-shadow': 'off',
'@typescript-eslint/no-shadow': ['error', { hoist: 'all' }],
'no-redeclare': 'off',
'no-use-before-define': ['error', { functions: false }],
'no-unused-vars': 'off',
'no-undef-init': 'warn',
'vue/no-unused-vars': [
'warn',
{
ignorePattern: '^_',
},
],
'vue/max-attributes-per-line': [
'warn',
{
singleline: {
max: 3,
},
multiline: {
max: 1,
},
},
],
'vue/first-attribute-linebreak': [
'warn',
{
singleline: 'ignore',
multiline: 'below',
},
],
'vue/html-closing-bracket-newline': [
'warn',
{
singleline: 'never',
multiline: 'always',
},
],
'vue/html-indent': [
'warn',
2,
{
attribute: 1,
baseIndent: 1,
closeBracket: 0,
alignAttributesVertically: true,
ignores: [],
},
],
'vue/no-v-html': [
'error',
{
ignorePattern: '^html|^t(.*)',
},
],
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'@typescript-eslint/no-empty-object-type': [
'warn',
{
allowInterfaces: 'with-single-extends',
},
],
};
export default defineConfig([
{
ignores: ['**/__demo__/**', '**/__docs__/**', '**/__tests__/**'],
},
{
files: ['**/*.{js,mjs,cjs,ts,mts,cts,vue}'],
plugins: { js, local: localPlugin },
extends: ['js/recommended'],
languageOptions: {
globals: globals.browser,
},
rules,
},
{
files: ['**/*.{ts,tsx,mts,cts}'],
rules: {
'no-undef': 'off',
},
},
tseslint.configs.base,
pluginVue.configs['flat/recommended'],
{
files: ['**/*.vue'],
plugins: { local: localPlugin },
languageOptions: {
parserOptions: { parser: tseslint.parser },
globals: {
...globals.browser,
ScrollBehavior: 'readonly',
ScrollToOptions: 'readonly',
IntersectionObserverInit: 'readonly',
},
},
rules,
},
eslintPrettier,
]);