type Proc = {
connect(sig: "stdout" | "stderr", fn: (_: any, out: string) => void): number
}
type Config
= {
defaultOut(stdout: string): void
defaultErr(stdout: string): void
subprocess(cmd: string): P
subprocessv(cmd: string[]): P
exec(cmd: string): string | null
execv(cmd: string[]): string | null
execAsync(cmd: string): P
execAsyncv(cmd: string[]): P
}
type Args = {
cmd: string | string[],
out?: (stdout: string) => Out,
err?: (stderr: string) => Err,
}
export default function (config: Config
) {
function args(argsOrCmd: Args | string | string[], onOut: O, onErr: E) {
const params = Array.isArray(argsOrCmd) || typeof argsOrCmd === "string"
return {
cmd: params ? argsOrCmd : argsOrCmd.cmd,
err: params ? onErr : argsOrCmd.err || onErr,
out: params ? onOut : argsOrCmd.out || onOut,
}
}
function subprocess(args: Args): P
function subprocess(
cmd: string | string[],
onOut?: (stdout: string) => void,
onErr?: (stderr: string) => void,
): P
function subprocess(
argsOrCmd: Args | string | string[],
onOut: (stdout: string) => void = config.defaultOut,
onErr: (stderr: string) => void = config.defaultErr,
) {
const { cmd, err, out } = args(argsOrCmd, onOut, onErr)
const proc = Array.isArray(cmd)
? config.subprocessv(cmd)
: config.subprocess(cmd)
proc.connect("stdout", (_, stdout: string) => out(stdout))
proc.connect("stderr", (_, stderr: string) => err(stderr))
return proc
}
function exec(
args: Args
): Out | Err
function exec(
cmd: string | string[],
onOut?: (stdout: string) => Out,
onErr?: (stderr: string) => Err,
): Out | Err
function exec(
argsOrCmd: Args | string | string[],
onOut: (stdout: string) => Out = out => out as Out,
onErr: (stderr: string) => Err = out => out as Err,
): Out | Err {
const { cmd, err, out } = args(argsOrCmd, onOut, onErr)
return Array.isArray(cmd)
? out(config.execv(cmd)!) as Out
: err(config.exec(cmd)!) as Err
}
function execAsync(cmd: string | string[]): Promise {
const proc = Array.isArray(cmd)
? config.execAsyncv(cmd)
: config.execAsync(cmd)
return new Promise((resolve, reject) => {
proc.connect("stdout", (_, out: string) => resolve(out))
proc.connect("stderr", (_, err: string) => reject(err))
})
}
return { subprocess, exec, execAsync }
}