Execr is intended to simplify the child_processspawn commands for use in the 99% of cases, where you don't want to worry about the specifics of managing the process.
Execr is not intended to manage long-running processes.
$ yarn add @markjm/execr
const{ exec, execAsync, wrap }=require('@markjm/execr');// Sync version to quickly grabconstbranch=exec("git",["branch"]).stdout;// Async versionexecAsync("yarn",["workspaces","info"]).then({ stdout }=>console.log(stdout));// Wrap a command for simple access to very nested sub-commands.constaz=wrap("az");az.artifacts.universal.download(["--file","my-file"]);// Actually, this will take a while, lets make it async...constaz=wrapAsync("az");az.artifacts.universal.download(["--file","my-file"]).then({ status }=>console.log(status));// If a failure is expected...consterrMsg=exec("git",["push"],{failOnError: false}).stderr;// Memoize expensive calls...constfiles=exec("git",["ls-files"],{memoize: true}).stdout.split("\n");