fast-extract
Version:
Extract contents from various archive types (tar, tar.bz2, tar.gz, tar.xz, tgz, zip)
55 lines (54 loc) • 2.62 kB
JavaScript
import SevenZipIterator from '7z-iterator';
import TarIterator from 'tar-iterator';
import unbzip2Stream from 'unbzip2-stream';
import { createXZDecoder } from 'xz-compat';
import ZipIterator from 'zip-iterator';
import zlib from 'zlib';
import extname from './extname.js';
import statsBasename from './sourceStats/basename.js';
import createFilePipeline from './streams/pipelines/file.js';
import DestinationExists from './streams/transforms/DestinationExists.js';
import DestinationRemove from './streams/transforms/DestinationRemove.js';
import EntryProgressTransform from './streams/transforms/EntryProgress.js';
import createIteratorTransform from './streams/transforms/IteratorTransform.js';
import createWriteEntriesStream from './streams/write/entries.js';
const TRANSFORMS = {
bz2: unbzip2Stream,
tgz: zlib.createUnzip.bind(zlib),
gz: zlib.createUnzip.bind(zlib),
xz: createXZDecoder
};
// Create transform classes for each iterator type
const ZipTransform = createIteratorTransform(ZipIterator);
const TarTransform = createIteratorTransform(TarIterator);
const SevenZTransform = createIteratorTransform(SevenZipIterator);
function createArchivePipeline(dest, streams, options, TransformClass) {
streams = streams.slice();
streams.push(new TransformClass());
if (options.progress) streams.push(new EntryProgressTransform(options));
streams.push(createWriteEntriesStream(dest, options));
return streams;
}
const WRITERS = {
zip: (dest, streams, options)=>createArchivePipeline(dest, streams, options, ZipTransform),
tar: (dest, streams, options)=>createArchivePipeline(dest, streams, options, TarTransform),
tgz: (dest, streams, options)=>createArchivePipeline(dest, streams, options, TarTransform),
'7z': (dest, streams, options)=>createArchivePipeline(dest, streams, options, SevenZTransform)
};
export default function createPipeline(dest, options) {
const type = options.type === undefined ? extname(statsBasename(options.source, options) || '') : options.type;
const parts = type.split('.');
const streams = [
options.force ? new DestinationRemove(dest) : new DestinationExists(dest)
];
for(let index = parts.length - 1; index >= 0; index--){
// append transform
const transform = TRANSFORMS[parts[index]];
if (transform) streams.push(transform());
// finish with a write stream
const writer = WRITERS[parts[index]];
if (writer) return writer(dest, streams, options);
}
// default is to write the result to a file
return createFilePipeline(dest, streams, options);
}