UNPKG

tar-iterator

Version:

Extract contents from tar archive type using an iterator API using streams or paths. Use stream interface and pipe transforms to add decompression algorithms

55 lines (54 loc) 2.29 kB
import once from 'call-once-fn'; import { DirectoryEntry, LinkEntry, SymbolicLinkEntry } from 'extract-base-iterator'; import compact from 'lodash.compact'; import path from 'path'; import FileEntry from './FileEntry.js'; export default function nextEntry(next, iterator, callback) { const extract = iterator.extract; if (!extract) return callback(new Error('Extract missing')); const nextCallback = once((err, entry, next)=>{ extract.removeListener('entry', onEntry); extract.removeListener('error', onError); extract.removeListener('finish', onEnd); // keep processing if (entry) iterator.push(nextEntry.bind(null, next)); err ? callback(err) : callback(null, entry ? { done: false, value: entry } : { done: true, value: null }); }); const onError = callback; const onEnd = callback.bind(null, null); const onEntry = function onEntry(header, stream, next) { if (iterator.isDone()) return nextCallback(null, null, next); const attributes = { ...header }; attributes.path = compact(header.name.split(path.sep)).join(path.sep); attributes.mtime = new Date(attributes.mtime); switch(attributes.type){ case 'directory': stream.resume(); // drain stream return nextCallback(null, new DirectoryEntry(attributes), next); case 'symlink': stream.resume(); // drain stream attributes.linkpath = header.linkname; return nextCallback(null, new SymbolicLinkEntry(attributes), next); case 'link': stream.resume(); // drain stream attributes.linkpath = header.linkname; return nextCallback(null, new LinkEntry(attributes), next); case 'file': return nextCallback(null, new FileEntry(attributes, stream, iterator.lock), next); } stream.resume(); // drain stream return nextCallback(new Error(`Unrecognized entry type: ${attributes.type}`), null, next); }; extract.on('entry', onEntry); extract.on('error', onError); extract.on('finish', onEnd); if (next) next(); }