From 3a3fb9c8ab0c798a278f76d40de216fa96f6e2c4 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Wed, 14 May 2025 18:02:34 -0700 Subject: moar --- u/process/env.ts | 2 +- u/process/run.ts | 97 +++++++++++++++++++++++++--------------- u/process/validate_identifier.ts | 19 +++++--- 3 files changed, 74 insertions(+), 44 deletions(-) (limited to 'u/process') diff --git a/u/process/env.ts b/u/process/env.ts index c3ae800..26e1158 100644 --- a/u/process/env.ts +++ b/u/process/env.ts @@ -1,4 +1,4 @@ -import { Either, type IEither } from "@emprespresso/utils"; +import { Either, type IEither } from "@emprespresso/pengueno"; export const getRequiredEnv = (name: string): IEither => Either diff --git a/u/process/run.ts b/u/process/run.ts index 6dc37d0..670f567 100644 --- a/u/process/run.ts +++ b/u/process/run.ts @@ -1,40 +1,63 @@ -import { Either, type Traceable } from "@emprespresso/utils"; +import { + Either, + type IEither, + type ITraceable, + LogLevel, + TraceUtil, +} from "@emprespresso/pengueno"; + +type Command = string[] | string; +type CommandOutputDecoded = { + code: number; + stdoutText: string; + stderrText: string; +}; export class ProcessError extends Error {} -export const getStdout = async ( - { item: cmd, logger: _logger }: Traceable, +export const getStdout = ( + c: ITraceable, options: Deno.CommandOptions = {}, -): Promise> => { - const logger = _logger.addTracer(() => "[getStdout]"); - - logger.log(`:> im gonna run this command!`, cmd); - const [exec, ...args] = (typeof cmd === "string") ? cmd.split(" ") : cmd; - const command = new Deno.Command(exec, { - args, - stdout: "piped", - stderr: "piped", - ...options, - }); - - try { - const { code, stdout, stderr } = await command.output(); - const stdoutText = new TextDecoder().decode(stdout); - const stderrText = new TextDecoder().decode(stderr); - - if (code !== 0) { - logger.error(`i weceived an exit code of ${code} i wanna zeroooo :<`); - return Either.left( - new ProcessError(`command failed\n${stderrText}`), - ); - } - - logger.log("yay! i got code 0 :3", cmd); - return Either.right(stdoutText); - } catch (e) { - logger.error(`o.o wat`, e); - if (e instanceof Error) { - return Either.left(e); - } - throw new Error("unknown error " + e); - } -}; +): Promise> => + c.bimap(TraceUtil.withFunctionTrace(getStdout)) + .map(({ item: cmd, trace }) => { + 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, + }).output(); + }) + .map(({ item: p }) => + Either.fromFailableAsync(p) + ) + .map( + TraceUtil.promiseify(({ item: eitherOutput, trace }) => + eitherOutput.flatMap(({ code, stderr, stdout }) => + Either + .fromFailable(() => { + const stdoutText = new TextDecoder().decode(stdout); + const stderrText = new TextDecoder().decode(stderr); + return { code, stdoutText, stderrText }; + }) + .mapLeft((e) => { + trace.addTrace(LogLevel.ERROR).trace(`o.o wat ${e}`); + return new ProcessError(`${e}`); + }) + .flatMap((decodedOutput): Either => { + const { code, stdoutText, stderrText } = decodedOutput; + trace.addTrace(LogLevel.DEBUG).trace( + `stderr hehehe ${stderrText}`, + ); + if (code !== 0) { + const msg = + `i weceived an exit code of ${code} i wanna zewoooo :<`; + trace.addTrace(LogLevel.ERROR).trace(msg); + return Either.left(new ProcessError(msg)); + } + return Either.right(stdoutText); + }) + ) + ), + ).item; diff --git a/u/process/validate_identifier.ts b/u/process/validate_identifier.ts index ec8b77b..32952a6 100644 --- a/u/process/validate_identifier.ts +++ b/u/process/validate_identifier.ts @@ -1,4 +1,4 @@ -import { Either } from "./mod.ts"; +import { Either, type IEither } from "@emprespresso/pengueno"; export const validateIdentifier = (token: string) => { return (/^[a-zA-Z0-9_\-:. \/]+$/).test(token) && !token.includes(".."); @@ -6,11 +6,18 @@ export const validateIdentifier = (token: string) => { // ensure {@param obj} is a Record with stuff that won't // have the potential for shell injection, just to be super safe. -export const validateExecutionEntries = ( - obj: Record, -): Either, Record> => { - const invalidEntries = Object.entries(obj).filter((e) => - !e.every((x) => typeof x === "string" && validateIdentifier(x)) +type InvalidEntry = [K, T]; +export const validateExecutionEntries = < + T, + K extends symbol | number | string = symbol | number | string, +>( + obj: Record, +): IEither< + Array>, + Record +> => { + const invalidEntries = >> Object.entries(obj).filter( + (e) => !e.every((x) => typeof x === "string" && validateIdentifier(x)), ); if (invalidEntries.length > 0) return Either.left(invalidEntries); return Either.right(> obj); -- cgit v1.2.3-70-g09d2