kui-shell
Version:
This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool
351 lines • 14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = require("debug");
const debug = debug_1.default('main/headless-pretty-print');
debug('loading');
const colors = require("colors/safe");
const mimic_dom_1 = require("../util/mimic-dom");
const table_1 = require("../webapp/models/table");
const entity_1 = require("../models/entity");
const is_1 = require("../models/mmr/is");
const types_1 = require("../util/types");
const log = console.log;
const error = console.error;
const verbose = process.argv.find(_ => _ === '-v');
const colorAlways = process.argv.find(_ => _ === '--color=always');
const neverColor = process.argv.find(_ => _ === '--no-color' || _ === '--no-colors');
const rawOutput = process.argv.find(_ => _ === '--raw-output');
const stdoutIsFIFO = process.platform !== 'win32' && process.stdout.isTTY;
const noColor = neverColor || (stdoutIsFIFO && !colorAlways);
debug('stdoutIsFIFO', stdoutIsFIFO, noColor);
const colorMap = {
'var(--color-brand-01)': colors.blue,
'var(--color-brand-02)': colors.blue,
'var(--color-support-02)': colors.blue,
'var(--color-black)': colors.black,
'var(--color-red)': colors.red,
'var(--color-green)': colors.green,
'var(--color-yellow)': colors.yellow,
'var(--color-blue)': colors.blue,
'var(--color-magenta)': colors.magenta,
'var(--color-cyan)': colors.cyan,
'var(--color-white)': colors.white,
'var(--color-gray)': colors.gray,
'var(--color-light-red)': colors.red,
'var(--color-light-green)': colors.green,
'var(--color-light-yellow)': colors.yellow
};
let graphicalShellIsOpen = false;
exports.setGraphicalShellIsOpen = () => {
graphicalShellIsOpen = true;
};
class DefaultPrettyOptions {
}
let firstPrettyDom = true;
const prettyDom = (dom, logger = log, stream = process.stdout, _color, { columnWidths, extraColor } = new DefaultPrettyOptions()) => {
debug('prettyDom');
const isHeader = dom.nodeType === 'h1' || dom.nodeType === 'h2' || dom.nodeType === 'h3' || dom.nodeType === 'h4';
const capitalize = false;
const hasMargin = dom.className.indexOf('bx--breadcrumb-item--slash') >= 0 ||
dom.className.indexOf('left-pad') >= 0 ||
dom.style['margin'] ||
dom.style['padding'];
if (hasMargin) {
stream.write(' ');
}
const extraColorChoice = isHeader || dom.hasStyle('fontWeight', 'bold')
? colors.bold
: dom.hasStyle('fontWeight', 500)
? colors.green
: dom.hasStyle('fontSize', '0.875em')
? colors.gray
: extraColor || colors.reset;
const colorFn = (dom.hasStyle('color') && colorMap[dom.style.color]) || _color;
if (isHeader) {
if (firstPrettyDom) {
firstPrettyDom = false;
}
else {
logger();
}
}
if (dom.innerText) {
const text = capitalize ? dom.innerText.charAt(0).toUpperCase() + dom.innerText.slice(1) : dom.innerText;
stream.write(extraColorChoice(colorFn(text)));
}
const newline = () => {
if (dom.nodeType === 'div' || isHeader) {
logger();
}
};
if (hasMargin) {
stream.write(' ');
}
if (dom.innerText) {
newline();
}
dom.children.forEach(child => prettyDom(child, logger, stream, _color, { extraColor: extraColorChoice }));
if (dom.rows) {
const columnWidths = [];
dom.rows.forEach(row => {
if (row.cells) {
row.cells.forEach((cell, idx) => {
const length = cell.recursiveInnerTextLength();
if (!columnWidths[idx])
columnWidths[idx] = length;
else
columnWidths[idx] = Math.max(columnWidths[idx], length);
});
}
});
dom.rows.forEach(row => {
prettyDom(row, logger, stream, _color, { columnWidths });
logger();
});
}
if (dom.cells) {
dom.cells.forEach((cell, idx) => {
prettyDom(cell, logger, stream, _color);
if (columnWidths && idx < dom.cells.length - 1) {
const slop = columnWidths[idx] - cell.recursiveInnerTextLength();
for (let jj = 0; jj < slop; jj++) {
stream.write(' ');
}
stream.write(' ');
}
});
}
if (isHeader && !dom.innerText) {
logger();
}
};
const prettyJSON = (msg, logger = log) => {
const serialized = JSON.stringify(msg, undefined, 2);
logger(serialized);
};
const pn = (actionName, packageName) => colors.dim(`${packageName ? packageName + '/' : ''}`) + colors.blue(actionName);
const prettyDate = (millis) => {
const date = new Date(millis);
const now = new Date();
if (date.getUTCFullYear() === now.getUTCFullYear() &&
date.getUTCMonth() === now.getUTCMonth() &&
date.getUTCDate() === now.getUTCDate()) {
return date.toLocaleTimeString();
}
else {
return date.toLocaleString();
}
};
const pp = (_) => colors.dim(_ ? 'public' : 'private');
const pk = (_) => colors.green(_.find(({ key }) => key === 'exec').value);
const rowifyAction = ({ name, packageName, publish, annotations, version }) => ({
name: pn(name, packageName),
'published?': pp(publish),
kind: pk(annotations),
version: colors.dim(version)
});
const rowifyPackage = ({ name, publish, binding }) => ({
name: pn(name),
'published?': pp(publish),
binding
});
const rowifySession = ({ sessionId, name, success, status, start }) => ({
sessionId,
app: pn(name),
start: colors.dim(prettyDate(start)),
status: status === 'pending' ? colors.yellow(status) : success ? colors.green(status) : colors.red(status)
});
const rowify = {
compositions: ({ name, packageName, prettyKind }) => ({
name: pn(name, packageName),
type: prettyKind
}),
session: rowifySession,
activations: ({ activationId, name }) => ({ activationId, name: pn(name) }),
actions: rowifyAction,
triggers: ({ name, publish }) => ({
name: pn(name),
'published?': pp(publish)
}),
packages: rowifyPackage,
plugins: ({ name, attributes }) => {
return {
name: pn(name),
version: colors.dim(attributes.find(({ key }) => key === 'version').value)
};
},
_default: ({ key, name, attributes }) => {
const row = {};
row[key || 'name'] = pn(name);
attributes.forEach(attr => {
if (!attr.placeholderValue) {
row[attr.key] = attr.value;
}
});
return row;
},
sequence: rowifyAction,
composer: rowifyAction,
binding: rowifyPackage,
live: rowifySession
};
function activationId(msg) {
return msg.activationId;
}
function name(msg) {
const entity = msg;
return entity.entity.name;
}
exports.print = (msg, logger = log, stream = process.stdout, colorFn = colors.reset, ok = 'ok') => {
if (ok === 'error') {
colorFn = colors.red;
}
if (verbose && typeof msg === 'string') {
debug('printing raw JSON, due to -v');
prettyJSON(msg, logger);
return;
}
if (msg && !graphicalShellIsOpen) {
try {
if (msg === true) {
debug('printing plain true');
logger(colors.green(ok));
}
else if (typeof msg === 'string' || typeof msg === 'boolean' || typeof msg === 'number') {
stream.write(msg);
}
else if (mimic_dom_1.ElementMimic.isFakeDom(msg)) {
debug('printing fake dom');
if (msg.className.indexOf('usage-error-wrapper') >= 0) {
stream = process.stdout;
logger = log;
}
prettyDom(msg, logger, stream, colorFn);
logger();
}
else if (types_1.isPromise(msg)) {
debug('printing promise');
return msg.then(msg => exports.print(msg, logger, stream, colorFn, ok));
}
else if (table_1.isTable(msg) || table_1.isMultiTable(msg)) {
debug('printing table');
if (table_1.isMultiTable(msg)) {
msg.tables.map(_ => exports.print(_, logger, stream, colorFn, ok));
}
else {
const type = (msg.header && (msg.header.prettyType || msg.header.type)) ||
(msg.body.length > 0 && (msg.body[0].prettyType || msg.body[0].type));
const print = (type && rowify[type]) || rowify._default;
logger(require('columnify')(msg.body.map(print), {
headingTransform: (_) => colors.dim(_)
}));
}
}
else if (entity_1.isMixedResponse(msg)) {
msg.forEach(_ => {
exports.print(_);
stream.write('\n');
});
return logger(colors.green(ok));
}
else if (is_1.isMultiModalResponse(msg)) {
throw new Error('cannot format this response in headless mode');
}
else if (Array.isArray(msg)) {
debug('printing array');
if (msg.length > 0) {
try {
if (typeof msg[0] === 'string') {
;
msg.forEach(_ => {
const logline = _.split(/(stdout|stderr)/);
if (logline && logline.length === 3 && !rawOutput) {
const colorFn = logline[1] === 'stdout' ? colors.reset : colors.red;
logger(colors.dim(new Date(logline[0].trim()).toLocaleString()) +
colorFn(logline[2].replace(/^:/, '')));
}
else {
logger(_);
}
});
return logger(colors.green(ok));
}
}
catch (err) {
error(err);
}
}
}
else if (types_1.isHTML(msg)) {
console.error('cannot format HTML message');
}
else if (entity_1.isMessageBearingEntity(msg)) {
if (mimic_dom_1.ElementMimic.isFakeDom(msg.message)) {
prettyDom(msg.message, logger, stream, colorFn);
logger();
}
else {
logger(msg.message);
}
}
else if (entity_1.isEntitySpec(msg)) {
debug('printing some sort of javascript object');
if (msg.verb && msg.name && (msg.verb === 'create' || msg.verb === 'update')) {
debug('printing create or update');
const isWebExported = msg.annotations && !!msg.annotations.find(({ key }) => key === 'web-export');
if (isWebExported) {
const contentType = (msg.annotations &&
msg.annotations.find(({ key }) => key === 'content-type-extension')) || { value: 'json' };
const apiHost = msg.apiHost;
const https = apiHost.startsWith('https://') || apiHost.startsWith('http://')
? ''
: apiHost === 'localhost'
? 'http://'
: 'https://';
const urlText = `${https}${apiHost}/api/v1/web/${msg.namespace}/${!msg.packageName ? 'default/' : ''}${msg.name}.${contentType.value}`;
logger(colors.blue(urlText));
}
logger(colors.green(`${ok}:`) + ` updated ${msg.type.replace(/s$/, '')} ${msg.name}`);
}
else if (msg.verb === 'delete') {
debug('printing delete');
logger(colors.green(`${ok}:`) + ` deleted ${msg.type.replace(/s$/, '')} ${msg.name}`);
}
else if (msg.verb === 'async' && activationId(msg)) {
msg.type === 'activations'
? logger(colors.green(`${ok}:`) + ` invoked ${name(msg)} with id ${activationId(msg)}`)
: logger(colors.green(`${ok}:`) + ` invoked ${msg.name} with id ${activationId(msg)}`);
}
else if (msg.verb === 'get' && activationId(msg)) {
debug('printing get activation');
delete msg.prettyType;
delete msg.verb;
delete msg.type;
delete msg.modes;
delete msg.version;
prettyJSON(msg, logger);
}
else {
if (msg.verb === 'get') {
delete msg.verb;
delete msg.type;
delete msg.modes;
delete msg.version;
}
prettyJSON(msg, logger);
}
}
else if (typeof msg === 'object') {
prettyJSON(msg, logger);
}
else {
logger(colorFn(msg));
}
}
catch (err) {
debug('got an error', err);
logger(colors.red(typeof msg === 'object' ? JSON.stringify(msg) : msg.toString()));
}
}
};
//# sourceMappingURL=headless-pretty-print.js.map