UNPKG

@nu-art/commando

Version:

Shell command execution framework with interactive sessions, CLI parameter resolution, and plugin system for building and executing shell scripts programmatically

96 lines (95 loc) 3.46 kB
/* * commando provides shell command execution framework with interactive sessions and plugin system * * Copyright (C) 2020 Adam van der Kruk aka TacB0sS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { exec } from 'child_process'; import { Logger } from '@nu-art/ts-common'; import { CliError } from '../core/CliError.js'; /** * Converts input to string, handling Buffer and ArrayBufferLike types. * * @param input - String, Buffer, or ArrayBufferLike to convert * @returns UTF-8 string representation */ function toStringWithNewlines(input) { if (typeof input === 'string') return input; return Buffer.isBuffer(input) ? input.toString('utf8') : Buffer.from(input).toString('utf8'); } /** * Simple shell command executor using Node.js child_process. * * Executes shell commands synchronously via `exec()` and handles * output conversion. Supports debug logging and custom shell/options. * * **Behavior**: * - Uses `/bin/bash` as default shell * - Converts Buffer output to UTF-8 strings * - Logs stdout as info, stderr as error * - Throws CliError on command failure * - Supports UID tagging for log identification */ export class SimpleShell extends Logger { /** Debug mode flag (enables verbose command logging) */ _debug = false; /** Execution options for child_process.exec() */ cliOptions = { shell: '/bin/bash' }; /** * Executes a shell command and returns stdout/stderr. * * **Behavior**: * - Logs command in debug mode (wrapped in triple quotes) * - Converts Buffer output to UTF-8 strings * - Logs stdout as info, stderr as error * - Throws CliError if command fails (non-zero exit code) * * @param command - Shell command string to execute * @returns Promise resolving to stdout and stderr strings * @throws CliError if command execution fails */ execute = async (command) => { if (this._debug) this.logDebug(`executing: `, `"""\n${command}\n"""`); return new Promise((resolve, reject) => { exec(command, this.cliOptions, (error, stdout, stderr) => { if (error) { return reject(new CliError(`executing:\n${command}\n`, toStringWithNewlines(stdout), toStringWithNewlines(stderr), error)); } if (stdout) this.logInfo(stdout); if (stderr) this.logError(stderr); resolve({ stdout: toStringWithNewlines(stdout), stderr: toStringWithNewlines(stderr) }); }); }); }; debug(debug) { this._debug = debug ?? !this._debug; return this; } setShell(shell) { (this.cliOptions || (this.cliOptions = {})).shell = shell; } setOptions(options) { this.cliOptions = options; } setUID(uid) { this.setTag(uid); return this; } }