import { Either, type IEither, type ITraceable, LogLevel, type LogTraceSupplier, TraceUtil, } from '@emprespresso/pengueno'; import { promisify } from 'node:util'; import { exec as execCallback } from 'node:child_process'; const exec = promisify(execCallback); export type Command = string[] | string; export type StdStreams = { stdout: string; stderr: string }; export const getStdout = ( c: ITraceable, options: { env?: Record; clearEnv?: boolean } = {}, ): Promise> => c .bimap(TraceUtil.withFunctionTrace(getStdout)) .bimap((tCmd) => { const cmd = tCmd.get(); tCmd.trace.trace(`Command = ${cmd} :> im gonna run this command! `); const _exec = typeof cmd === 'string' ? cmd : cmd.join(' '); const env = options.clearEnv ? options.env : { ...process.env, ...options.env }; const p: Promise> = Either.fromFailableAsync(exec(_exec, { env })); return [p, `Command = ${_exec}`]; }) .map( TraceUtil.promiseify( (tEitherProcess): IEither => tEitherProcess.get().fold(({ isLeft, value }) => { if (isLeft) { return Either.left(value); } if (value.stderr) { tEitherProcess.trace.addTrace(LogLevel.DEBUG).trace(`StdErr = ${value.stderr}`); } return Either.right(value.stdout); }), ), ) .get();