import { exec, execSync } from 'child_process';
import { promisify } from 'util';
import { existsSync } from 'fs';
const execAsync = promisify(exec);
export interface EnvironmentInfo {
node: string;
python?: string;
conda?: string;
idb?: string;
xcrun?: string;
chrome?: string;
}
export async function getEnvironmentInfo(): Promise<EnvironmentInfo> {
const info: EnvironmentInfo = {
node: process.execPath,
};
try {
const { stdout: pythonPath } = await execAsync('which python3');
info.python = pythonPath.trim();
} catch {
// Python not in PATH
}
try {
const { stdout: idbPath } = await execAsync('which idb');
info.idb = idbPath.trim();
} catch {
// idb not installed
}
try {
const { stdout: xcrunPath } = await execAsync('which xcrun');
info.xcrun = xcrunPath.trim();
} catch {
// xcrun not available
}
// Check for Chrome
const chromePath = findChromePath();
if (chromePath) {
info.chrome = chromePath;
}
// Check for conda environment
if (process.env.CONDA_DEFAULT_ENV) {
info.conda = process.env.CONDA_DEFAULT_ENV;
}
return info;
}
export function findChromePath(): string | null {
const possiblePaths = [
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
'/Applications/Chromium.app/Contents/MacOS/Chromium',
'/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
];
for (const path of possiblePaths) {
if (existsSync(path)) {
return path;
}
}
return null;
}
// idb availability state
let idbAvailable = false;
export async function checkIdbAvailability(): Promise<boolean> {
try {
await execAsync('which idb');
idbAvailable = true;
return true;
} catch {
idbAvailable = false;
return false;
}
}
export function isIdbAvailable(): boolean {
return idbAvailable;
}
export function setIdbAvailable(available: boolean): void {
idbAvailable = available;
}