/**
 * SSH command builder — array-based construction with shell escaping.
 *
 * Use cmd() to build commands from typed arguments. Each argument is
 * shell-escaped, preventing command injection via crafted inputs.
 *
 * Use raw() ONLY for hardcoded static strings (heredocs, complex redirections)
 * that cannot be expressed via cmd(). Never pass user input to raw().
 */
/**
 * POSIX-safe shell escaping.
 * - Safe chars (alphanumeric + ._:/@=+-) → returned as-is
 * - Empty string → ''
 * - Everything else → wrapped in single quotes, with embedded single quotes
 *   replaced by the POSIX idiom: '\''
 */
export function shellEscape(arg) {
    if (arg.length === 0)
        return "''";
    if (/^[a-zA-Z0-9._:/@=+-]+$/.test(arg))
        return arg;
    return "'" + arg.replace(/'/g, "'\\''") + "'";
}
/**
 * Build a single command from program + arguments.
 * Each argument is shell-escaped before joining with spaces.
 */
export function cmd(...args) {
    if (args.some((a) => a.length === 0)) {
        throw new Error("cmd() received an empty string argument — this is likely a bug");
    }
    return args.map(shellEscape).join(" ");
}
/**
 * Wrap a pre-validated static string as SshCommand.
 *
 * WARNING: Only use for hardcoded constants or complex shell constructs
 * (heredocs, multi-line scripts, redirections) that cannot be expressed
 * via cmd(). Never pass user input to raw() — it is NOT escaped.
 */
export function raw(command) {
    return command;
}
/** Join commands with ' && ' (fail-fast sequential execution). */
export function and(...commands) {
    return commands.join(" && ");
}
/** Join commands with ' | ' (pipe stdout to next command). */
export function pipe(...commands) {
    return commands.join(" | ");
}
/** Join commands with ' || ' (run next if previous fails). */
export function or(...commands) {
    return commands.join(" || ");
}
/** Join commands with ' ; ' (sequential, regardless of exit code). */
export function seq(...commands) {
    return commands.join(" ; ");
}
/** Wrap a command in a subshell: ( ... ) */
export function subshell(command) {
    return `( ${command} )`;
}
/**
 * Extract the final shell string from an SshCommand.
 * Provides semantic clarity at call sites — SshCommand is already a string.
 */
export function buildCommandString(command) {
    return command;
}
//# sourceMappingURL=sshCommand.js.map