1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- 'use strict';
- const fileType = require('file-type');
- const getStream = require('get-stream');
- const pify = require('pify');
- const yauzl = require('yauzl');
- const getType = (entry, mode) => {
- const IFMT = 61440;
- const IFDIR = 16384;
- const IFLNK = 40960;
- const madeBy = entry.versionMadeBy >> 8;
- if ((mode & IFMT) === IFLNK) {
- return 'symlink';
- }
- if ((mode & IFMT) === IFDIR || (madeBy === 0 && entry.externalFileAttributes === 16)) {
- return 'directory';
- }
- return 'file';
- };
- const extractEntry = (entry, zip) => {
- const file = {
- mode: (entry.externalFileAttributes >> 16) & 0xFFFF,
- mtime: entry.getLastModDate(),
- path: entry.fileName
- };
- file.type = getType(entry, file.mode);
- if (file.mode === 0 && file.type === 'directory') {
- file.mode = 493;
- }
- if (file.mode === 0) {
- file.mode = 420;
- }
- return pify(zip.openReadStream.bind(zip))(entry)
- .then(getStream.buffer)
- .then(buf => {
- file.data = buf;
- if (file.type === 'symlink') {
- file.linkname = buf.toString();
- }
- return file;
- })
- .catch(err => {
- zip.close();
- throw err;
- });
- };
- const extractFile = zip => new Promise((resolve, reject) => {
- const files = [];
- zip.readEntry();
- zip.on('entry', entry => {
- extractEntry(entry, zip)
- .catch(reject)
- .then(file => {
- files.push(file);
- zip.readEntry();
- });
- });
- zip.on('error', reject);
- zip.on('end', () => resolve(files));
- });
- module.exports = () => buf => {
- if (!Buffer.isBuffer(buf)) {
- return Promise.reject(new TypeError(`Expected a Buffer, got ${typeof buf}`));
- }
- if (!fileType(buf) || fileType(buf).ext !== 'zip') {
- return Promise.resolve([]);
- }
- return pify(yauzl.fromBuffer)(buf, {lazyEntries: true}).then(extractFile);
- };
|