import { Either, type IEither, type ITraceable, LogLevel, TraceUtil, } from "@emprespresso/pengueno"; export type Command = string[] | string; type CommandOutputDecoded = { code: number; stdoutText: string; stderrText: string; }; export const getStdout = ( c: ITraceable, options: Deno.CommandOptions = {}, ): Promise> => c .bimap(TraceUtil.withFunctionTrace(getStdout)) .map((tCmd) => { const cmd = tCmd.get(); tCmd.trace.trace(`:> im gonna run this command! ${cmd}`); const [exec, ...args] = typeof cmd === "string" ? cmd.split(" ") : cmd; return new Deno.Command(exec, { args, stdout: "piped", stderr: "piped", ...options, }); }) .map((tCmd) => Either.fromFailableAsync(() => tCmd.get().output(), ), ) .map( TraceUtil.promiseify((tEitherOut) => tEitherOut.get().flatMap(({ code, stderr, stdout }) => Either.fromFailable(() => { const stdoutText = new TextDecoder().decode(stdout); const stderrText = new TextDecoder().decode(stderr); return { code, stdoutText, stderrText }; }) .mapLeft((e) => { tEitherOut.trace.addTrace(LogLevel.ERROR).trace(`o.o wat ${e}`); return new Error(`${e}`); }) .flatMap((decodedOutput): IEither => { const { code, stdoutText, stderrText } = decodedOutput; if (stderrText) { tEitherOut.trace .addTrace(LogLevel.DEBUG) .trace(`stderr: ${stderrText}`); } if (code !== 0) { const msg = `i weceived an exit code of ${code} i wanna zewoooo :<`; tEitherOut.trace.addTrace(LogLevel.ERROR).trace(msg); return Either.left(new Error(msg)); } return Either.right(stdoutText); }), ), ), ) .get();