UNPKG

fast-extract

Version:

Extract contents from various archive types (tar, tar.bz2, tar.gz, tar.xz, tgz, zip)

147 lines 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return createWriteStream; } }); var _calloncefn = /*#__PURE__*/ _interop_require_default(require("call-once-fn")); var _onone = /*#__PURE__*/ _interop_require_default(require("on-one")); var _flushwritestreamts = /*#__PURE__*/ _interop_require_default(require("./compat/flush-write-stream.js")); var _createPipelinets = /*#__PURE__*/ _interop_require_default(require("./createPipeline.js")); var _exitCleanupts = /*#__PURE__*/ _interop_require_default(require("./exitCleanup.js")); function _define_property(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _object_spread(target) { for(var i = 1; i < arguments.length; i++){ var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _define_property(target, key, source[key]); }); } return target; } function createWriteStream(dest, options_) { if (typeof options_ === 'string') options_ = { type: options_ }; var options = _object_spread({}, options_); var streams = (0, _createPipelinets.default)(dest, options); _exitCleanupts.default.add(dest); // Get first and last streams var first = streams[0]; var last = streams[streams.length - 1]; var error = null; var ended = false; var lastFinished = false; var finishCallback = null; var errorEmittedOnWrite = false; // Manually pipe streams (instead of using pump which has complex completion semantics) for(var i = 0; i < streams.length - 1; i++){ streams[i].pipe(streams[i + 1]); } // Handle errors from all streams - use on-one to ensure each stream only triggers once var errorHandling = false; function handleError(err) { if (!err || errorHandling) return; // only handle actual errors, once errorHandling = true; error = err; // Emit error immediately to prevent 'finish' from being emitted (Node 12 timing issue) if (!errorEmittedOnWrite) { errorEmittedOnWrite = true; write.destroy(err); } // Note: Don't clean up dest on error - if user retries with force, safeRm will handle it. // Background cleanup here causes race conditions where new files get deleted. _exitCleanupts.default.remove(dest); } // Listen for errors on all streams (errors may not propagate through all pipe types) for(var i1 = 0; i1 < streams.length; i1++){ (0, _onone.default)(streams[i1], [ 'error' ], handleError); } // Track when last stream finishes (use on-one for cross-version compatibility) (0, _onone.default)(last, [ 'end', 'close', 'finish' ], function() { if (error) return; // don't complete if errored lastFinished = true; if (finishCallback) { finishCallback(); finishCallback = null; } }); function onEnd(callback) { if (error || ended) return callback(); ended = true; _exitCleanupts.default.remove(dest); callback(); } var write = (0, _flushwritestreamts.default)(function write(chunk, encoding, callback) { if (error) return callback(error); first.write(chunk, encoding, function(err) { if (error) return; // skip if errored if (err) { error = err; errorEmittedOnWrite = true; // error will be emitted by Writable base class via callback callback(err); } else { callback(); } }); }, function flush(callback) { if (error) { errorEmittedOnWrite = true; // error will be emitted by Writable base class via callback return callback(error); } // Ensure callback is only called once (race conditions on older Node) var cb = (0, _calloncefn.default)(callback); var onComplete = function() { if (error) return cb(error); onEnd(cb); }; // If last already finished, complete immediately if (lastFinished) { onComplete(); } else { // Wait for last stream to finish finishCallback = onComplete; // End the first stream to signal no more data - this propagates through the pipeline first.end(); } }); // Track when error is emitted on write stream (from any source) write.on('error', function() { errorEmittedOnWrite = true; }); return write; } /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }