import { $ } from "bun"; import { logger } from "./logger"; /** * List all configured rclone remotes * @returns Array of remote names */ export async function listRcloneRemotes(): Promise { const result = await $`rclone listremotes`.nothrow(); if (result.exitCode !== 0) { logger.error(`Failed to list rclone remotes: ${result.stderr}`); return []; } // Parse output - each line is a remote name ending with ":" const remotes = result.stdout .toString() .split("\n") .map((line) => line.trim()) .filter((line) => line.endsWith(":")) .map((line) => line.slice(0, -1)); // Remove trailing ":" return remotes; } /** * Get information about a specific rclone remote * @param remote Remote name * @returns Remote type and configuration info */ export async function getRcloneRemoteInfo( remote: string, ): Promise<{ type: string; config: Record } | null> { try { const result = await $`rclone config show ${remote}`.quiet(); if (result.exitCode !== 0) { logger.error(`Failed to get info for remote ${remote}: ${result.stderr}`); return null; } // Parse the output to extract type and config const output = result.stdout.toString(); const lines = output .split("\n") .map((l) => l.trim()) .filter((l) => l); const config: Record = {}; let type = "unknown"; for (const line of lines) { if (line.includes("=")) { const parts = line.split("="); const key = parts[0]; if (!key) continue; const valueParts = parts.slice(1); const value = valueParts.join("=").trim(); const cleanKey = key.trim(); if (cleanKey === "type") { type = value; } config[cleanKey] = value; } } return { type, config }; } catch (error) { logger.error(`Error getting remote info for ${remote}: ${error}`); return null; } }