| Leo Repp | 58b9f11 | 2021-11-22 11:57:47 +0100 | [diff] [blame^] | 1 | 'use strict'; |
| 2 | const fileType = require('file-type'); |
| 3 | const isStream = require('is-stream'); |
| 4 | const tarStream = require('tar-stream'); |
| 5 | |
| 6 | module.exports = () => input => { |
| 7 | if (!Buffer.isBuffer(input) && !isStream(input)) { |
| 8 | return Promise.reject(new TypeError(`Expected a Buffer or Stream, got ${typeof input}`)); |
| 9 | } |
| 10 | |
| 11 | if (Buffer.isBuffer(input) && (!fileType(input) || fileType(input).ext !== 'tar')) { |
| 12 | return Promise.resolve([]); |
| 13 | } |
| 14 | |
| 15 | const extract = tarStream.extract(); |
| 16 | const files = []; |
| 17 | |
| 18 | extract.on('entry', (header, stream, cb) => { |
| 19 | const chunk = []; |
| 20 | |
| 21 | stream.on('data', data => chunk.push(data)); |
| 22 | stream.on('end', () => { |
| 23 | const file = { |
| 24 | data: Buffer.concat(chunk), |
| 25 | mode: header.mode, |
| 26 | mtime: header.mtime, |
| 27 | path: header.name, |
| 28 | type: header.type |
| 29 | }; |
| 30 | |
| 31 | if (header.type === 'symlink' || header.type === 'link') { |
| 32 | file.linkname = header.linkname; |
| 33 | } |
| 34 | |
| 35 | files.push(file); |
| 36 | cb(); |
| 37 | }); |
| 38 | }); |
| 39 | |
| 40 | const promise = new Promise((resolve, reject) => { |
| 41 | if (!Buffer.isBuffer(input)) { |
| 42 | input.on('error', reject); |
| 43 | } |
| 44 | |
| 45 | extract.on('finish', () => resolve(files)); |
| 46 | extract.on('error', reject); |
| 47 | }); |
| 48 | |
| 49 | extract.then = promise.then.bind(promise); |
| 50 | extract.catch = promise.catch.bind(promise); |
| 51 | |
| 52 | if (Buffer.isBuffer(input)) { |
| 53 | extract.end(input); |
| 54 | } else { |
| 55 | input.pipe(extract); |
| 56 | } |
| 57 | |
| 58 | return extract; |
| 59 | }; |