const path = require("path");
const mkdirp = require("mkdirp");
const semver = require("semver");
const zlib = require("zlib");
const tar = require("tar");
const fse = require("fs-extra");
const constant_1 = require("@appworks/constant");
const axios_1 = require("axios");
const urlJoin = require("url-join");
function getAndExtractTarball(destDir, tarball, progressFunc = (state) => { }, formatFilename = (filename) => {
// 为了兼容
if (filename === '_package.json') {
return filename.replace(/^_/, '');
}
else {
return filename.replace(/^_/, '.');
}
}) {
return new Promise((resolve, reject) => {
const allFiles = [];
const allWriteStream = [];
const dirCollector = [];
axios_1.default({
url: tarball,
timeout: 10000,
responseType: 'stream',
onDownloadProgress: (progressEvent) => {
progressFunc(progressEvent);
},
}).then((response) => {
const totalLength = Number(response.headers['content-length']);
let downloadLength = 0;
response.data
// @ts-ignore
.on('data', (chunk) => {
downloadLength += chunk.length;
progressFunc({
percent: (downloadLength - 50) / totalLength,
});
})
// @ts-ignore
.pipe(zlib.Unzip())
// @ts-ignore
.pipe(new tar.Parse())
.on('entry', (entry) => {
if (entry.type === 'Directory') {
entry.resume();
return;
}
const realPath = entry.path.replace(/^package\//, '');
let filename = path.basename(realPath);
filename = formatFilename(filename);
const destPath = path.join(destDir, path.dirname(realPath), filename);
const dirToBeCreate = path.dirname(destPath);
if (!dirCollector.includes(dirToBeCreate)) {
dirCollector.push(dirToBeCreate);
mkdirp.sync(dirToBeCreate);
}
allFiles.push(destPath);
allWriteStream.push(new Promise((streamResolve) => {
entry
.pipe(fse.createWriteStream(destPath))
.on('finish', () => streamResolve())
.on('close', () => streamResolve()); // resolve when file is empty in node v8
}));
})
.on('end', () => {
if (progressFunc) {
progressFunc({
percent: 1,
});
}
Promise.all(allWriteStream)
.then(() => resolve(allFiles))
.catch(reject);
});
});
});
}
getAndExtractTarball()