@modyqyw/fabric
Version:
Opinionated shareable specifications for git-based JavaScript/TypeScript projects.
1,298 lines (1,278 loc) • 122 kB
JavaScript
'use strict';
const utils = require('./fabric.Ch5WLaHx.cjs');
const constants = require('./fabric.Bxa-91bp.cjs');
const env = require('./fabric.B2dPjHjl.cjs');
const compat = require('@eslint/compat');
const _configGitignore = require('eslint-config-flat-gitignore');
const _parserBabel = require('@babel/eslint-parser');
const _parserTypeScript = require('@typescript-eslint/parser');
const _pluginTypeScript = require('@typescript-eslint/eslint-plugin');
const _configCommand = require('eslint-plugin-command/config');
const _pluginJsdoc = require('eslint-plugin-jsdoc');
const _pluginImportX = require('eslint-plugin-import-x');
const _importResolverOxc = require('eslint-import-resolver-oxc');
const _pluginUnusedImports = require('eslint-plugin-unused-imports');
const _pluginNoBarrelFiles = require('eslint-plugin-no-barrel-files');
const _pluginPromise = require('eslint-plugin-promise');
const _pluginRegexp = require('eslint-plugin-regexp');
const _pluginN = require('eslint-plugin-n');
const _pluginPerfectionist = require('eslint-plugin-perfectionist');
const _pluginUnicorn = require('eslint-plugin-unicorn');
const _pluginReactX = require('eslint-plugin-react-x');
const _pluginReactDom = require('eslint-plugin-react-dom');
const _pluginReactWebApi = require('eslint-plugin-react-web-api');
const _pluginReactHooksExtra = require('eslint-plugin-react-hooks-extra');
const _pluginReactNamingConvention = require('eslint-plugin-react-naming-convention');
const _pluginReactHooks = require('eslint-plugin-react-hooks');
const _pluginReactPerf = require('eslint-plugin-react-perf');
const _pluginReactRefresh = require('eslint-plugin-react-refresh');
const _pluginReactNative = require('eslint-plugin-react-native');
const _pluginNext = require('@next/eslint-plugin-next');
const _parserVue = require('vue-eslint-parser');
const _pluginVue = require('eslint-plugin-vue');
const _pluginVueScopedCss = require('eslint-plugin-vue-scoped-css');
const _pluginNuxt2 = require('eslint-plugin-nuxt');
const _pluginNuxt3 = require('@nuxt/eslint-plugin');
const _pluginTailwindcss = require('eslint-plugin-tailwindcss');
const _pluginUnocss = require('@unocss/eslint-plugin');
const _pluginMarkdown = require('eslint-plugin-markdown');
const _parserJsonc = require('jsonc-eslint-parser');
const _pluginJsonc = require('eslint-plugin-jsonc');
const _pluginPackageJson = require('eslint-plugin-package-json');
const _parserToml = require('toml-eslint-parser');
const _pluginToml = require('eslint-plugin-toml');
const _pluginYml = require('eslint-plugin-yml');
const _parserYml = require('yaml-eslint-parser');
const defu = require('defu');
const globals = require('globals');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
function _interopNamespaceCompat(e) {
if (e && typeof e === 'object' && 'default' in e) return e;
const n = Object.create(null);
if (e) {
for (const k in e) {
n[k] = e[k];
}
}
n.default = e;
return n;
}
const _configGitignore__namespace = /*#__PURE__*/_interopNamespaceCompat(_configGitignore);
const _parserBabel__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserBabel);
const _parserTypeScript__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserTypeScript);
const _pluginTypeScript__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginTypeScript);
const _configCommand__namespace = /*#__PURE__*/_interopNamespaceCompat(_configCommand);
const _pluginJsdoc__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginJsdoc);
const _pluginImportX__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginImportX);
const _importResolverOxc__namespace = /*#__PURE__*/_interopNamespaceCompat(_importResolverOxc);
const _pluginUnusedImports__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginUnusedImports);
const _pluginNoBarrelFiles__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginNoBarrelFiles);
const _pluginPromise__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginPromise);
const _pluginRegexp__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginRegexp);
const _pluginN__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginN);
const _pluginPerfectionist__default = /*#__PURE__*/_interopDefaultCompat(_pluginPerfectionist);
const _pluginUnicorn__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginUnicorn);
const _pluginReactX__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactX);
const _pluginReactDom__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactDom);
const _pluginReactWebApi__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactWebApi);
const _pluginReactHooksExtra__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactHooksExtra);
const _pluginReactNamingConvention__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactNamingConvention);
const _pluginReactHooks__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactHooks);
const _pluginReactPerf__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactPerf);
const _pluginReactRefresh__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactRefresh);
const _pluginReactNative__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginReactNative);
const _pluginNext__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginNext);
const _parserVue__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserVue);
const _pluginVue__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginVue);
const _pluginVueScopedCss__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginVueScopedCss);
const _pluginNuxt2__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginNuxt2);
const _pluginNuxt3__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginNuxt3);
const _pluginTailwindcss__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginTailwindcss);
const _pluginUnocss__default = /*#__PURE__*/_interopDefaultCompat(_pluginUnocss);
const _pluginMarkdown__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginMarkdown);
const _parserJsonc__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserJsonc);
const _pluginJsonc__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginJsonc);
const _pluginPackageJson__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginPackageJson);
const _parserToml__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserToml);
const _pluginToml__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginToml);
const _pluginYml__namespace = /*#__PURE__*/_interopNamespaceCompat(_pluginYml);
const _parserYml__namespace = /*#__PURE__*/_interopNamespaceCompat(_parserYml);
const globals__default = /*#__PURE__*/_interopDefaultCompat(globals);
const configGitignore = utils.interopDefault(_configGitignore__namespace);
const parserBabel = utils.interopDefault(_parserBabel__namespace);
const parserTypeScript = utils.interopDefault(_parserTypeScript__namespace);
const pluginTypeScript = utils.interopDefault(
_pluginTypeScript__namespace
);
const configCommand = utils.interopDefault(_configCommand__namespace);
const pluginJsdoc = utils.interopDefault(
_pluginJsdoc__namespace
);
const pluginImportX = utils.interopDefault(
_pluginImportX__namespace
);
const importResolverOxc = utils.interopDefault(_importResolverOxc__namespace);
const pluginUnusedImports = utils.interopDefault(_pluginUnusedImports__namespace);
const pluginNoBarrelFiles = utils.interopDefault(_pluginNoBarrelFiles__namespace);
const pluginPromise = utils.interopDefault(
_pluginPromise__namespace
);
const pluginRegexp = utils.interopDefault(
_pluginRegexp__namespace
);
const pluginN = utils.interopDefault(_pluginN__namespace);
const pluginPerfectionist = utils.interopDefault(
_pluginPerfectionist__default
);
const pluginUnicorn = utils.interopDefault(
_pluginUnicorn__namespace
);
const pluginReactX = utils.interopDefault(
_pluginReactX__namespace
);
const pluginReactDom = utils.interopDefault(
_pluginReactDom__namespace
);
const pluginReactWebApi = utils.interopDefault(
_pluginReactWebApi__namespace
);
const pluginReactHooksExtra = utils.interopDefault(
_pluginReactHooksExtra__namespace
);
const pluginReactNamingConvention = utils.interopDefault(
_pluginReactNamingConvention__namespace
);
const pluginReactHooks = compat.fixupPluginRules(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
utils.interopDefault(_pluginReactHooks__namespace)
);
const pluginReactPerf = compat.fixupPluginRules(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
utils.interopDefault(_pluginReactPerf__namespace)
);
const pluginReactRefresh = utils.interopDefault(
_pluginReactRefresh__namespace
);
const pluginReactNative = compat.fixupPluginRules(
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
utils.interopDefault(_pluginReactNative__namespace)
);
const pluginNext = utils.interopDefault(
_pluginNext__namespace
);
const parserVue = utils.interopDefault(_parserVue__namespace);
const pluginVue = utils.interopDefault(_pluginVue__namespace);
const pluginVueScopedCss = utils.interopDefault(
_pluginVueScopedCss__namespace
);
const pluginNuxt2 = utils.interopDefault(
_pluginNuxt2__namespace
);
const pluginNuxt3 = utils.interopDefault(
_pluginNuxt3__namespace
);
const pluginTailwindcss = utils.interopDefault(
_pluginTailwindcss__namespace
);
const pluginUnocss = utils.interopDefault(
_pluginUnocss__default
);
const pluginMarkdown = utils.interopDefault(
_pluginMarkdown__namespace
);
const parserJsonc = utils.interopDefault(_parserJsonc__namespace);
const pluginJsonc = utils.interopDefault(
_pluginJsonc__namespace
);
const pluginPackageJson = utils.interopDefault(
_pluginPackageJson__namespace
);
const parserToml = utils.interopDefault(_parserToml__namespace);
const pluginToml = utils.interopDefault(
_pluginToml__namespace
);
const parserYml = utils.interopDefault(_parserYml__namespace);
const pluginYml = utils.interopDefault(_pluginYml__namespace);
function barrel(options = {}) {
const {
files = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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.defu(options, {
files: [".gitignore", ".eslintignore"],
strict: false
})
),
name: "ignores/gitignore"
}
];
}
function ignores(options = {}) {
return [
{
name: "ignores/base",
ignores: options.ignores ?? constants.GLOB_EXCLUDE
}
];
}
function imports(options = {}) {
const {
files = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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 = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
parserOptions = {},
languageOptions = {}
} = options;
return [
{
name: "languages/javascript",
files,
languageOptions: {
ecmaVersion: "latest",
globals: {
...globals__default.browser,
...globals__default.es2025,
...globals__default.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 = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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 = [constants.GLOB_JSON, constants.GLOB_JSON5, constants.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 = [constants.GLOB_MARKDOWN],
markdownInnerFiles = [constants.GLOB_MARKDOWN_SCRIPT, constants.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 = [constants.GLOB_JSX, constants.GLOB_TSX],
rules = {},
typescriptFiles = [constants.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 = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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 = [constants.GLOB_VUE], rules = {}, typescriptRules = {} } = options;
return [
{
name: "frameworks/nuxt",
files,
plugins: {
nuxt: env.hasNuxt3 ? pluginNuxt3 : pluginNuxt2
},
rules: {
...env.hasNuxt3 ? nuxt3Rules : nuxt2Rules,
...rules,
...env.hasTypeScript ? typescriptRules : {}
}
},
env.hasNuxt3 ? {
name: "nuxt-config",
files: ["**/nuxt.config.?([cm])[jt]s?(x)"],
rules: {
"nuxt/nuxt-config-keys-order": "error"
}
} : {}
];
}
function promise(options = {}) {
const {
files = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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 = [constants.GLOB_SCRIPT, constants.GLOB_VUE],
rules = {},
typescriptFiles = env.hasTypeScript && env.hasVue ? [constants.GLOB_DTS, constants.GLOB_TS, constants.GLOB_TSX, constants.GLOB_VUE] : [constants.GLOB_DTS, constants.GLOB_TS, constants.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 = [constants.GLOB_JSX, constants.GLOB_TSX],
rules = {},
parserOptions = {},
languageOptions = {},
typescriptFiles = [constants.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: [
...env.hasRemix || env.hasReactRouter ? ["meta", "links", "headers", "loader", "action"] : [],
...env.hasNext ? [
"dynamic",
"dynamicParams",
"revalidate",
"fetchCache",
"runtime",
"preferredRegion",
"maxDuration",
"config",
"generateStaticParams",
"metadata",
"generateMetadata",
"viewport",
"generateViewport"
] : []
],
allowConstantExport: env.hasVite
}
],
...rules
},
settings: {
...settings
}
},
{
name: "frameworks/react/typescript",
files: typescriptFiles,
languageOptions: {
parser: parserTypeScript,
...typeCheck ? {
parserOptions: {
proj