import fs from "node:fs"; import path from "node:path"; export function isTruthy(value: unknown): boolean { if (value === undefined || value === null) { return false; } if (typeof value === "boolean") { return value; } if (typeof value === "number") { return value !== 0; } if (typeof value === "string") { return value.trim().length > 0; } return true; } export function resolveConfigPath(config: unknown, pathStr: string): unknown { const parts = pathStr.split(".").filter(Boolean); let current: unknown = config; for (const part of parts) { if (typeof current !== "object" || current === null) { return undefined; } current = (current as Record)[part]; } return current; } export function isConfigPathTruthyWithDefaults( config: unknown, pathStr: string, defaults: Record, ): boolean { const value = resolveConfigPath(config, pathStr); if (value === undefined && pathStr in defaults) { return defaults[pathStr] ?? false; } return isTruthy(value); } export function resolveRuntimePlatform(): string { return process.platform; } function windowsPathExtensions(): string[] { const raw = process.env.PATHEXT; const list = raw !== undefined ? raw.split(";").map((v) => v.trim()) : [".EXE", ".CMD", ".BAT", ".COM"]; return ["", ...list.filter(Boolean)]; } export function hasBinary(bin: string): boolean { const pathEnv = process.env.PATH ?? ""; const parts = pathEnv.split(path.delimiter).filter(Boolean); const extensions = process.platform === "win32" ? windowsPathExtensions() : [""]; for (const part of parts) { for (const ext of extensions) { const candidate = path.join(part, bin + ext); try { fs.accessSync(candidate, fs.constants.X_OK); return true; } catch { // keep scanning } } } return false; }