Bootstrap

加载远程压缩文件

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()
;