1import fs from 'node:fs';
2import os from 'node:os';
3import path from 'node:path';
4import { get } from 'node:https';
5import { randomBytes } from 'node:crypto';
6import decompress from 'decompress';
7import decompressTarGz from 'decompress-targz';
8import decompressUnzip from 'decompress-unzip';
9
10export const tmpFile = (suffix = '') =>
11 path.join(os.tmpdir(), randomBytes(16).toString('hex') + suffix);
12
13export const downloadToFile = (url, destPath) => new Promise((resolve, reject) => {
14 get(url, (res) => {
15 if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
16 res.resume();
17 return resolve(downloadToFile(res.headers.location, destPath));
18 }
19 if (res.statusCode !== 200) {
20 res.resume();
21 return reject(new Error(`Download failed: ${url} returned ${res.statusCode}`));
22 }
23 const writeStream = fs.createWriteStream(destPath);
24 res.pipe(writeStream);
25 writeStream.on('finish', () => resolve());
26 writeStream.on('error', reject);
27 res.on('error', reject);
28 }).on('error', reject);
29});
30
31export const extractBinary = (archivePath, outputDir, binaryRegex, outputName) =>
32 decompress(archivePath, outputDir, {
33 plugins: [decompressTarGz(), decompressUnzip()],
34 filter: file => binaryRegex.test(file.path),
35 map: file => {
36 file.path = outputName;
37 return file;
38 }
39 });
40