feat: add pure ssh2 remote operations

This commit is contained in:
云服务部-叶林立
2026-08-21 19:51:43 +08:00
parent d3bf562189
commit 0ac50eb581
62 changed files with 3701 additions and 47 deletions
+53
View File
@@ -0,0 +1,53 @@
import { execFileSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
export type EffectiveSshConfig = Map<string, string[]>;
export function parseSshG(text: string): EffectiveSshConfig {
const values: EffectiveSshConfig = new Map();
for (const line of text.split(/\r?\n/)) {
const separator = line.indexOf(" ");
if (separator < 1) continue;
const key = line.slice(0, separator).trim().toLowerCase();
const value = line.slice(separator + 1).trim();
if (!key || !value) continue;
const current = values.get(key) ?? [];
current.push(value);
values.set(key, current);
}
return values;
}
export function resolveOpenSshAlias(alias: string): EffectiveSshConfig {
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(alias)) throw new Error(`invalid SSH alias: ${alias}`);
const output = execFileSync("ssh", ["-G", "--", alias], {
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
});
return parseSshG(output);
}
export function effectiveValue(config: EffectiveSshConfig, key: string): string | undefined {
return config.get(key.toLowerCase())?.at(-1);
}
export function effectiveValues(config: EffectiveSshConfig, key: string): string[] {
return config.get(key.toLowerCase()) ?? [];
}
export function listDirectSshAliases(configPath = join(homedir(), ".ssh", "config")): string[] {
if (!existsSync(configPath)) return [];
const aliases: string[] = [];
const text = readFileSync(configPath, "utf8");
for (const line of text.split(/\r?\n/)) {
const match = /^\s*Host\s+(.+?)\s*$/i.exec(line);
if (!match) continue;
for (const alias of match[1].split(/\s+/)) {
if (!alias || alias.includes("*") || alias.includes("?") || alias.startsWith("!")) continue;
if (!aliases.includes(alias)) aliases.push(alias);
}
}
return aliases;
}