@bfra.me/eslint-config
Version:
Shared ESLint configuration for bfra.me
191 lines (188 loc) • 5.99 kB
JavaScript
import "./chunk-EGRHWZRV.js";
// src/rules/missing-module-for-config.ts
import { Linter } from "eslint";
// src/package-utils.ts
import { spawnSync } from "child_process";
import fs from "fs";
import path from "path";
import { AGENTS, LOCKS, resolveCommand } from "package-manager-detector";
var installedModules = /* @__PURE__ */ new Set();
function tryInstall(module, targetFile) {
if (installedModules.has(module)) {
return null;
}
const { moduleName, version } = parseModule(module);
const packageId = version === void 0 ? moduleName : `${moduleName}@^${version}`;
try {
installPackageSync(packageId, {
cwd: path.dirname(targetFile),
dev: true
});
installedModules.add(module);
return { success: true };
} catch (error) {
installedModules.add(module);
const errorMessage = error instanceof Error ? error.message : String(error);
return { output: errorMessage, success: false };
}
}
function getPackageInstallCommand(module, targetFile) {
try {
const { args, command } = resolvePackageInstallCommand(module, path.dirname(targetFile));
return `${command} ${args.join(" ")}`;
} catch {
return null;
}
}
function parseModule(name) {
const parts = name.split(/@/u);
const hasVersion = parts.length > 1 && parts.slice(0, -1).join("@").length > 0;
if (hasVersion) {
return {
moduleName: parts.slice(0, -1).join("@"),
version: parts.at(-1)
};
}
return { moduleName: name };
}
function resolvePackageInstallCommand(module, cwd) {
const agent = detectPackageManagerSync(cwd);
if (agent == null) {
throw new Error(`Unable to detect package manager for cwd: ${cwd}`);
}
const args = [];
if (agent === "pnpm" && fs.existsSync(path.resolve(cwd, "pnpm-workspace.yaml"))) {
args.unshift(
"-w",
// Prevent pnpm from removing installed development deps when NODE_ENV is production
"--prod=false"
);
}
const command = resolveCommand(agent, "add", [...args, "-D", module]);
if (command == null) {
throw new Error(`Unable to resolve command for package manager: ${agent}`);
}
return command;
}
function installPackageSync(packageId, options) {
const { args, command } = resolvePackageInstallCommand(packageId, options.cwd);
const result = spawnSync(command, args.filter(Boolean), {
cwd: options.cwd,
maxBuffer: Infinity,
stdio: "inherit",
windowsHide: true
});
if (result.error != null || result.status !== 0) {
const errorMessage = result.error?.message ?? `Package installation failed with status ${result.status}`;
throw new Error(errorMessage);
}
return result.output?.toString() ?? "";
}
function isAgentName(name) {
return AGENTS.includes(name);
}
function getPackageManagerFromPackageJson(cwd) {
try {
const packageJsonPath = path.join(cwd, "package.json");
if (!fs.existsSync(packageJsonPath)) {
return null;
}
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
if (typeof packageJson.packageManager === "string") {
const [name] = packageJson.packageManager.split("@");
return name != null && isAgentName(name) ? name : null;
}
const devEngines = packageJson.devEngines;
if (devEngines != null && typeof devEngines === "object" && "packageManager" in devEngines) {
const pkgManager = devEngines.packageManager;
if (pkgManager != null && typeof pkgManager === "object" && "name" in pkgManager && typeof pkgManager.name === "string") {
return isAgentName(pkgManager.name) ? pkgManager.name : null;
}
}
return null;
} catch {
return null;
}
}
function detectPackageManagerSync(cwd) {
try {
let directory = path.resolve(cwd);
const { root } = path.parse(directory);
while (directory && directory !== root) {
for (const [lockfile, agent] of Object.entries(LOCKS)) {
if (fs.existsSync(path.resolve(directory, lockfile))) {
return getPackageManagerFromPackageJson(directory) ?? agent;
}
}
const pkgManager = getPackageManagerFromPackageJson(directory);
if (pkgManager != null) {
return pkgManager;
}
directory = path.dirname(directory);
}
return null;
} catch {
return null;
}
}
// src/rules/missing-module-for-config.ts
var shouldFix = false;
(function patch() {
const { verify } = Linter.prototype;
Object.defineProperty(Linter.prototype, "verify", {
configurable: true,
value(...args) {
const options = args[2];
shouldFix = typeof options === "object" && options !== null && "fix" in options && Boolean(options.fix);
return verify.call(this, ...args);
},
writable: true
});
})();
var meta = {
docs: {
description: "Missing module for config",
url: "https://github.com/bfra-me/works"
},
fixable: "code",
schema: [
{
items: { type: "string" },
type: "array"
}
],
type: "problem"
};
function buildInstallMessage(module, filename, errorOutput) {
const command = getPackageInstallCommand(module, filename) ?? `npm i -D ${module}`;
const suffix = errorOutput == null ? "" : `
${errorOutput}`;
return `Missing module for config: ${module}. Run: \`${command}\`${suffix}`;
}
function create(context) {
const [modules] = context.options;
for (const module of modules) {
if (shouldFix) {
const result = tryInstall(module, context.filename);
if (result?.success === true) {
continue;
}
const errorOutput = result?.success === false ? result.output : void 0;
context.report({
loc: { column: 0, line: 1 },
message: buildInstallMessage(module, context.filename, errorOutput)
});
} else {
context.report({
loc: { column: 0, line: 1 },
message: buildInstallMessage(module, context.filename)
});
}
}
return {};
}
export {
create,
meta
};
//# sourceMappingURL=missing-module-for-config-XLDTAVYJ.js.map