UNPKG

@grasplabs/grasp

Version:

TypeScript SDK for browser automation and secure command execution in highly available and scalable cloud browser environments

125 lines 4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TerminalService = void 0; const logger_1 = require("../utils/logger"); const node_stream_1 = require("node:stream"); const uuid_1 = require("uuid"); class CommandSession { /** * Gets or creates a default logger instance * @returns Logger instance */ getDefaultLogger() { try { return (0, logger_1.getLogger)().child('TerminalService'); } catch (error) { // If logger is not initialized, create a default one const defaultLogger = new logger_1.Logger({ level: this.sandbox.isDebug ? 'debug' : 'info', console: true, }); return defaultLogger.child('TerminalService'); } } constructor(sandbox, connection, id = 'default0') { this.cwd = ''; this.sandbox = sandbox; this.connection = connection; this.logger = this.getDefaultLogger(); this.id = id; } async getCwd() { return this.cwd || (await this.updateCwd()); } async updateCwd() { try { this.cwd = (await this.sandbox.readFileFromSandbox(`~/.pwd.${this.id}`, { encoding: 'utf8', })).trim(); } catch (ex) { this.cwd = '/home/user'; } return this.cwd; } create() { return new CommandSession(this.sandbox, this.connection, (0, uuid_1.v4)()); } async runCommand(command, options = {}) { try { options.envs = options.envs || {}; options.envs.BROWSER_ENDPOINT = this.connection.wsUrl; command = `${command} && pwd > ~/.pwd.${this.id}`; const cwd = await this.getCwd(); const emitter = await this.sandbox.runCommand(command, { cwd, ...options, nohup: false, background: true, }); const task = emitter .wait() .then(async (res) => { stdoutStream.push(null); stderrStream.push(null); cleanup(); await this.updateCwd(); return res; }) .catch(ex => { // this.logger.debug('Run command failed', ex); return ex.result; }); const stdoutStream = new node_stream_1.Readable({ read() { }, }); const stderrStream = new node_stream_1.Readable({ read() { }, }); // stdout 处理 const onStdout = (chunk) => { stdoutStream.push(chunk); }; // stderr 处理 const onStderr = (chunk) => { stderrStream.push(chunk); }; // 清理函数 const cleanup = () => { emitter.off('stdout', onStdout); emitter.off('stderr', onStderr); }; emitter.on('stdout', onStdout); emitter.on('stderr', onStderr); return { stdout: stdoutStream, stderr: stderrStream, end: async () => { await task; }, json: async () => task, kill: async () => { await emitter.kill(); stdoutStream.push(null); stderrStream.push(null); cleanup(); }, }; } catch (error) { this.logger.error('Run command failed', error); throw error; } } } class TerminalService extends CommandSession { constructor(sandbox, connection) { super(sandbox, connection); } close() { // TODO } } exports.TerminalService = TerminalService; //# sourceMappingURL=terminal.service.js.map