@bfra.me/eslint-config
Version:
Shared ESLint configuration for bfra.me
147 lines (144 loc) • 4.36 kB
JavaScript
import {createRequire} from 'node:module';const require=createRequire(import.meta.url);
// src/rules/missing-module-for-config.ts
import { Linter } from "eslint";
// src/package-utils.ts
import { spawnSync } from "child_process";
import { existsSync } from "fs";
import { resolve } from "path";
import process from "process";
import { packageDirectorySync } from "package-directory";
import { resolveCommand } from "package-manager-detector";
var installedModules = /* @__PURE__ */ new Set();
function tryInstall(module, targetFile = process.cwd()) {
if (installedModules.has(module)) {
return null;
}
const cwd = packageDirectorySync({ cwd: targetFile }) ?? "";
if (cwd) {
installedModules.add(module);
const { moduleName, version = "" } = parseModule(module);
const result = installPackageSync(moduleName + (version ? `@^${version}` : ""), {
cwd,
dev: true
});
return result;
}
return null;
}
function getPackageInstallCommand(module, targetFile = process.cwd()) {
const cwd = packageDirectorySync({ cwd: targetFile }) ?? "";
if (!cwd) {
return null;
}
const agent = detectPackageManagerSync(cwd);
if (!agent) {
return null;
}
const command = resolveCommand(agent, "install", ["-D", module]);
return command ? `${command.command} ${command.args.join(" ")}` : null;
}
function parseModule(name) {
const parts = name.split(/@/u);
if (parts.length > 1 && parts.slice(0, -1).join("@")) {
return {
moduleName: parts.slice(0, -1).join("@"),
version: parts.at(-1)
};
}
return { moduleName: name };
}
function installPackageSync(packages, options) {
const manager = (detectPackageManagerSync(options.cwd)?.split("@")[0] ?? "") || "npm";
if (!Array.isArray(packages)) {
packages = [packages];
}
const args = [];
if (manager === "pnpm" && existsSync(resolve(options.cwd ?? process.cwd(), "pnpm-workspace.yaml"))) {
args.unshift(
"-w",
/**
* Prevent pnpm from removing installed development deps when `NODE_ENV` is `production`
* @see https://pnpm.io/cli/install#--prod--p
*/
"--prod=false"
);
}
const result = spawnSync(
manager,
[manager === "yarn" ? "add" : "install", options.dev ? "-D" : "", ...args, ...packages].filter(
Boolean
),
{ cwd: options.cwd, maxBuffer: Infinity, stdio: "inherit", windowsHide: true }
);
if (result.error || result.status !== 0) {
const errorMessage = (result.error?.message ?? "") || `Package installation failed with status ${result.status}`;
throw new Error(errorMessage);
}
return `${result.output?.toString() ?? ""}`;
}
function detectPackageManagerSync(cwd = process.cwd()) {
try {
if (existsSync(resolve(cwd, "package-lock.json"))) {
return "npm";
}
if (existsSync(resolve(cwd, "yarn.lock"))) {
return "yarn";
}
if (existsSync(resolve(cwd, "pnpm-lock.yaml"))) {
return "pnpm";
}
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 create(context) {
const [modules] = context.options;
for (const module of modules) {
let output = "";
if (shouldFix) {
const result = tryInstall(module, context.filename || context.getFilename()) ?? "";
output = result ? `
${result}` : "";
}
const command = getPackageInstallCommand(module, context.filename || context.getFilename()) ?? "";
context.report({
loc: { column: 0, line: 1 },
message: `Missing module for config: ${module}. Run: \`${command || `npm i -D ${module}`}\`${output}`
});
}
return {};
}
export {
create,
meta
};
//# sourceMappingURL=missing-module-for-config-YSY2AGPQ.js.map