@aurracloud/mcp-cli
Version:
A command-line tool to install, manage, and setup MCP (Model Context Protocol) servers with Docker support
126 lines • 4.61 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkPackageExistence = checkPackageExistence;
exports.isNpxExecutable = isNpxExecutable;
exports.getNpxCommand = getNpxCommand;
const node_fetch_1 = __importDefault(require("node-fetch"));
const logger_1 = require("./utils/logger");
/**
* Checks if a package exists on npm registry and whether it's executable
*
* @param packageName - The name of the package to check
* @returns Promise resolving to package existence and executability information
*/
async function checkPackageExistence(packageName) {
try {
const response = await (0, node_fetch_1.default)(`https://registry.npmjs.org/${packageName}`);
if (!response.ok) {
// If response status is 404, package doesn't exist
if (response.status === 404) {
return {
exists: false,
isExecutable: false
};
}
// For other errors, throw
const errorText = await response.text();
throw new Error(`Failed to check package existence: ${response.status} ${response.statusText} - ${errorText}`);
}
const data = await response.json();
// Get the latest version
const latestVersion = data['dist-tags']?.latest;
if (!latestVersion) {
return {
exists: true,
isExecutable: false,
packageInfo: data
};
}
// Get package information for the latest version
const packageInfo = data.versions[latestVersion];
// Check if the package is executable (has bin field or "start" script)
const isExecutable = Boolean(packageInfo.bin) || Boolean(packageInfo.scripts && 'start' in packageInfo.scripts);
// Determine executable name and path if it's executable
let executableName;
let executablePath;
if (packageInfo.bin) {
if (typeof packageInfo.bin === 'string') {
executableName = packageInfo.name;
executablePath = packageInfo.bin;
}
else {
// If bin is an object, use the first key as executable name
const binEntries = Object.entries(packageInfo.bin);
if (binEntries.length > 0) {
executableName = binEntries[0][0];
executablePath = binEntries[0][1];
}
}
}
else if (packageInfo.scripts && packageInfo.scripts.start) {
executableName = 'start';
executablePath = packageInfo.scripts.start;
}
return {
exists: true,
isExecutable,
packageInfo,
executableName,
executablePath
};
}
catch (error) {
logger_1.logger.error(`Error checking package existence for ${packageName}`, error);
throw error;
}
}
/**
* Verifies if a package can be installed and executed via npx
*
* @param packageName - The name of the package to verify
* @returns Promise resolving to a boolean indicating if the package is npx-executable
*/
async function isNpxExecutable(packageName) {
try {
const result = await checkPackageExistence(packageName);
if (!result.exists) {
logger_1.logger.warn(`Package ${packageName} does not exist on npm registry`);
return false;
}
if (!result.isExecutable) {
logger_1.logger.warn(`Package ${packageName} exists but is not executable`);
return false;
}
return true;
}
catch (error) {
logger_1.logger.error(`Error checking if ${packageName} is npx-executable`, error);
return false;
}
}
/**
* Gets the recommended npx command to run a package
*
* @param packageName - The name of the package to run
* @returns Promise resolving to command and arguments, or null if not executable
*/
async function getNpxCommand(packageName) {
try {
const isExecutable = await isNpxExecutable(packageName);
if (!isExecutable) {
return null;
}
return {
command: 'npx',
args: ['-y', packageName]
};
}
catch (error) {
logger_1.logger.error(`Error getting npx command for ${packageName}`, error);
return null;
}
}
//# sourceMappingURL=npm.js.map