minify-html/nodejs/postinstall.js

60 lines
1.6 KiB
JavaScript

const fs = require('fs');
const https = require('https');
const path = require('path');
const pkg = require('./package.json');
const MAX_DOWNLOAD_ATTEMPTS = 4;
const binaryName = [process.platform, process.arch, process.versions.modules].join('__');
const binaryPath = path.join(__dirname, 'dist', 'native.node');
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
class StatusError extends Error {
constructor (status) {
super(`Bad status of ${status}`);
this.status = status;
}
}
const fetch = url => new Promise((resolve, reject) => {
const stream = https.get(url, resp => {
if (!resp.statusCode || resp.statusCode < 200 || resp.statusCode > 299) {
return reject(new StatusError(resp.statusCode));
}
const parts = [];
resp.on('data', chunk => parts.push(chunk));
resp.on('end', () => resolve(Buffer.concat(parts)));
});
stream.on('error', reject);
});
const downloadNativeBinary = async () => {
for (let attempt = 0; ; attempt++) {
let binary;
try {
binary = await fetch(`https://wilsonl.in/hyperbuild/bin/nodejs/${pkg.version}/${binaryName}.node`);
} catch (e) {
if (e instanceof StatusError && attempt < MAX_DOWNLOAD_ATTEMPTS) {
await wait(Math.random() * 2500 + 500);
continue;
}
throw e;
}
fs.writeFileSync(binaryPath, binary);
break;
}
};
if (!fs.existsSync(path.join(__dirname, '.no-postinstall')) && !fs.existsSync(binaryPath)) {
downloadNativeBinary()
.then(
() => console.log(`Downloaded ${pkg.name}`),
err => {
console.error(`Failed to download ${pkg.name}: ${err}`);
process.exit(1);
},
);
}