github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/ui/app/utils/classes/exec-socket-xterm-adapter.js (about) 1 const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m'; 2 3 import base64js from 'base64-js'; 4 import { TextDecoderLite, TextEncoderLite } from 'text-encoder-lite'; 5 6 export default class ExecSocketXtermAdapter { 7 constructor(terminal, socket, token) { 8 this.terminal = terminal; 9 this.socket = socket; 10 this.token = token; 11 12 socket.onopen = () => { 13 this.sendWsHandshake(); 14 this.sendTtySize(); 15 16 terminal.onData(data => { 17 this.handleData(data); 18 }); 19 }; 20 21 socket.onmessage = e => { 22 let json = JSON.parse(e.data); 23 24 // stderr messages will not be produced as the socket is opened with the tty flag 25 if (json.stdout && json.stdout.data) { 26 terminal.write(decodeString(json.stdout.data)); 27 } 28 }; 29 30 socket.onclose = () => { 31 this.terminal.writeln(''); 32 this.terminal.write(ANSI_UI_GRAY_400); 33 this.terminal.writeln('The connection has closed.'); 34 // Issue to add interpretation of close events: https://github.com/hashicorp/nomad/issues/7464 35 }; 36 37 terminal.resized = () => { 38 this.sendTtySize(); 39 }; 40 } 41 42 sendTtySize() { 43 this.socket.send( 44 JSON.stringify({ tty_size: { width: this.terminal.cols, height: this.terminal.rows } }) 45 ); 46 } 47 48 sendWsHandshake() { 49 this.socket.send(JSON.stringify({ version: 1, auth_token: this.token || '' })); 50 } 51 52 handleData(data) { 53 this.socket.send(JSON.stringify({ stdin: { data: encodeString(data) } })); 54 } 55 } 56 57 function encodeString(string) { 58 let encoded = new TextEncoderLite('utf-8').encode(string); 59 return base64js.fromByteArray(encoded); 60 } 61 62 function decodeString(b64String) { 63 let uint8array = base64js.toByteArray(b64String); 64 return new TextDecoderLite('utf-8').decode(uint8array); 65 }