index.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { exec as shell_exec, spawn as shell_spawn } from 'child_process';
  2. const MAX_BUFFER = 10 * Math.pow(2, 20);
  3. export function exec(command: string, stdout?: ((...args: any[]) => void) | NodeJS.WriteStream, stderr?: ((...args: any[]) => void) | NodeJS.WriteStream) {
  4. return new Promise<string>((resolve, reject) => {
  5. try {
  6. let stdoutbuf = "";
  7. let stderrbuf = "";
  8. // EXEC CHILD PROCESS
  9. const p = shell_exec(command, { maxBuffer: MAX_BUFFER }, (err, out) => {
  10. if (err) return reject(err);
  11. if (stdoutbuf.length > 0 && typeof stdout === 'function') stdout(stdoutbuf);
  12. if (stderrbuf.length > 0 && typeof stderr === 'function') stderr(stderrbuf);
  13. resolve(out);
  14. });
  15. // PIPE STDOUT
  16. if (typeof stdout === 'function') {
  17. p.stdout?.on("data", chunk => {
  18. stdoutbuf += chunk;
  19. let i = -1;
  20. while ((i = stdoutbuf.indexOf('\n')) >= 0) {
  21. const line = stdoutbuf.substring(0, i);
  22. stdoutbuf = stdoutbuf.substring(i + 1);
  23. if (typeof stdout === 'function') {
  24. stdout(line);
  25. }
  26. }
  27. });
  28. } else if (typeof stdout !== 'undefined') {
  29. p.stdout?.pipe(stdout);
  30. }
  31. // PIPE STDERR
  32. if (typeof stderr === 'function') {
  33. p.stderr?.on("data", chunk => {
  34. stderrbuf += chunk;
  35. let i = -1;
  36. while ((i = stderrbuf.indexOf('\n')) >= 0) {
  37. const line = stderrbuf.substring(0, i);
  38. stderrbuf = stderrbuf.substring(i + 1);
  39. if (typeof stderr === 'function') {
  40. stderr(line);
  41. }
  42. }
  43. });
  44. } else if (typeof stderr !== 'undefined') {
  45. p.stderr?.pipe(stderr);
  46. }
  47. } catch (err) {
  48. reject(err);
  49. }
  50. });
  51. }
  52. export function spawn(command: string, args: string[], stdout?: NodeJS.WriteStream, stderr?: NodeJS.WriteStream) {
  53. return new Promise<void>((resolve, reject) => {
  54. try {
  55. const p = shell_spawn(command, args);
  56. if (stdout) p.stdout.pipe(stdout);
  57. if (stderr) p.stderr.pipe(stderr);
  58. p.on('close', (code, sig) => {
  59. if (!code) resolve();
  60. else reject();
  61. });
  62. p.on('error', reject);
  63. p.on('exit', (code, sig) => {
  64. if (!code) resolve();
  65. else reject();
  66. });
  67. } catch (err) {
  68. reject(err);
  69. }
  70. });
  71. }