File: //home/ubuntu/.nvm/versions/node/v22.3.0/lib/node_modules/chromium/install.js
'use strict';
const path = require('path');
const fs = require('fs');
const extractZip = require('extract-zip');
const got = require('got');
const tmp = require('tmp');
const debug = require('debug')('node-chromium');
const rimraf = require('rimraf');
const ProgressBar = require('progress');
const config = require('./config');
const utils = require('./utils');
const cache = require('./cache');
let progressBar = null;
/* eslint unicorn/prevent-abbreviations: ["off"] */
function createTempFile() {
return new Promise((resolve, reject) => {
tmp.file((error, path) => {
if (error) {
console.log('An error occured while trying to create temporary file', error);
reject(error);
} else {
resolve(path);
}
});
});
}
/**
* Downloads the Chromium archive from the default CDN or mirror if configured.
* If the required archive is retrieved from the cache directory then the download will be skipped.
* @param {string} revision The Chromium revision to download.
*/
async function downloadChromiumRevision(revision) {
const cacheEntry = cache.get(revision);
if (cacheEntry) {
debug('Found Chromium archive in cache, skipping download');
return Promise.resolve(cacheEntry);
}
debug('Downloading Chromium archive from Google CDN');
const url = utils.getDownloadUrl(revision);
const tmpPath = await createTempFile();
return _downloadFile(url, tmpPath).then(tmpPath => {
cache.put(revision, tmpPath);
return tmpPath;
});
}
function _downloadFile(url, destPath) {
return new Promise((resolve, reject) => {
got.stream(url, utils.getRequestOptions(url))
.on('downloadProgress', onProgress)
.on('error', error => {
console.error('An error occurred while trying to download file', error.message);
reject(error);
})
.pipe(fs.createWriteStream(destPath))
.on('error', error => {
console.error('An error occurred while trying to save file to disk', error);
reject(error);
})
.on('finish', () => {
resolve(destPath);
});
});
}
/**
* Handles download progress events.
* @param progress Information about progress so far.
*/
function onProgress(progress) {
const fakeProgressBar = {tick: () => {}};
try {
if (!progressBar) {
const formatBytes = bytes => {
const mb = bytes / 1024 / 1024;
return `${Math.round(mb * 10) / 10} MB`;
};
if (progress.total) {
progressBar = new ProgressBar(`Downloading Chromium - ${formatBytes(progress.total)} [:bar] :percent :etas `, {
width: 20,
total: progress.total
});
} else {
progressBar = fakeProgressBar;
console.info('\tPlease wait, this may take a while...');
}
}
progressBar.tick(progress.transferred - progressBar.curr);
} catch (error) {
// Don't die on progress bar failure, log it and stop progress
console.error('Error displaying progress bar. Continuing anyway...', error);
progressBar = fakeProgressBar;
}
}
function unzipArchive(archivePath, outputFolder) {
debug('Started extracting archive', archivePath);
return new Promise((resolve, reject) => {
const osOutputFolder = path.join(outputFolder, utils.getOsChromiumFolderName());
rimraf(osOutputFolder, () => {
extractZip(archivePath, {dir: outputFolder}, error => {
if (error) {
console.error('An error occurred while trying to extract archive', error);
reject(error);
} else {
debug('Archive was successfully extracted');
resolve(true);
}
});
});
});
}
async function install() {
const chromiumRevision = config.getEnvVar('NODE_CHROMIUM_REVISION');
try {
console.info('Step 1. Retrieving Chromium revision number');
const revision = chromiumRevision || await utils.getLatestRevisionNumber();
console.info(`Step 2. Downloading Chromium revision ${revision}`);
const archivePath = await downloadChromiumRevision(revision);
console.info('Step 3. Setting up Chromium binaries');
await unzipArchive(archivePath, config.BIN_OUT_PATH);
console.info('Process is successfully finished');
} catch (error) {
console.error('An error occurred while trying to setup Chromium. Resolve all issues and restart the process', error);
}
}
if (require.main === module) {
// Module called directly, not via "require", so execute install...
if (config.getEnvVar('NODE_CHROMIUM_SKIP_INSTALL').toLowerCase() === 'true') {
console.info('Skipping chromium install');
} else {
install();
}
}
tmp.setGracefulCleanup(); // Ensure temporary files are cleaned up when process exits
module.exports = install;