import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import jsdoc from 'eslint-plugin-jsdoc';
import globals from 'globals';
import configPrettier from 'eslint-config-prettier';
import { defineConfig } from 'eslint/config';

/** 是否有TS验证规则 */
const tsVerify = true;

export default defineConfig(
  eslint.configs.recommended,
  configPrettier,
  ...tseslint.configs.strict,
  ...tseslint.configs.stylistic,
  {
    languageOptions: {
      globals: {
        ...globals.node,
        __APP_VERSION_TIMESTAMP__: 'readonly', // APP版本号时间戳(在vite.config中配置)
      },
    },
    plugins: {
      jsdoc,
    },
    rules: {
      ...getBaseRules(),
      ...getJsDocRules(),
    },
  },
  {
    files: ['**/*.ts', '**/*.cts', '**/*.mts', '**/*.ctsx', '**/*.mtsx', '**/*.tsx'],
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: {
        sourceType: 'module',
      },
    },
    plugins: {
      '@typescript-eslint': tseslint.plugin,
    },
    rules: {
      ...getTypescriptRules(),
    },
  },
  {
    files: ['**/*.d.ts'],

    rules: {
      'init-declarations': 'off',
    },
  },
  // NestJS 文件的特殊配置
  {
    files: ['src/**/*.controller.ts', 'src/**/*.service.ts', 'src/**/*.module.ts', 'src/**/*.dto.ts'],
    rules: {
      // NestJS 装饰器要关闭这些规则
      '@typescript-eslint/explicit-member-accessibility': 'off',
      '@typescript-eslint/consistent-type-imports': 'off',
      '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
      // 允许装饰器语法
      '@typescript-eslint/no-useless-constructor': 'off',
    },
  },
  // MikroORM 生成的实体文件配置
  {
    files: ['src/entities/*.ts'],
    rules: {
      // MikroORM v7 生成的实体不需要访问修饰符
      '@typescript-eslint/explicit-member-accessibility': 'off',
      // 允许导入类型而不使用 type 导入
      '@typescript-eslint/consistent-type-imports': 'off',
      // 允许未使用的变量 (MikroORM 的特殊属性)
      '@typescript-eslint/no-unused-vars': 'off',
    },
  },
  {
    files: ['**/*.js', '**/*.cjs', '**/*.mjs', '**/*.cjsx', '**/*.mjsx', '**/*.jsx'],
    rules: {
      '@typescript-eslint/no-require-imports': 'off',
      '@typescript-eslint/no-var-requires': 'off',
    },
  }
);

/**
 * 得到eslint的规则
 */
function getBaseRules() {
  return {
    /** *************************************************** 这些规则与代码中可能的逻辑错误有关 */
    // 强制数组方法的回调函数中有 return 语句
    'array-callback-return': 'error',
    // 强制在子类构造函数中用super()调用父类构造函数,TypeScrip的编译器也会提示
    'constructor-super': 'error',
    // 强制 “for” 循环中更新子句的计数器朝着正确的方向移动
    'for-direction': 'error',
    // 强制在 getter 属性中出现一个 return 语句。每个 getter 都期望有返回值。
    'getter-return': 'error',
    // 禁止使用异步函数作为 Promise executor
    'no-async-promise-executor': 'error',
    // 不允许await在循环体内使用。
    'no-await-in-loop': 'error',
    // 禁止修改类声明的变量
    'no-class-assign': 'error',
    // 针对试图与-0进行比较的代码发出警告,因为这不会按预期工作。也就是说,像x === -0这样的代码将通过+0和-0。作者可能打算 Object.is(x,-0)。
    'no-compare-neg-zero': 'error',
    // 禁止条件表达式中出现赋值操作符
    'no-cond-assign': 'error',
    // 禁止修改 const 声明的变量
    'no-const-assign': 'error',
    // 将始终评估为真或假的比较以及始终短路或从不短路的逻辑表达式 ( ||, &&, ??) 都可能表明程序员错误
    'no-constant-binary-expression': 'error',
    // [对应 vue/no-constant-condition]禁止在条件中使用常量表达式  [if (false) {} 错] [if (aa===false) {} 对]
    'no-constant-condition': 'error',
    // 不允许从构造函数返回值
    'no-constructor-return': 'error',
    // 禁止在正则表达式中使用控制字符 ：new RegExp("\x1f")
    'no-control-regex': 'error',
    // 禁用 debugger
    'no-debugger': 'error',
    // 禁止 function 定义中出现重名参数
    'no-dupe-args': 'error',
    // 禁止类成员中出现重复的名称
    'no-dupe-class-members': 'error',
    // 不允许 if-else-if 链中的重复条件
    'no-dupe-else-if': 'error',
    // 禁止对象字面量中出现重复的 key
    'no-dupe-keys': 'error',
    // 禁止重复的 case 标签
    'no-duplicate-case': 'error',
    // 不允许复制模块的进口
    'no-duplicate-imports': 'error',
    // 禁止在正则表达式中使用空字符集 (/^abc[]/)
    'no-empty-character-class': 'error',
    // [对应 vue/no-empty-pattern]禁止使用空解构模式no-empty-pattern
    'no-empty-pattern': 'error',
    // 禁止对 catch 子句的参数重新赋值
    'no-ex-assign': 'error',
    // 禁止 case 语句落空
    'no-fallthrough': 'error',
    // 禁止对 function 声明重新赋值
    'no-func-assign': 'error',
    // 禁止对 function 声明重新赋值
    'no-import-assign': 'error',
    // 禁止在嵌套的块中出现 function 或 var 声明
    'no-inner-declarations': ['error', 'both'],
    // 禁止 RegExp 构造函数中无效的正则表达式字符串
    'no-invalid-regexp': 'error',
    // 禁止在字符串和注释之外不规则的空白
    'no-irregular-whitespace': ['error', { skipStrings: true }],
    // 不允许丢失精度的数值
    'no-loss-of-precision': 'error',
    // 不允许在字符类语法中出现由多个代码点组成的字符,  因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符
    'no-misleading-character-class': 'error',
    // 不允许在字符类语法中出现由多个代码点组成的字符,  因为Unicode 包括由多个代码点组成的字符。RegExp 字符类语法 (/[abc]/) 不能处理由多个代码点组成的字符
    'no-new-native-nonconstructor': 'error', // 禁止在不能使用new的变量前使用new
    // 禁止 Symbol 的构造函数
    'no-new-symbol': 'error',
    // 禁止把全局对象 (Math 和 JSON) 作为函数调用 错误：var math = Math();
    'no-obj-calls': 'error',
    // 不允许从 Promise 执行器函数返回值
    'no-promise-executor-return': 'error',
    // 禁止直接使用 Object.prototypes的内置属性 例如,foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar")
    'no-prototype-builtins': 'error',
    // 禁止自我赋值
    'no-self-assign': 'error',
    // 禁止自身比较
    'no-self-compare': 'error',
    // 虽然从 setter 返回值不会产生错误,但返回的值将被忽略。因此,从 setter 返回值要么是不必要的,要么是可能的错误,因为不能使用返回的值。
    'no-setter-return': 'error',
    // [对应 vue/no-sparse-arrays]禁用稀疏数组
    'no-sparse-arrays': 'error',
    // 警告常规字符串包含看起来像模板字面占位符的内容。"Hello ${name}!";
    'no-template-curly-in-string': 'error',
    // 禁止在构造函数中,在调用 super() 之前使用 this 或 super
    'no-this-before-super': 'error',
    // 禁用未声明的变量,除非它们在 /*global */ 注释中被提到
    'no-undef': tsVerify ? 'off' : 'error',
    // 禁止出现令人困惑的多行表达式
    'no-unexpected-multiline': 'error',
    // 禁用一成不变的循环条件
    'no-unmodified-loop-condition': 'error',
    // 禁止在return、throw、continue 和 break语句之后出现不可达代码
    'no-unreachable': 'error',
    // 禁止无法访问的循环
    'no-unreachable-loop': 'error',
    // 禁止在 finally 语句块中出现控制流语句
    'no-unsafe-finally': 'error',
    // 禁止否定关系运算符的左操作数
    'no-unsafe-negation': ['error', { enforceForOrderingRelations: true }],
    // 禁止在不允许使用值的上下文中使用[可选链?.] 如(undefined)
    'no-unsafe-optional-chaining': 'error',
    // 禁止未使用的私有类成员
    'no-unused-private-class-members': 'error',
    // 禁止出现未使用过的变量
    'no-unused-vars': tsVerify ? 'off' : 'error',
    // 不允许在变量定义之前使用它们
    'no-use-before-define': ['error', { functions: false, classes: true, variables: true }],
    // 禁止在正则表达式中使用无用的反向引用
    'no-useless-backreference': 'error',
    // 禁止由于 await 或 yield的使用而可能导致出现竞态条件的赋值
    'require-atomic-updates': ['error', { allowProperties: true }],
    // 不允许比较"NaN"。判断数字是否是NaN,得用isNaN
    'use-isnan': 'error',
    // 强制 typeof 表达式与有效的字符串进行比较
    'valid-typeof': 'error',

    /** *************************************************** 这些规则建议了不同的做事方式 */

    // 定义对象的set存取器属性时,强制定义get
    'accessor-pairs': ['error', { setWithoutGet: true, getWithoutSet: true }],
    // 要求箭头函数体使用大括号
    'arrow-body-style': ['off', 'as-needed'],
    // 强制把变量的使用限制在其定义的作用域范围内
    'block-scoped-var': 'error',
    // [对应 vue/camelcase] 强制执行驼峰命名约定
    camelcase: 'off',
    // 注释 大写字母开头,不推荐 注释的代码会报错
    'capitalized-comments': 'off',
    // 如果一个类方法没有使用this,它有时可以变成一个静态函数。如果将该方法转换为静态函数,那么调用该特定方法的类的实例也必须转换为静态调用
    'class-methods-use-this': 'off',
    // 限制圈复杂度,也就是类似if else能连续接多少个
    complexity: 'off',
    // 要求 return 语句要么总是指定返回的值,要么不指定
    'consistent-return': 'error',
    // 用于指统一在回调函数中指向this的变量名, var that = this; that不能指向其他任何值,this也不能赋值给that以外的其他值
    'consistent-this': ['off', 'that'],
    // 强制所有控制语句使用一致的括号风格
    curly: ['error', 'all'],
    // switch 语句强制 default 分支,也可添加 // no default 注释取消此次警告
    'default-case': 'error',
    // 将 switch 语句中的缺省子句强制为最后一个
    'default-case-last': 'error',
    // 将默认参数强制放在最后
    'default-param-last': tsVerify ? 'off' : 'error',
    // [对应 vue/dot-notation]强制使用.号取属性
    'dot-notation': 'error',
    // [对应 vue/eqeqeq]使用 === 替代 == allow-null允许null和undefined==
    eqeqeq: ['error', 'always'],
    // 要求函数名称与它们所分配的变量或属性的名称相匹配
    'func-name-matching': 'error',
    // 强制使用命名的 function 表达式
    'func-names': ['error', 'always', { generators: 'as-needed' }],
    // 强制一致地使用函数声明或函数表达式,方法定义风格
    'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
    // 强制如果一个属性有一个 getter 和一个 setter,那么 setter 应该在 getter 之后定义
    'grouped-accessor-pairs': ['error', 'getBeforeSet'],
    // 要求 for-in 循环中有一个 if 语句
    'guard-for-in': 'off',
    // 禁止使用指定的标识符
    'id-denylist': 'off',
    // 强制标识符的最小和最大长度 (变量名长度)
    'id-length': 'off',
    // 要求标识符匹配一个指定的正则表达式
    'id-match': 'off',
    // 要求或禁止 var 声明中的初始化(初值)
    'init-declarations': tsVerify ? 'off' : ['error', 'always'],
    // 要求或禁止逻辑赋值逻辑运算符速记
    'logical-assignment-operators': ['error', 'never'],
    // 强制实施每个文件的最大类数
    'max-classes-per-file': 'off',
    // 强制执行嵌套块的最大深度,以降低代码复杂度。"max"(默认为4)
    'max-depth': ['off', { max: 6 }],
    // 强制文件的最大行数
    'max-lines': 'off',
    // 强制文件的最大行数
    'max-lines-per-function': 'off',
    // 强制回调函数最大嵌套深度 5层
    'max-nested-callbacks': ['off', { max: 5 }],
    // 强制 function 定义中最多允许的参数数量
    'max-params': ['off', { max: 12 }],
    // 强制 function 块最多允许的的语句数量
    'max-statements': 'off',
    // 强化多行评论的特定风格。
    'multiline-comment-style': 'off',
    // 要求构造函数首字母大写 (要求调用 new 操作符时有首字母大小的函数,允许调用首字母大写的函数时没有 new 操作符。)
    'new-cap': ['error', { newIsCap: true, capIsNew: false }],
    // 禁用 alert、confirm 和 prompt
    'no-alert': 'error',
    // 禁止使用 Array 构造函数
    'no-array-constructor': 'error',
    // 禁用按位运算符
    'no-bitwise': 'error',
    // 禁用 arguments.caller 或 arguments.callee
    'no-caller': 'error',
    // 不允许在 case 子句中使用词法声明
    'no-case-declarations': 'error',
    // 禁用 console
    'no-console': 'off',
    // 禁用 continue 语句
    'no-continue': 'error',
    // 禁止删除变量
    'no-delete-var': 'error',
    // 禁止除法操作符显式的出现在正则表达式开始的位置
    'no-div-regex': 'error',
    // 禁止 if 语句中有 return 之后有 else
    'no-else-return': 'off',
    // 禁止空语句块
    'no-empty': ['error', { allowEmptyCatch: true }],
    // 禁止出现空函数. 如果一个函数包含了一条注释,它将不会被认为有问题。
    'no-empty-function': tsVerify ? 'off' : 'error',
    // 禁止空静态块
    'no-empty-static-block': 'error',
    // 禁止在没有类型检查操作符的情况下与 null 进行比较
    'no-eq-null': 'error',
    // 禁用 eval()
    'no-eval': 'error',
    // 禁止扩展原生类型
    'no-extend-native': ['error', { exceptions: ['Object', 'Array'] }],
    // 禁止不必要的 .bind() 调用
    'no-extra-bind': 'error',
    // 禁止不必要的布尔转换
    'no-extra-boolean-cast': 'error',
    // 禁用不必要的标签
    'no-extra-label': 'error',
    // 此规则不允许修改只读全局变量。
    'no-global-assign': 'error',
    // 禁止使用短符号进行类型转换(!!fOO)
    'no-implicit-coercion': 'error',
    // 禁止在全局范围内使用 var 和命名的 function 声明
    'no-implicit-globals': 'error',
    // 禁止使用类似 eval() 的方法
    'no-implied-eval': 'error',
    // 禁止在代码行后使用内联注释
    'no-inline-comments': 'off',
    // 禁止 this 关键字出现在类和类对象之外
    'no-invalid-this': 'error',
    // 禁用 __iterator__ 属性
    'no-iterator': 'error',
    // 不允许标签与变量同名
    'no-label-var': 'error',
    // 禁用标签语句
    'no-labels': 'error',
    // 禁用不必要的嵌套块
    'no-lone-blocks': 'error',
    // 禁止 if 作为唯一的语句出现在 else 语句中
    'no-lonely-if': 'off',
    // 禁止在循环中出现 function 声明和表达式
    'no-loop-func': 'error',
    // 禁用魔术数字(3.14什么的用常量代替)
    'no-magic-numbers': 'off',
    // 不允许在单个语句中使用多个分配。a = b = c = d;
    'no-multi-assign': 'error',
    // 禁止使用多行字符串,在 JavaScript 中,可以在新行之前使用斜线创建多行字符串
    'no-multi-str': 'error',
    // 不允许否定的表达式
    'no-negated-condition': 'off',
    // 不允许使用嵌套的三元表达式 var foo = bar ? baz : qux === quxx ? bing : bam;
    'no-nested-ternary': 'off',
    // 禁止在非赋值或条件语句中使用 new 操作符
    'no-new': 'off',
    // 禁止对 Function 对象使用 new 操作符
    'no-new-func': 'error',
    // 禁止对 String,Number 和 Boolean 使用 new 操作符
    'no-new-wrappers': 'error',
    // 禁止字符串文本中的序列并转义序列\8\9
    'no-nonoctal-decimal-escape': 'error',
    // 通常不鼓励使用构造函数来构造新的空对象，而支持对象文字表示法，因为简洁，并且全局可以重新定义。 例外情况是，当构造函数用于有意包装作为参数传递的指定值时
    'no-object-constructor': 'error',
    // 禁用八进制字面量
    'no-octal': 'error',
    // 禁止在字符串中使用八进制转义序列
    'no-octal-escape': 'error',
    // 不允许对 function 的参数进行重新赋值
    'no-param-reassign': 'error',
    // 禁止使用一元操作符 ++ 和 --
    'no-plusplus': 'off',
    // 禁用 __proto__ 属性
    'no-proto': 'error',
    // 禁止使用 var 多次声明同一变量
    'no-redeclare': 'error',
    // 禁止正则表达式字面量中出现多个空格
    'no-regex-spaces': 'error',
    // 禁止在导出中指定名称
    'no-restricted-exports': 'off',
    // 禁止在导出中指定名称 restrictedNamedExports中就是限制导出的名称 禁用特定的全局变量
    'no-restricted-globals': ['error', { name: 'event', message: 'event请在方法的参数中定义event' }],
    // 禁止加载指定的模块 paths中就是需要禁止加载的模块
    'no-restricted-imports': ['off', { paths: ['import1', 'import2'] }],
    // 禁止某些对象上的某些属性 如果省略对象名称,则不允许所有对象使用该属性;如果省略属性名称,则不允许访问给定对象的任何属性
    'no-restricted-properties': [
      'off',
      {
        object: '对象名称',
        property: '对象对象下的属性名称',
        message: '提示消息',
      },
    ],
    // 禁止使用特定的语法
    'no-restricted-syntax': ['off', { selector: '语法', message: '提示消息' }],
    // 禁止在返回语句中赋值 (return foo = bar + 2; 错误)
    'no-return-assign': 'error',
    // 禁止使用 javascript: url
    'no-script-url': 'error',
    // 禁用逗号操作符
    'no-sequences': 'error',
    // 禁止变量声明与外层作用域的变量同名
    'no-shadow': tsVerify ? 'off' : 'error',
    // 禁止覆盖受限制的标识符
    'no-shadow-restricted-names': 'error',
    // 不允许使用三元操作符
    'no-ternary': 'off',
    // 禁止抛出非异常字面量
    'no-throw-literal': 'error',
    // 禁止将变量初始化为undefined
    'no-undef-init': 'off',
    // 禁止将 undefined 作为标识符
    'no-undefined': 'off',
    // 禁止标识符中有悬空下划线_bar
    'no-underscore-dangle': 'off',
    // 禁止在有比三元操作符更简单表达式时使用三元操作符
    'no-unneeded-ternary': 'error',
    // 禁止出现未使用过的表达式
    'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
    // 禁用未使用过的标签
    'no-unused-labels': 'error',
    // 禁止不必要的 .call() 和 .apply()
    'no-useless-call': 'error',
    // 禁止不必要的 catch 子句
    'no-useless-catch': 'error',
    // 禁止不必要的计算性能键对象的文字
    'no-useless-computed-key': 'error',
    // [对应 vue/no-useless-concat]禁止不必要的字符串字面量或模板字面量的连接
    'no-useless-concat': 'error',
    // ES2015 会提供默认的类构造函数。因此,没有必要提供一个空构造函数或一个简单地委托给它的父类的构造函数,
    'no-useless-constructor': 'error',
    // 禁用不必要的转义字符
    'no-useless-escape': 'error',
    // 不允许将导入、导出和解构分配重命名为相同的名称。
    'no-useless-rename': 'error',
    // 禁止冗余返回语句
    'no-useless-return': 'error',
    // 要求使用 let 或 const 而不是 var
    'no-var': 'error',
    // 禁用 void 操作符
    'no-void': 'error',
    // 禁止在注释中使用特定的警告术语
    'no-warning-comments': 'off',
    // 禁用 with 语句
    'no-with': 'error',
    // 要求或禁止对象字面量中方法和属性使用简写语法
    'object-shorthand': ['error', 'always'],
    // 强制函数中的变量要么一起声明要么分开声明
    'one-var': ['error', 'never'],
    // 要求或禁止在可能的情况下要求使用简化的赋值操作符
    'operator-assignment': ['error', 'always'],
    // 要求使用箭头函数作为回调
    'prefer-arrow-callback': 'error',
    // 要求使用 const 声明那些声明后不再被修改的变量
    'prefer-const': 'error',
    // 优先使用数组和对象解构
    'prefer-destructuring': 'off',
    // 禁止使用 有利于运营商的Math.pow()
    'prefer-exponentiation-operator': 'error',
    // 强制在正则表达式中使用命名捕获组
    'prefer-named-capture-group': 'off',
    // 禁止调用parseInt()或Number.parseInt()使用两个参数调用：一个字符串; 和2(二进制),8(八进制)或16(十六进制)的基数选项。
    'prefer-numeric-literals': 'error',
    // 禁止使用Object.prototype.hasOwnProperty.call() 而应该使用Object.hasOwn()
    'prefer-object-has-own': 'error',
    // 优先使用扩展("...")而不是Object.assign
    'prefer-object-spread': 'error',
    // 确保承诺只被Error对象拒绝。
    'prefer-promise-reject-errors': 'off',
    // 不允许使用构造函数创建正则表达式
    'prefer-regex-literals': 'off',
    // 禁止使用 arguments 而应该使用 ...args
    'prefer-rest-params': 'error',
    // 要求使用扩展运算符而非 .apply()
    'prefer-spread': 'error',
    // [对应 vue/prefer-template]要求使用模板字面量而非字符串连接
    'prefer-template': 'error',
    // 强制在parseInt()使用基数参数
    radix: ['error', 'as-needed'],
    // 异步函数必须具有await表达式
    'require-await': 'off',
    // 在正则表达式上强制使用标志
    'require-unicode-regexp': 'off',
    // 要求generator 函数内有 yield
    'require-yield': 'error',
    // 强制模块内的 import 排序
    'sort-imports': ['error', { ignoreDeclarationSort: true }],
    // 所有属性定义并验证所有变量是按字母顺序排序的。
    'sort-keys': 'off',
    // 要求同一个声明块中的变量按顺序排列
    'sort-vars': 'error',
    // 要求或禁止使用严格模式指令
    strict: ['error', 'global'],
    // var foo = Symbol("some description"); 一定要有描述
    'symbol-description': 'error',
    // 要求所有的 var 声明出现在它们所在的作用域顶部
    'vars-on-top': 'error',
    // 要求或禁止 “Yoda” 条件
    yoda: 'error',

    /** *************************************************** 这些规则关心代码的外观,而不是它的执行方式 */
    // 强制行注释可以位于代码上方或旁边。该规则有助于团队保持一致的风格。
    'line-comment-position': 'off',
    // 要求或不允许 Unicode 字节顺序标记
    'unicode-bom': ['error', 'never'],
  };
}

/**
 * typescript使用的规则
 */
function getTypescriptRules() {
  return {
    // 要求函数重载签名是连续的
    '@typescript-eslint/adjacent-overload-signatures': 'error',
    // 要求一致地使用或用于数组T[]Array<T>
    '@typescript-eslint/array-type': 'off',
    // 禁止直接使用await处理同步函数 💭
    // '@typescript-eslint/await-thenable': 'error',
    // 不允许在指令后添加注释或要求说明
    '@typescript-eslint/ban-ts-comment': 'error',
    // 禁止使用tslint注释
    '@typescript-eslint/ban-tslint-comment': 'error',
    // 不允许某些类型 已废弃
    // '@typescript-eslint/ban-types': 'error',
    // 强制以一致的样式公开类的文本
    '@typescript-eslint/class-literal-property-style': 'error',
    // 强制类方法使用 .this
    '@typescript-eslint/class-methods-use-this': 'off',
    // 强制在构造函数调用的类型注释或构造函数名称上指定泛型类型参数
    '@typescript-eslint/consistent-generic-constructors': ['error', 'constructor'],
    // 需要或禁止 使用Record
    '@typescript-eslint/consistent-indexed-object-style': ['error', 'record'],
    // 并不是所有函数里的代码都有返回值时,抛出错误 这里关闭，因为 tsconfig.json 中 noImplicitReturns 更好 💭
    // '@typescript-eslint/consistent-return': 'error',
    // 强制一致地使用类型断言
    '@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'as' }], // 强制一致地使用类型断言
    // 强制类型定义一致地使用 interface 或 type
    '@typescript-eslint/consistent-type-definitions': ['off', 'type'],
    // 强制一致地使用类型导出 💭
    // '@typescript-eslint/consistent-type-exports': ['error', { fixMixedExportsWithInlineTypeSpecifier: false }],
    // 强制一致使用类型导入
    '@typescript-eslint/consistent-type-imports': [
      'off',
      {
        prefer: 'type-imports',
        disallowTypeAnnotations: false,
        fixStyle: 'inline-type-imports',
      },
    ],
    // 需要函数和类方法的显式返回类型
    '@typescript-eslint/default-param-last': 'error',
    // 尽可能强制使用点表示法  💭
    // '@typescript-eslint/dot-notation': 'error',
    // 需要函数和类方法的显式返回类型
    '@typescript-eslint/explicit-function-return-type': 'off',
    // 需要对类属性和方法使用显式辅助功能修饰符
    '@typescript-eslint/explicit-member-accessibility': 'error',
    // 要求对导出的函数和类的公共类方法进行显式返回和参数类型
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    // 要求或禁止在变量声明中初始化
    '@typescript-eslint/init-declarations': ['error', 'always'],
    // 在函数定义中强制参数的最大数目
    '@typescript-eslint/max-params': 'off',
    // 需要一致的成员声明顺序
    '@typescript-eslint/member-ordering': 'off',
    // 强制使用特定方法签名语法
    '@typescript-eslint/method-signature-style': ['error', 'property'],
    // 对代码库中的所有内容强制实施命名约定。💭
    // '@typescript-eslint/naming-convention': 'off',
    // 禁止使用泛型constructor array
    '@typescript-eslint/no-array-constructor': 'error',
    // 禁止在数组values上使用delete操作符。💭
    '@typescript-eslint/no-array-delete': 'off',
    // 要求仅在字符串化时提供有用信息的对象上调用.toString() 💭
    // '@typescript-eslint/no-base-to-string': 'error',
    // 禁止在可能造成混淆的位置使用非空断言
    '@typescript-eslint/no-confusing-non-null-assertion': 'error',
    // 无混淆空洞表达  💭
    // '@typescript-eslint/no-confusing-void-expression': 'error',
    // 禁止重复的类成员
    // '@typescript-eslint/no-dupe-class-members': 'error', // 此 ESLint 规则检查的代码问题由 TypeScript 编译器自动检查
    // 不允许重复的枚举成员值
    '@typescript-eslint/no-duplicate-enum-values': 'error',
    // 禁止联合或交集类型的重复成分 💭
    // '@typescript-eslint/no-duplicate-type-constituents': 'off',
    // 禁止在计算键表达式上使用运算符delete
    '@typescript-eslint/no-dynamic-delete': 'off',
    // 禁止声明空接口
    '@typescript-eslint/no-empty-interface': 'error',
    /** 禁止使用空函数 */
    '@typescript-eslint/no-empty-function': 'off',
    // 禁止使用any
    '@typescript-eslint/no-explicit-any': ['off', { ignoreRestArgs: true }],
    // 不允许额外的非空断言
    '@typescript-eslint/no-extra-non-null-assertion': 'error',
    // 禁止将类用作命名空间
    '@typescript-eslint/no-extraneous-class': 'off',
    // 要求正确处理类似 Promise 的语句 💭
    // '@typescript-eslint/no-floating-promises': 'off',
    // 不允许使用传入循环遍历数组 💭
    // '@typescript-eslint/no-for-in-array': 'error',
    // 禁止使用类似eval()的方法 💭
    // '@typescript-eslint/no-implied-eval': 'off',
    // 当导入只有带有内联类型限定符的说明符时，强制使用顶级导入类型限定符
    '@typescript-eslint/no-import-type-side-effects': 'error',
    // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明
    '@typescript-eslint/no-inferrable-types': 'error',
    // 禁止在类或类类对象this之外使用关键字
    '@typescript-eslint/no-invalid-this': 'error',
    // 禁止泛型或返回类型之外的void类型
    '@typescript-eslint/no-invalid-void-type': 'error',
    // 禁止在循环语句中包含不安全引用的函数声明
    '@typescript-eslint/no-loop-func': 'error',
    // Disallow literal numbers that lose precision
    '@typescript-eslint/no-loss-of-precision': 'error',
    // 禁用魔术数字(3.14什么的用常量代替)
    '@typescript-eslint/no-magic-numbers': 'off',
    // 禁止没有无意义的空运算符 💭
    // '@typescript-eslint/no-meaningless-void-operator': 'error',
    // 强制实施 和 的有效定义newconstructor
    '@typescript-eslint/no-misused-new': 'error',
    // 禁止在非设计用于处理承诺的地方发布承诺 💭
    // '@typescript-eslint/no-misused-promises': 'off',
    // 禁止枚举同时具有数字和字符串成员 💭
    // '@typescript-eslint/no-mixed-enums':'off',
    // 禁止使用命名空间
    '@typescript-eslint/no-namespace': 'error',
    // 不允许在空合并运算符的左操作数中使用非空断言
    '@typescript-eslint/no-non-null-asserted-nullish-coalescing': 'error',
    // 不允许在可选链表达式后使用非空断言
    '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
    // 禁止使用后缀运算符的非空断言
    '@typescript-eslint/no-non-null-assertion': 'off',
    // 禁止变量重声明 此 ESLint 规则检查的代码问题由 TypeScript 编译器自动检查。因此，不建议在新的 TypeScript 项目中启用此规则。仅当您更喜欢 ESLint 错误消息而不是 TypeScript 编译器错误消息时，才需要启用此规则。
    '@typescript-eslint/no-redeclare': 'off',
    // 禁止不执行任何操作或覆盖类型信息的联合和交叉点的成员。 💭
    // '@typescript-eslint/no-redundant-type-constituents': 'off',
    // 禁止调用require()
    '@typescript-eslint/no-require-imports': 'error',
    // 禁止通过import加载指定模块
    '@typescript-eslint/no-restricted-imports': 'off',
    // 有时，禁止在类型批注中使用特定类型会很有用。 例如，项目可能正在从使用一种类型迁移到另一种类型，并希望禁止对旧类型的引用。此规则可以配置为禁止特定类型的列表，并可以建议替代方法。 请注意，它不会禁止使用相应的运行时对象。
    '@typescript-eslint/no-restricted-types': 'off',

    // 禁止变量声明掩盖在外部作用域中声明的变量
    '@typescript-eslint/no-shadow': 'error',
    // 禁止混叠this
    '@typescript-eslint/no-this-alias': ['error', { allowedNames: ['that'] }],
    // 不允许对布尔文本进行不必要的相等比较  💭
    // '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'error',
    // 不允许类型始终为真实或始终为虚假的条件 💭
    //  '@typescript-eslint/no-unnecessary-condition': 'off',
    // 不允许不必要的命名空间限定符💭
    // '@typescript-eslint/no-unnecessary-qualifier': 'error',
    // 禁止等于默认值的类型参数💭
    // '@typescript-eslint/no-unnecessary-type-arguments': 'error',
    // 禁止不更改表达式类型的类型断言💭
    // '@typescript-eslint/no-unnecessary-type-assertion': 'error',
    // 不允许对泛型类型进行不必要的约束
    '@typescript-eslint/no-unnecessary-type-constraint': 'error',
    // 禁止调用具有any类型值的函数 💭
    // '@typescript-eslint/no-unsafe-argument': 'off',
    // 不允许将any类型值分配给变量和属性 💭
    //'@typescript-eslint/no-unsafe-assignment': 'off',
    // 不允许调用带有any类型的值 💭
    //  '@typescript-eslint/no-unsafe-call': 'off',
    // 禁止不安全声明合并
    '@typescript-eslint/no-unsafe-declaration-merging': 'error',
    // 禁止将枚举值与非枚举值进行比较 💭
    //'@typescript-eslint/no-unsafe-enum-comparison': 'off',
    // 禁止使用不安全的内置函数类型。
    '@typescript-eslint/no-unsafe-function-type': 'error',

    // 禁止成员访问any类型为的值 💭
    // '@typescript-eslint/no-unsafe-member-access': 'off',
    // 禁止从函数返回带有any类型的值 💭
    // '@typescript-eslint/no-unsafe-return': 'off',
    // 求一元否定取一个数 💭
    // '@typescript-eslint/no-unsafe-unary-minus': 'off',
    // 禁止使用未使用的表达式
    '@typescript-eslint/no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }],
    // 禁止出现未使用过的变量
    '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', caughtErrors: 'none' }],
    // 禁止在定义变量之前使用它们
    '@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: true, variables: true }],
    // 禁止使用不必要的构造函数
    '@typescript-eslint/no-useless-constructor': 'error',
    // 禁止不会更改模块文件中的任何内容的空导出
    '@typescript-eslint/no-useless-empty-export': 'error',
    // 禁止使用不必要的模板字面值  💭
    // '@typescript-eslint/no-useless-template-literals': 'off',
    // 禁止语句(导入语句require除外)
    '@typescript-eslint/no-var-requires': 'error',
    // 不允许使用令人困惑的内置基元类包装器。
    '@typescript-eslint/no-wrapper-object-types': 'error',
    // 对显式类型强制转换强制实施非空断言 💭
    // '@typescript-eslint/non-nullable-type-assertion-style': 'error',
    // 禁止在 throw 抛出非 new Error() 的值 💭
    // '@typescript-eslint/only-throw-error': 'off',
    // 在类构造函数中要求或禁止参数属性
    '@typescript-eslint/parameter-properties': 'off',
    // 强制使用过度文本as const类型
    '@typescript-eslint/prefer-as-const': 'error',
    // 要求对数组和/或对象进行解构 💭
    // '@typescript-eslint/prefer-destructuring': 'off',
    // 要求显式初始化每个枚举成员值
    '@typescript-eslint/prefer-enum-initializers': 'error',
    // 在查找单个结果时，强制使用Array.prototype.find()而不是Array.prototype.filter()，后面跟着[0]  💭
    // '@typescript-eslint/prefer-find': 'off',
    // 尽可能强制使用标准循环for-of for
    '@typescript-eslint/prefer-for-of': 'error',
    // 强制使用函数类型而不是带有调用签名的接口 (与vue语法有冲突)
    '@typescript-eslint/prefer-function-type': 'off',
    // 优先使用includes()方法而不是indexOf()  💭
    // '@typescript-eslint/prefer-includes': 'off',
    // 要求所有枚举成员都是文本值
    '@typescript-eslint/prefer-literal-enum-member': 'off',
    //  需要使用namespace关键字而不是module关键字来声明自定义 TypeScript 模块
    '@typescript-eslint/prefer-namespace-keyword': 'error',
    // 强制使用空合并运算符而不是逻辑链接 (如果未启用 strictNullChecks，则此规则将无法按预期工作) 💭
    // '@typescript-eslint/prefer-nullish-coalescing': 'off',
    // 强制使用简洁的可选链表达式，而不是链式逻辑 and、否定逻辑 or 或空对象
    '@typescript-eslint/prefer-optional-chain': 'off',
    // 要求使用Error对象作为拒绝承诺的原因 💭
    // '@typescript-eslint/prefer-promise-reject-errors': 'off',
    // 要求将私有成员标记为readonly,从未在构造函数外部修改 💭
    // '@typescript-eslint/prefer-readonly': 'error',
    // 要求键入函数参数readonly以防止输入意外突变 💭
    // '@typescript-eslint/prefer-readonly-parameter-types': 'error',
    // 用时强制使用类型参数Array#reduce而不是强制转换💭
    // '@typescript-eslint/prefer-reduce-type-parameter': 'off',
    // 如果未提供全局 RegExp#exec标志，则强制String#match执行 💭
    // '@typescript-eslint/prefer-regexp-exec': 'off',
    // 强制在仅返回类型时使用this 💭
    // '@typescript-eslint/prefer-return-this-type': 'off',
    // 强制使用String#startsWith和String#endsWith超过其他等效的方法来检查子字符串 💭
    // '@typescript-eslint/prefer-string-starts-ends-with': 'off',
    // 强制使用过度@ts-expect-error @ts-ignore
    '@typescript-eslint/prefer-ts-expect-error': 'error',
    // 要求将返回 Promise 的任何函数或方法标记为异步 💭
    // '@typescript-eslint/promise-function-async': 'warn',
    // 要求调用始终提供 Array#sort 💭
    // '@typescript-eslint/require-array-sort-compare': 'warn',
    // 禁止没有await的async函数
    '@typescript-eslint/require-await': 'off',
    // 要求加法的两个操作数是相同的类型，并且是bigint number string 💭
    // '@typescript-eslint/restrict-plus-operands': 'error',
    // 强制模板文本表达式为类型string 💭
    //@typescript-eslint/restrict-template-expressions': 'off',
    // 强制等待值的一致返回  💭
    '@typescript-eslint/return-await': 'off',
    // 强制按字母顺序对类型并集/交集的成分进行排序
    '@typescript-eslint/sort-type-constituents': 'error',
    // 禁止布尔表达式中的某些类型 💭
    // '@typescript-eslint/strict-boolean-expressions': 'off',
    // 要求开关大小写语句对联合类型详尽无遗 💭
    // '@typescript-eslint/switch-exhaustiveness-check': 'error',
    // 禁止某些三斜杠指令以支持 ES6 样式的导入声明
    '@typescript-eslint/triple-slash-reference': 'error',
    // 要求文字批注周围的间距一致 (强烈建议您不要使用此规则)
    // "@typescript-eslint/type-annotation-spacing": "warn",
    // 在某些位置需要类型批注
    '@typescript-eslint/typedef': 'error',
    // 强制调用未绑定方法及其预期范围 💭
    // '@typescript-eslint/unbound-method': 'error',
    // 不允许两个重载，这两个重载可以通过联合或可选/rest 参数统一为一个
    '@typescript-eslint/unified-signatures': 'off',
    // 强制回调中的类型参数为.catch() unknown
    '@typescript-eslint/use-unknown-in-catch-callback-variable': 'off',
  };
}

/**
 * 得到eslint的规则
 */
function getJsDocRules() {
  return {
    'jsdoc/check-access': 'off', // 强制执行有效标记@access
    'jsdoc/check-alignment': 'warn', // 强制对齐 JSDoc 块星号
    'jsdoc/check-examples': 'off', // 内部 JavaScript 的 Linting@example
    'jsdoc/check-indentation': [
      'warn',
      {
        // 允许嵌套内容缩进（如列表、项目符号、多行描述）
        allowIndentedSections: true,
        // 排除这些标签的缩进检查
        excludeTags: ['param', 'returns', 'property', 'example', 'description', 'see', 'throws'],
      },
    ],
    'jsdoc/check-line-alignment': 'warn', // 检查 JSDoc 块行的无效对齐方式
    'jsdoc/check-param-names': 'off', // 确保 JSDoc 中的参数名称与 中的相应项匹配 函数声明。
    'jsdoc/check-property-names': 'warn', // 确保 JSDoc 中的属性名称不会在同一块上重复 并且嵌套属性已定义根
    'jsdoc/check-syntax': 'warn', // 针对不鼓励使用该模式的语法的报告(例如，Google 关闭 “jsdoc”或“typescript”模式下的编译器)。请注意，此规则不会检查 对于对于给定模式完全无效的类型，如 中所述。valid-types
    'jsdoc/check-tag-names': 'warn', // 报告无效的块标记名称
    'jsdoc/check-types': 'warn', // 报告无效类型
    'jsdoc/check-values': 'warn', // 此规则检查少数标签的值
    'jsdoc/empty-tags': 'warn', // 期望某些标记中没有任何内容
    'jsdoc/implements-on-classes': 'warn', // 使用 报告任何非构造函数的问题
    'jsdoc/informative-docs': 'off', // 报告仅用于重新启动其附加名称的 JSDoc 文本。
    'jsdoc/match-description': 'off', // 为标签描述定义可自定义的正则表达式规则
    'jsdoc/match-name': 'off', //  报告 JSDoc 标记的名称部分(是否与给定的正则表达式匹配或不匹配)
    'jsdoc/multiline-blocks': 'warn', // 控制 jsdoc 块如何以及是否可以表示为单行或多行块
    'jsdoc/no-bad-blocks': 'warn', // 此规则检查不符合 jsdoc 块条件的多行样式注释
    'jsdoc/no-blank-block-descriptions': 'warn', // 检查重复名称，嵌套的参数名称是否具有根，以及函数声明中的参数名称是否与 jsdoc 参数名称匹配。@param
    'jsdoc/no-blank-blocks': 'warn', // 报告并选择性地删除仅带有空格的块
    'jsdoc/no-defaults': 'warn', // 此规则报告在 或 的相关部分使用的默认值。它还可以选择报告是否存在 方括号内的可选参数
    'jsdoc/no-missing-syntax': 'off', // 通过此规则，您可以报告是否缺少某些始终预期的注释结构。
    'jsdoc/no-multi-asterisks': 'warn', // 防止在行首使用多个星号
    'jsdoc/no-restricted-syntax': 'off', // 报告存在某些注释结构
    'jsdoc/no-types': 'off', // 此规则报告在 @param或 @returns上使用的类型。 该规则旨在防止在标记上指示以下类型 类型信息对于 TypeScript 来说是多余的。
    'jsdoc/no-undefined-types': 'off', //  检查 jsdoc 注释中的类型是否已定义。这可用于检查 未导入的类型
    'jsdoc/require-asterisk-prefix': 'warn', // 要求每个 JSDoc 行都以*开头
    'jsdoc/require-description': 'warn', // 要求所有函数都有说明
    'jsdoc/require-description-complete-sentence': 'off', // 要求块描述、显式 和 / 标签描述用完整的句子编写，
    'jsdoc/require-example': 'off', // 要求所有函数都有示例
    'jsdoc/require-file-overview': 'off', // 将报告给定文件中的重复文件概述标记
    'jsdoc/require-hyphen-before-param-description': ['warn', 'always'], // 将报告给定文件中的重复文件概述标记
    'jsdoc/require-jsdoc': ['warn', { enableFixer: false }], // 检查是否存在 jsdoc 注释、类声明以及 功能
    'jsdoc/require-param': 'off', // 要求记录所有函数参数
    'jsdoc/require-param-description': 'warn', // 要求每个标记都有一个值
    'jsdoc/require-param-name': 'warn', // 要求所有函数参数都具有名称
    'jsdoc/require-param-type': 'off', // 要求每个@param标记都设置类型
    'jsdoc/require-property': 'off',
    'jsdoc/require-property-description': 'off', // 要求每个@property标记都有一个description值
    'jsdoc/require-property-name': 'off', // 要求所有函数标记都具有名称
    'jsdoc/require-property-type': 'off', // 要求每个个@property标记都有一个type值
    'jsdoc/require-returns': 'off', // 要求有返回值的函数必须使用@returns标志
    'jsdoc/require-returns-check': 'warn', // 检查返回
    'jsdoc/require-returns-description': 'warn', // R要求标记具有值。错误 如果返回值为 OR，或者为 或，则不会报告。
    'jsdoc/require-returns-type': 'off', // 要求@returns标记具有type值
    'jsdoc/require-throws': 'off', //
    'jsdoc/require-yields': 'off', // Recommended
    'jsdoc/require-yields-check': 'off', // Recommended
    'jsdoc/sort-tags': 'warn', // 根据标签名称按指定顺序对标签进行排序，可以选择在标签组之间添加换行符
    'jsdoc/tag-lines': 'warn', // 在标记之间强制执换行
    'jsdoc/text-escaping': 'off', // 此规则可以自动转义在块和标记描述中输入的某些字符
    'jsdoc/valid-types': 'off', // 要求所有类型/名称路径都是有效的 JSDoc、Closure 编译器或 TypeScript 类型(可在设置中配置)
  };
}
