@decaf-ts/utils
Version:
module management utils for decaf-ts
129 lines • 15.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.StandardOutputWriter = void 0;
const constants_1 = require("./../utils/constants.cjs");
const styled_string_builder_1 = require("styled-string-builder");
const logging_1 = require("@decaf-ts/logging");
/**
* @description A standard output writer for handling command execution output.
* @summary This class implements the OutputWriter interface and provides methods for
* handling various types of output from command execution, including standard output,
* error output, and exit codes. It also includes utility methods for parsing commands
* and resolving or rejecting promises based on execution results.
*
* @template R - The type of the resolved value, defaulting to number.
*
* @param lock - A PromiseExecutor to control the asynchronous flow.
* @param args - Additional arguments (unused in the current implementation).
*
* @class
*/
class StandardOutputWriter {
/**
* @description Initializes a new instance of StandardOutputWriter.
* @summary Constructs the StandardOutputWriter with a lock mechanism and optional arguments.
*
* @param cmd
* @param lock - A PromiseExecutor to control the asynchronous flow.
* @param args - Additional arguments (currently unused).
*/
constructor(cmd, lock,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
...args) {
this.cmd = cmd;
this.lock = lock;
this.logger = logging_1.Logging.for(this.cmd);
}
/**
* @description Logs output to the console.
* @summary Formats and logs the given data with a timestamp and type indicator.
*
* @param type - The type of output (stdout or stderr).
* @param data - The data to be logged.
*/
log(type, data) {
data = Buffer.isBuffer(data) ? data.toString(constants_1.Encoding) : data;
const log = type === "stderr" ? (0, styled_string_builder_1.style)(data).red.text : data;
this.logger.info(log);
}
/**
* @description Handles standard output data.
* @summary Logs the given chunk as standard output.
*
* @param chunk - The data chunk to be logged.
*/
data(chunk) {
this.log("stdout", String(chunk));
}
/**
* @description Handles error output data.
* @summary Logs the given chunk as error output.
*
* @param chunk - The error data chunk to be logged.
*/
error(chunk) {
this.log("stderr", String(chunk));
}
/**
* @description Handles error objects.
* @summary Logs the error message from the given Error object.
*
* @param err - The Error object to be logged.
*/
errors(err) {
this.log("stderr", `Error executing command exited : ${err}`);
}
/**
* @description Handles the exit of a command.
* @summary Logs the exit code and resolves or rejects the promise based on the code.
*
* @param code - The exit code of the command.
* @param logs
*/
exit(code, logs) {
this.log("stdout", `command exited code : ${code === 0 ? (0, styled_string_builder_1.style)(code.toString()).green.text : (0, styled_string_builder_1.style)(code === null ? "null" : code.toString()).red.text}`);
if (code === 0) {
this.resolve(logs.map((l) => l.trim()).join("\n"));
}
else {
this.reject(new Error(logs.length ? logs.join("\n") : code.toString()));
}
}
/**
* @description Parses a command string or array into components.
* @summary Converts the command into a consistent format and stores it, then returns it split into command and arguments.
*
* @param command - The command as a string or array of strings.
* @return A tuple containing the command and its arguments as separate elements.
*/
parseCommand(command) {
command = typeof command === "string" ? command.split(" ") : command;
this.cmd = command.join(" ");
return [command[0], command.slice(1)];
}
/**
* @description Resolves the promise with a success message.
* @summary Logs a success message and resolves the promise with the given reason.
*
* @param reason - The reason for resolving the promise.
*/
resolve(reason) {
this.log("stdout", `${this.cmd} executed successfully: ${(0, styled_string_builder_1.style)(reason ? "ran to completion" : reason).green}`);
this.lock.resolve(reason);
}
/**
* @description Rejects the promise with an error message.
* @summary Logs an error message and rejects the promise with the given reason.
*
* @param reason - The reason for rejecting the promise, either a number (exit code) or a string.
*/
reject(reason) {
if (!(reason instanceof Error)) {
reason = new Error(typeof reason === "number" ? `Exit code ${reason}` : reason);
}
this.log("stderr", `${this.cmd} failed to execute: ${(0, styled_string_builder_1.style)(reason.message).red}`);
this.lock.reject(reason);
}
}
exports.StandardOutputWriter = StandardOutputWriter;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU3RhbmRhcmRPdXRwdXRXcml0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd3JpdGVycy9TdGFuZGFyZE91dHB1dFdyaXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3REFBOEM7QUFJOUMsaUVBQThDO0FBQzlDLCtDQUFvRDtBQUVwRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBYSxvQkFBb0I7SUFHL0I7Ozs7Ozs7T0FPRztJQUNILFlBQ1ksR0FBVyxFQUNYLElBQXdCO0lBQ2xDLDZEQUE2RDtJQUM3RCxHQUFHLElBQWU7UUFIUixRQUFHLEdBQUgsR0FBRyxDQUFRO1FBQ1gsU0FBSSxHQUFKLElBQUksQ0FBb0I7UUFJbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQkFBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNPLEdBQUcsQ0FBQyxJQUFnQixFQUFFLElBQXFCO1FBQ25ELElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzlELE1BQU0sR0FBRyxHQUFHLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUEsNkJBQUssRUFBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDNUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsSUFBSSxDQUFDLEtBQVU7UUFDYixJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7O09BS0c7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QU0sQ0FBQyxDQUFDO0lBQzNCLENBQUM7Q0FDRjtBQS9IRCxvREErSEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbmNvZGluZyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IE91dHB1dFdyaXRlciB9IGZyb20gXCIuL091dHB1dFdyaXRlclwiO1xuaW1wb3J0IHsgUHJvbWlzZUV4ZWN1dG9yIH0gZnJvbSBcIi4uL3V0aWxzL3R5cGVzXCI7XG5pbXBvcnQgeyBPdXRwdXRUeXBlIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IHN0eWxlIH0gZnJvbSBcInN0eWxlZC1zdHJpbmctYnVpbGRlclwiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgc3RhbmRhcmQgb3V0cHV0IHdyaXRlciBmb3IgaGFuZGxpbmcgY29tbWFuZCBleGVjdXRpb24gb3V0cHV0LlxuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBpbXBsZW1lbnRzIHRoZSBPdXRwdXRXcml0ZXIgaW50ZXJmYWNlIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvclxuICogaGFuZGxpbmcgdmFyaW91cyB0eXBlcyBvZiBvdXRwdXQgZnJvbSBjb21tYW5kIGV4ZWN1dGlvbiwgaW5jbHVkaW5nIHN0YW5kYXJkIG91dHB1dCxcbiAqIGVycm9yIG91dHB1dCwgYW5kIGV4aXQgY29kZXMuIEl0IGFsc28gaW5jbHVkZXMgdXRpbGl0eSBtZXRob2RzIGZvciBwYXJzaW5nIGNvbW1hbmRzXG4gKiBhbmQgcmVzb2x2aW5nIG9yIHJlamVjdGluZyBwcm9taXNlcyBiYXNlZCBvbiBleGVjdXRpb24gcmVzdWx0cy5cbiAqXG4gKiBAdGVtcGxhdGUgUiAtIFRoZSB0eXBlIG9mIHRoZSByZXNvbHZlZCB2YWx1ZSwgZGVmYXVsdGluZyB0byBudW1iZXIuXG4gKlxuICogQHBhcmFtIGxvY2sgLSBBIFByb21pc2VFeGVjdXRvciB0byBjb250cm9sIHRoZSBhc3luY2hyb25vdXMgZmxvdy5cbiAqIEBwYXJhbSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgKHVudXNlZCBpbiB0aGUgY3VycmVudCBpbXBsZW1lbnRhdGlvbikuXG4gKlxuICogQGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGFuZGFyZE91dHB1dFdyaXRlcjxSID0gc3RyaW5nPiBpbXBsZW1lbnRzIE91dHB1dFdyaXRlciB7XG4gIHByb3RlY3RlZCBsb2dnZXI6IExvZ2dlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemVzIGEgbmV3IGluc3RhbmNlIG9mIFN0YW5kYXJkT3V0cHV0V3JpdGVyLlxuICAgKiBAc3VtbWFyeSBDb25zdHJ1Y3RzIHRoZSBTdGFuZGFyZE91dHB1dFdyaXRlciB3aXRoIGEgbG9jayBtZWNoYW5pc20gYW5kIG9wdGlvbmFsIGFyZ3VtZW50cy5cbiAgICpcbiAgICogQHBhcmFtIGNtZFxuICAgKiBAcGFyYW0gbG9jayAtIEEgUHJvbWlzZUV4ZWN1dG9yIHRvIGNvbnRyb2wgdGhlIGFzeW5jaHJvbm91cyBmbG93LlxuICAgKiBAcGFyYW0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIChjdXJyZW50bHkgdW51c2VkKS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBjbWQ6IHN0cmluZyxcbiAgICBwcm90ZWN0ZWQgbG9jazogUHJvbWlzZUV4ZWN1dG9yPFI+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiB1bmtub3duW11cbiAgKSB7XG4gICAgdGhpcy5sb2dnZXIgPSBMb2dnaW5nLmZvcih0aGlzLmNtZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExvZ3Mgb3V0cHV0IHRvIHRoZSBjb25zb2xlLlxuICAgKiBAc3VtbWFyeSBGb3JtYXRzIGFuZCBsb2dzIHRoZSBnaXZlbiBkYXRhIHdpdGggYSB0aW1lc3RhbXAgYW5kIHR5cGUgaW5kaWNhdG9yLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIFRoZSB0eXBlIG9mIG91dHB1dCAoc3Rkb3V0IG9yIHN0ZGVycikuXG4gICAqIEBwYXJhbSBkYXRhIC0gVGhlIGRhdGEgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgcHJvdGVjdGVkIGxvZyh0eXBlOiBPdXRwdXRUeXBlLCBkYXRhOiBzdHJpbmcgfCBCdWZmZXIpIHtcbiAgICBkYXRhID0gQnVmZmVyLmlzQnVmZmVyKGRhdGEpID8gZGF0YS50b1N0cmluZyhFbmNvZGluZykgOiBkYXRhO1xuICAgIGNvbnN0IGxvZyA9IHR5cGUgPT09IFwic3RkZXJyXCIgPyBzdHlsZShkYXRhKS5yZWQudGV4dCA6IGRhdGE7XG4gICAgdGhpcy5sb2dnZXIuaW5mbyhsb2cpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIHN0YW5kYXJkIG91dHB1dCBkYXRhLlxuICAgKiBAc3VtbWFyeSBMb2dzIHRoZSBnaXZlbiBjaHVuayBhcyBzdGFuZGFyZCBvdXRwdXQuXG4gICAqXG4gICAqIEBwYXJhbSBjaHVuayAtIFRoZSBkYXRhIGNodW5rIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIGRhdGEoY2h1bms6IGFueSkge1xuICAgIHRoaXMubG9nKFwic3Rkb3V0XCIsIFN0cmluZyhjaHVuaykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBIYW5kbGVzIGVycm9yIG91dHB1dCBkYXRhLlxuICAgKiBAc3VtbWFyeSBMb2dzIHRoZSBnaXZlbiBjaHVuayBhcyBlcnJvciBvdXRwdXQuXG4gICAqXG4gICAqIEBwYXJhbSBjaHVuayAtIFRoZSBlcnJvciBkYXRhIGNodW5rIHRvIGJlIGxvZ2dlZC5cbiAgICovXG4gIGVycm9yKGNodW5rOiBhbnkpIHtcbiAgICB0aGlzLmxvZyhcInN0ZGVyclwiLCBTdHJpbmcoY2h1bmspKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSGFuZGxlcyBlcnJvciBvYmplY3RzLlxuICAgKiBAc3VtbWFyeSBMb2dzIHRoZSBlcnJvciBtZXNzYWdlIGZyb20gdGhlIGdpdmVuIEVycm9yIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIGVyciAtIFRoZSBFcnJvciBvYmplY3QgdG8gYmUgbG9nZ2VkLlxuICAgKi9cbiAgZXJyb3JzKGVycjogRXJyb3IpIHtcbiAgICB0aGlzLmxvZyhcInN0ZGVyclwiLCBgRXJyb3IgZXhlY3V0aW5nIGNvbW1hbmQgZXhpdGVkIDogJHtlcnJ9YCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEhhbmRsZXMgdGhlIGV4aXQgb2YgYSBjb21tYW5kLlxuICAgKiBAc3VtbWFyeSBMb2dzIHRoZSBleGl0IGNvZGUgYW5kIHJlc29sdmVzIG9yIHJlamVjdHMgdGhlIHByb21pc2UgYmFzZWQgb24gdGhlIGNvZGUuXG4gICAqXG4gICAqIEBwYXJhbSBjb2RlIC0gVGhlIGV4aXQgY29kZSBvZiB0aGUgY29tbWFuZC5cbiAgICogQHBhcmFtIGxvZ3NcbiAgICovXG4gIGV4aXQoY29kZTogbnVtYmVyIHwgc3RyaW5nLCBsb2dzOiBzdHJpbmdbXSkge1xuICAgIHRoaXMubG9nKFxuICAgICAgXCJzdGRvdXRcIixcbiAgICAgIGBjb21tYW5kIGV4aXRlZCBjb2RlIDogJHtjb2RlID09PSAwID8gc3R5bGUoY29kZS50b1N0cmluZygpKS5ncmVlbi50ZXh0IDogc3R5bGUoY29kZSA9PT0gbnVsbCA/IFwibnVsbFwiIDogY29kZS50b1N0cmluZygpKS5yZWQudGV4dH1gXG4gICAgKTtcbiAgICBpZiAoY29kZSA9PT0gMCkge1xuICAgICAgdGhpcy5yZXNvbHZlKGxvZ3MubWFwKChsKSA9PiBsLnRyaW0oKSkuam9pbihcIlxcblwiKSBhcyBSKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZWplY3QobmV3IEVycm9yKGxvZ3MubGVuZ3RoID8gbG9ncy5qb2luKFwiXFxuXCIpIDogY29kZS50b1N0cmluZygpKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQYXJzZXMgYSBjb21tYW5kIHN0cmluZyBvciBhcnJheSBpbnRvIGNvbXBvbmVudHMuXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIHRoZSBjb21tYW5kIGludG8gYSBjb25zaXN0ZW50IGZvcm1hdCBhbmQgc3RvcmVzIGl0LCB0aGVuIHJldHVybnMgaXQgc3BsaXQgaW50byBjb21tYW5kIGFuZCBhcmd1bWVudHMuXG4gICAqXG4gICAqIEBwYXJhbSBjb21tYW5kIC0gVGhlIGNvbW1hbmQgYXMgYSBzdHJpbmcgb3IgYXJyYXkgb2Ygc3RyaW5ncy5cbiAgICogQHJldHVybiBBIHR1cGxlIGNvbnRhaW5pbmcgdGhlIGNvbW1hbmQgYW5kIGl0cyBhcmd1bWVudHMgYXMgc2VwYXJhdGUgZWxlbWVudHMuXG4gICAqL1xuICBwYXJzZUNvbW1hbmQoY29tbWFuZDogc3RyaW5nIHwgc3RyaW5nW10pOiBbc3RyaW5nLCBzdHJpbmdbXV0ge1xuICAgIGNvbW1hbmQgPSB0eXBlb2YgY29tbWFuZCA9PT0gXCJzdHJpbmdcIiA/IGNvbW1hbmQuc3BsaXQoXCIgXCIpIDogY29tbWFuZDtcbiAgICB0aGlzLmNtZCA9IGNvbW1hbmQuam9pbihcIiBcIik7XG4gICAgcmV0dXJuIFtjb21tYW5kWzBdLCBjb21tYW5kLnNsaWNlKDEpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVzb2x2ZXMgdGhlIHByb21pc2Ugd2l0aCBhIHN1Y2Nlc3MgbWVzc2FnZS5cbiAgICogQHN1bW1hcnkgTG9ncyBhIHN1Y2Nlc3MgbWVzc2FnZSBhbmQgcmVzb2x2ZXMgdGhlIHByb21pc2Ugd2l0aCB0aGUgZ2l2ZW4gcmVhc29uLlxuICAgKlxuICAgKiBAcGFyYW0gcmVhc29uIC0gVGhlIHJlYXNvbiBmb3IgcmVzb2x2aW5nIHRoZSBwcm9taXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlc29sdmUocmVhc29uOiBSKSB7XG4gICAgdGhpcy5sb2coXG4gICAgICBcInN0ZG91dFwiLFxuICAgICAgYCR7dGhpcy5jbWR9IGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseTogJHtzdHlsZShyZWFzb24gPyBcInJhbiB0byBjb21wbGV0aW9uXCIgOiAocmVhc29uIGFzIHN0cmluZykpLmdyZWVufWBcbiAgICApO1xuICAgIHRoaXMubG9jay5yZXNvbHZlKHJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlamVjdHMgdGhlIHByb21pc2Ugd2l0aCBhbiBlcnJvciBtZXNzYWdlLlxuICAgKiBAc3VtbWFyeSBMb2dzIGFuIGVycm9yIG1lc3NhZ2UgYW5kIHJlamVjdHMgdGhlIHByb21pc2Ugd2l0aCB0aGUgZ2l2ZW4gcmVhc29uLlxuICAgKlxuICAgKiBAcGFyYW0gcmVhc29uIC0gVGhlIHJlYXNvbiBmb3IgcmVqZWN0aW5nIHRoZSBwcm9taXNlLCBlaXRoZXIgYSBudW1iZXIgKGV4aXQgY29kZSkgb3IgYSBzdHJpbmcuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVqZWN0KHJlYXNvbjogbnVtYmVyIHwgc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBpZiAoIShyZWFzb24gaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgIHJlYXNvbiA9IG5ldyBFcnJvcihcbiAgICAgICAgdHlwZW9mIHJlYXNvbiA9PT0gXCJudW1iZXJcIiA/IGBFeGl0IGNvZGUgJHtyZWFzb259YCA6IHJlYXNvblxuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5sb2coXG4gICAgICBcInN0ZGVyclwiLFxuICAgICAgYCR7dGhpcy5jbWR9IGZhaWxlZCB0byBleGVjdXRlOiAke3N0eWxlKHJlYXNvbi5tZXNzYWdlKS5yZWR9YFxuICAgICk7XG4gICAgdGhpcy5sb2NrLnJlamVjdChyZWFzb24pO1xuICB9XG59XG4iXX0=