zip-iterator
Version:
Extract contents from zip archive type using an iterator API using streams or paths. Use stream interface and pipe transforms to add decompression algorithms
59 lines (58 loc) • 2.32 kB
JavaScript
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';
import parseExternalFileAttributes from './lib/parseExternalFileAttributes.js';
import streamToString from './lib/streamToString.js';
export default function nextEntry(iterator, callback) {
if (!iterator.iterator) {
callback(new Error('iterator missing'));
return;
}
let entry = null;
while(!entry){
try {
entry = iterator.iterator.next();
} catch (err) {
if (err === 'stop-iteration') break;
if (err === 'skip-iteration') continue;
throw err;
}
}
const nextCallback = once((err, entry)=>{
// keep processing
if (entry) iterator.push(nextEntry);
err ? callback(err) : callback(null, entry ? {
done: false,
value: entry
} : {
done: true,
value: null
});
});
// done: use null to indicate iteration is complete
if (iterator.isDone() || !entry) return callback(null, null);
const localHeader = entry.localHeader;
const centralHeader = entry.centralHeader;
const attributes = parseExternalFileAttributes(centralHeader.external_file_attributes, centralHeader.version >> 8);
attributes.path = compact(localHeader.file_name.split(path.sep)).join(path.sep);
attributes.mtime = entry.lastModified();
switch(attributes.type){
case 'directory':
return nextCallback(null, new DirectoryEntry(attributes));
case 'symlink':
case 'link':
streamToString(entry.getStream(), (err, string)=>{
if (err) return callback(err);
const linkAttributes = attributes;
linkAttributes.linkpath = string;
const Link = attributes.type === 'symlink' ? SymbolicLinkEntry : LinkEntry;
return nextCallback(null, new Link(linkAttributes));
});
return;
case 'file':
return nextCallback(null, new FileEntry(attributes, entry, iterator.lock));
}
return callback(new Error(`Unrecognized entry type: ${attributes.type}`));
}