ultimate-mcp-server
Version:
The definitive all-in-one Model Context Protocol server for AI-assisted coding across 30+ platforms
403 lines • 11 kB
JavaScript
/**
* Platform Utilities
*
* Cross-platform compatibility helpers for Ultimate MCP
*/
import * as path from 'path';
import * as os from 'os';
import { promises as fs } from 'fs';
import { exec as execCallback, spawn } from 'child_process';
import { promisify } from 'util';
const exec = promisify(execCallback);
export var Platform;
(function (Platform) {
Platform["WINDOWS"] = "win32";
Platform["MAC"] = "darwin";
Platform["LINUX"] = "linux";
Platform["UNKNOWN"] = "unknown";
})(Platform || (Platform = {}));
/**
* Get current platform
*/
export function getPlatform() {
const platform = os.platform();
switch (platform) {
case 'win32':
return Platform.WINDOWS;
case 'darwin':
return Platform.MAC;
case 'linux':
return Platform.LINUX;
default:
return Platform.UNKNOWN;
}
}
/**
* Check if running on Windows
*/
export function isWindows() {
return getPlatform() === Platform.WINDOWS;
}
/**
* Check if running on Mac
*/
export function isMac() {
return getPlatform() === Platform.MAC;
}
/**
* Check if running on Linux
*/
export function isLinux() {
return getPlatform() === Platform.LINUX;
}
/**
* Get platform-specific path separator
*/
export function getPathSeparator() {
return path.sep;
}
/**
* Join paths in a cross-platform way
*/
export function joinPath(...paths) {
return path.join(...paths);
}
/**
* Normalize path for current platform
*/
export function normalizePath(inputPath) {
// Replace all forward slashes and backslashes with the platform separator
return inputPath.split(/[/\\]/).join(path.sep);
}
/**
* Convert to platform-specific absolute path
*/
export function toAbsolutePath(inputPath) {
if (path.isAbsolute(inputPath)) {
return normalizePath(inputPath);
}
return path.resolve(inputPath);
}
/**
* Get platform-specific temp directory
*/
export function getTempDir() {
return os.tmpdir();
}
/**
* Get platform-specific home directory
*/
export function getHomeDir() {
return os.homedir();
}
/**
* Get platform-specific config directory
*/
export function getConfigDir(appName = 'ultimate-mcp') {
const platform = getPlatform();
const home = getHomeDir();
switch (platform) {
case Platform.WINDOWS:
return joinPath(process.env.APPDATA || joinPath(home, 'AppData', 'Roaming'), appName);
case Platform.MAC:
return joinPath(home, 'Library', 'Application Support', appName);
case Platform.LINUX:
return joinPath(process.env.XDG_CONFIG_HOME || joinPath(home, '.config'), appName);
default:
return joinPath(home, `.${appName}`);
}
}
/**
* Get platform-specific data directory
*/
export function getDataDir(appName = 'ultimate-mcp') {
const platform = getPlatform();
const home = getHomeDir();
switch (platform) {
case Platform.WINDOWS:
return joinPath(process.env.LOCALAPPDATA || joinPath(home, 'AppData', 'Local'), appName);
case Platform.MAC:
return joinPath(home, 'Library', 'Application Support', appName);
case Platform.LINUX:
return joinPath(process.env.XDG_DATA_HOME || joinPath(home, '.local', 'share'), appName);
default:
return joinPath(home, `.${appName}`, 'data');
}
}
/**
* Get platform-specific cache directory
*/
export function getCacheDir(appName = 'ultimate-mcp') {
const platform = getPlatform();
const home = getHomeDir();
switch (platform) {
case Platform.WINDOWS:
return joinPath(process.env.TEMP || getTempDir(), appName);
case Platform.MAC:
return joinPath(home, 'Library', 'Caches', appName);
case Platform.LINUX:
return joinPath(process.env.XDG_CACHE_HOME || joinPath(home, '.cache'), appName);
default:
return joinPath(getTempDir(), appName);
}
}
/**
* Execute command in a cross-platform way
*/
export async function executeCommand(command, args = [], options = {}) {
const platform = getPlatform();
// On Windows, use cmd.exe for shell commands
if (platform === Platform.WINDOWS) {
const cmdArgs = ['/c', command, ...args];
return exec(`cmd ${cmdArgs.join(' ')}`, {
cwd: options.cwd,
env: { ...process.env, ...options.env }
});
}
// On Unix-like systems, use the command directly
return exec(`${command} ${args.join(' ')}`, {
cwd: options.cwd,
env: { ...process.env, ...options.env }
});
}
/**
* Spawn process in a cross-platform way
*/
export function spawnProcess(command, args = [], options = {}) {
const platform = getPlatform();
// On Windows, use shell mode for better compatibility
if (platform === Platform.WINDOWS) {
return spawn(command, args, {
...options,
shell: true,
env: { ...process.env, ...options.env }
});
}
return spawn(command, args, {
...options,
env: { ...process.env, ...options.env }
});
}
/**
* Get platform-specific executable extension
*/
export function getExecutableExtension() {
return isWindows() ? '.exe' : '';
}
/**
* Get platform-specific script extension
*/
export function getScriptExtension() {
return isWindows() ? '.bat' : '.sh';
}
/**
* Convert line endings for current platform
*/
export function normalizeLineEndings(text) {
const platform = getPlatform();
if (platform === Platform.WINDOWS) {
// Convert to CRLF for Windows
return text.replace(/\r?\n/g, '\r\n');
}
else {
// Convert to LF for Unix-like systems
return text.replace(/\r\n/g, '\n');
}
}
/**
* Get platform-specific environment variable
*/
export function getEnvVar(name, fallback) {
// Handle case-insensitive env vars on Windows
if (isWindows()) {
const upperName = name.toUpperCase();
for (const [key, value] of Object.entries(process.env)) {
if (key.toUpperCase() === upperName) {
return value;
}
}
}
return process.env[name] || fallback;
}
/**
* Check if a file is executable
*/
export async function isExecutable(filePath) {
try {
const stats = await fs.stat(filePath);
if (isWindows()) {
// On Windows, check file extension
const ext = path.extname(filePath).toLowerCase();
return ['.exe', '.bat', '.cmd', '.com'].includes(ext);
}
else {
// On Unix-like systems, check execute permission
// Check if owner, group, or others have execute permission
const hasExecute = (stats.mode & 0o111) !== 0;
return hasExecute;
}
}
catch (error) {
return false;
}
}
/**
* Make a file executable (Unix-like systems only)
*/
export async function makeExecutable(filePath) {
if (!isWindows()) {
await fs.chmod(filePath, '755');
}
// On Windows, executable status is determined by file extension
}
/**
* Get platform-specific null device
*/
export function getNullDevice() {
return isWindows() ? 'NUL' : '/dev/null';
}
/**
* Get platform info
*/
export function getPlatformInfo() {
return {
platform: getPlatform(),
platformName: os.platform(),
arch: os.arch(),
release: os.release(),
hostname: os.hostname(),
cpus: os.cpus().length,
totalMemory: os.totalmem(),
freeMemory: os.freemem(),
homeDir: getHomeDir(),
tempDir: getTempDir(),
pathSeparator: path.sep,
eol: os.EOL
};
}
/**
* Resolve module path in a cross-platform way
*/
export function resolveModulePath(moduleName, basePath) {
const paths = basePath ? [basePath] : [];
// Add node_modules paths
if (basePath) {
let currentPath = basePath;
while (currentPath !== path.dirname(currentPath)) {
paths.push(joinPath(currentPath, 'node_modules'));
currentPath = path.dirname(currentPath);
}
}
// Add global paths based on platform
const platform = getPlatform();
if (platform === Platform.WINDOWS) {
const appData = process.env.APPDATA;
if (appData) {
paths.push(joinPath(appData, 'npm', 'node_modules'));
}
}
else {
paths.push('/usr/local/lib/node_modules');
paths.push('/usr/lib/node_modules');
const home = getHomeDir();
paths.push(joinPath(home, '.npm-global', 'lib', 'node_modules'));
}
// Try to resolve the module
for (const searchPath of paths) {
try {
const modulePath = joinPath(searchPath, moduleName);
require.resolve(modulePath);
return modulePath;
}
catch {
// Continue searching
}
}
// Fallback to default resolution
return require.resolve(moduleName);
}
/**
* Get platform-specific browser command
*/
export function getBrowserCommand() {
const platform = getPlatform();
switch (platform) {
case Platform.WINDOWS:
return 'start';
case Platform.MAC:
return 'open';
case Platform.LINUX:
return 'xdg-open';
default:
return 'open';
}
}
/**
* Open URL in default browser
*/
export async function openInBrowser(url) {
const command = getBrowserCommand();
if (isWindows()) {
// Windows needs special handling for URLs
await executeCommand('cmd', ['/c', 'start', '""', url]);
}
else {
await executeCommand(command, [url]);
}
}
/**
* Ensure directory exists
*/
export async function ensureDir(dirPath) {
await fs.mkdir(dirPath, { recursive: true });
}
/**
* Safe file write with atomic operation
*/
export async function safeWriteFile(filePath, data, encoding = 'utf8') {
const tempPath = `${filePath}.tmp`;
try {
// Write to temp file
await fs.writeFile(tempPath, data, encoding);
// Rename atomically
await fs.rename(tempPath, filePath);
}
catch (error) {
// Clean up temp file on error
try {
await fs.unlink(tempPath);
}
catch {
// Ignore cleanup errors
}
throw error;
}
}
/**
* Check if running in a container (Docker, etc.)
*/
export async function isContainer() {
if (await fileExists('/.dockerenv')) {
return true;
}
try {
const cgroup = await fs.readFile('/proc/1/cgroup', 'utf8');
return cgroup.includes('docker') || cgroup.includes('containerd');
}
catch {
return false;
}
}
/**
* Check if file exists
*/
async function fileExists(filePath) {
try {
await fs.access(filePath);
return true;
}
catch {
return false;
}
}
//# sourceMappingURL=platform-utils.js.map