@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
162 lines • 6.94 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { inject, injectable } from 'tsyringe-neo';
import { InjectTokens } from './dependency-injection/inject-tokens.js';
import { patchInject } from './dependency-injection/container-helper.js';
let HelpRenderer = class HelpRenderer {
logger;
constructor(logger) {
this.logger = logger;
this.logger = patchInject(logger, InjectTokens.SoloLogger, this.constructor.name);
}
splitAtClosestWhitespace(input, maxLength = 120) {
if (input.length <= maxLength) {
return [input, ''];
}
const splitIndex = input.lastIndexOf(' ', maxLength);
if (splitIndex === -1) {
return [input, ''];
}
return [input.slice(0, Math.max(0, splitIndex)), input.slice(Math.max(0, splitIndex + 1))];
}
createFlagsTable(lines) {
const table = [];
for (const line of lines) {
let columns = line.split(/(--[1-9a-zA-Z|-]+)/);
// if the description contains --flag there will be more than the expected amount of columns
// joins all columns after columns[2]
if (columns.length > 3) {
const firstPart = columns.slice(0, 2);
const secondPart = columns.slice(2).join(' ');
columns = [...firstPart, secondPart];
}
else if (columns.length === 1 && table.length > 0) {
const descriptions = columns[0].split(/(\[.+])/);
table.at(-1)[2] += ` ${descriptions[0].trim()}`;
if (descriptions[1]) {
table.at(-1)[3] += ` ${descriptions[1].trim()}`.trim();
}
}
try {
const descriptions = columns[2].split(/(\[.+])/);
columns[2] = descriptions[0];
columns[3] = descriptions[1] || '';
columns = columns.map((column) => column.trim());
table.push(columns);
}
catch (error) {
this.logger.debug(`Error processing line for help rendering: ${line}`, error);
}
}
return table;
}
sortFlagsTable(table) {
table.sort((row1, row2) => {
return row1[1].localeCompare(row2[1]);
});
const requiredTable = table.filter((row) => row[3].includes('required'));
const optionalTable = table.filter((row) => !row[3].includes('required'));
return [
...requiredTable,
['', '', '', ''], // add a blank line between required and optional flags
...optionalTable,
];
}
calculateMaxColumnLengths(table) {
const columnMaxLengths = [0, 0, 0, 0];
for (const row of table) {
for (const [index, element] of row.entries()) {
columnMaxLengths[index] = Math.max(columnMaxLengths[index], element.length);
}
}
return columnMaxLengths;
}
wrapFlagsTable(table, columnMaxLengths, wrap) {
const wrappedTable = [];
for (const row of table) {
if (row[2].length > wrap) {
const description = row[2];
let splitDescription = this.splitAtClosestWhitespace(description, wrap);
wrappedTable.push([row[0], row[1], splitDescription[0], row[3]]);
while (splitDescription[1] && splitDescription[1].length > 0) {
splitDescription = this.splitAtClosestWhitespace(splitDescription[1], wrap);
wrappedTable.push(['', '', splitDescription[0], '']);
}
}
else {
wrappedTable.push(row);
}
}
return wrappedTable;
}
getDescriptionWrap(terminalWidth, columnMaxLengths) {
let wrap = terminalWidth - columnMaxLengths[0] - columnMaxLengths[1] - columnMaxLengths[3] - 6;
if (wrap < 30) {
wrap = 30;
} // set min and max values
if (wrap > 70) {
wrap = 70;
}
if (columnMaxLengths[2] < wrap) {
wrap = columnMaxLengths[2];
}
else {
columnMaxLengths[2] = wrap;
}
return wrap;
}
addColumnPadding(table, columnMaxLengths) {
const outputLines = [];
for (const row of table) {
const line = [];
for (const [index, element] of row.entries()) {
line.push(element.padEnd(columnMaxLengths[index]));
}
outputLines.push(line.join(' '));
}
return outputLines;
}
render(rootCmd, rawHelp) {
const splittingString = 'Options:\n';
const splitOutput = rawHelp.split(splittingString);
if (splitOutput.length < 2) {
this.logger.showUser(rawHelp);
return;
}
let finalOutput = splitOutput[0] + splittingString;
let lines = splitOutput[1].split('\n');
lines = lines.map((line) => line.replace(/^\s+/, ''));
// Formatting for flag options
const table = this.createFlagsTable(lines);
// apply sorting
const sortedTable = this.sortFlagsTable(table);
const columnMaxLengths = this.calculateMaxColumnLengths(sortedTable);
// wrap the description column at the wrapping point
const terminalWidth = rootCmd.terminalWidth();
const wrap = this.getDescriptionWrap(terminalWidth, columnMaxLengths);
const wrappedTable = this.wrapFlagsTable(sortedTable, columnMaxLengths, wrap);
const outputLines = this.addColumnPadding(wrappedTable, columnMaxLengths);
finalOutput += '\n';
finalOutput += outputLines.join('\n');
finalOutput += '\n';
this.logger.showUser(finalOutput);
}
};
HelpRenderer = __decorate([
injectable(),
__param(0, inject(InjectTokens.SoloLogger)),
__metadata("design:paramtypes", [Object])
], HelpRenderer);
export { HelpRenderer };
//# sourceMappingURL=help-renderer.js.map