@sankeyangshu/eslint-config
Version:
ESLint config for @sankeyangshu.
1,587 lines (1,562 loc) • 47.9 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
defineConfig: () => defineConfig
});
module.exports = __toCommonJS(index_exports);
var import_eslint_flat_config_utils = require("eslint-flat-config-utils");
// src/constants/index.ts
var GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
var GLOB_SRC = "**/*.?([cm])[jt]s?(x)";
var GLOB_JSX = "**/*.?([cm])jsx";
var GLOB_TSX = "**/*.?([cm])tsx";
var GLOB_VUE = "**/*.vue";
var GLOB_ASTRO = "**/*.astro";
var GLOB_SVELTE = "**/*.svelte";
var GLOB_HTML = "**/*.htm?(l)";
var GLOB_CSS = "**/*.css";
var GLOB_POSTCSS = "**/*.{p,post}css";
var GLOB_LESS = "**/*.less";
var GLOB_SCSS = "**/*.scss";
var GLOB_JSON = "**/*.json";
var GLOB_JSON5 = "**/*.json5";
var GLOB_JSONC = "**/*.jsonc";
var GLOB_MARKDOWN = "**/*.md";
var GLOB_YAML = "**/*.y?(a)ml";
var GLOB_TOML = "**/*.toml";
var GLOB_PRETTIER_LINT = [GLOB_SRC, GLOB_VUE];
var GLOB_TESTS = [
`**/__tests__/**/*.${GLOB_SRC_EXT}`,
`**/*.spec.${GLOB_SRC_EXT}`,
`**/*.test.${GLOB_SRC_EXT}`,
`**/*.bench.${GLOB_SRC_EXT}`,
`**/*.benchmark.${GLOB_SRC_EXT}`
];
var GLOB_EXCLUDE = [
"**/node_modules",
"**/dist",
"**/package-lock.json",
"**/yarn.lock",
"**/pnpm-lock.yaml",
"**/bun.lockb",
"**/output",
"**/coverage",
"**/temp",
"**/.temp",
"**/tmp",
"**/.tmp",
"**/.history",
"**/.vitepress/cache",
"**/.nuxt",
"**/.next",
"**/.vercel",
"**/.changeset",
"**/.idea",
"**/.cache",
"**/.output",
"**/.vite-inspect",
"**/CHANGELOG*.md",
"**/*.min.*",
"**/LICENSE*",
"**/__snapshots__",
"**/auto-import?(s).d.ts",
"**/components.d.ts",
"**/.github/workflows/*.yml"
];
var DEFAULT_PRETTIER_RULES = {
useTabs: false,
tabWidth: 2,
printWidth: 100,
singleQuote: true,
trailingComma: "es5",
bracketSpacing: true,
semi: true,
jsdocCapitalizeDescription: false
};
// src/utils/index.ts
var import_promises = require("fs/promises");
var import_node_path = __toESM(require("path"), 1);
var import_node_process = __toESM(require("process"), 1);
var import_local_pkg = require("local-pkg");
async function interopDefault(m) {
const resolved = await m;
return resolved.default || resolved;
}
async function ensurePackages(packages) {
if (import_node_process.default.env.CI || import_node_process.default.stdout.isTTY === false) return;
const nonExistingPackages = packages.filter((i) => !(0, import_local_pkg.isPackageExists)(i));
if (nonExistingPackages.length === 0) return;
const { default: prompts } = await import("prompts");
const message = `${nonExistingPackages.length === 1 ? "Package is" : "Packages are"} required for this config: ${nonExistingPackages.join(", ")}. Do you want to install them?`;
const { result } = await prompts([
{
message,
name: "result",
type: "confirm"
}
]);
if (result) {
const { installPackage } = await import("@antfu/install-pkg");
await installPackage(nonExistingPackages, { dev: true });
}
}
async function loadPrettierConfig(cwd) {
let prettierConfig = {};
try {
const prettierrc = await (0, import_promises.readFile)(import_node_path.default.join(cwd, ".prettierrc"), "utf-8");
prettierConfig = JSON.parse(prettierrc);
} catch {
}
return prettierConfig;
}
function getOverridesRules(overrides = {}) {
const overrideRecord = {
js: {}
};
const rulePrefixes = {
ts: "@typescript-eslint/",
import: "import/",
perfectionist: "perfectionist/",
jsdoc: "jsdoc/",
jsonc: "jsonc/",
n: "n/",
unicorn: "unicorn/",
vue: "vue/",
"react-native": "react-native/",
react: "react/",
astro: "astro/",
svelte: "svelte/",
solid: "solid/",
unocss: "unocss/"
};
const overrideRuleKeys = Object.keys(rulePrefixes);
overrideRuleKeys.forEach((key) => {
overrideRecord[key] = {};
});
const ruleKeys = Object.keys(overrides);
ruleKeys.forEach((key) => {
const hasMatch = overrideRuleKeys.some((overrideKey) => {
const prefix = rulePrefixes[overrideKey];
const matched = key.startsWith(prefix);
if (matched) {
overrideRecord[overrideKey][key] = overrides[key];
}
return matched;
});
if (!hasMatch) {
overrideRecord.js[key] = overrides[key];
}
});
return overrideRecord;
}
// src/configs/typescript.ts
async function createTypescriptRules() {
const pluginTs = await interopDefault(import("@typescript-eslint/eslint-plugin"));
const { rules: recommendedRules } = pluginTs.configs["eslint-recommended"].overrides[0];
const tsRules = {
...pluginTs.configs.base.rules,
...recommendedRules,
...pluginTs.configs.strict.rules,
"@typescript-eslint/consistent-type-imports": [
"error",
{ prefer: "type-imports", disallowTypeAnnotations: false }
],
"@typescript-eslint/no-empty-interface": [
"error",
{
allowSingleExtends: true
}
],
// Override JS
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": "error",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
vars: "all",
args: "all",
ignoreRestSiblings: false,
varsIgnorePattern: "^_",
argsIgnorePattern: "^_"
}
],
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": [
"error",
{ functions: false, classes: false, variables: true }
],
"no-shadow": "off",
"@typescript-eslint/no-shadow": "error",
// off
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/unified-signatures": "off"
};
return tsRules;
}
async function createTypescriptConfig(overrides = {}) {
const [pluginTs, parserTs] = await Promise.all([
interopDefault(import("@typescript-eslint/eslint-plugin")),
interopDefault(import("@typescript-eslint/parser"))
]);
const tsRules = await createTypescriptRules();
return [
{
files: [GLOB_SRC],
languageOptions: {
parser: parserTs,
parserOptions: {
sourceType: "module"
}
},
plugins: {
"@typescript-eslint": pluginTs
},
rules: {
...tsRules,
...overrides
}
},
{
files: ["**/*.js", "**/*.cjs"],
rules: {
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-var-requires": "off"
}
}
];
}
// src/configs/astro.ts
async function createAstroConfig(options, prettierRules2 = {}, overrides = {}) {
if (!options) return [];
const { files = [GLOB_ASTRO] } = options;
await ensurePackages(["eslint-plugin-astro", "astro-eslint-parser", "prettier-plugin-astro"]);
const [pluginAstro, pluginTs, pluginPrettier] = await Promise.all([
interopDefault(import("eslint-plugin-astro")),
interopDefault(import("@typescript-eslint/eslint-plugin")),
interopDefault(import("eslint-plugin-prettier"))
]);
const tsRules = await createTypescriptRules();
const { plugins = [] } = prettierRules2;
const pRules = {
...prettierRules2,
plugins: plugins.concat("prettier-plugin-astro")
};
return [
...pluginAstro.configs.recommended,
{
files,
plugins: {
"@typescript-eslint": pluginTs,
prettier: pluginPrettier
},
rules: {
...tsRules,
...overrides,
"prettier/prettier": [
"warn",
{
...pRules,
parser: "astro"
}
]
}
}
];
}
// src/configs/disables.ts
async function createDisablesConfig() {
return [
{
files: [`**/scripts/${GLOB_SRC}`],
rules: {
"no-console": "off",
"ts/explicit-function-return-type": "off"
}
},
{
files: [`**/cli/${GLOB_SRC}`, `**/cli.${GLOB_SRC_EXT}`],
rules: {
"no-console": "off"
}
},
{
files: ["**/*.d.?([cm])ts"],
rules: {
"eslint-comments/no-unlimited-disable": "off",
"import/no-duplicates": "off",
"no-restricted-syntax": "off",
"unused-imports/no-unused-vars": "off"
}
},
{
files: ["**/*.js", "**/*.cjs"],
rules: {
"ts/no-require-imports": "off"
}
},
{
files: [`**/*.config.${GLOB_SRC_EXT}`, `**/*.config.*.${GLOB_SRC_EXT}`],
rules: {
"no-console": "off",
"ts/explicit-function-return-type": "off"
}
}
];
}
// src/configs/formatter.ts
async function createFormatterConfig(options, prettierRules2 = {}) {
const { html = true, css = true, markdown, yaml, toml } = options || {};
const [pluginPrettier, parserPlain] = await Promise.all([
interopDefault(import("eslint-plugin-prettier")),
interopDefault(import("eslint-parser-plain"))
]);
function createPrettierFormatter(files, parser, plugins) {
const rules = {
...prettierRules2,
parser
};
if (plugins?.length) {
rules.plugins = [...rules.plugins || [], ...plugins];
}
const config = {
files,
languageOptions: {
parser: parserPlain
},
plugins: {
prettier: pluginPrettier
},
rules: {
"prettier/prettier": ["warn", rules]
}
};
return config;
}
const configs = [];
if (css) {
const cssConfig = createPrettierFormatter([GLOB_CSS, GLOB_POSTCSS], "css");
const scssConfig = createPrettierFormatter([GLOB_SCSS], "scss");
const lessConfig = createPrettierFormatter([GLOB_LESS], "less");
configs.push(cssConfig, scssConfig, lessConfig);
}
if (html) {
const htmlConfig = createPrettierFormatter([GLOB_HTML], "html");
configs.push(htmlConfig);
}
if (markdown) {
const markdownConfig = createPrettierFormatter([GLOB_MARKDOWN], "markdown");
configs.push(markdownConfig);
}
if (yaml) {
const yamlConfig = createPrettierFormatter([GLOB_YAML], "yaml");
configs.push(yamlConfig);
}
if (toml) {
await ensurePackages(["@toml-tools/parser", "prettier-plugin-toml"]);
const tomlConfig = createPrettierFormatter([GLOB_TOML], "toml", ["prettier-plugin-toml"]);
configs.push(tomlConfig);
}
return configs;
}
// src/configs/gitignore.ts
async function createGitIgnoresConfig(options) {
if (!options) return [];
const configs = [];
const configItem = await interopDefault(import("eslint-config-flat-gitignore")).then((r) => [
r(typeof options !== "boolean" ? options : { strict: false })
]);
configs.push(...configItem);
return configs;
}
async function createIgnoresConfig(userIgnores = []) {
return [
{
ignores: [...userIgnores]
}
];
}
// src/configs/imports.ts
async function createImportsConfig(overrides = {}) {
const pluginImport = await interopDefault(import("eslint-plugin-import-x"));
return [
{
plugins: {
import: pluginImport
},
rules: {
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error",
"import/no-mutable-exports": "error",
"import/no-named-default": "error",
"import/no-self-import": "error",
"import/no-webpack-loader-syntax": "error",
"import/order": "off",
...overrides
}
}
];
}
// src/configs/javascript.ts
var import_js = __toESM(require("@eslint/js"), 1);
var import_eslint_plugin_unused_imports = __toESM(require("eslint-plugin-unused-imports"), 1);
var import_globals = __toESM(require("globals"), 1);
async function createJavascriptConfig(overrides = {}) {
return [
{
languageOptions: {
ecmaVersion: "latest",
globals: {
...import_globals.default.browser,
...import_globals.default.es2025,
...import_globals.default.node,
document: "readonly",
navigator: "readonly",
window: "readonly"
},
parserOptions: {
ecmaFeatures: {
jsx: true
},
ecmaVersion: "latest",
sourceType: "module"
},
sourceType: "module"
},
linterOptions: {
reportUnusedDisableDirectives: true
},
plugins: {
"unused-imports": import_eslint_plugin_unused_imports.default
},
rules: {
...import_js.default.configs.recommended.rules,
"accessor-pairs": ["error", { enforceForClassMembers: true, setWithoutGet: true }],
"array-callback-return": "error",
"block-scoped-var": "error",
"constructor-super": "error",
"default-case-last": "error",
"dot-notation": ["error", { allowKeywords: true }],
eqeqeq: ["error", "always"],
"keyword-spacing": "off",
"new-cap": ["error", { capIsNew: false, newIsCap: true, properties: true }],
"no-alert": "error",
"no-array-constructor": "error",
"no-async-promise-executor": "error",
"no-caller": "error",
"no-case-declarations": "error",
"no-class-assign": "error",
"no-compare-neg-zero": "error",
"no-cond-assign": ["error", "always"],
"no-console": ["error", { allow: ["warn", "error"] }],
"no-const-assign": "error",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": ["error", { allowEmptyCatch: true }],
"no-empty-character-class": "error",
"no-empty-function": "off",
"no-empty-pattern": "error",
"no-eval": "error",
"no-ex-assign": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-boolean-cast": "error",
"no-fallthrough": "error",
"no-func-assign": "error",
"no-global-assign": "error",
"no-implied-eval": "error",
"no-import-assign": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-iterator": "error",
"no-labels": ["error", { allowLoop: false, allowSwitch: false }],
"no-lone-blocks": "error",
"no-loss-of-precision": "error",
"no-misleading-character-class": "error",
"no-multi-str": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-object": "error",
"no-new-symbol": "error",
"no-new-wrappers": "error",
"no-obj-calls": "error",
"no-octal": "error",
"no-octal-escape": "error",
"no-proto": "error",
"no-prototype-builtins": "error",
"no-redeclare": ["error", { builtinGlobals: false }],
"no-regex-spaces": "error",
"no-restricted-globals": [
"error",
{ message: "Use `globalThis` instead.", name: "global" },
{ message: "Use `globalThis` instead.", name: "self" }
],
"no-restricted-properties": [
"error",
{
message: "Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.",
property: "__proto__"
},
{
message: "Use `Object.defineProperty` instead.",
property: "__defineGetter__"
},
{
message: "Use `Object.defineProperty` instead.",
property: "__defineSetter__"
},
{
message: "Use `Object.getOwnPropertyDescriptor` instead.",
property: "__lookupGetter__"
},
{
message: "Use `Object.getOwnPropertyDescriptor` instead.",
property: "__lookupSetter__"
}
],
"no-restricted-syntax": [
"error",
"DebuggerStatement",
"LabeledStatement",
"WithStatement",
"TSEnumDeclaration[const=true]",
"TSExportAssignment"
],
"no-self-assign": ["error", { props: true }],
"no-self-compare": "error",
"no-sequences": "error",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-template-curly-in-string": "error",
"no-this-before-super": "error",
"no-throw-literal": "error",
"no-undef": "off",
"no-undef-init": "error",
"no-unexpected-multiline": "error",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": ["error", { defaultAssignment: false }],
"no-unreachable": "error",
"no-unreachable-loop": "error",
"no-unsafe-finally": "error",
"no-unsafe-negation": "error",
"no-unused-expressions": [
"error",
{
allowShortCircuit: true,
allowTaggedTemplates: true,
allowTernary: true
}
],
"no-unused-vars": [
"error",
{
args: "none",
caughtErrors: "none",
ignoreRestSiblings: true,
vars: "all"
}
],
"no-use-before-define": ["error", { classes: false, functions: false, variables: true }],
"no-useless-backreference": "error",
"no-useless-call": "error",
"no-useless-catch": "error",
"no-useless-computed-key": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-useless-return": "error",
"no-var": "error",
"no-with": "error",
"object-shorthand": ["error", "always", { avoidQuotes: true, ignoreConstructors: false }],
"one-var": ["error", { initialized: "never" }],
"prefer-arrow-callback": [
"error",
{
allowNamedFunctions: false,
allowUnboundThis: true
}
],
"prefer-const": [
"error",
{
destructuring: "all",
ignoreReadBeforeAssign: true
}
],
"prefer-exponentiation-operator": "error",
"prefer-promise-reject-errors": "error",
"prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"space-before-function-paren": "off",
"spaced-comment": "error",
"symbol-description": "error",
"unicode-bom": ["error", "never"],
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"error",
{
args: "after-used",
argsIgnorePattern: "^_",
vars: "all",
varsIgnorePattern: "^_"
}
],
"use-isnan": ["error", { enforceForIndexOf: true, enforceForSwitchCase: true }],
"valid-typeof": ["error", { requireStringLiterals: true }],
"vars-on-top": "error",
yoda: ["error", "never"],
...overrides
}
}
];
}
// src/configs/jsdoc.ts
async function createJsdocConfig(overrides = {}) {
const pluginJsdoc = await interopDefault(import("eslint-plugin-jsdoc"));
return [
{
plugins: {
jsdoc: pluginJsdoc
},
rules: {
"jsdoc/check-access": "warn",
"jsdoc/check-param-names": "warn",
"jsdoc/check-property-names": "warn",
"jsdoc/check-types": "warn",
"jsdoc/empty-tags": "warn",
"jsdoc/implements-on-classes": "warn",
"jsdoc/no-defaults": "warn",
"jsdoc/no-multi-asterisks": "warn",
"jsdoc/require-param-name": "warn",
"jsdoc/require-property": "warn",
"jsdoc/require-property-description": "warn",
"jsdoc/require-property-name": "warn",
"jsdoc/require-returns-check": "warn",
"jsdoc/require-returns-description": "warn",
"jsdoc/require-yields-check": "warn",
...overrides
}
}
];
}
// src/configs/jsonc.ts
async function createJsoncConfig(overrides = {}) {
const [pluginJsonc, parserJsonc] = await Promise.all([
interopDefault(import("eslint-plugin-jsonc")),
interopDefault(import("jsonc-eslint-parser"))
]);
return [
{
plugins: {
jsonc: pluginJsonc
}
},
{
files: [GLOB_JSON, GLOB_JSON5, GLOB_JSONC],
languageOptions: {
parser: parserJsonc
},
rules: {
"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": "error",
"jsonc/no-octal-escape": "error",
"jsonc/no-octal-numeric-literals": "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/space-unary-ops": "error",
"jsonc/valid-json-number": "error",
"jsonc/vue-custom-block/no-parsing-error": "error",
"jsonc/array-bracket-spacing": ["error", "never"],
"jsonc/comma-dangle": ["error", "never"],
"jsonc/comma-style": ["error", "last"],
"jsonc/indent": ["error", 2],
"jsonc/key-spacing": ["error", { afterColon: true, beforeColon: false }],
"jsonc/object-curly-newline": ["error", { consistent: true, multiline: true }],
"jsonc/object-curly-spacing": ["error", "always"],
"jsonc/object-property-newline": ["error", { allowMultiplePropertiesPerLine: true }],
"jsonc/quote-props": "error",
"jsonc/quotes": "error",
...overrides
}
}
];
}
// src/configs/node.ts
async function createNodeConfig(overrides = {}) {
const pluginNode = await interopDefault(import("eslint-plugin-n"));
return [
{
plugins: {
n: pluginNode
},
rules: {
"n/handle-callback-err": ["error", "^(err|error)$"],
"n/no-deprecated-api": "error",
"n/no-exports-assign": "error",
"n/no-new-require": "error",
"n/no-path-concat": "error",
"n/prefer-global/buffer": ["error", "never"],
"n/prefer-global/process": ["error", "never"],
"n/process-exit-as-throw": "error",
...overrides
}
}
];
}
// src/configs/prettier.ts
var import_eslint_config_prettier = __toESM(require("eslint-config-prettier"), 1);
var { rules: eslintRules } = import_eslint_config_prettier.default;
async function createPrettierConfig(rules) {
const pluginPrettier = await interopDefault(import("eslint-plugin-prettier"));
const pRules = {
...rules
// plugins: plugins.concat('prettier-plugin-jsdoc'),
};
return [
{
files: GLOB_PRETTIER_LINT,
plugins: {
prettier: pluginPrettier
},
rules: {
...eslintRules,
"prettier/prettier": ["warn", pRules],
"arrow-body-style": "off",
"prefer-arrow-callback": "off"
}
}
];
}
// src/configs/react.ts
var import_local_pkg2 = require("local-pkg");
async function createReactConfig(options, overrides = {}) {
if (!options) return [];
const { files } = options;
await ensurePackages([
"eslint-plugin-react",
"eslint-plugin-react-hooks",
"eslint-plugin-react-refresh"
]);
const [pluginReact, pluginReactHooks, pluginReactRefresh] = await Promise.all([
interopDefault(import("eslint-plugin-react")),
interopDefault(import("eslint-plugin-react-hooks")),
interopDefault(import("eslint-plugin-react-refresh"))
]);
const ReactRefreshAllowConstantExportPackages = ["vite"];
const isAllowConstantExport = ReactRefreshAllowConstantExportPackages.some(
(i) => (0, import_local_pkg2.isPackageExists)(i)
);
return [
{
plugins: {
react: pluginReact,
"react-hooks": pluginReactHooks,
"react-refresh": pluginReactRefresh
},
settings: {
react: {
version: "detect"
}
}
},
{
files,
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true
}
}
},
rules: {
// recommended rules react-hooks
"react-hooks/exhaustive-deps": "warn",
"react-hooks/rules-of-hooks": "error",
// react refresh
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: isAllowConstantExport }
],
...pluginReact.configs.recommended.rules,
// react runtime
"react/react-in-jsx-scope": "off",
"react/jsx-uses-react": "off",
...overrides
}
}
];
}
// src/configs/reactNative.ts
async function createReactNativeConfig(options, overrides = {}) {
if (!options) return [];
const { files } = options;
await ensurePackages(["eslint-plugin-react-native"]);
const pluginReactNative = await interopDefault(import("eslint-plugin-react-native"));
return [
{
plugins: {
"react-native": pluginReactNative
}
},
{
files,
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
globals: {
...pluginReactNative.environments["react-native"].globals
}
},
rules: {
...pluginReactNative.configs.all.rules,
...overrides
}
}
];
}
// src/configs/solid.ts
async function createSolidConfig(options, overrides = {}) {
if (!options) return [];
const { files = [GLOB_JSX, GLOB_TSX], typescript = true } = options;
await ensurePackages(["eslint-plugin-solid"]);
const [pluginSolid, parserTs] = await Promise.all([
interopDefault(import("eslint-plugin-solid")),
interopDefault(import("@typescript-eslint/parser"))
]);
return [
{
plugins: {
solid: pluginSolid
}
},
{
files,
languageOptions: {
parser: parserTs,
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
sourceType: "module"
},
rules: {
// reactivity
"solid/components-return-once": "warn",
"solid/event-handlers": [
"error",
{
// if true, don't warn on ambiguously named event handlers like `onclick` or `onchange`
ignoreCase: false,
// if true, warn when spreading event handlers onto JSX. Enable for Solid < v1.6.
warnOnSpread: false
}
],
// these rules are mostly style suggestions
"solid/imports": "error",
// identifier usage is important
"solid/jsx-no-duplicate-props": "error",
"solid/jsx-no-script-url": "error",
"solid/jsx-no-undef": "error",
"solid/jsx-uses-vars": "error",
"solid/no-destructure": "error",
// security problems
"solid/no-innerhtml": ["error", { allowStatic: true }],
"solid/no-react-deps": "error",
"solid/no-react-specific-props": "error",
"solid/no-unknown-namespaces": "error",
"solid/prefer-for": "error",
"solid/reactivity": "warn",
"solid/self-closing-comp": "error",
"solid/style-prop": ["error", { styleProps: ["style", "css"] }],
...typescript ? {
"solid/jsx-no-undef": ["error", { typescriptEnabled: true }],
"solid/no-unknown-namespaces": "off"
} : {},
// overrides
...overrides
}
}
];
}
// src/configs/sort.ts
async function createPerfectionistConfig(overrides = {}) {
const pluginPerfectionist = await interopDefault(import("eslint-plugin-perfectionist"));
return [
{
plugins: {
perfectionist: pluginPerfectionist
},
rules: {
"perfectionist/sort-imports": [
"warn",
{
groups: [
"builtin",
"external",
"internal",
"internal-type",
"parent",
"parent-type",
"sibling",
"sibling-type",
"index",
"index-type",
"object",
"type",
"side-effect",
"side-effect-style"
],
internalPattern: ["^[~@#]/.*"],
newlinesBetween: "ignore"
}
],
"perfectionist/sort-named-exports": ["warn", { groupKind: "values-first" }],
"perfectionist/sort-named-imports": ["warn", { groupKind: "values-first" }],
...overrides
}
}
];
}
function createSortPackageJsonConfig() {
return [
{
files: ["**/package.json"],
rules: {
"jsonc/sort-array-values": [
"error",
{
order: { type: "asc" },
pathPattern: "^files$"
}
],
"jsonc/sort-keys": [
"error",
{
order: [
"name",
"version",
"type",
"private",
"packageManager",
"description",
"author",
"license",
"homepage",
"repository",
"bugs",
"keywords",
"contributors",
"funding",
"main",
"module",
"types",
"files",
"engines",
"exports",
"typesVersions",
"sideEffects",
"unpkg",
"jsdelivr",
"browser",
"bin",
"man",
"directories",
"publishConfig",
"scripts",
"peerDependencies",
"peerDependenciesMeta",
"optionalDependencies",
"dependencies",
"devDependencies",
"pnpm",
"config",
"overrides",
"husky",
"simple-git-hooks",
"lint-staged",
"eslintConfig",
"prettier"
],
pathPattern: "^$"
},
{
order: { type: "asc" },
pathPattern: "^(?:dev|peer|optional|bundled)?[Dd]ependencies(Meta)?$"
},
{
order: { type: "asc" },
pathPattern: "^(?:resolutions|overrides|pnpm.overrides)$"
},
{
order: ["types", "import", "require", "default"],
pathPattern: "^exports.*$"
},
{
order: [
// client hooks only
"pre-commit",
"prepare-commit-msg",
"commit-msg",
"post-commit",
"pre-rebase",
"post-rewrite",
"post-checkout",
"post-merge",
"pre-push",
"pre-auto-gc"
],
pathPattern: "^(?:gitHooks|husky|simple-git-hooks)$"
}
]
}
}
];
}
function createSortTsConfig() {
return [
{
files: ["**/tsconfig.json", "**/tsconfig.*.json"],
rules: {
"jsonc/sort-keys": [
"error",
{
order: ["extends", "compilerOptions", "references", "files", "include", "exclude"],
pathPattern: "^$"
},
{
order: [
/* Projects */
"incremental",
"composite",
"tsBuildInfoFile",
"disableSourceOfProjectReferenceRedirect",
"disableSolutionSearching",
"disableReferencedProjectLoad",
/* Language and Environment */
"target",
"jsx",
"jsxFactory",
"jsxFragmentFactory",
"jsxImportSource",
"lib",
"moduleDetection",
"noLib",
"reactNamespace",
"useDefineForClassFields",
"emitDecoratorMetadata",
"experimentalDecorators",
/* Modules */
"baseUrl",
"rootDir",
"rootDirs",
"customConditions",
"module",
"moduleResolution",
"moduleSuffixes",
"noResolve",
"paths",
"resolveJsonModule",
"resolvePackageJsonExports",
"resolvePackageJsonImports",
"typeRoots",
"types",
"allowArbitraryExtensions",
"allowImportingTsExtensions",
"allowUmdGlobalAccess",
/* JavaScript Support */
"allowJs",
"checkJs",
"maxNodeModuleJsDepth",
/* Type Checking */
"strict",
"strictBindCallApply",
"strictFunctionTypes",
"strictNullChecks",
"strictPropertyInitialization",
"allowUnreachableCode",
"allowUnusedLabels",
"alwaysStrict",
"exactOptionalPropertyTypes",
"noFallthroughCasesInSwitch",
"noImplicitAny",
"noImplicitOverride",
"noImplicitReturns",
"noImplicitThis",
"noPropertyAccessFromIndexSignature",
"noUncheckedIndexedAccess",
"noUnusedLocals",
"noUnusedParameters",
"useUnknownInCatchVariables",
/* Emit */
"declaration",
"declarationDir",
"declarationMap",
"downlevelIteration",
"emitBOM",
"emitDeclarationOnly",
"importHelpers",
"importsNotUsedAsValues",
"inlineSourceMap",
"inlineSources",
"mapRoot",
"newLine",
"noEmit",
"noEmitHelpers",
"noEmitOnError",
"outDir",
"outFile",
"preserveConstEnums",
"preserveValueImports",
"removeComments",
"sourceMap",
"sourceRoot",
"stripInternal",
/* Interop Constraints */
"allowSyntheticDefaultImports",
"esModuleInterop",
"forceConsistentCasingInFileNames",
"isolatedDeclarations",
"isolatedModules",
"preserveSymlinks",
"verbatimModuleSyntax",
/* Completeness */
"skipDefaultLibCheck",
"skipLibCheck"
],
pathPattern: "^compilerOptions$"
}
]
}
}
];
}
// src/configs/svelte.ts
async function createSvelteConfig(options, prettierRules2 = {}, overrides = {}) {
if (!options) return [];
const { files } = options;
await ensurePackages(["eslint-plugin-svelte", "svelte-eslint-parser", "prettier-plugin-svelte"]);
const [pluginSvelte, parserSvelte, pluginTs, pluginPrettier] = await Promise.all([
interopDefault(import("eslint-plugin-svelte")),
interopDefault(import("svelte-eslint-parser")),
interopDefault(import("@typescript-eslint/eslint-plugin")),
interopDefault(import("eslint-plugin-prettier"))
]);
const tsRules = await createTypescriptRules();
const { plugins = [] } = prettierRules2;
const pRules = {
...prettierRules2,
plugins: plugins.concat("prettier-plugin-svelte")
};
return [
{
files,
languageOptions: {
parser: parserSvelte,
parserOptions: {
extraFileExtensions: [".svelte"],
parser: "@typescript-eslint/parser",
sourceType: "module"
}
},
plugins: {
"@typescript-eslint": pluginTs,
svelte: pluginSvelte,
prettier: pluginPrettier
},
processor: pluginSvelte.processors.svelte,
rules: {
...tsRules,
...pluginSvelte.configs["flat/recommended"].reduce(
(acc, config) => ({
...acc,
...config.rules
}),
{}
),
...overrides,
"prettier/prettier": [
"warn",
{
...pRules,
parser: "svelte"
}
]
}
}
];
}
// src/configs/unicorn.ts
async function createUnicornConfig(overrides = {}) {
const pluginUnicorn = await interopDefault(import("eslint-plugin-unicorn"));
return [
{
plugins: {
unicorn: pluginUnicorn
},
rules: {
"unicorn/error-message": "error",
"unicorn/escape-case": "error",
"unicorn/no-instanceof-array": "error",
"unicorn/no-new-array": "error",
"unicorn/no-new-buffer": "error",
"unicorn/number-literal-case": "error",
"unicorn/prefer-dom-node-text-content": "error",
"unicorn/prefer-includes": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-number-properties": "error",
"unicorn/prefer-string-starts-ends-with": "error",
"unicorn/prefer-type-error": "error",
"unicorn/throw-new-error": "error",
...overrides
}
}
];
}
// src/configs/unocss.ts
async function createUnoCssConfig(enable, overrides = {}) {
if (!enable) return [];
await ensurePackages(["@unocss/eslint-plugin"]);
const pluginUnoCSS = await interopDefault(interopDefault(import("@unocss/eslint-plugin")));
return [
{
plugins: {
unocss: pluginUnoCSS
},
rules: {
"unocss/order": "warn",
"unocss/order-attributify": "off",
"unocss/blocklist": "off",
...overrides
}
}
];
}
// src/configs/vue.ts
async function createVueConfig(options, overrides = {}) {
if (!options) return [];
const { version = 3, files } = options;
await ensurePackages(["eslint-plugin-vue", "vue-eslint-parser"]);
const [pluginVue, parserVue, pluginTs] = await Promise.all([
interopDefault(import("eslint-plugin-vue")),
interopDefault(import("vue-eslint-parser")),
interopDefault(import("@typescript-eslint/eslint-plugin"))
]);
const tsRules = await createTypescriptRules();
const configKeys = version === 3 ? ["essential", "strongly-recommended", "recommended"] : ["vue2-essential", "vue2-strongly-recommended", "vue2-recommended"];
const vueRules = configKeys.reduce((preRules, key) => {
const config = pluginVue.configs[key];
return {
...preRules,
...config.rules
};
}, {});
return [
{
plugins: {
vue: pluginVue
}
},
{
files,
languageOptions: {
parser: parserVue,
parserOptions: {
ecmaFeatures: {
jsx: true
},
extraFileExtensions: [".vue"],
parser: "@typescript-eslint/parser",
sourceType: "module"
}
},
processor: pluginVue.processors[".vue"],
plugins: {
"@typescript-eslint": pluginTs
},
rules: {
...tsRules,
...pluginVue.configs.base.rules,
...vueRules,
"vue/block-order": ["warn", { order: ["template", "script", "style"] }],
"vue/component-api-style": ["warn", ["script-setup", "composition"]],
"vue/component-name-in-template-casing": [
"warn",
"PascalCase",
{ registeredComponentsOnly: false, ignores: [] }
],
"vue/component-options-name-casing": ["warn", "PascalCase"],
"vue/custom-event-name-casing": ["warn", "camelCase"],
"vue/define-emits-declaration": ["warn", "type-based"],
"vue/define-macros-order": "off",
"vue/define-props-declaration": ["warn", "type-based"],
"vue/html-comment-content-newline": "warn",
"vue/multi-word-component-names": "warn",
"vue/next-tick-style": ["warn", "promise"],
"vue/no-duplicate-attr-inheritance": "warn",
"vue/no-required-prop-with-default": "warn",
"vue/no-static-inline-styles": "warn",
"vue/no-template-target-blank": "error",
"vue/no-this-in-before-route-enter": "error",
"vue/no-undef-properties": "warn",
"vue/no-unsupported-features": "warn",
"vue/no-unused-emit-declarations": "warn",
"vue/no-unused-properties": "warn",
"vue/no-unused-refs": "warn",
"vue/no-use-v-else-with-v-for": "error",
"vue/no-useless-mustaches": "warn",
"vue/no-useless-v-bind": "error",
"vue/no-v-text": "warn",
"vue/padding-line-between-blocks": "warn",
"vue/prefer-define-options": "warn",
"vue/prefer-separate-static-class": "warn",
"vue/prop-name-casing": ["warn", "camelCase"],
"vue/require-macro-variable-name": [
"warn",
{
defineProps: "props",
defineEmits: "emit",
defineSlots: "slots",
useSlots: "slots",
useAttrs: "attrs"
}
],
"vue/valid-define-options": "warn",
...overrides
}
}
];
}
// src/utils/options.ts
var import_node_process2 = __toESM(require("process"), 1);
async function createOptions(options = {}) {
const opts = {
cwd: import_node_process2.default.cwd(),
ignores: GLOB_EXCLUDE,
gitignore: true,
overrides: {},
prettierRules: {
...DEFAULT_PRETTIER_RULES
},
usePrettierrc: true,
formatter: {
html: true,
css: true
}
};
const {
cwd,
ignores,
gitignore,
overrides,
prettierRules: prettierRules2,
usePrettierrc,
formatter,
unocss,
...rest
} = options;
if (cwd) {
opts.cwd = cwd;
}
if (ignores?.length) {
opts.ignores = [...opts.ignores, ...ignores];
}
if (gitignore) {
opts.gitignore = gitignore;
}
if (overrides) {
opts.overrides = overrides;
}
if (prettierRules2) {
opts.prettierRules = { ...opts.prettierRules, ...prettierRules2 };
}
if (usePrettierrc !== void 0) {
opts.usePrettierrc = usePrettierrc;
}
if (opts.usePrettierrc) {
const prettierConfig = await loadPrettierConfig(opts.cwd);
Object.assign(opts.prettierRules, prettierConfig);
}
if (formatter) {
Object.assign(opts.formatter, formatter);
}
const onDemandKeys = [
"vue",
"react",
"react-native",
"solid",
"svelte",
"astro"
];
const onDemandFiles = {
vue: [GLOB_VUE],
react: [GLOB_JSX, GLOB_TSX],
"react-native": [GLOB_JSX, GLOB_TSX],
solid: [GLOB_JSX, GLOB_TSX],
svelte: [GLOB_SVELTE],
astro: [GLOB_ASTRO]
};
onDemandKeys.forEach((key) => {
if (key === "vue") {
opts[key] = createItemDemandOptions(
key,
rest[key],
onDemandFiles[key]
);
} else {
opts[key] = createItemDemandOptions(key, rest[key], onDemandFiles[key]);
}
});
if (rest["react-native"] && !rest.react) {
opts.react = createItemDemandOptions("react", true, onDemandFiles.react);
}
opts.unocss = Boolean(unocss);
return opts;
}
function createItemDemandOptions(key, options, files) {
if (!options) return void 0;
if (key === "vue") {
const vueOptions = {
version: 3,
files
};
if (typeof options === "object") {
Object.assign(vueOptions, options);
}
return vueOptions;
}
const itemOptions = {
files
};
if (typeof options === "object") {
Object.assign(itemOptions, options);
}
return itemOptions;
}
// src/index.ts
async function defineConfig(options = {}, ...userConfigs) {
const {
gitignore: enableGitignore = true,
usePrettierrc: enablePrettier = true,
astro: enableAstro = false,
react: enableReact = false,
"react-native": enableReactNative = false,
solid: enableSolid = false,
svelte: enableSvelte = false,
unocss: enableUnoCSS = false,
vue: enableVue = false
} = options;
const opts = await createOptions(options);
const overrideRecord = getOverridesRules(opts.overrides);
const configs = [];
if (enableGitignore) {
configs.push(createGitIgnoresConfig(opts.gitignore));
}
configs.push(
createIgnoresConfig(opts.ignores),
createJavascriptConfig(overrideRecord.js),
createNodeConfig(overrideRecord.n),
createJsdocConfig(overrideRecord.jsdoc),
createImportsConfig(overrideRecord.import),
createPerfectionistConfig(overrideRecord.perfectionist),
createUnicornConfig(overrideRecord.unicorn),
createTypescriptConfig(overrideRecord.ts)
);
if (enableVue) {
configs.push(createVueConfig(opts.vue, overrideRecord.vue));
}
if (enableReact) {
configs.push(createReactConfig(opts.react, overrideRecord.react));
}
if (enableReactNative) {
configs.push(createReactNativeConfig(opts["react-native"], overrideRecord["react-native"]));
}
if (enableSolid) {
configs.push(createSolidConfig(opts.solid, overrideRecord.solid));
}
if (enableSvelte) {
configs.push(createSvelteConfig(opts.svelte, opts.prettierRules, overrideRecord.svelte));
}
if (enableUnoCSS) {
configs.push(createUnoCssConfig(opts.unocss, overrideRecord.unocss));
}
if (enableAstro) {
configs.push(createAstroConfig(opts.astro, opts.prettierRules, overrideRecord.astro));
}
configs.push(
createJsoncConfig(overrideRecord.jsonc),
createSortPackageJsonConfig(),
createSortTsConfig()
);
configs.push(createDisablesConfig());
if (enablePrettier) {
configs.push(createPrettierConfig(opts.prettierRules));
}
configs.push(createFormatterConfig(opts.formatter, opts.prettierRules));
let composer = new import_eslint_flat_config_utils.FlatConfigComposer();
composer = composer.append(...configs, ...userConfigs);
return composer;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
defineConfig
});