HEX
Server: Apache/2.4.41 (Ubuntu)
System: Linux ip-172-31-42-149 5.15.0-1084-aws #91~20.04.1-Ubuntu SMP Fri May 2 07:00:04 UTC 2025 aarch64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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;