1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.extractArchiveTo = exports.convertToZip = exports.makeArchiveFromDirectory = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const fslib_1 = require("@yarnpkg/fslib");
|
6 | const libzip_1 = require("@yarnpkg/libzip");
|
7 | const tar_stream_1 = tslib_1.__importDefault(require("tar-stream"));
|
8 | const util_1 = require("util");
|
9 | const zlib_1 = tslib_1.__importDefault(require("zlib"));
|
10 | const gunzip = util_1.promisify(zlib_1.default.gunzip);
|
11 | async function makeArchiveFromDirectory(source, { baseFs = new fslib_1.NodeFS(), prefixPath = fslib_1.PortablePath.root, compressionLevel, inMemory = false } = {}) {
|
12 | const libzip = await libzip_1.getLibzipPromise();
|
13 | let zipFs;
|
14 | if (inMemory) {
|
15 | zipFs = new fslib_1.ZipFS(null, { libzip, level: compressionLevel });
|
16 | }
|
17 | else {
|
18 | const tmpFolder = await fslib_1.xfs.mktempPromise();
|
19 | const tmpFile = fslib_1.ppath.join(tmpFolder, `archive.zip`);
|
20 | zipFs = new fslib_1.ZipFS(tmpFile, { create: true, libzip, level: compressionLevel });
|
21 | }
|
22 | const target = fslib_1.ppath.resolve(fslib_1.PortablePath.root, prefixPath);
|
23 | await zipFs.copyPromise(target, source, { baseFs, stableTime: true, stableSort: true });
|
24 | return zipFs;
|
25 | }
|
26 | exports.makeArchiveFromDirectory = makeArchiveFromDirectory;
|
27 | async function convertToZip(tgz, opts) {
|
28 | const tmpFolder = await fslib_1.xfs.mktempPromise();
|
29 | const tmpFile = fslib_1.ppath.join(tmpFolder, `archive.zip`);
|
30 | const { compressionLevel, ...bufferOpts } = opts;
|
31 | return await extractArchiveTo(tgz, new fslib_1.ZipFS(tmpFile, { create: true, libzip: await libzip_1.getLibzipPromise(), level: compressionLevel }), bufferOpts);
|
32 | }
|
33 | exports.convertToZip = convertToZip;
|
34 | async function extractArchiveTo(tgz, targetFs, { stripComponents = 0, prefixPath = fslib_1.PortablePath.dot } = {}) {
|
35 |
|
36 | const defaultTime = 315532800;
|
37 | const parser = tar_stream_1.default.extract();
|
38 | function ignore(entry) {
|
39 |
|
40 | if (entry.name[0] === `/`)
|
41 | return true;
|
42 | const parts = entry.name.split(/\//g);
|
43 |
|
44 | if (parts.some((part) => part === `..`))
|
45 | return true;
|
46 | if (parts.length <= stripComponents)
|
47 | return true;
|
48 | return false;
|
49 | }
|
50 | parser.on(`entry`, (header, stream, next) => {
|
51 | var _a, _b;
|
52 | if (ignore(header)) {
|
53 | next();
|
54 | return;
|
55 | }
|
56 | const parts = fslib_1.ppath.normalize(fslib_1.npath.toPortablePath(header.name)).replace(/\/$/, ``).split(/\//g);
|
57 | if (parts.length <= stripComponents) {
|
58 | stream.resume();
|
59 | next();
|
60 | return;
|
61 | }
|
62 | const slicePath = parts.slice(stripComponents).join(`/`);
|
63 | const mappedPath = fslib_1.ppath.join(prefixPath, slicePath);
|
64 | let mode = 0o644;
|
65 |
|
66 | if (header.type === `directory` || (((_a = header.mode) !== null && _a !== void 0 ? _a : 0) & 0o111) !== 0)
|
67 | mode |= 0o111;
|
68 | switch (header.type) {
|
69 | case `directory`:
|
70 | {
|
71 | targetFs.mkdirpSync(fslib_1.ppath.dirname(mappedPath), { chmod: 0o755, utimes: [defaultTime, defaultTime] });
|
72 | targetFs.mkdirSync(mappedPath);
|
73 | targetFs.chmodSync(mappedPath, mode);
|
74 | targetFs.utimesSync(mappedPath, defaultTime, defaultTime);
|
75 | next();
|
76 | }
|
77 | break;
|
78 | case `file`:
|
79 | {
|
80 | targetFs.mkdirpSync(fslib_1.ppath.dirname(mappedPath), { chmod: 0o755, utimes: [defaultTime, defaultTime] });
|
81 | const chunks = [];
|
82 | stream.on(`data`, (chunk) => chunks.push(chunk));
|
83 | stream.on(`end`, () => {
|
84 | targetFs.writeFileSync(mappedPath, Buffer.concat(chunks));
|
85 | targetFs.chmodSync(mappedPath, mode);
|
86 | targetFs.utimesSync(mappedPath, defaultTime, defaultTime);
|
87 | next();
|
88 | });
|
89 | }
|
90 | break;
|
91 | case `symlink`:
|
92 | {
|
93 | targetFs.mkdirpSync(fslib_1.ppath.dirname(mappedPath), { chmod: 0o755, utimes: [defaultTime, defaultTime] });
|
94 | targetFs.symlinkSync(header.linkname, mappedPath);
|
95 | (_b = targetFs.lutimesSync) === null || _b === void 0 ? void 0 : _b.call(targetFs, mappedPath, defaultTime, defaultTime);
|
96 | next();
|
97 | }
|
98 | break;
|
99 | default: {
|
100 | stream.resume();
|
101 | next();
|
102 | }
|
103 | }
|
104 | });
|
105 | const gunzipped = await gunzip(tgz);
|
106 | return await new Promise((resolve, reject) => {
|
107 | parser.on(`error`, (error) => {
|
108 | reject(error);
|
109 | });
|
110 | parser.on(`finish`, () => {
|
111 | resolve(targetFs);
|
112 | });
|
113 | parser.end(gunzipped);
|
114 | });
|
115 | }
|
116 | exports.extractArchiveTo = extractArchiveTo;
|