import * as pty from 'node-pty'; import * as os from 'os'; import { homedir } from 'os'; import { Socket } from 'socket.io'; const shell: string = os.platform() === 'win32' ? 'powershell.exe' : 'zsh'; interface Option { name: string; cols?: number; rows?: number; cwd?: string; } let ptyContainers: { [key: string]: pty.IPty } = {}; export const terminal = (socket: Socket) => { socket.on('create', (option: Option) => { let ptyProcess = pty.spawn(shell, ['--login'], { name: 'xterm-color', cols: option.cols || 80, rows: option.rows || 24, cwd: option.cwd || homedir(), env: process.env, }) as any; console.log('create', option.name); ptyProcess.on('data', (data: string) => socket.emit(option.name + '-output', data)); socket.on(option.name + '-input', (data: string) => ptyProcess.write(data)); socket.on(option.name + '-resize', (size: [number, number]) => { ptyProcess.resize(size[0], size[1]); }); socket.on(option.name + '-exit', () => { console.log('exit', option.name) ptyProcess.destroy(); }); socket.emit(option.name + '-pid', ptyProcess.pid); ptyContainers[option.name] = ptyProcess; }); socket.on('remove', (name: string) => { socket.removeAllListeners(name + '-input'); socket.removeAllListeners(name + '-resize'); socket.removeAllListeners(name + '-exit'); if (name && ptyContainers[name] && ptyContainers[name].pid) { const curentContainer = ptyContainers[name] as any; curentContainer.destroy(); delete ptyContainers[name]; } }); };