Files
heroui-inc--heroui/lint-staged.config.mjs
2026-07-13 12:12:33 +08:00

99 lines
2.8 KiB
JavaScript

import fs from "fs";
import {dirname, relative, resolve} from "path";
import {ESLint} from "eslint";
const projectRoot = process.cwd();
// Eslint mode: "Experimental" | "Legacy"
const LINT_MODE = "Experimental";
const removeIgnoredFilesNew = async (files) => {
try {
const eslint = new ESLint();
const cwd = process.cwd();
const relativePaths = files.map((file) => relative(cwd, file));
const isIgnored = await Promise.all(relativePaths.map((file) => eslint.isPathIgnored(file)));
return files.filter((_, i) => !isIgnored[i]).join(" ");
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
process.exit(1);
}
};
function findPackageRoot(file) {
let dir = dirname(file);
while (dir !== "/") {
if (fs.existsSync(`${dir}/package.json`)) return dir;
const parentDir = dirname(dir);
if (parentDir === dir) break;
dir = parentDir;
}
return projectRoot;
}
async function removeIgnoredFilesLegacy(files, eslint) {
const isIgnored = await Promise.all(files.map((file) => eslint.isPathIgnored(file)));
return files.filter((_, i) => !isIgnored[i]);
}
const lintStaged = {
"**/*.{cjs,mjs,js,ts,jsx,tsx}": async (files) => {
if (LINT_MODE === "Experimental") {
// use ESLint with experimental configuration file resolution
const filesToLint = await removeIgnoredFilesNew(files);
return [
`eslint --flag v10_config_lookup_from_file --max-warnings=0 --no-warn-ignored --fix ${filesToLint}`,
];
}
if (LINT_MODE === "Legacy") {
// Legacy with group files by package root and resolve ESLint config
const filesByPackage = new Map();
for (const file of files) {
const pkgRoot = findPackageRoot(file);
if (!filesByPackage.has(pkgRoot)) filesByPackage.set(pkgRoot, []);
filesByPackage.get(pkgRoot).push(file);
}
const commands = [];
for (const [pkgRoot, pkgFiles] of filesByPackage.entries()) {
// Check if the package has its own eslint.config.mjs
const configPath = fs.existsSync(resolve(pkgRoot, "eslint.config.mjs"))
? resolve(pkgRoot, "eslint.config.mjs")
: resolve(projectRoot, "eslint.config.mjs");
const eslint = new ESLint({cwd: pkgRoot, overrideConfigFile: configPath});
const filesToLint = await removeIgnoredFilesLegacy(pkgFiles, eslint);
if (filesToLint.length) {
commands.push(
`eslint --config ${configPath} --max-warnings=0 --fix ${filesToLint.join(" ")}`,
);
}
}
return commands;
}
return [];
},
"**/*.{html,css,scss,json,jsonc,md,mdx}": async (files) => {
return [`prettier --ignore-path .prettierignore --write ${files.join(" ")}`];
},
};
export default lintStaged;