1'use strict'; 2 3const { 4 SymbolDispose, 5} = primordials; 6 7const { 8 AbortError, 9 codes, 10} = require('internal/errors'); 11 12const { 13 isNodeStream, 14 isWebStream, 15 kControllerErrorFunction, 16} = require('internal/streams/utils'); 17 18const eos = require('internal/streams/end-of-stream'); 19const { ERR_INVALID_ARG_TYPE } = codes; 20let addAbortListener; 21 22// This method is inlined here for readable-stream 23// It also does not allow for signal to not exist on the stream 24// https://github.com/nodejs/node/pull/36061#discussion_r533718029 25const validateAbortSignal = (signal, name) => { 26 if (typeof signal !== 'object' || 27 !('aborted' in signal)) { 28 throw new ERR_INVALID_ARG_TYPE(name, 'AbortSignal', signal); 29 } 30}; 31 32module.exports.addAbortSignal = function addAbortSignal(signal, stream) { 33 validateAbortSignal(signal, 'signal'); 34 if (!isNodeStream(stream) && !isWebStream(stream)) { 35 throw new ERR_INVALID_ARG_TYPE('stream', ['ReadableStream', 'WritableStream', 'Stream'], stream); 36 } 37 return module.exports.addAbortSignalNoValidate(signal, stream); 38}; 39 40module.exports.addAbortSignalNoValidate = function(signal, stream) { 41 if (typeof signal !== 'object' || !('aborted' in signal)) { 42 return stream; 43 } 44 const onAbort = isNodeStream(stream) ? 45 () => { 46 stream.destroy(new AbortError(undefined, { cause: signal.reason })); 47 } : 48 () => { 49 stream[kControllerErrorFunction](new AbortError(undefined, { cause: signal.reason })); 50 }; 51 if (signal.aborted) { 52 onAbort(); 53 } else { 54 addAbortListener ??= require('events').addAbortListener; 55 const disposable = addAbortListener(signal, onAbort); 56 eos(stream, disposable[SymbolDispose]); 57 } 58 return stream; 59}; 60