kui-shell
Version:
This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool
851 lines • 36.5 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = require("debug");
const path = require("path");
const uuid_1 = require("uuid");
const xterm = require("xterm");
const strip_ansi_1 = require("strip-ansi");
const js_yaml_1 = require("js-yaml");
const webLinks_1 = require("xterm/lib/addons/webLinks/webLinks");
const core_1 = require("@kui-shell/core");
const sidecar_1 = require("@kui-shell/core/webapp/views/sidecar");
const cli_1 = require("@kui-shell/core/webapp/cli");
const ascii_to_usage_1 = require("@kui-shell/core/webapp/util/ascii-to-usage");
const ascii_to_table_1 = require("@kui-shell/core/webapp/util/ascii-to-table");
const ui = require("./ui");
const session = require("./session");
const util_1 = require("./util");
const channel_1 = require("./channel");
const debug = debug_1.default('plugins/bash-like/pty/client');
const enterApplicationModePattern = /\x1b\[\?1h/;
const exitApplicationModePattern = /\x1b\[\?1l/;
const enterAltBufferPattern = /\x1b\[\??(47|1047|1049)h/;
const exitAltBufferPattern = /\x1b\[\??(47|1047|1049)l/;
let resizeGeneration = 0;
if (window) {
window.addEventListener('resize', () => {
resizeGeneration++;
});
}
function getCachedSize(tab) {
const cachedSize = tab['_kui_pty_cachedSize'];
if (cachedSize &&
cachedSize.sidecarState === sidecar_1.getSidecarState(tab) &&
cachedSize.resizeGeneration === resizeGeneration) {
return cachedSize;
}
}
function setCachedSize(tab, { rows, cols }) {
tab['_kui_pty_cachedSize'] = {
rows,
cols,
sidecarState: sidecar_1.getSidecarState(tab),
resizeGeneration
};
}
class Resizer {
constructor(terminal, tab, execOptions) {
this.alt = false;
this.wasAlt = false;
this.app = false;
this._frozen = false;
this.tab = tab;
this.execOptions = execOptions;
this.terminal = terminal;
this.resizeNow = this.resize.bind(this, true);
window.addEventListener('resize', this.resizeNow);
this.clearXtermSelectionNow = () => {
terminal.clearSelection();
};
document.addEventListener('select', this.clearXtermSelectionNow);
const ourTab = tab;
core_1.eventBus.on('/sidecar/toggle', ({ tab }) => {
if (cli_1.sameTab(tab, ourTab)) {
this.resizeNow();
}
else {
debug('toggle event, but not for our sidecar');
}
});
this.resize();
}
get ws() {
return this._ws;
}
set ws(ws) {
this._ws = ws;
}
destroy() {
this.exitAltBufferMode();
this.exitApplicationMode();
window.removeEventListener('resize', this.resizeNow);
document.removeEventListener('select', this.clearXtermSelectionNow);
}
isEmptyCursorRow(row) {
return row.children.length === 1 && row.children[0].classList.contains('xterm-cursor');
}
reflowLineWraps(element = this.terminal.element) {
const rows = element.querySelector('.xterm-rows').children;
const nLines = this.terminal.buffer.length;
for (let idx = 0; idx < nLines - 1; idx++) {
const line = this.terminal.buffer.getLine(idx);
const nextLine = this.terminal.buffer.getLine(idx + 1);
if (nextLine.isWrapped) {
if (rows[idx + 1]) {
rows[idx + 1].classList.add('xterm-is-wrapped');
}
if (!line.isWrapped) {
if (rows[idx]) {
rows[idx].classList.add('xterm-is-wrapped');
rows[idx].classList.add('xterm-is-wrapped-with-prefix-break');
}
}
}
}
}
hideTrailingEmptyBlanks(remove = false, element = this.terminal.element, from = 0) {
if (this.frozen) {
return;
}
if (!remove) {
const hidden = element.querySelectorAll('.xterm-rows > .xterm-hidden-row');
for (let idx = 0; idx < hidden.length; idx++) {
hidden[idx].classList.remove('xterm-hidden-row');
}
}
else {
this.frozen = true;
}
const rows = element.querySelector('.xterm-rows').children;
for (let idx = rows.length - 1; idx >= from; idx--) {
if (rows[idx].children.length === 0) {
if (remove) {
rows[idx].remove();
}
else {
rows[idx].classList.add('xterm-hidden-row');
}
}
else {
break;
}
}
}
static hideCursorOnlyRow(element) {
util_1.cleanupTerminalAfterTermination(element);
}
static paddingHorizontal(elt) {
const style = window.getComputedStyle(elt);
return (parseInt(style.getPropertyValue('padding-left') || '0', 10) +
parseInt(style.getPropertyValue('padding-right') || '0', 10));
}
static paddingVertical(elt) {
const style = window.getComputedStyle(elt);
return (parseInt(style.getPropertyValue('padding-top') || '0', 10) +
parseInt(style.getPropertyValue('padding-bottom') || '0', 10));
}
getSize(forceRecompute) {
const cachedSize = getCachedSize(this.tab);
if (!forceRecompute && cachedSize !== undefined) {
return cachedSize;
}
const _core = this.terminal._core;
const hack = _core.viewport;
const dimensions = hack._dimensions;
const scaledCharWidth = hack._terminal.charMeasure.width * window.devicePixelRatio;
const ratio = scaledCharWidth / dimensions.scaledCharWidth;
const selectorForSize = '.repl-inner';
const sizeElement = this.tab.querySelector(selectorForSize);
const enclosingRect = sizeElement.getBoundingClientRect();
const selectorForWidthPad = '.repl-inner .repl-block .repl-output';
const widthPadElement = this.tab.querySelector(selectorForWidthPad);
const heightPadElement = sizeElement;
const width = enclosingRect.width - Resizer.paddingHorizontal(widthPadElement);
const height = enclosingRect.height - Resizer.paddingVertical(heightPadElement);
const cols = Math.floor(width / dimensions.actualCellWidth / ratio);
const rows = Math.floor(height / dimensions.actualCellHeight);
debug('getSize', cols, rows, width, height);
const newSize = { rows, cols };
if (!isNaN(rows) && !isNaN(cols)) {
setCachedSize(this.tab, newSize);
}
return newSize;
}
set frozen(val) {
this._frozen = val;
}
get frozen() {
return this._frozen;
}
resize(flush = false, force = false) {
if (this.frozen) {
return;
}
const { rows, cols } = this.getSize(flush);
if (this.terminal.rows !== rows || this.terminal.cols !== cols || force) {
debug('resize', cols, rows, this.terminal.cols, this.terminal.rows, this.inAltBufferMode());
try {
if (!isNaN(rows) && !isNaN(cols)) {
this.terminal.resize(cols, rows);
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type: 'resize', cols, rows }));
}
}
}
catch (err) {
debug(err.message);
}
}
}
inApplicationMode() {
return this.app;
}
inAltBufferMode() {
return this.alt;
}
wasEverInAltBufferMode() {
return this.wasAlt;
}
enterApplicationMode() {
debug('switching to application mode');
this.app = true;
this.tab.classList.add('xterm-application-mode');
}
exitApplicationMode() {
debug('switching from application mode');
this.app = false;
this.tab.classList.remove('xterm-application-mode');
}
enterAltBufferMode() {
debug('switching to alt buffer mode');
this.alt = true;
this.wasAlt = true;
if (this.exitAlt) {
clearTimeout(this.exitAlt);
}
if (this.execOptions['pty/force-resize']) {
const { rows, cols } = this.getSize(false);
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({ type: 'resize', cols, rows: rows + 1 }));
setTimeout(() => {
this.ws.send(JSON.stringify({ type: 'resize', cols, rows: rows }));
this.tab.classList.add('xterm-alt-buffer-mode');
}, 1);
}
}
else {
this.tab.classList.add('xterm-alt-buffer-mode');
}
}
exitAltBufferMode() {
debug('switching from alt buffer mode');
this.alt = false;
this.tab.classList.remove('xterm-alt-buffer-mode');
}
}
let cachedFontProperties;
function getFontProperties(flush) {
if (flush || !cachedFontProperties) {
debug('computing font properties');
const fontTheme = getComputedStyle(document.querySelector('body .repl .repl-input input'));
const val = (key, kind = 'color') => fontTheme.getPropertyValue(`--${kind}-${key}`).trim();
const fontSize = parseFloat(fontTheme.fontSize.replace(/px$/, ''));
const fontFamily = val('monospace', 'font');
cachedFontProperties = { fontFamily, fontSize };
}
return cachedFontProperties;
}
const injectFont = (terminal, flush = false) => {
try {
const { fontFamily, fontSize } = getFontProperties(flush);
terminal.setOption('fontFamily', fontFamily);
terminal.setOption('fontSize', fontSize);
debug('fontSize', fontSize);
terminal.setOption('fontWeight', 400);
terminal.setOption('fontWeightBold', 600);
}
catch (err) {
console.error('Error setting terminal font size', err);
}
};
const remoteChannelFactory = (tab) => __awaiter(void 0, void 0, void 0, function* () {
try {
const { url, uid, gid } = yield tab.REPL.qexec('bash websocket open', undefined, undefined, {
rethrowErrors: true
});
debug('websocket url', url, uid, gid);
const WebSocketChannel = (yield Promise.resolve().then(() => require('./websocket-channel'))).default;
return new WebSocketChannel(url, uid, gid);
}
catch (err) {
const error = err;
if (error.statusCode !== 503) {
console.error('error opening websocket', err);
}
throw err;
}
});
const electronChannelFactory = () => __awaiter(void 0, void 0, void 0, function* () {
const channel = new channel_1.InProcessChannel();
channel.init();
return channel;
});
const webviewChannelFactory = () => __awaiter(void 0, void 0, void 0, function* () {
console.log('webviewChannelFactory');
const channel = new channel_1.WebViewChannelRendererSide();
channel.init();
return channel;
});
const focus = (terminal) => {
if (!terminal._kuiAlreadyFocused) {
setTimeout(() => {
if (!terminal._kuiAlreadyFocused) {
terminal._kuiAlreadyFocused = true;
terminal.focus();
}
}, 0);
}
};
const getOrCreateChannel = (cmdline, uuid, tab, execOptions, terminal) => __awaiter(void 0, void 0, void 0, function* () {
const channelFactory = core_1.Capabilities.inBrowser()
? window['webview-proxy'] !== undefined
? webviewChannelFactory
: remoteChannelFactory
: electronChannelFactory;
const env = Object.assign({}, process.env, execOptions.env || {});
const doExec = (ws) => {
const msg = {
type: 'exec',
cmdline,
uuid,
rows: terminal.rows,
cols: terminal.cols,
cwd: process.env.PWD || (!core_1.Capabilities.inBrowser() && process.cwd()),
env: Object.keys(env).length > 0 && env
};
debug('exec after open', msg);
ws.send(JSON.stringify(msg));
};
const cachedws = session.getChannelForTab(tab);
if (!cachedws || cachedws.readyState === WebSocket.CLOSING || cachedws.readyState === WebSocket.CLOSED) {
const ws = yield channelFactory(tab);
tab['ws'] = ws;
ws.on('open', () => doExec(ws));
ws.on('close', () => {
debug('channel has closed');
if (!tab['state'].closed) {
debug('attempting to reestablish connection, because the tab is still open ');
ui.setOffline();
session.pollUntilOnline(tab);
}
});
return ws;
}
else {
doExec(cachedws);
focus(terminal);
return cachedws;
}
});
function safeLoadWithCatch(raw) {
try {
return js_yaml_1.safeLoad(raw);
}
catch (err) {
console.error(err);
}
}
function squashRow(row) {
if (row.children.length > 1) {
let previous = row.children[0];
let current = row.children[1];
let runningSquash = previous.innerText;
while (current) {
const next = current.nextElementSibling;
if (previous.className === current.className) {
current.remove();
runningSquash += current.innerText;
}
else {
if (runningSquash !== previous.innerText) {
previous.innerText = runningSquash;
}
previous = current;
runningSquash = previous.innerText;
}
current = next;
}
if (runningSquash !== previous.innerText) {
previous.innerText = runningSquash;
}
}
if (row.children.length === 1) {
const singleton = row.firstElementChild;
if (!singleton.className) {
singleton.remove();
row.innerText = singleton.innerText;
}
}
}
function squash(elt) {
const rows = elt.querySelectorAll('.xterm-rows > div');
for (let idx = 0; idx < rows.length; idx++) {
squashRow(rows[idx]);
}
}
let alreadyInjectedCSS;
function injectXtermCSS() {
if (!alreadyInjectedCSS) {
if (core_1.Capabilities.inBrowser()) {
core_1.UI.injectCSS({ css: require('xterm/lib/xterm.css'), key: 'xtermjs' });
core_1.UI.injectCSS({
css: require('@kui-shell/plugin-bash-like/web/css/xterm.css'),
key: 'kui-xtermjs'
});
}
else {
core_1.UI.injectCSS({
path: path.join(path.dirname(require.resolve('xterm/package.json')), 'lib/xterm.css'),
key: 'xtermjs'
});
core_1.UI.injectCSS({
path: path.join(path.dirname(require.resolve('@kui-shell/plugin-bash-like/package.json')), 'web/css/xterm.css'),
key: 'kui-xtermjs'
});
}
alreadyInjectedCSS = true;
return true;
}
else {
return false;
}
}
exports.doExec = (tab, block, cmdline, argvNoOptions, parsedOptions, execOptions) => new Promise((resolve, reject) => {
const contentType = parsedOptions.o ||
parsedOptions.output ||
parsedOptions.out ||
(argvNoOptions[0] === 'cat' && /json$/.test(argvNoOptions[1]) && 'json') ||
(argvNoOptions[0] === 'cat' && (/yaml$/.test(argvNoOptions[1]) || /yml$/.test(argvNoOptions[1])) && 'yaml');
const expectingSemiStructuredOutput = /yaml|json/.test(contentType);
const injectingCSS = injectXtermCSS();
const exec = () => __awaiter(void 0, void 0, void 0, function* () {
try {
const parent = block.querySelector('.repl-result');
const xtermContainer = document.createElement('xterm');
xtermContainer.classList.add('xterm-container');
xtermContainer.classList.add('repl-output-like');
parent.appendChild(xtermContainer);
if (execOptions.replSilence) {
debug('repl silence');
xtermContainer.style.display = 'none';
xtermContainer.classList.add('repl-temporary');
}
cli_1.setCustomCaret(block);
const cachedSize = getCachedSize(tab);
const { fontFamily, fontSize } = getFontProperties(false);
const terminal = new xterm.Terminal({
rendererType: 'dom',
cols: cachedSize && cachedSize.cols,
rows: cachedSize && cachedSize.rows,
fontFamily,
fontSize
});
let cbAfterPendingWrites;
let pendingWrites = 0;
terminal.open(xtermContainer);
webLinks_1.webLinksInit(terminal);
const doInjectTheme = () => injectFont(terminal, true);
core_1.eventBus.on('/theme/change', doInjectTheme);
const resizer = new Resizer(terminal, tab, execOptions);
const doZoom = () => {
injectFont(terminal, true);
resizer.resize();
};
core_1.eventBus.on('/zoom', doZoom);
const cleanupEventHandlers = () => {
core_1.eventBus.off('/zoom', doZoom);
core_1.eventBus.off('/theme/change', doInjectTheme);
};
terminal.element.classList.add('xterm-empty-row-heuristic');
setTimeout(() => terminal.element.classList.remove('xterm-empty-row-heuristic'), 100);
const cleanUpTerminal = () => {
cleanupEventHandlers();
resizer.destroy();
if (execOptions.type === core_1.Commands.ExecType.Nested && execOptions.quiet !== false) {
xtermContainer.remove();
}
else {
xtermContainer.classList.add('xterm-terminated');
}
};
const ourUUID = uuid_1.v4();
const ws = yield getOrCreateChannel(cmdline, ourUUID, tab, execOptions, terminal).catch((err) => {
if (err.code !== 503) {
console.error('error creating channel', err);
}
cleanUpTerminal();
throw err;
});
resizer.ws = ws;
let definitelyNotUsage = argvNoOptions[0] === 'git' || execOptions.rawResponse;
let definitelyNotTable = expectingSemiStructuredOutput || argvNoOptions[0] === 'grep' || execOptions.rawResponse;
let queuedInput = '';
let flushAsync;
terminal.on('key', (key) => {
if (ws.readyState === WebSocket.CLOSING || ws.readyState === WebSocket.CLOSED) {
debug('queued input out back', key);
queuedInput += key;
}
else {
queuedInput += key;
definitelyNotTable = true;
definitelyNotUsage = true;
if (flushAsync) {
clearTimeout(flushAsync);
}
flushAsync = setTimeout(() => {
if (queuedInput && ws.readyState === WebSocket.OPEN) {
const data = queuedInput;
queuedInput = '';
ws.send(JSON.stringify({ type: 'data', data, uid: ourUUID }));
}
}, 20);
}
});
const maybeClearSelection = () => {
if (!terminal.hasSelection()) {
cli_1.clearPendingTextSelection();
}
};
terminal.on('focus', maybeClearSelection);
terminal.on('blur', maybeClearSelection);
terminal.on('paste', (data) => {
ws.send(JSON.stringify({ type: 'data', data }));
});
terminal.on('selection', () => {
cli_1.clearTextSelection();
cli_1.setPendingTextSelection(terminal.getSelection());
});
const activeDiv = tab.querySelector('.repl-inner');
const doScroll = () => {
if (!resizer.inAltBufferMode()) {
activeDiv.scrollTop = activeDiv.scrollHeight;
}
};
const scrollPoll = setInterval(doScroll, 200);
const notifyOfWriteCompletion = () => {
if (pendingWrites > 0) {
pendingWrites = 0;
if (cbAfterPendingWrites) {
cbAfterPendingWrites();
cbAfterPendingWrites = undefined;
}
}
};
let first = true;
const onRefresh = (evt) => __awaiter(void 0, void 0, void 0, function* () {
if (evt.end > evt.start || first) {
resizer.hideTrailingEmptyBlanks();
}
notifyOfWriteCompletion();
first = false;
});
terminal.on('refresh', onRefresh);
let bytesWereWritten = false;
let sawCode;
let pendingUsage = false;
let pendingTable;
let raw = '';
let nLinesRaw = 0;
const onFirstMessage = () => {
const queuedInput = cli_1.disableInputQueueing();
if (queuedInput.length > 0) {
debug('queued input up front', queuedInput);
setTimeout(() => ws.send(JSON.stringify({ type: 'data', data: queuedInput })), 50);
}
focus(terminal);
};
const onMessage = (data) => __awaiter(void 0, void 0, void 0, function* () {
const msg = JSON.parse(data);
if (msg.uuid !== ourUUID) {
return;
}
if (msg.type === 'state' && msg.state === 'ready') {
onFirstMessage();
}
else if (msg.type === 'data') {
if (!terminal._kuiAlreadyFocused) {
onFirstMessage();
}
const flush = () => {
if (pendingTable) {
pendingTable = undefined;
definitelyNotTable = true;
definitelyNotUsage = true;
bytesWereWritten = true;
sawCode = /File exists/i.test(raw)
? 409
: /no such/i.test(raw) || /not found/i.test(raw)
? 404
: sawCode;
terminal.write(raw);
raw = '';
}
};
if (enterApplicationModePattern.test(msg.data)) {
flush();
resizer.enterApplicationMode();
focus(terminal);
}
else if (exitApplicationModePattern.test(msg.data)) {
resizer.exitApplicationMode();
}
if (enterAltBufferPattern.test(msg.data)) {
flush();
focus(terminal);
resizer.enterAltBufferMode();
}
else if (exitAltBufferPattern.test(msg.data)) {
resizer.exitAltBufferMode();
}
else if (!resizer.inAltBufferMode()) {
raw += msg.data;
}
const maybeUsage = !resizer.wasEverInAltBufferMode() &&
!definitelyNotUsage &&
(pendingUsage ||
ascii_to_usage_1.formatUsage(cmdline, strip_ansi_1.default(raw), {
drilldownWithPip: true
}));
if (!definitelyNotTable && raw.length > 0 && !resizer.wasEverInAltBufferMode()) {
try {
const tables = (yield ascii_to_table_1.preprocessTable(raw.split(/^(?=NAME|Name|ID|\n\*)/m))).filter(x => x);
if (tables && tables.length > 0) {
const tableRows = core_1.Util.flatten(tables.filter(_ => _.rows !== undefined).map(_ => _.rows));
if (tableRows && tableRows.length > 0) {
const entityType = /\w+/.test(argvNoOptions[2]) && argvNoOptions[2];
const tableModel = ascii_to_table_1.formatTable(entityType, tableRows);
debug('tableModel', tableModel);
const trailingStrings = tables.map(_ => _.trailingString).filter(x => x);
if (trailingStrings && trailingStrings.length > 0) {
const trailers = yield core_1.UI.PrettyPrinters.ansi(trailingStrings);
if (!trailers) {
pendingTable = [tableModel];
}
else {
pendingTable = [tableModel, trailers];
}
}
else {
pendingTable = [tableModel];
}
}
else if (raw.length > 1000) {
definitelyNotTable = true;
}
}
else {
debug('definitelyNotTable');
definitelyNotTable = true;
}
}
catch (err) {
console.error('error parsing as table', err);
definitelyNotTable = true;
}
}
if (pendingTable || expectingSemiStructuredOutput) {
}
else if (maybeUsage) {
debug('pending usage');
pendingUsage = true;
}
else {
if (raw.length > 500) {
definitelyNotUsage = true;
}
else if (raw.length > 1500) {
definitelyNotTable = true;
}
if (execOptions.type !== core_1.Commands.ExecType.Nested || execOptions.quiet === false) {
pendingWrites++;
definitelyNotUsage = true;
bytesWereWritten = true;
sawCode = /File exists/i.test(raw)
? 409
: /no such/i.test(raw) || /not found/i.test(raw)
? 404
: sawCode;
for (let idx = 0; idx < msg.data.length; idx++) {
if (msg.data[idx] === '\n') {
nLinesRaw++;
}
}
terminal.write(msg.data);
raw = '';
}
}
}
else if (msg.type === 'exit') {
if (pendingTable && !pendingTable.some(_ => core_1.Tables.isTable(_) && _.body.length > 0)) {
if (execOptions.type !== core_1.Commands.ExecType.Nested || execOptions.quiet === false) {
bytesWereWritten = true;
sawCode = /File exists/i.test(raw)
? 409
: /no such/i.test(raw) || /not found/i.test(raw)
? 404
: sawCode;
terminal.write(raw);
raw = '';
}
pendingTable = undefined;
}
const respondToRepl = () => {
if (pendingUsage) {
execOptions.stdout(ascii_to_usage_1.formatUsage(cmdline, strip_ansi_1.default(raw), {
drilldownWithPip: true
}));
xtermContainer.classList.add('xterm-invisible');
}
else if (pendingTable) {
const response = pendingTable;
execOptions.stdout(response.length === 1 ? response[0] : response);
}
else if (expectingSemiStructuredOutput) {
try {
const resource = contentType === 'yaml' ? safeLoadWithCatch(strip_ansi_1.default(raw)) : JSON.parse(strip_ansi_1.default(raw));
if (typeof resource === 'string') {
execOptions.stdout(resource);
}
else {
execOptions.stdout({
type: 'custom',
isEntity: true,
name: argvNoOptions[0] === 'cat' ? path.basename(argvNoOptions[1]) : argvNoOptions.slice(3).join(' '),
packageName: argvNoOptions[0] === 'cat' && path.dirname(argvNoOptions[1]),
prettyType: argvNoOptions[0] === 'cat' ? contentType : argvNoOptions[2],
contentType,
content: strip_ansi_1.default(raw),
resource,
modes: [{ mode: 'raw', direct: cmdline, defaultMode: true }]
});
}
}
catch (err) {
console.error('error parsing as semi structured output');
console.error(strip_ansi_1.default(raw));
execOptions.stdout(strip_ansi_1.default(raw));
}
}
if (msg.exitCode !== 0 && bytesWereWritten) {
const error = new Error('');
if (sawCode === 409)
error['code'] = 409;
else if (msg.exitCode !== 127 && sawCode === 404)
error['code'] = 404;
else
error['code'] = msg.exitCode;
if (msg.exitCode === 127) {
xtermContainer.classList.add('hide');
}
else {
error['hide'] = true;
}
reject(error);
}
else {
if (queuedInput && queuedInput.length > 0) {
cli_1.pasteQueuedInput(queuedInput);
}
resolve(true);
}
};
const finishUpAfterFinalResize = () => {
clearInterval(scrollPoll);
doScroll();
ws.removeEventListener('message', onMessage);
cleanUpTerminal();
const copy = terminal.element.cloneNode(true);
squash(copy);
copy.querySelector('.xterm-viewport').remove();
copy.querySelector('.xterm-helpers').remove();
copy.querySelector('.xterm-selection').remove();
const styles = copy.querySelectorAll('style');
for (let idx = 0; idx < styles.length; idx++) {
styles[idx].remove();
}
copy.classList.remove('enable-mouse-events');
resizer.reflowLineWraps(copy);
resizer.hideTrailingEmptyBlanks(true, copy);
Resizer.hideCursorOnlyRow(copy);
xtermContainer.removeChild(terminal.element);
xtermContainer.appendChild(copy);
respondToRepl();
};
const finishUp = () => {
const nLines = terminal.buffer.length;
if (resizer.wasEverInAltBufferMode() || (nLines <= terminal.rows && nLinesRaw < terminal.rows)) {
setTimeout(finishUpAfterFinalResize, 50);
}
else {
terminal.off('refresh', onRefresh);
terminal.on('refresh', finishUpAfterFinalResize);
terminal.resize(terminal.cols, nLines);
}
};
const nLines = terminal.buffer.length;
doScroll();
if (pendingWrites > 0) {
if (!resizer.wasEverInAltBufferMode() && nLines <= terminal.rows && nLinesRaw < terminal.rows) {
cbAfterPendingWrites = finishUp;
}
else {
cbAfterPendingWrites = () => setTimeout(finishUp, 50);
}
}
else {
if (nLines <= terminal.rows && nLinesRaw < terminal.rows) {
setTimeout(finishUp, 100);
}
else {
setTimeout(finishUp, 400);
}
}
}
});
ws.on('message', onMessage);
}
catch (error) {
const err = error;
if (err.code === 127 || err.code === 404) {
err.code = 127;
reject(err);
}
else {
if (err.code !== 503) {
debug('error in pty/client', err);
}
if (!err.message) {
err.message = 'Internal Error';
}
reject(err);
}
}
});
if (injectingCSS) {
setTimeout(exec, 0);
}
else {
exec();
}
});
//# sourceMappingURL=client.js.map