UNPKG

@qodalis/angular-cli

Version:

A lightweight and flexible command-line interface (CLI) tool designed to streamline workflows and automate tasks for developers.

84 lines 13.8 kB
import { CliForegroundColor, CliIcon, formatJson, } from '@qodalis/cli-core'; export class CliTerminalWriter { constructor(terminal) { this.terminal = terminal; } write(text) { this.terminal.write(text); } writeln(text) { this.terminal.writeln(text || ''); } writeSuccess(message) { this.writeLog(message, CliForegroundColor.Green, CliIcon.CheckIcon); } writeInfo(message) { this.writeLog(message, CliForegroundColor.Cyan, CliIcon.InfoIcon); } writeWarning(message) { this.writeLog(message, CliForegroundColor.Yellow, CliIcon.WarningIcon); } writeError(message) { this.writeLog(message, CliForegroundColor.Red, CliIcon.CrossIcon); } writeLog(message, color, icon) { this.terminal.writeln(this.wrapInColor(icon ? icon + ' ' + message : message, color)); } writeDivider(options) { const { color, length: oLength, char: oChar } = options || {}; let length = oLength ?? 80; let char = oChar ?? '-'; if (this.terminal.cols < length) { length = this.terminal.cols; } let text = char.repeat(length); if (color) { text = this.wrapInColor(text, color); } this.writeln(text); } wrapInColor(text, color) { return color + text + CliForegroundColor.Reset; } wrapInBackgroundColor(text, color) { return color + text + CliForegroundColor.Reset; } writeJson(json) { this.terminal.writeln(formatJson(json)); } writeToFile(fileName, content) { const blob = new Blob([content], { type: 'text/plain' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); } writeObjectsAsTable(objects) { if (objects.length === 0) { this.writeInfo('No objects to display'); return; } const headers = Object.keys(objects[0]); const rows = objects.map((object) => headers.map((header) => object[header])); this.writeTable(headers, rows); } writeTable(headers, rows) { // Calculate column widths const colWidths = headers.map((header, colIndex) => Math.max(header.length, ...rows.map((row) => row[colIndex]?.length || 0))); // Function to pad text to a specific width const padText = (text, width) => text?.toString()?.padEnd(width, ' '); // Write the header this.write(headers .map((header, i) => this.wrapInColor(padText(header, colWidths[i]), CliForegroundColor.Yellow)) .join(' | ') + '\r\n'); this.write('-'.repeat(colWidths.reduce((sum, w) => sum + w + 3, -3)) + '\r\n'); // Write the rows rows.forEach((row) => { this.write(row.map((cell, i) => padText(cell, colWidths[i])).join(' | ') + '\r\n'); }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXRlcm1pbmFsLXdyaXRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NsaS9zcmMvbGliL2NsaS9zZXJ2aWNlcy9jbGktdGVybWluYWwtd3JpdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFFSCxrQkFBa0IsRUFDbEIsT0FBTyxFQUNQLFVBQVUsR0FFYixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLE1BQU0sT0FBTyxpQkFBaUI7SUFDMUIsWUFBNEIsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtJQUFHLENBQUM7SUFFbEQsS0FBSyxDQUFDLElBQVk7UUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBQ0QsT0FBTyxDQUFDLElBQWE7UUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTSxZQUFZLENBQUMsT0FBZTtRQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFTSxTQUFTLENBQUMsT0FBZTtRQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFFTSxZQUFZLENBQUMsT0FBZTtRQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFTSxVQUFVLENBQUMsT0FBZTtRQUM3QixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxH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LEVBQUUsRUFBRTtZQUNqQixJQUFJLENBQUMsS0FBSyxDQUNOLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztnQkFDekQsTUFBTSxDQUNiLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRlcm1pbmFsIH0gZnJvbSAnQHh0ZXJtL3h0ZXJtJztcbmltcG9ydCB7XG4gICAgQ2xpQmFja2dyb3VuZENvbG9yLFxuICAgIENsaUZvcmVncm91bmRDb2xvcixcbiAgICBDbGlJY29uLFxuICAgIGZvcm1hdEpzb24sXG4gICAgSUNsaVRlcm1pbmFsV3JpdGVyLFxufSBmcm9tICdAcW9kYWxpcy9jbGktY29yZSc7XG5cbmV4cG9ydCBjbGFzcyBDbGlUZXJtaW5hbFdyaXRlciBpbXBsZW1lbnRzIElDbGlUZXJtaW5hbFdyaXRlciB7XG4gICAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHRlcm1pbmFsOiBUZXJtaW5hbCkge31cblxuICAgIHdyaXRlKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLnRlcm1pbmFsLndyaXRlKHRleHQpO1xuICAgIH1cbiAgICB3cml0ZWxuKHRleHQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50ZXJtaW5hbC53cml0ZWxuKHRleHQgfHwgJycpO1xuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZVN1Y2Nlc3MobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMud3JpdGVMb2cobWVzc2FnZSwgQ2xpRm9yZWdyb3VuZENvbG9yLkdyZWVuLCBDbGlJY29uLkNoZWNrSWNvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlSW5mbyhtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy53cml0ZUxvZyhtZXNzYWdlLCBDbGlGb3JlZ3JvdW5kQ29sb3IuQ3lhbiwgQ2xpSWNvbi5JbmZvSWNvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlV2FybmluZyhtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy53cml0ZUxvZyhtZXNzYWdlLCBDbGlGb3JlZ3JvdW5kQ29sb3IuWWVsbG93LCBDbGlJY29uLldhcm5pbmdJY29uKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVFcnJvcihtZXNzYWdlOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy53cml0ZUxvZyhtZXNzYWdlLCBDbGlGb3JlZ3JvdW5kQ29sb3IuUmVkLCBDbGlJY29uLkNyb3NzSWNvbik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB3cml0ZUxvZyhcbiAgICAgICAgbWVzc2FnZTogc3RyaW5nLFxuICAgICAgICBjb2xvcjogQ2xpRm9yZWdyb3VuZENvbG9yLFxuICAgICAgICBpY29uPzogQ2xpSWNvbixcbiAgICApIHtcbiAgICAgICAgdGhpcy50ZXJtaW5hbC53cml0ZWxuKFxuICAgICAgICAgICAgdGhpcy53cmFwSW5Db2xvcihpY29uID8gaWNvbiArICcgJyArIG1lc3NhZ2UgOiBtZXNzYWdlLCBjb2xvciksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlRGl2aWRlcihvcHRpb25zPzoge1xuICAgICAgICBjb2xvcj86IENsaUZvcmVncm91bmRDb2xvcjtcbiAgICAgICAgbGVuZ3RoPzogbnVtYmVyO1xuICAgICAgICBjaGFyPzogc3RyaW5nO1xuICAgIH0pIHtcbiAgICAgICAgY29uc3QgeyBjb2xvciwgbGVuZ3RoOiBvTGVuZ3RoLCBjaGFyOiBvQ2hhciB9ID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICBsZXQgbGVuZ3RoID0gb0xlbmd0aCA/PyA4MDtcbiAgICAgICAgbGV0IGNoYXIgPSBvQ2hhciA/PyAnLSc7XG5cbiAgICAgICAgaWYgKHRoaXMudGVybWluYWwuY29scyA8IGxlbmd0aCkge1xuICAgICAgICAgICAgbGVuZ3RoID0gdGhpcy50ZXJtaW5hbC5jb2xzO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRleHQgPSBjaGFyLnJlcGVhdChsZW5ndGgpO1xuXG4gICAgICAgIGlmIChjb2xvcikge1xuICAgICAgICAgICAgdGV4dCA9IHRoaXMud3JhcEluQ29sb3IodGV4dCwgY29sb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy53cml0ZWxuKHRleHQpO1xuICAgIH1cblxuICAgIHB1YmxpYyB3cmFwSW5Db2xvcih0ZXh0OiBzdHJpbmcsIGNvbG9yOiBDbGlGb3JlZ3JvdW5kQ29sb3IpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gY29sb3IgKyB0ZXh0ICsgQ2xpRm9yZWdyb3VuZENvbG9yLlJlc2V0O1xuICAgIH1cblxuICAgIHB1YmxpYyB3cmFwSW5CYWNrZ3JvdW5kQ29sb3IodGV4dDogc3RyaW5nLCBjb2xvcjogQ2xpQmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgIHJldHVybiBjb2xvciArIHRleHQgKyBDbGlGb3JlZ3JvdW5kQ29sb3IuUmVzZXQ7XG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlSnNvbihqc29uOiBhbnkpIHtcbiAgICAgICAgdGhpcy50ZXJtaW5hbC53cml0ZWxuKGZvcm1hdEpzb24oanNvbikpO1xuICAgIH1cblxuICAgIHB1YmxpYyB3cml0ZVRvRmlsZShmaWxlTmFtZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjb250ZW50XSwgeyB0eXBlOiAndGV4dC9wbGFpbicgfSk7XG4gICAgICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIGxpbmsuaHJlZiA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGxpbmsuZG93bmxvYWQgPSBmaWxlTmFtZTtcblxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuICAgICAgICBsaW5rLmNsaWNrKCk7XG4gICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgfVxuXG4gICAgcHVibGljIHdyaXRlT2JqZWN0c0FzVGFibGUob2JqZWN0czogYW55W10pOiB2b2lkIHtcbiAgICAgICAgaWYgKG9iamVjdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLndyaXRlSW5mbygnTm8gb2JqZWN0cyB0byBkaXNwbGF5Jyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBoZWFkZXJzID0gT2JqZWN0LmtleXMob2JqZWN0c1swXSk7XG4gICAgICAgIGNvbnN0IHJvd3MgPSBvYmplY3RzLm1hcCgob2JqZWN0KSA9PlxuICAgICAgICAgICAgaGVhZGVycy5tYXAoKGhlYWRlcikgPT4gb2JqZWN0W2hlYWRlcl0pLFxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMud3JpdGVUYWJsZShoZWFkZXJzLCByb3dzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgd3JpdGVUYWJsZShoZWFkZXJzOiBzdHJpbmdbXSwgcm93czogc3RyaW5nW11bXSk6IHZvaWQge1xuICAgICAgICAvLyBDYWxjdWxhdGUgY29sdW1uIHdpZHRoc1xuICAgICAgICBjb25zdCBjb2xXaWR0aHMgPSBoZWFkZXJzLm1hcCgoaGVhZGVyLCBjb2xJbmRleCkgPT5cbiAgICAgICAgICAgIE1hdGgubWF4KFxuICAgICAgICAgICAgICAgIGhlYWRlci5sZW5ndGgsXG4gICAgICAgICAgICAgICAgLi4ucm93cy5tYXAoKHJvdykgPT4gcm93W2NvbEluZGV4XT8ubGVuZ3RoIHx8IDApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBGdW5jdGlvbiB0byBwYWQgdGV4dCB0byBhIHNwZWNpZmljIHdpZHRoXG4gICAgICAgIGNvbnN0IHBhZFRleHQgPSAodGV4dDogc3RyaW5nLCB3aWR0aDogbnVtYmVyKSA9PlxuICAgICAgICAgICAgdGV4dD8udG9TdHJpbmcoKT8ucGFkRW5kKHdpZHRoLCAnICcpO1xuXG4gICAgICAgIC8vIFdyaXRlIHRoZSBoZWFkZXJcbiAgICAgICAgdGhpcy53cml0ZShcbiAgICAgICAgICAgIGhlYWRlcnNcbiAgICAgICAgICAgICAgICAubWFwKChoZWFkZXIsIGkpID0+XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud3JhcEluQ29sb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBwYWRUZXh0KGhlYWRlciwgY29sV2lkdGhzW2ldKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3csXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5qb2luKCcgfCAnKSArICdcXHJcXG4nLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLndyaXRlKFxuICAgICAgICAgICAgJy0nLnJlcGVhdChjb2xXaWR0aHMucmVkdWNlKChzdW0sIHcpID0+IHN1bSArIHcgKyAzLCAtMykpICsgJ1xcclxcbicsXG4gICAgICAgICk7XG5cbiAgICAgICAgLy8gV3JpdGUgdGhlIHJvd3NcbiAgICAgICAgcm93cy5mb3JFYWNoKChyb3cpID0+IHtcbiAgICAgICAgICAgIHRoaXMud3JpdGUoXG4gICAgICAgICAgICAgICAgcm93Lm1hcCgoY2VsbCwgaSkgPT4gcGFkVGV4dChjZWxsLCBjb2xXaWR0aHNbaV0pKS5qb2luKCcgfCAnKSArXG4gICAgICAgICAgICAgICAgICAgICdcXHJcXG4nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIl19