UNPKG

@nu-art/commando

Version:
181 lines (180 loc) 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CommandoInteractive = void 0; const ts_common_1 = require("@nu-art/ts-common"); const InteractiveShell_1 = require("./InteractiveShell"); const BaseCommando_1 = require("../core/BaseCommando"); class CommandoInteractive extends BaseCommando_1.BaseCommando { /** * Creates a new instance of CommandoInteractive merged with the provided plugins. * @param {Constructor<any>[]} plugins - The plugins to merge with CommandoInteractive. * @returns {CommandoInteractive} - The new instance of CommandoInteractive merged with the plugins. */ static create(...plugins) { const _commando = BaseCommando_1.BaseCommando._create(CommandoInteractive, ...plugins); const commando = _commando; commando.shell = new InteractiveShell_1.InteractiveShell(); commando.shell.setMinLevel(ts_common_1.LogLevel.Verbose); return commando; } /** * Constructs a CommandoInteractive instance. */ constructor() { super(); this.shell = new InteractiveShell_1.InteractiveShell(); } /** * Toggles or sets the debug mode. * @param {boolean} [debug] - If provided, sets the debug mode to this value. Otherwise, toggles the current debug mode. * @returns {boolean} - The current state of debug mode. */ debug(debug) { this.shell.debug(debug); return super.debug(debug); } /** * Sets the UID for the shell. * @param {string} uid - The UID to set. * @returns {this} - The CommandoInteractive instance for method chaining. */ setUID(uid) { this.shell.setUID(uid); return this; } /** * Closes the shell, optionally with a callback function. * @returns {this} - The CommandoInteractive instance for method chaining. */ close() { return this.shell.endInteractive(); } /** * Kills the shell process with a given signal. * @param {NodeJS.Signals | number} [signal] - The signal to send to the process. * @returns {boolean} - Whether the kill signal was successfully sent. */ kill(signal) { return this.shell.kill(signal); } /** * Gracefully kills a process by its PID. * @param {number} [pid] - The PID of the process to kill. */ async gracefullyKill(pid) { return this.shell.gracefullyKill(pid); } /** * Waits for a log entry that matches a specified pattern, then executes a callback. * @param {string | RegExp} filter - The pattern to match in log entries. * @param {(match: RegExpMatchArray) => any} callback - The callback to execute when a match is found. */ onLog(filter, callback) { const regexp = typeof filter === 'string' ? new RegExp(filter) : filter; const logFilter = (log) => { const match = log.match(regexp); if (!match) return true; callback(match); return true; }; this.addLogProcessor(logFilter); return this; } /** * Executes commands asynchronously and listens for the PID. * * @param {Function} pidListener - A listener function to handle the PID. * @param {Function} [callback] - A callback function to handle the command output. * @returns {Promise<T>} - The result of the callback function. */ async executeAsync(pidListener, callback) { const pidUniqueKey = (0, ts_common_1.generateHex)(16); const regexp = new RegExp(`${pidUniqueKey}=(\\d+)`); const functionContent = this.builder.reset().trim() + ' &'; const pidLogProcessor = (log) => { const match = log.match(regexp); if (!match) return true; const pid = +match[1]; pidListener(pid); return false; }; return await this .append(functionContent) .append('pid=$!') .append(`echo "${pidUniqueKey}=\${pid}"`) .append(`wait \$pid`) .addLogProcessor(pidLogProcessor) .execute(callback); } /** * Executes commands and processes logs to extract exit code. * @param {Function} [callback] - A callback function to handle the command output. * @returns {Promise<T>} - The result of the callback function. */ async execute(callback) { return await new Promise((resolve, reject) => { const uniqueKey = (0, ts_common_1.generateHex)(16); const regexp = new RegExp(`${uniqueKey}=(\\d+)`); let _stderr = ''; let _stdout = ''; const logProcessor = (log, type) => { if (type === 'err') _stderr += `${log}\n`; else _stdout += `${log}\n`; if (!log.includes(uniqueKey)) return true; const match = log.match(regexp); if (!match) return true; const exitCode = match === null || match === void 0 ? void 0 : match[1]; this.removeLogProcessor(logProcessor); try { resolve(callback === null || callback === void 0 ? void 0 : callback(_stdout, _stderr, +exitCode)); } catch (err) { reject(err); } return false; }; this.builder.append(`echo ${uniqueKey}=$?`); const command = this.builder.reset(); this.shell.addLogProcessor(logProcessor); this.shell.execute(command); }); } /** * Adds a log processor to the shell. * @param {Function} processor - The log processor function to add. * @returns {this} - The CommandoInteractive instance for method chaining. */ addLogProcessor(processor) { this.shell.addLogProcessor(processor); return this; } setLogLevelFilter(processor) { this.shell.setLogLevelFilter(processor); return this; } /** * Removes a log processor from the shell. * @param {Function} processor - The log processor function to remove. * @returns {this} - The CommandoInteractive instance for method chaining. */ removeLogProcessor(processor) { this.shell.removeLogProcessor(processor); return this; } /** * Appends a command to the command list. * @param {string} command - The command to append. * @returns {this} - The CommandoInteractive instance for method chaining. */ append(command) { this.builder.append(command); return this; } } exports.CommandoInteractive = CommandoInteractive;