chrome-cmd
Version:
Control Chrome from the command line - List tabs, execute JavaScript, and more
171 lines (170 loc) • 5.81 kB
JavaScript
import { Command } from "commander";
import { CLI_NAME } from "../../shared/constants/constants.js";
import { APP_INFO } from "../../shared/constants/constants-node.js";
import { logger } from "../../shared/utils/helpers/logger.js";
import { PathHelper } from "../../shared/utils/helpers/path.helper.js";
import { detectShell, getShellRestartCommand } from "../../shared/utils/helpers/shell-utils.js";
import { CommandNames } from "../schemas/definitions.js";
import { createCommandFromSchema } from "../schemas/utils.js";
import { execAsync } from "../utils/cli-utils.js";
import { reinstallCompletionSilently } from "./completion/utils.js";
function createUpdateCommand() {
return createCommandFromSchema(CommandNames.UPDATE).action(async () => {
try {
logger.blue("Checking current version...");
const currentVersion = APP_INFO.version;
logger.blue("Checking latest version...");
const latestVersion = await getLatestVersion();
if (!latestVersion) {
logger.error("Could not fetch latest version from npm");
return;
}
logger.info(`\u{1F4E6} Current version: ${currentVersion}`);
logger.info(`\u{1F4E6} Latest version: ${latestVersion}`);
if (currentVersion === latestVersion) {
logger.success(`\u2705 ${CLI_NAME} is already up to date!`);
return;
}
logger.blue("Detecting package manager...");
const packageManager = await detectPackageManager();
if (!packageManager) {
logger.error(`Could not detect how ${CLI_NAME} was installed`);
logger.dim("Please update manually using your package manager");
return;
}
logger.info(`\u{1F4E6} Detected package manager: ${packageManager}`);
logger.blue(`Updating ${CLI_NAME} from ${currentVersion} to ${latestVersion}...`);
const updateCommand = getUpdateCommand(packageManager);
const { stdout, stderr } = await execAsync(updateCommand);
if (stderr && !stderr.includes("npm WARN")) {
logger.error(`Error updating: ${stderr}`);
return;
}
logger.success(`\u2705 ${CLI_NAME} updated successfully from ${currentVersion} to ${latestVersion}!`);
if (stdout) {
logger.dim(stdout);
}
if (!PathHelper.isWindows()) {
const completionReinstalled = await reinstallCompletionSilently();
if (completionReinstalled) {
const shell = detectShell();
logger.newline();
logger.success("\u2728 Shell completion updated");
logger.newline();
logger.warning("\u26A0\uFE0F To apply completion changes, run:");
const command = getShellRestartCommand(shell);
if (command.includes("exec")) {
logger.cyan(` ${command}`);
logger.newline();
logger.dim(" Or restart your terminal");
} else {
logger.cyan(` ${command}`);
}
}
}
} catch (error) {
logger.error("Error updating:", error);
}
});
}
async function detectPackageManager() {
const execPath = await getExecutablePath();
if (execPath) {
const manager = detectManagerFromPath(execPath);
if (manager) {
return manager;
}
}
const nullRedirect = PathHelper.isWindows() ? "2>nul" : "2>/dev/null";
const npmCheckCmd = `npm list -g --depth=0 ${CLI_NAME} ${nullRedirect}`;
try {
const { stdout } = await execAsync(npmCheckCmd);
if (stdout.includes(CLI_NAME)) {
return "npm";
}
} catch {
}
const managers = ["pnpm", "yarn"];
for (const manager of managers) {
const checkCmd = `${manager} list -g ${CLI_NAME} ${nullRedirect}`;
try {
const { stdout } = await execAsync(checkCmd);
if (stdout.includes(CLI_NAME)) {
return manager;
}
} catch {
}
}
return null;
}
async function getExecutablePath() {
const isWindows = PathHelper.isWindows();
const isMac = PathHelper.isMac();
try {
const whereCommand = isWindows ? "where" : "which";
const { stdout } = await execAsync(`${whereCommand} ${CLI_NAME}`);
const execPath = stdout.trim().split("\n")[0].trim();
if (!execPath) {
return null;
}
if (!isWindows) {
try {
if (isMac) {
try {
const { stdout: linkedPath } = await execAsync(`readlink "${execPath}"`);
if (linkedPath.trim()) {
return linkedPath.trim();
}
} catch {
return execPath;
}
} else {
const { stdout: realPath } = await execAsync(`readlink -f "${execPath}"`);
return realPath.trim() || execPath;
}
} catch {
return execPath;
}
}
return execPath;
} catch {
return null;
}
}
function detectManagerFromPath(path) {
const normalizedPath = path.replace(/\\/g, "/").toLowerCase();
const patterns = [
{ manager: "pnpm", patterns: ["/pnpm/", "/.pnpm/"] },
{ manager: "yarn", patterns: ["/yarn/", "/.yarn/"] },
{ manager: "npm", patterns: ["/npm/", "/node_modules/", "/node/"] }
];
for (const { manager, patterns: managerPatterns } of patterns) {
if (managerPatterns.some((pattern) => normalizedPath.includes(pattern))) {
return manager;
}
}
return "npm";
}
async function getLatestVersion() {
try {
const { stdout } = await execAsync(`npm view ${CLI_NAME} version`);
return stdout.trim();
} catch {
return null;
}
}
function getUpdateCommand(packageManager) {
switch (packageManager) {
case "npm":
return `npm update -g ${CLI_NAME}`;
case "yarn":
return `yarn global upgrade ${CLI_NAME}`;
case "pnpm":
return `pnpm update -g ${CLI_NAME}`;
default:
return `npm update -g ${CLI_NAME}`;
}
}
export {
createUpdateCommand
};