UNPKG

@xtail/ssh

Version:

X-Tail SSH 库,包含 SSH 连接服务器的类和工具方法等

167 lines (166 loc) 5.84 kB
var l = Object.defineProperty; var g = (n, s, t) => s in n ? l(n, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[s] = t; var i = (n, s, t) => g(n, typeof s != "symbol" ? s + "" : s, t); import f from "ssh2-promise"; import a from "../node_modules/.pnpm/strip-ansi@7.1.0/node_modules/strip-ansi/index.js"; import u from "../node_modules/.pnpm/split-lines@3.0.0/node_modules/split-lines/index.js"; import { SSHUtil as e } from "../utils/index.js"; const R = "SSH"; class B { constructor(s) { // 服务器连接配置 i(this, "config"); // 服务器连接实例 i(this, "ssh", null); // 是否已连接服务器 i(this, "connected", !1); // 与服务器 Shell 交互的 socket 实例 i(this, "socket", null); // 是否已经与服务器创建会话 i(this, "isSession", !1); // 当前执行的命令 i(this, "currentCmd", {}); this.config = s; } /** * 是否已经 SSH 连接到服务器 * * @returns {boolean} true 已连接,false 未连接 */ get isConnected() { return this.connected; } /** * SSH 连接服务器 * * @returns {Promise<SSHResultType>} SSH 连接结果 */ async connect() { if (this.connected) return e.genSuccessResultByConf(this.config, { message: "已连接成功" }); try { return this.ssh = new f(this.config), await this.ssh.connect(), this.connected = !0, e.genSuccessResultByConf(this.config, { message: "连接成功" }); } catch (s) { return this.connected = !1, this.ssh = null, e.genFailResultByConf(this.config, { message: s.message ?? "连接失败", detail: s }); } } /** * 断开与服务器的 SSH 连接 * * @returns {Promise<SSHResultType>} 断开与服务器的 SSH 连接的结果 */ async close() { var s; (!this.ssh || !this.connected) && e.genSuccessResultByConf(this.config, { message: "已断开服务器连接" }); try { return await ((s = this.ssh) == null ? void 0 : s.close()), this.connected = !1, this.ssh = null, e.genSuccessResultByConf(this.config, { message: "断开服务器连接成功" }); } catch (t) { return e.genFailResultByConf(this.config, { message: t.message ?? "断开服务器连接失败", detail: t }); } } /** * SSH 连接服务器后执行命令<br/> * 注意:如果未连接服务器,会返回失败结果,所以需要先调用 {@link connect} 方法连接服务器 * * @param {string} cmd 需要执行的命令 * @returns {Promise<SSHResultType>} 执行命令结果 */ async exec(s) { if (!this.ssh || !this.connected) return e.genFailResultByConf(this.config, { message: "未连接服务器,请先连接服务器" }); try { const t = await this.ssh.exec(s); return e.genSuccessResultByConf(this.config, { message: `${s} 执行成功`, detail: t }); } catch (t) { return e.genFailResultByConf(this.config, { message: t.message ?? `${s} 执行失败`, detail: t }); } } /** * 是否已经与服务器创建会话 * * @returns {boolean} true 已创建会话,false 未创建会话 */ get isSessionOpen() { return this.isSession; } /** * 与服务器创建 Shell 会话 * * @param {(data: string) => void} onData 服务器返回数据时的回调函数 * @param {() => void} onClose 与服务器之间的 Shell 会话关闭时的回调函数 * @returns {Promise<SSHResultType>} 创建会话结果 */ async sessionOpen(s, t) { if (!this.ssh || !this.connected) return e.genFailResultByConf(this.config, { message: "未连接服务器,请先连接服务器" }); try { return this.socket = await this.ssh.shell(), this.socket.on("data", (r) => { let o = ""; const h = u(r.toString("utf8")); for (const c of h) Reflect.has(this.currentCmd, c.trim()) ? Reflect.deleteProperty(this.currentCmd, c.trim()) : Reflect.has(this.currentCmd, a(c).trim()) ? Reflect.deleteProperty(this.currentCmd, a(c).trim()) : o += c + ` `; o.trim() && s(o); }), this.socket.on("close", t), this.isSession = !0, e.genSuccessResultByConf(this.config, { message: "会话创建成功" }); } catch (r) { return this.isSession = !1, this.socket = null, e.genFailResultByConf(this.config, { message: r.message ?? "会话创建失败", detail: r }); } } /** * 在与服务器创建的 Shell 会话中执行命令 * * @param {string} cmd 需要执行的命令 * @returns {Promise<SSHResultType>} 命令执行结果 */ async sessionExec(s) { if (!this.socket || !this.isSession) return e.genFailResultByConf(this.config, { message: "未与服务器创建会话,请先创建会话" }); try { return this.currentCmd[s] = s, this.socket.write(s + ` `), e.genSuccessResultByConf(this.config, { message: `${s} 执行成功` }); } catch (t) { return e.genFailResultByConf(this.config, { message: t.message ?? `${s} 执行失败`, detail: t }); } } /** * 关闭与服务器创建的 Shell 会话 * * @returns {Promise<SSHResultType>} 关闭会话结果 */ async sessionClose() { if (!this.socket || !this.isSession) return e.genSuccessResultByConf(this.config, { message: "会话已关闭" }); try { return await this.socket.destroy(), this.currentCmd = {}, this.isSession = !1, this.socket = null, e.genSuccessResultByConf(this.config, { message: "会话关闭成功" }); } catch (s) { return e.genFailResultByConf(this.config, { message: s.message ?? "会话关闭失败", detail: s }); } } } export { B as SSH, R as SSH_Name };