You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.4 KiB
97 lines
2.4 KiB
// Ported from https://github.com/mafintosh/pump with |
|
// permission from the author, Mathias Buus (@mafintosh). |
|
'use strict'; |
|
|
|
var eos; |
|
|
|
function once(callback) { |
|
var called = false; |
|
return function () { |
|
if (called) return; |
|
called = true; |
|
callback.apply(void 0, arguments); |
|
}; |
|
} |
|
|
|
var _require$codes = require('../../../errors').codes, |
|
ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, |
|
ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; |
|
|
|
function noop(err) { |
|
// Rethrow the error if it exists to avoid swallowing it |
|
if (err) throw err; |
|
} |
|
|
|
function isRequest(stream) { |
|
return stream.setHeader && typeof stream.abort === 'function'; |
|
} |
|
|
|
function destroyer(stream, reading, writing, callback) { |
|
callback = once(callback); |
|
var closed = false; |
|
stream.on('close', function () { |
|
closed = true; |
|
}); |
|
if (eos === undefined) eos = require('./end-of-stream'); |
|
eos(stream, { |
|
readable: reading, |
|
writable: writing |
|
}, function (err) { |
|
if (err) return callback(err); |
|
closed = true; |
|
callback(); |
|
}); |
|
var destroyed = false; |
|
return function (err) { |
|
if (closed) return; |
|
if (destroyed) return; |
|
destroyed = true; // request.destroy just do .end - .abort is what we want |
|
|
|
if (isRequest(stream)) return stream.abort(); |
|
if (typeof stream.destroy === 'function') return stream.destroy(); |
|
callback(err || new ERR_STREAM_DESTROYED('pipe')); |
|
}; |
|
} |
|
|
|
function call(fn) { |
|
fn(); |
|
} |
|
|
|
function pipe(from, to) { |
|
return from.pipe(to); |
|
} |
|
|
|
function popCallback(streams) { |
|
if (!streams.length) return noop; |
|
if (typeof streams[streams.length - 1] !== 'function') return noop; |
|
return streams.pop(); |
|
} |
|
|
|
function pipeline() { |
|
for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { |
|
streams[_key] = arguments[_key]; |
|
} |
|
|
|
var callback = popCallback(streams); |
|
if (Array.isArray(streams[0])) streams = streams[0]; |
|
|
|
if (streams.length < 2) { |
|
throw new ERR_MISSING_ARGS('streams'); |
|
} |
|
|
|
var error; |
|
var destroys = streams.map(function (stream, i) { |
|
var reading = i < streams.length - 1; |
|
var writing = i > 0; |
|
return destroyer(stream, reading, writing, function (err) { |
|
if (!error) error = err; |
|
if (err) destroys.forEach(call); |
|
if (reading) return; |
|
destroys.forEach(call); |
|
callback(error); |
|
}); |
|
}); |
|
return streams.reduce(pipe); |
|
} |
|
|
|
module.exports = pipeline; |