@xec-sh/core
Version:
Universal shell execution engine
149 lines • 4.75 kB
JavaScript
import { TextDecoder } from 'util';
export class ProcessOutput extends Error {
constructor(options) {
const message = ProcessOutput.formatErrorMessage(options);
super(message);
this.name = 'ProcessOutput';
this.stdout = ProcessOutput.bufferToString(options.stdout);
this.stderr = ProcessOutput.bufferToString(options.stderr);
this.stdall = options.stdall !== undefined
? ProcessOutput.bufferToString(options.stdall)
: this.stdout + this.stderr;
this.exitCode = options.exitCode;
this.signal = options.signal || null;
this.duration = options.duration || 0;
this.command = options.command;
this.cwd = options.cwd;
Error.captureStackTrace(this, ProcessOutput);
}
get ok() {
return this.exitCode === 0 && this.signal === null;
}
toString() {
return this.stdout.trim();
}
valueOf() {
return this.stdout.trim();
}
text(encoding = 'utf8') {
if (encoding === 'utf8')
return this.stdout.trim();
return Buffer.from(this.stdout).toString(encoding).trim();
}
json() {
const text = this.stdout.trim();
if (!text) {
throw new Error('Empty stdout');
}
try {
return JSON.parse(text);
}
catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to parse JSON: ${message}\nOutput: ${text}`);
}
}
lines(delimiter = '\n') {
return this.stdout.split(delimiter).filter(line => line.length > 0);
}
buffer() {
return Buffer.from(this.stdout);
}
blob() {
if (typeof Blob === 'undefined') {
throw new Error('Blob is not available in this environment');
}
return new Blob([this.stdout]);
}
[Symbol.iterator]() {
const lines = this.lines();
let index = 0;
return {
next() {
if (index < lines.length) {
return { value: lines[index++], done: false };
}
return { done: true, value: undefined };
}
};
}
async *[Symbol.asyncIterator]() {
for (const line of this.lines()) {
yield line;
}
}
static bufferToString(data) {
if (!data)
return '';
if (typeof data === 'string')
return data;
return new TextDecoder().decode(data);
}
static formatErrorMessage(options) {
if (options.exitCode === 0 && !options.signal) {
return '';
}
const parts = [];
if (options.command) {
parts.push(`Command failed: ${options.command}`);
}
else {
parts.push('Command failed');
}
if (options.exitCode !== null && options.exitCode !== 0) {
parts.push(`Exit code: ${options.exitCode}`);
const errorMessage = ProcessOutput.getErrorMessage(options.exitCode);
if (errorMessage) {
parts.push(`(${errorMessage})`);
}
}
if (options.signal) {
parts.push(`Signal: ${options.signal}`);
}
if (options.cwd) {
parts.push(`Working directory: ${options.cwd}`);
}
const stderr = ProcessOutput.bufferToString(options.stderr);
if (stderr) {
parts.push(`\nstderr:\n${stderr}`);
}
return parts.join('\n');
}
static getErrorMessage(code) {
const errorMessages = {
1: 'General error',
2: 'Misuse of shell builtins',
126: 'Command invoked cannot execute',
127: 'Command not found',
128: 'Invalid exit argument',
129: 'Hangup',
130: 'Interrupt',
131: 'Quit and dump core',
132: 'Illegal instruction',
133: 'Trace/breakpoint trap',
134: 'Process aborted',
135: 'Bus error',
136: 'Floating point exception',
137: 'Kill',
138: 'User defined signal 1',
139: 'Segmentation fault',
140: 'User defined signal 2',
141: 'Broken pipe',
142: 'Alarm clock',
143: 'Termination',
};
return errorMessages[code] || null;
}
static fromResult(result) {
return new ProcessOutput(result);
}
static success(stdout = '') {
return new ProcessOutput({
stdout,
stderr: '',
exitCode: 0,
signal: null,
});
}
}
//# sourceMappingURL=process-output.js.map