UNPKG

@modyqyw/fabric

Version:

Opinionated shareable specifications for git-based JavaScript/TypeScript projects.

1,377 lines (1,359 loc) 115 kB
import { i as interopDefault, a as isBoolean } from './fabric.Cj4waNRr.mjs'; import { a as GLOB_SCRIPT, r as GLOB_VUE, d as GLOB_DTS, e as GLOB_TS, f as GLOB_TSX, C as GLOB_EXCLUDE, l as GLOB_JSON, m as GLOB_JSON5, n as GLOB_JSONC, q as GLOB_MARKDOWN, v as GLOB_MARKDOWN_SCRIPT, w as GLOB_MARKDOWN_VUE, c as GLOB_JSX, o as GLOB_TOML, p as GLOB_YAML } from './fabric.DrBYK7XE.mjs'; import { h as hasTypeScript, k as hasVue, b as hasNuxt3, o as hasRemix, p as hasReactRouter, n as hasNext, J as hasVite, m as hasVue3, D as hasMiniProgram, u as hasReact, q as hasReactNative, a as hasNuxt, I as hasTailwindCss, G as hasUnoCss } from './fabric.UWmAURsN.mjs'; import { fixupPluginRules } from '@eslint/compat'; import * as _configGitignore from 'eslint-config-flat-gitignore'; import * as _parserBabel from '@babel/eslint-parser'; import * as _parserTypeScript from '@typescript-eslint/parser'; import * as _pluginTypeScript from '@typescript-eslint/eslint-plugin'; import * as _configCommand from 'eslint-plugin-command/config'; import * as _pluginJsdoc from 'eslint-plugin-jsdoc'; import * as _pluginImportX from 'eslint-plugin-import-x'; import * as _importResolverOxc from 'eslint-import-resolver-oxc'; import * as _pluginUnusedImports from 'eslint-plugin-unused-imports'; import * as _pluginNoBarrelFiles from 'eslint-plugin-no-barrel-files'; import * as _pluginPromise from 'eslint-plugin-promise'; import * as _pluginRegexp from 'eslint-plugin-regexp'; import * as _pluginN from 'eslint-plugin-n'; import _pluginPerfectionist from 'eslint-plugin-perfectionist'; import * as _pluginUnicorn from 'eslint-plugin-unicorn'; import * as _pluginReactX from 'eslint-plugin-react-x'; import * as _pluginReactDom from 'eslint-plugin-react-dom'; import * as _pluginReactWebApi from 'eslint-plugin-react-web-api'; import * as _pluginReactHooksExtra from 'eslint-plugin-react-hooks-extra'; import * as _pluginReactNamingConvention from 'eslint-plugin-react-naming-convention'; import * as _pluginReactHooks from 'eslint-plugin-react-hooks'; import * as _pluginReactPerf from 'eslint-plugin-react-perf'; import * as _pluginReactRefresh from 'eslint-plugin-react-refresh'; import * as _pluginReactNative from 'eslint-plugin-react-native'; import * as _pluginNext from '@next/eslint-plugin-next'; import * as _parserVue from 'vue-eslint-parser'; import * as _pluginVue from 'eslint-plugin-vue'; import * as _pluginVueScopedCss from 'eslint-plugin-vue-scoped-css'; import * as _pluginNuxt2 from 'eslint-plugin-nuxt'; import * as _pluginNuxt3 from '@nuxt/eslint-plugin'; import * as _pluginTailwindcss from 'eslint-plugin-tailwindcss'; import _pluginUnocss from '@unocss/eslint-plugin'; import * as _pluginMarkdown from 'eslint-plugin-markdown'; import * as _parserJsonc from 'jsonc-eslint-parser'; import * as _pluginJsonc from 'eslint-plugin-jsonc'; import * as _pluginPackageJson from 'eslint-plugin-package-json'; import * as _parserToml from 'toml-eslint-parser'; import * as _pluginToml from 'eslint-plugin-toml'; import * as _pluginYml from 'eslint-plugin-yml'; import * as _parserYml from 'yaml-eslint-parser'; import { defu } from 'defu'; import globals from 'globals'; const configGitignore = interopDefault(_configGitignore); const parserBabel = interopDefault(_parserBabel); const parserTypeScript = interopDefault(_parserTypeScript); const pluginTypeScript = interopDefault( _pluginTypeScript ); const configCommand = interopDefault(_configCommand); const pluginJsdoc = interopDefault( _pluginJsdoc ); const pluginImportX = interopDefault( _pluginImportX ); const importResolverOxc = interopDefault(_importResolverOxc); const pluginUnusedImports = interopDefault(_pluginUnusedImports); const pluginNoBarrelFiles = interopDefault(_pluginNoBarrelFiles); const pluginPromise = interopDefault( _pluginPromise ); const pluginRegexp = interopDefault( _pluginRegexp ); const pluginN = interopDefault(_pluginN); const pluginPerfectionist = interopDefault( _pluginPerfectionist ); const pluginUnicorn = interopDefault( _pluginUnicorn ); const pluginReactX = interopDefault( _pluginReactX ); const pluginReactDom = interopDefault( _pluginReactDom ); const pluginReactWebApi = interopDefault( _pluginReactWebApi ); const pluginReactHooksExtra = interopDefault( _pluginReactHooksExtra ); const pluginReactNamingConvention = interopDefault( _pluginReactNamingConvention ); const pluginReactHooks = fixupPluginRules( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument interopDefault(_pluginReactHooks) ); const pluginReactPerf = fixupPluginRules( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument interopDefault(_pluginReactPerf) ); const pluginReactRefresh = interopDefault( _pluginReactRefresh ); const pluginReactNative = fixupPluginRules( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument interopDefault(_pluginReactNative) ); const pluginNext = interopDefault( _pluginNext ); const parserVue = interopDefault(_parserVue); const pluginVue = interopDefault(_pluginVue); const pluginVueScopedCss = interopDefault( _pluginVueScopedCss ); const pluginNuxt2 = interopDefault( _pluginNuxt2 ); const pluginNuxt3 = interopDefault( _pluginNuxt3 ); const pluginTailwindcss = interopDefault( _pluginTailwindcss ); const pluginUnocss = interopDefault( _pluginUnocss ); const pluginMarkdown = interopDefault( _pluginMarkdown ); const parserJsonc = interopDefault(_parserJsonc); const pluginJsonc = interopDefault( _pluginJsonc ); const pluginPackageJson = interopDefault( _pluginPackageJson ); const parserToml = interopDefault(_parserToml); const pluginToml = interopDefault( _pluginToml ); const parserYml = interopDefault(_parserYml); const pluginYml = interopDefault(_pluginYml); function barrel(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/imports", files, plugins: { "no-barrel-files": pluginNoBarrelFiles }, rules: { "no-barrel-files/no-barrel-files": "error", ...rules } }, { name: "base/imports/typescript", files: typescriptFiles, rules: { ...typescriptRules } } ]; } function command(options = {}) { return [ { ...configCommand(options), name: "base/command" } ]; } function gitignore(options = {}) { return [ { ...configGitignore( defu(options, { files: [".gitignore", ".eslintignore"], strict: false }) ), name: "ignores/gitignore" } ]; } function ignores(options = {}) { return [ { name: "ignores/base", ignores: options.ignores ?? GLOB_EXCLUDE } ]; } function imports(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/imports", files, plugins: { import: pluginImportX }, rules: { // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/export.md "import/export": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/extensions.md // https://vite.dev/guide/performance.html#reduce-resolve-operations "import/extensions": [ "warn", "ignorePackages", { checkTypeImports: true } ], // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-mutable-exports.md "import/no-mutable-exports": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-named-as-default.md "import/no-named-as-default": "warn", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-named-as-default-member.md "import/no-named-as-default-member": "warn", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/default.md "import/default": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/named.md "import/named": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/namespace.md "import/namespace": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-self-import.md "import/no-self-import": "error", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-duplicates.md "import/no-duplicates": "warn", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-unresolved.md "import/no-unresolved": [ "error", { commonjs: true, ignore: [ String.raw`^virtual\:`, String.raw`^\~`, String.raw`^\@`, String.raw`^windi\:`, String.raw`windi\.css`, String.raw`^uno\:`, String.raw`uno\.css`, "vue-router/auto", "vue-router/auto-routes", "@intlify/unplugin-vue-i18n" ] } ], // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/order.md "import/order": [ "error", { groups: [ "builtin", "external", "internal", "parent", "sibling", "index", "object", "type" ], pathGroups: [ { pattern: "~/**", group: "internal" }, { pattern: "~~/**", group: "internal" }, { pattern: "@/**", group: "internal" }, { pattern: "@@/**", group: "internal" } ] } ], ...rules }, settings: { // https://github.com/un-ts/eslint-plugin-import-x#import-xcore-modules "import/core-modules": ["electron"], // https://github.com/un-ts/eslint-plugin-import-x#import-xextensions "import/extensions": [".js", ".cjs", ".mjs", ".jsx"], // https://github.com/un-ts/eslint-plugin-import-x#import-xignore "import/ignore": [ "node_modules", String.raw`\.(scss|sass|less|css|svg|json)$` ], // https://github.com/un-ts/eslint-plugin-import-x#resolvers "import/resolver": "oxc" } }, { name: "base/imports/typescript", files: typescriptFiles, rules: { // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-named-as-default-member.md // https://typescript-eslint.io/troubleshooting/typed-linting/performance/#eslint-plugin-import "import/no-named-as-default-member": "off", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/default.md // https://typescript-eslint.io/troubleshooting/typed-linting/performance/#eslint-plugin-import "import/default": "off", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/named.md // https://typescript-eslint.io/troubleshooting/typed-linting/performance/#eslint-plugin-import "import/named": "off", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/namespace.md // https://typescript-eslint.io/troubleshooting/typed-linting/performance/#eslint-plugin-import "import/namespace": "off", // https://github.com/un-ts/eslint-plugin-import-x/blob/v4.6.1/docs/rules/no-unresolved.md // See https://github.com/iamturns/eslint-config-airbnb-typescript#why-is-importno-unresolved-disabled "import/no-unresolved": "off", ...typescriptRules }, settings: { // https://github.com/un-ts/eslint-plugin-import-x#import-xextensions "import/extensions": [ ".js", ".cjs", ".mjs", ".jsx", ".ts", ".cts", ".mts", ".tsx", ".d.ts" ], // https://github.com/un-ts/eslint-plugin-import-x#import-xparsers "import/parsers": { "@typescript-eslint/parser": [".ts", ".cts", ".mts", ".tsx", ".d.ts"] }, // https://github.com/un-ts/eslint-plugin-import-x#resolvers "import/resolver": "oxc" } } ]; } function javascript(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, parserOptions = {}, languageOptions = {} } = options; return [ { name: "languages/javascript", files, languageOptions: { ecmaVersion: "latest", globals: { ...globals.browser, ...globals.es2025, ...globals.node, dd: "readonly", // https://open.dingtalk.com/ jd: "readonly", // https://mp.jd.com/ ks: "readonly", // https://mp.kuaishou.com/ my: "readonly", // https://opendocs.alipay.com/mini plus: "readonly", // http://www.html5plus.org/doc/h5p.html qh: "readonly", // https://mp.360.cn/ qq: "readonly", // https://q.qq.com/ swan: "readonly", // https://smartprogram.baidu.com/docs tt: "readonly", // https://developer.open-douyin.com/ https://open.feishu.cn/ uni: "readonly", // https://uniapp.dcloud.io/ uniCloud: "readonly", // https://uniapp.dcloud.io weex: "readonly", // https://weex.apache.org/ wx: "readonly" // https://developers.weixin.qq.com/miniprogram/dev/framework/ }, parser: parserBabel, parserOptions: { ecmaFeatures: { globalReturn: false, jsx: true }, ecmaVersion: "latest", requireConfigFile: false, sourceType: "module", ...parserOptions }, sourceType: "module", ...languageOptions }, linterOptions: { reportUnusedDisableDirectives: true }, rules: { // https://github.com/eslint/eslint/blob/main/packages/js/src/configs/eslint-recommended.js "constructor-super": "error", "for-direction": "error", "getter-return": "error", "no-async-promise-executor": "error", "no-case-declarations": "error", "no-class-assign": "error", "no-compare-neg-zero": "error", "no-cond-assign": "error", "no-const-assign": "error", "no-constant-binary-expression": "error", "no-constant-condition": "error", "no-control-regex": "error", "no-debugger": "error", "no-delete-var": "error", "no-dupe-args": "error", "no-dupe-class-members": "error", "no-dupe-else-if": "error", "no-dupe-keys": "error", "no-duplicate-case": "error", "no-empty": "error", "no-empty-character-class": "error", "no-empty-pattern": "error", "no-empty-static-block": "error", "no-ex-assign": "error", "no-extra-boolean-cast": "error", "no-fallthrough": "error", "no-func-assign": "error", "no-global-assign": "error", "no-import-assign": "error", "no-invalid-regexp": "error", "no-irregular-whitespace": "error", "no-loss-of-precision": "error", "no-misleading-character-class": "error", "no-new-native-nonconstructor": "error", "no-nonoctal-decimal-escape": "error", "no-obj-calls": "error", "no-octal": "error", "no-prototype-builtins": "error", "no-redeclare": "error", "no-regex-spaces": "error", "no-self-assign": "error", "no-setter-return": "error", "no-shadow-restricted-names": "error", "no-sparse-arrays": "error", "no-this-before-super": "error", "no-undef": "error", // 'no-unexpected-multiline': 'error', // Conflicts with Prettier. "no-unreachable": "error", "no-unsafe-finally": "error", "no-unsafe-negation": "error", "no-unsafe-optional-chaining": "error", "no-unused-labels": "error", "no-unused-private-class-members": "error", "no-unused-vars": "error", "no-useless-backreference": "error", "no-useless-catch": "error", "no-useless-escape": "error", "no-with": "error", "require-yield": "error", "use-isnan": "error", "valid-typeof": "error", // https://eslint.org/docs/latest/rules/no-array-constructor // Comes with https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v55.0.0/docs/rules/no-new-array.md. "no-array-constructor": "error", // https://eslint.org/docs/latest/rules/no-console // Use consola, pino, winston, etc. "no-console": "warn", // https://eslint.org/docs/latest/rules/no-eval "no-eval": "error", // https://eslint.org/docs/latest/rules/no-implied-eval "no-implied-eval": "error", // https://eslint.org/docs/latest/rules/no-lonely-if // Comes with https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v55.0.0/docs/rules/no-lonely-if.md. "no-lonely-if": "error", // https://eslint.org/docs/latest/rules/no-shadow "no-shadow": "warn", // https://eslint.org/docs/latest/rules/no-throw-literal "no-throw-literal": "error", // https://eslint.org/docs/latest/rules/no-use-before-define "no-use-before-define": "warn", // https://eslint.org/docs/latest/rules/no-var "no-var": "error", // https://eslint.org/docs/latest/rules/prefer-const "prefer-const": "error", // https://eslint.org/docs/latest/rules/prefer-promise-reject-errors "prefer-promise-reject-errors": "off", // https://eslint.org/docs/latest/rules/prefer-rest-params "prefer-rest-params": "error", // https://eslint.org/docs/latest/rules/prefer-spread "prefer-spread": "error", // https://eslint.org/docs/latest/rules/require-await "require-await": "off", ...rules } } ]; } function jsdoc(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/jsdoc", files, plugins: { jsdoc: pluginJsdoc }, rules: { // https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.6.1/src/index.js#L298 // https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.6.1/src/index.js#L244-L261 "jsdoc/check-access": "warn", // 'jsdoc/check-alignment': 'warn', // Conflicts with prettier // 'jsdoc/check-examples': 'off', // 'jsdoc/check-indentation': 'off', // 'jsdoc/check-line-alignment': 'off', "jsdoc/check-param-names": "warn", "jsdoc/check-property-names": "warn", // 'jsdoc/check-syntax': 'off', "jsdoc/check-tag-names": "warn", // 'jsdoc/check-template-names': 'off', "jsdoc/check-types": "warn", "jsdoc/check-values": "warn", // 'jsdoc/convert-to-jsdoc-comments': 'off', "jsdoc/empty-tags": "warn", "jsdoc/implements-on-classes": "warn", // 'jsdoc/imports-as-dependencies': 'off', // 'jsdoc/informative-docs': 'off', // 'jsdoc/lines-before-block': 'off', // 'jsdoc/match-description': 'off', // 'jsdoc/match-name': 'off', // 'jsdoc/multiline-blocks': 'warn', // Conflicts with prettier // 'jsdoc/no-bad-blocks': 'off', // 'jsdoc/no-blank-block-descriptions': 'off', // 'jsdoc/no-blank-blocks': 'off', "jsdoc/no-defaults": "warn", // 'jsdoc/no-missing-syntax': 'off', "jsdoc/no-multi-asterisks": "warn", // 'jsdoc/no-restricted-syntax': 'off', // 'jsdoc/no-types': 'off', // 'jsdoc/no-undefined-types': 'off', // 'jsdoc/require-asterisk-prefix': 'off', // 'jsdoc/require-description': 'off', // 'jsdoc/require-description-complete-sentence': 'off', // 'jsdoc/require-example': 'off', // 'jsdoc/require-file-overview': 'off', // 'jsdoc/require-hyphen-before-param-description': 'off', "jsdoc/require-jsdoc": "warn", "jsdoc/require-param": "warn", "jsdoc/require-param-description": "warn", "jsdoc/require-param-name": "warn", "jsdoc/require-param-type": "warn", "jsdoc/require-property": "warn", "jsdoc/require-property-description": "warn", "jsdoc/require-property-name": "warn", "jsdoc/require-property-type": "warn", "jsdoc/require-returns": "warn", "jsdoc/require-returns-check": "warn", "jsdoc/require-returns-description": "warn", "jsdoc/require-returns-type": "warn", // 'jsdoc/require-template': 'off', // 'jsdoc/require-throws': 'off', "jsdoc/require-yields": "warn", "jsdoc/require-yields-check": "warn", // 'jsdoc/sort-tags': 'off', // 'jsdoc/tag-lines': 'warn', // 'jsdoc/tag-lines': 'off', // 'jsdoc/text-escaping': 'off', "jsdoc/valid-types": "warn", ...rules } }, { name: "jsdoc-typescript", files: typescriptFiles, rules: { // https://github.com/gajus/eslint-plugin-jsdoc/blob/v50.6.1/src/index.js#L216-L242 "jsdoc/check-tag-names": ["warn", { typed: true }], "jsdoc/no-types": "warn", // 'jsdoc/no-undefined-types': 'off', "jsdoc/require-param-type": "off", "jsdoc/require-property-type": "off", "jsdoc/require-returns-type": "off", ...typescriptRules } } ]; } function jsonc(options = {}) { const { files = [GLOB_JSON, GLOB_JSON5, GLOB_JSONC], rules = {} } = options; return [ { name: "other/jsonc", files, languageOptions: { parser: parserJsonc }, plugins: { jsonc: pluginJsonc, "package-json": pluginPackageJson }, rules: { // https://github.com/ota-meshi/eslint-plugin-jsonc/blob/v2.18.1/lib/configs/base.ts strict: "off", "no-unused-expressions": "off", "no-unused-vars": "off", // https://github.com/ota-meshi/eslint-plugin-jsonc/blob/v2.18.1/lib/configs/recommended-with-jsonc.ts "jsonc/no-bigint-literals": "error", "jsonc/no-binary-expression": "error", "jsonc/no-binary-numeric-literals": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-escape-sequence-in-identifier": "error", // 'jsonc/no-floating-decimal': 'error', "jsonc/no-hexadecimal-numeric-literals": "error", "jsonc/no-infinity": "error", "jsonc/no-multi-str": "error", "jsonc/no-nan": "error", "jsonc/no-number-props": "error", "jsonc/no-numeric-separators": "error", "jsonc/no-octal-numeric-literals": "error", "jsonc/no-octal": "error", "jsonc/no-parenthesized": "error", "jsonc/no-plus-sign": "error", "jsonc/no-regexp-literals": "error", "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-unicode-codepoint-escapes": "error", "jsonc/no-useless-escape": "error", // 'jsonc/quote-props': 'error', // 'jsonc/quotes': 'error', // 'jsonc/space-unary-ops': 'error', "jsonc/valid-json-number": "error", "jsonc/vue-custom-block/no-parsing-error": "error", // https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/v0.19.0/src/configs/recommended.ts "package-json/order-properties": "error", "package-json/repository-shorthand": "error", "package-json/sort-collections": "error", "package-json/unique-dependencies": "error", "package-json/valid-local-dependency": "error", "package-json/valid-name": "error", "package-json/valid-package-definition": "error", "package-json/valid-repository-directory": "error", "package-json/valid-version": "error", ...rules } } ]; } function markdown(options = {}) { const { markdownFiles = [GLOB_MARKDOWN], markdownInnerFiles = [GLOB_MARKDOWN_SCRIPT, GLOB_MARKDOWN_VUE], rules = {} } = options; return [ { name: "other/markdown", files: markdownFiles, plugins: { markdown: pluginMarkdown }, processor: "markdown/markdown" }, { name: "other/markdown/code-blocks", files: markdownInnerFiles, rules: { // https://github.com/eslint/markdown/blob/v5.1.0/lib/index.js "no-console": "off", "no-redeclare": "off", "no-undef": "off", "no-unused-vars": "off", "@typescript-eslint/consistent-type-imports": "off", "@typescript-eslint/no-require-imports": "off", "@typescript-eslint/no-unused-vars": "off", "import/no-unresolved": "off", "n/no-extraneous-import": "off", "n/no-extraneous-require": "off", "n/no-unpublished-bin": "off", "n/no-unpublished-import": "off", "n/no-unpublished-require": "off", "unicorn/prefer-module": "off", "unused-imports/no-unused-imports": "off", "unused-imports/no-unused-vars": "off", "vue/no-unused-emit-declarations": "off", ...rules } } ]; } function next(options = {}) { const { files = [GLOB_JSX, GLOB_TSX], rules = {}, typescriptFiles = [GLOB_TSX], typescriptRules = {} } = options; return [ { name: "frameworks/next", files, plugins: { "@next/next": pluginNext }, rules: { // https://nextjs.org/docs/messages/google-font-display "@next/next/google-font-display": "warn", // https://nextjs.org/docs/messages/google-font-preconnect "@next/next/google-font-preconnect": "warn", // https://nextjs.org/docs/messages/inline-script-id "@next/next/inline-script-id": "error", // https://nextjs.org/docs/messages/next-script-for-ga "@next/next/next-script-for-ga": "warn", // Handled by ESLint globals. // '@next/next/no-assign-module-variable': 'error', // https://nextjs.org/docs/messages/no-async-client-component "@next/next/no-async-client-component": "warn", // https://nextjs.org/docs/messages/no-before-interactive-script-outside-document "@next/next/no-before-interactive-script-outside-document": "warn", // https://nextjs.org/docs/messages/no-css-tags "@next/next/no-css-tags": "warn", // https://nextjs.org/docs/messages/no-document-import-in-page "@next/next/no-document-import-in-page": "error", // https://nextjs.org/docs/messages/no-duplicate-head "@next/next/no-duplicate-head": "error", // https://nextjs.org/docs/messages/no-head-element "@next/next/no-head-element": "warn", // https://nextjs.org/docs/messages/no-head-import-in-document "@next/next/no-head-import-in-document": "error", // https://nextjs.org/docs/messages/no-html-link-for-pages "@next/next/no-html-link-for-pages": "error", // https://nextjs.org/docs/messages/no-img-element "@next/next/no-img-element": "warn", // https://nextjs.org/docs/messages/no-page-custom-font "@next/next/no-page-custom-font": "warn", // https://nextjs.org/docs/messages/no-script-component-in-head "@next/next/no-script-component-in-head": "error", // https://nextjs.org/docs/messages/no-styled-jsx-in-document "@next/next/no-styled-jsx-in-document": "warn", // https://nextjs.org/docs/messages/no-sync-scripts "@next/next/no-sync-scripts": "error", // https://nextjs.org/docs/messages/no-title-in-document-head "@next/next/no-title-in-document-head": "warn", "@next/next/no-typos": "warn", // https://nextjs.org/docs/messages/no-unwanted-polyfillio "@next/next/no-unwanted-polyfillio": "error", ...rules } }, { files: typescriptFiles, rules: { ...typescriptRules } } ]; } function node(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/node", files, plugins: { n: pluginN }, rules: { // https://github.com/eslint-community/eslint-plugin-n/blob/v17.15.1/lib/configs/_commons.js "n/no-deprecated-api": "error", "n/no-extraneous-import": "error", "n/no-extraneous-require": "error", "n/no-exports-assign": "error", // 'n/no-missing-import': 'error', // Handled by eslint-plugin-import-x. // 'n/no-missing-require': 'error', // Handled by eslint-plugin-import-x. "n/no-process-exit": "error", "n/no-unpublished-bin": "error", "n/no-unpublished-import": "error", "n/no-unpublished-require": "error", // 'n/no-unsupported-features/es-builtins': 'error', // 'n/no-unsupported-features/es-syntax': 'error', // 'n/no-unsupported-features/node-builtins': 'error', "n/process-exit-as-throw": "error", // 'n/hashbang': 'error', // Allow source code to use hashbang for building. ...rules } }, { name: "base/node/typescript", files: typescriptFiles, rules: { ...typescriptRules } } ]; } const nuxt3Rules = { "nuxt/prefer-import-meta": "error" }; const nuxt2Rules = { // https://github.com/nuxt/eslint-plugin-nuxt/blob/v4.0.0/lib/configs/base.js "nuxt/no-env-in-context": "error", "nuxt/no-env-in-hooks": "error", "nuxt/no-globals-in-created": "error", "nuxt/no-this-in-fetch-data": "error", "nuxt/no-cjs-in-config": "error", // https://github.com/nuxt/eslint-plugin-nuxt/blob/v4.0.0/lib/configs/recommended.js "nuxt/no-timing-in-fetch-data": "error" }; function nuxt(options = {}) { const { files = [GLOB_VUE], rules = {}, typescriptRules = {} } = options; return [ { name: "frameworks/nuxt", files, plugins: { nuxt: hasNuxt3 ? pluginNuxt3 : pluginNuxt2 }, rules: { ...hasNuxt3 ? nuxt3Rules : nuxt2Rules, ...rules, ...hasTypeScript ? typescriptRules : {} } }, hasNuxt3 ? { name: "nuxt-config", files: ["**/nuxt.config.?([cm])[jt]s?(x)"], rules: { "nuxt/nuxt-config-keys-order": "error" } } : {} ]; } function promise(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/promise", files, plugins: { promise: pluginPromise }, rules: { // https://github.com/eslint-community/eslint-plugin-promise/blob/v7.2.1/index.js "promise/always-return": "error", // 'promise/avoid-new': 'off', "promise/catch-or-return": "error", "promise/no-callback-in-promise": "warn", "promise/no-multiple-resolved": "warn", // 'promise/no-native': 'off', "promise/no-nesting": "warn", "promise/no-new-statics": "error", "promise/no-promise-in-callback": "warn", "promise/no-return-in-finally": "warn", "promise/no-return-wrap": "error", "promise/param-names": "error", "promise/prefer-await-to-callbacks": "warn", "promise/prefer-await-to-then": "warn", "promise/spec-only": "warn", "promise/valid-params": "warn", ...rules } }, { name: "base/promise/typescript", files: typescriptFiles, rules: { ...typescriptRules } } ]; } function perfectionist(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/perfectionist", files, plugins: { perfectionist: pluginPerfectionist }, rules: { // https://perfectionist.dev/rules/sort-array-includes "perfectionist/sort-array-includes": "error", // https://perfectionist.dev/rules/sort-classes "perfectionist/sort-classes": "error", // https://perfectionist.dev/rules/sort-decorators "perfectionist/sort-decorators": "error", // https://perfectionist.dev/rules/sort-enums "perfectionist/sort-enums": "error", // https://perfectionist.dev/rules/sort-exports "perfectionist/sort-exports": "error", // https://perfectionist.dev/rules/sort-heritage-clauses "perfectionist/sort-heritage-clauses": "error", // https://perfectionist.dev/rules/sort-imports "import/order": "off", "perfectionist/sort-imports": [ "error", { internalPattern: ["^~{1,2}/.*", "^@{1,2}/.*"], newlinesBetween: "ignore", groups: [ "builtin", "external", "internal", "parent", "sibling", "side-effect", "side-effect-style", "index", "object", "style", "external-type", "builtin-type", "internal-type", "parent-type", "sibling-type", "index-type", "unknown" ] } ], // https://perfectionist.dev/rules/sort-interfaces "@typescript-eslint/adjacent-overload-signatures": "off", "perfectionist/sort-interfaces": "error", // https://perfectionist.dev/rules/sort-intersection-types // deprecated // "@typescript-eslint/sort-type-constituents": "off", "perfectionist/sort-intersection-types": [ "error", { groups: [ "conditional", "function", "import", "intersection", "keyword", "literal", "named", "object", "operator", "tuple", "union", "nullish", "unknown" ] } ], // https://perfectionist.dev/rules/sort-jsx-props "perfectionist/sort-jsx-props": [ "error", { groups: ["reserved", "unknown", "callback"], customGroups: { reserved: ["children", "dangerouslySetInnerHTML", "key", "ref"], callback: "on*" } } ], // https://perfectionist.dev/rules/sort-maps "perfectionist/sort-maps": "error", // https://perfectionist.dev/rules/sort-modules "perfectionist/sort-modules": "error", // https://perfectionist.dev/rules/sort-named-exports "perfectionist/sort-named-exports": "error", // https://perfectionist.dev/rules/sort-named-imports "perfectionist/sort-named-imports": "error", // https://perfectionist.dev/rules/sort-object-types // '@typescript-eslint/adjacent-overload-signatures': 'off', "perfectionist/sort-object-types": "error", // https://perfectionist.dev/rules/sort-objects "sort-keys": "off", "perfectionist/sort-objects": [ "error", { groups: ["top", "unknown", "method"], customGroups: { top: ["name", "key", "id", "queryKey", "queryFn"] } } ], // https://perfectionist.dev/rules/sort-sets "perfectionist/sort-sets": "error", // https://perfectionist.dev/rules/sort-switch-case "perfectionist/sort-switch-case": "error", // https://perfectionist.dev/rules/sort-union-types // deprecated // '@typescript-eslint/sort-type-constituents': 'off', "perfectionist/sort-union-types": [ "error", { groups: [ "conditional", "function", "import", "intersection", "keyword", "literal", "named", "object", "operator", "tuple", "union", "nullish", "unknown" ] } ], // https://perfectionist.dev/rules/sort-variable-declarations "perfectionist/sort-variable-declarations": "error", ...rules }, settings: { perfectionist: { type: "natural", order: "asc", ignoreCase: true, ignorePattern: [], specialCharacters: "keep", locales: "en-US", partitionByComment: true, partitionByNewLine: true } } }, { name: "base/perfectionist/typescript", files: typescriptFiles, rules: { ...typescriptRules } } ]; } function react(options = {}) { const { files = [GLOB_JSX, GLOB_TSX], rules = {}, parserOptions = {}, languageOptions = {}, typescriptFiles = [GLOB_TSX], typescriptRules = {}, typescriptParserOptions = {}, typescriptLanguageOptions = {}, typeCheck = true, settings = {} } = options; return [ { name: "frameworks/react", files, languageOptions: { parser: parserBabel, parserOptions: { babelOptions: { babelrc: false, configFile: false, presets: ["@babel/preset-env", "@babel/preset-react"] }, ecmaFeatures: { globalReturn: false, jsx: true }, ecmaVersion: "latest", requireConfigFile: false, sourceType: "module", ...parserOptions }, ...languageOptions }, plugins: { "react-x": pluginReactX, "react-dom": pluginReactDom, "react-web-api": pluginReactWebApi, "react-hooks-extra": pluginReactHooksExtra, "react-naming-convention": pluginReactNamingConvention, "react-hooks": pluginReactHooks, "react-perf": pluginReactPerf, "react-refresh": pluginReactRefresh }, rules: { // https://github.com/Rel1cx/eslint-react/blob/v1.23.2/packages/plugins/eslint-plugin-react-x/README.md "react-x/ensure-forward-ref-using-ref": "warn", "react-x/no-access-state-in-setstate": "error", "react-x/no-array-index-key": "warn", "react-x/no-children-count": "warn", "react-x/no-children-for-each": "warn", "react-x/no-children-map": "warn", "react-x/no-children-only": "warn", "react-x/no-children-to-array": "warn", "react-x/no-clone-element": "warn", "react-x/no-comment-textnodes": "warn", "react-x/no-component-will-mount": "error", "react-x/no-component-will-receive-props": "error", "react-x/no-component-will-update": "error", "react-x/no-context-provider": "warn", "react-x/no-create-ref": "error", "react-x/no-default-props": "error", "react-x/no-direct-mutation-state": "error", "react-x/no-duplicate-jsx-props": "warn", "react-x/no-duplicate-key": "error", "react-x/no-forward-ref": "warn", "react-x/no-implicit-key": "warn", "react-x/no-missing-key": "error", "react-x/no-nested-components": "error", "react-x/no-prop-types": "error", "react-x/no-redundant-should-component-update": "error", "react-x/no-set-state-in-component-did-mount": "warn", "react-x/no-set-state-in-component-did-update": "warn", "react-x/no-set-state-in-component-will-update": "warn", "react-x/no-string-refs": "error", "react-x/no-unsafe-component-will-mount": "warn", "react-x/no-unsafe-component-will-receive-props": "warn", "react-x/no-unsafe-component-will-update": "warn", "react-x/no-unstable-context-value": "warn", "react-x/no-unstable-default-props": "warn", "react-x/no-unused-class-component-members": "warn", "react-x/no-unused-state": "warn", "react-x/use-jsx-vars": "warn", // https://github.com/Rel1cx/eslint-react/blob/v1.23.2/packages/plugins/eslint-plugin-react-dom/README.md "react-dom/no-dangerously-set-innerhtml-with-children": "error", "react-dom/no-dangerously-set-innerhtml": "warn", "react-dom/no-find-dom-node": "error", "react-dom/no-missing-button-type": "warn", "react-dom/no-missing-iframe-sandbox": "warn", "react-dom/no-namespace": "error", "react-dom/no-render-return-value": "error", "react-dom/no-script-url": "warn", "react-dom/no-unknown-property": "warn", "react-dom/no-unsafe-iframe-sandbox": "warn", "react-dom/no-unsafe-target-blank": "warn", "react-dom/no-void-elements-with-children": "warn", // https://github.com/Rel1cx/eslint-react/blob/v1.23.2/packages/plugins/eslint-plugin-react-web-api/README.md "react-web-api/no-leaked-event-listener": "warn", "react-web-api/no-leaked-interval": "warn", "react-web-api/no-leaked-resize-observer": "warn", "react-web-api/no-leaked-timeout": "warn", // https://github.com/Rel1cx/eslint-react/blob/v1.23.2/packages/plugins/eslint-plugin-react-hooks-extra/README.md "react-hooks-extra/no-direct-set-state-in-use-effect": "warn", "react-hooks-extra/no-useless-custom-hooks": "warn", "react-hooks-extra/prefer-use-state-lazy-initialization": "warn", // https://github.com/Rel1cx/eslint-react/blob/v1.23.2/packages/plugins/eslint-plugin-react-naming-convention/README.md "react-naming-convention/filename-extension": ["warn", "as-needed"], "react-naming-convention/use-state": "warn", // https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks // eslint-plugin-react-hooks v5.1.0 "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", // https://github.com/cvazac/eslint-plugin-react-perf/commit/9bfa930661a23218f5460ebd39d35d76ccdb5724 // eslint-plugin-react-perf v3.3.3 "react-perf/jsx-no-new-object-as-prop": "error", "react-perf/jsx-no-new-array-as-prop": "error", "react-perf/jsx-no-new-function-as-prop": "error", // https://github.com/ArnaudBarre/eslint-plugin-react-refresh/tree/v0.4.18 "react-refresh/only-export-components": [ "warn", { allowExportNames: [ ...hasRemix || hasReactRouter ? ["meta", "links", "headers", "loader", "action"] : [], ...hasNext ? [ "dynamic", "dynamicParams", "revalidate", "fetchCache", "runtime", "preferredRegion", "maxDuration", "config", "generateStaticParams", "metadata", "generateMetadata", "viewport", "generateViewport" ] : [] ], allowConstantExport: hasVite } ], ...rules }, settings: { ...settings } }, { name: "frameworks/react/typescript", files: typescriptFiles, languageOptions: { parser: parserTypeScript, ...typeCheck ? { parserOptions: { projectService: { allowDefaultProject: ["*.js", "*.config.*"] }, ...typescriptParserOptions } } : { parserOptions: { ...typescriptParserOptions } }, ...typescriptLanguageOptions }, rules: { "react-x/no-duplicate-jsx-props": "off", "react-x/use-jsx-vars": "warn", "react-dom/no-unknown-property": "off", ...typeCheck ? { "react-x/no-leaked-conditional-rendering": "warn" } : {}, ...typescriptRules } } ]; } function reactNative(options = {}) { const { files = [GLOB_JSX, GLOB_TSX], rules = {}, typescriptFiles = [GLOB_TSX], typescriptRules = {} } = options; return [ { name: "frameworks/react-native", files, plugins: { "react-native": pluginReactNative }, rules: { // https://github.com/Intellicode/eslint-plugin-react-native/blob/v4.1.0/index.js "react-native/no-unused-styles": "error", "react-native/split-platform-components": "error", "react-native/no-inline-styles": "error", "react-native/no-color-literals": "error", "react-native/no-raw-text": "error", "react-native/no-single-element-style-arrays": "error", ...rules } }, { name: "react-native-typescript", files: typescriptFiles, rules: { ...typescriptRules } } ]; } function regexp(options = {}) { const { files = [GLOB_SCRIPT, GLOB_VUE], rules = {}, typescriptFiles = hasTypeScript && hasVue ? [GLOB_DTS, GLOB_TS, GLOB_TSX, GLOB_VUE] : [GLOB_DTS, GLOB_TS, GLOB_TSX], typescriptRules = {} } = options; return [ { name: "base/regexp", files, plugins: { regexp: pluginRegexp }, rules: { // https://github.com/ota-meshi/eslint-plugin-regexp/blob/v2.7.0/lib/configs/rules/recommended.ts "no-control-regex": "error", "no-misleading-character-class": "error", "no-regex-spaces": "error", "prefer-regex-literals": "error", "no-invalid-regexp": "off", "no-useless-backreference": "off", "no-empty-character-class": "off", "regexp/confusing-quantifier": "warn", "regexp/control-character-escape": "error", "regexp/match-any": "error", "regexp/negation": "error", "regexp/no-contradiction-with-assertion": "error", "regexp/no-dupe-characters-character-class": "error", "regexp/no-dupe-disjunctions": "error", "regexp/no-empty-alternative": "warn", "regexp/no-empty-capturing-group": "error", "regexp/no-empty-character-class": "error", "regexp/no-empty-group": "error", "regexp/no-empty-lookarounds-assertion": "error", "regexp/no-empty-string-literal": "error", "regexp/no-escape-backspace": "error", "regexp/no-extra-lookaround-assertions": "error", "regexp/no-invalid-regexp": "error", "regexp/no-invisible-character": "error", "regexp/no-lazy-ends": "warn", "regexp/no-legacy-features": "error", "regexp/no-misleading-capturing-group": "error", "regexp/no-misleading-unicode-character": "error", "regexp/no-missing-g-flag": "error", "regexp/no-non-standard-flag": "error", "regexp/no-obscure-range": "error", "regexp/no-optional-assertion": "error", "regexp/no-potentially-useless-backreference": "warn", "regexp/no-super-linear-backtracking": "error", "regexp/no-trivially-nested-assertion": "error", "regexp/no-trivially-nested-quantifier": "error", "regexp/no-unused-capturing-group": "error", "regexp/no-useless-assertions": "error", "regexp/no-useless-backreference": "error", "regexp/no-useless-character-class": "error", "regexp/no-useless-dollar-replacements": "error", "regexp/no-useless-escape": "error", "regexp/no-useless-flag": "warn", "regexp/no-useless-lazy": "error", "regexp/no-useless-non-capturing-group": "error", "regexp/no-useless-quantifier": "error", "regexp/no-useless-range": "error", "regexp/no-useless-set-operand": "error", "regexp/no-useless-string-literal": "error", "regexp/no-useless-two-nums-quantifier": "error", "regexp/no-zero-quantifier": "error", "regexp/optimal-lookaround-quantifier": "warn", "regexp/optimal-quantifier-concatenation": "error", "regexp/prefer-character-class": "error", "regexp/prefer-d": "error", "regexp/prefer-plus-quantifier": "error", "regexp/prefer-predefined-assertion": "error", "regexp/prefer-question-quantifier": "error", "regexp/prefer-range": "error", "regexp/prefer-set-operation": "error", "regexp/prefer-star-quantifier": "error", "regexp/prefer-unicode-codepo