UNPKG

@visulima/package

Version:

One Package to rule them all, finds your root-dir, monorepo, or package manager.

171 lines (166 loc) 6.07 kB
import { execSync } from 'node:child_process'; import { existsSync, readFileSync } from 'node:fs'; import { findUp, findUpSync } from '@visulima/fs'; import { NotFoundError } from '@visulima/fs/error'; import { join, dirname } from '@visulima/path'; import { parsePackageJson } from './package-json.mjs'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); const lockFileNames = ["yarn.lock", "package-lock.json", "pnpm-lock.yaml", "npm-shrinkwrap.json", "bun.lockb"]; const packageMangerFindUpMatcher = /* @__PURE__ */ __name((directory) => { let lockFile; lockFileNames.forEach((lockFileName) => { if (!lockFile && existsSync(join(directory, lockFileName))) { lockFile = join(directory, lockFileName); } }); if (lockFile) { return lockFile; } const packageJsonFilePath = join(directory, "package.json"); if (existsSync(packageJsonFilePath)) { const packageJson = parsePackageJson(readFileSync(packageJsonFilePath, "utf8")); if (packageJson.packageManager !== void 0) { return packageJsonFilePath; } } return void 0; }, "packageMangerFindUpMatcher"); const findPackageManagerOnFile = /* @__PURE__ */ __name((foundFile) => { if (!foundFile) { throw new NotFoundError("Could not find a package manager"); } if (foundFile.endsWith("package.json")) { const packageJson = parsePackageJson(foundFile); if (packageJson.packageManager) { const packageManagerNames = ["npm", "yarn", "pnpm", "bun"]; const foundPackageManager = packageManagerNames.find((prefix) => packageJson.packageManager.startsWith(prefix)); if (foundPackageManager) { return { packageManager: foundPackageManager, path: dirname(foundFile) }; } } } if (foundFile.endsWith("yarn.lock")) { return { packageManager: "yarn", path: dirname(foundFile) }; } if (foundFile.endsWith("package-lock.json") || foundFile.endsWith("npm-shrinkwrap.json")) { return { packageManager: "npm", path: dirname(foundFile) }; } if (foundFile.endsWith("pnpm-lock.yaml")) { return { packageManager: "pnpm", path: dirname(foundFile) }; } if (foundFile.endsWith("bun.lockb")) { return { packageManager: "bun", path: dirname(foundFile) }; } throw new NotFoundError("Could not find a package manager"); }, "findPackageManagerOnFile"); const findLockFile = /* @__PURE__ */ __name(async (cwd) => { const filePath = await findUp(lockFileNames, { type: "file", ...cwd && { cwd } }); if (!filePath) { throw new Error("Could not find lock file"); } return filePath; }, "findLockFile"); const findLockFileSync = /* @__PURE__ */ __name((cwd) => { const filePath = findUpSync(lockFileNames, { type: "file", ...cwd && { cwd } }); if (!filePath) { throw new Error("Could not find lock file"); } return filePath; }, "findLockFileSync"); const findPackageManager = /* @__PURE__ */ __name(async (cwd) => { const foundFile = await findUp(packageMangerFindUpMatcher, { ...cwd && { cwd } }); return findPackageManagerOnFile(foundFile); }, "findPackageManager"); const findPackageManagerSync = /* @__PURE__ */ __name((cwd) => { const foundFile = findUpSync(packageMangerFindUpMatcher, { ...cwd && { cwd } }); return findPackageManagerOnFile(foundFile); }, "findPackageManagerSync"); const getPackageManagerVersion = /* @__PURE__ */ __name((name) => execSync(`${name} --version`).toString("utf8").trim(), "getPackageManagerVersion"); const identifyInitiatingPackageManager = /* @__PURE__ */ __name(async () => { if (!process.env.npm_config_user_agent) { return void 0; } const pmSpec = process.env.npm_config_user_agent.split(" ")[0]; const separatorPos = pmSpec.lastIndexOf("/"); const name = pmSpec.slice(0, Math.max(0, separatorPos)); return { name: name === "npminstall" ? "cnpm" : name, version: pmSpec.slice(Math.max(0, separatorPos + 1)) }; }, "identifyInitiatingPackageManager"); const generateMissingPackagesInstallMessage = /* @__PURE__ */ __name((packageName, missingPackages, options) => { const s = missingPackages.length === 1 ? "" : "s"; if (options.packageManagers === void 0) { options.packageManagers = ["npm", "pnpm", "yarn"]; } if (options.packageManagers.length === 0) { throw new Error("No package managers provided, please provide at least one package manager"); } if (missingPackages.length === 0) { throw new Error("No missing packages provided, please provide at least one missing package"); } let message = ` ${options.preMessage ?? ""} ${packageName} could not find the following package${s} ${missingPackages.join("\n ")} To install the missing package${s}, please run the following command: `; const atLatest = /* @__PURE__ */ __name((name) => { if (!name.split("@").includes("@")) { return `${name}@latest`; } return name; }, "atLatest"); const packageManagerCommands = options.packageManagers.map((packageManager) => { const missingPackagesString = missingPackages.map((element) => atLatest(element)).join(" "); switch (packageManager) { case "bun": { return ` bun add ${missingPackagesString} -D`; } case "npm": { return ` npm install ${missingPackagesString} --save-dev`; } case "pnpm": { return ` pnpm add ${missingPackagesString} -D`; } case "yarn": { return ` yarn add ${missingPackagesString} --dev`; } default: { throw new Error("Unknown package manager"); } } }); message += packageManagerCommands.join("\n\nor\n\n"); if (options.postMessage) { message += options.postMessage; } return message; }, "generateMissingPackagesInstallMessage"); export { findLockFile, findLockFileSync, findPackageManager, findPackageManagerSync, generateMissingPackagesInstallMessage, getPackageManagerVersion, identifyInitiatingPackageManager };