No Description

stream.js 2.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. 'use strict';
  2. const isStream = require('is-stream');
  3. const getStream = require('get-stream');
  4. const mergeStream = require('merge-stream');
  5. // `input` option
  6. const handleInput = (spawned, input) => {
  7. // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852
  8. // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0
  9. if (input === undefined || spawned.stdin === undefined) {
  10. return;
  11. }
  12. if (isStream(input)) {
  13. input.pipe(spawned.stdin);
  14. } else {
  15. spawned.stdin.end(input);
  16. }
  17. };
  18. // `all` interleaves `stdout` and `stderr`
  19. const makeAllStream = (spawned, {all}) => {
  20. if (!all || (!spawned.stdout && !spawned.stderr)) {
  21. return;
  22. }
  23. const mixed = mergeStream();
  24. if (spawned.stdout) {
  25. mixed.add(spawned.stdout);
  26. }
  27. if (spawned.stderr) {
  28. mixed.add(spawned.stderr);
  29. }
  30. return mixed;
  31. };
  32. // On failure, `result.stdout|stderr|all` should contain the currently buffered stream
  33. const getBufferedData = async (stream, streamPromise) => {
  34. if (!stream) {
  35. return;
  36. }
  37. stream.destroy();
  38. try {
  39. return await streamPromise;
  40. } catch (error) {
  41. return error.bufferedData;
  42. }
  43. };
  44. const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => {
  45. if (!stream || !buffer) {
  46. return;
  47. }
  48. if (encoding) {
  49. return getStream(stream, {encoding, maxBuffer});
  50. }
  51. return getStream.buffer(stream, {maxBuffer});
  52. };
  53. // Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all)
  54. const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => {
  55. const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer});
  56. const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer});
  57. const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2});
  58. try {
  59. return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]);
  60. } catch (error) {
  61. return Promise.all([
  62. {error, signal: error.signal, timedOut: error.timedOut},
  63. getBufferedData(stdout, stdoutPromise),
  64. getBufferedData(stderr, stderrPromise),
  65. getBufferedData(all, allPromise)
  66. ]);
  67. }
  68. };
  69. const validateInputSync = ({input}) => {
  70. if (isStream(input)) {
  71. throw new TypeError('The `input` option cannot be a stream in sync mode');
  72. }
  73. };
  74. module.exports = {
  75. handleInput,
  76. makeAllStream,
  77. getSpawnedResult,
  78. validateInputSync
  79. };