UNPKG

@bfra.me/eslint-config

Version:
191 lines (188 loc) 5.99 kB
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