HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux ip-172-31-4-197 6.8.0-1036-aws #38~22.04.1-Ubuntu SMP Fri Aug 22 15:44:33 UTC 2025 x86_64
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: //var/www/api-storage/node_modules/@xhmikosr/bin-wrapper/index.js
import {promises as fs} from 'node:fs';
import path from 'node:path';
import binCheck from '@xhmikosr/bin-check';
import binVersionCheck from 'bin-version-check';
import download from '@xhmikosr/downloader';
import osFilterObject from '@xhmikosr/os-filter-obj';

/**
 * Initialize a new `BinWrapper`
 *
 * @param {Object} options
 * @api public
 */
export default class BinWrapper {
	constructor(options = {}) {
		this.options = options;

		if (this.options.strip <= 0) {
			this.options.strip = 0;
		// eslint-disable-next-line logical-assignment-operators
		} else if (!this.options.strip) {
			this.options.strip = 1;
		}
	}

	/**
	 * Get or set files to download
	 *
	 * @param {String} src
	 * @param {String} os
	 * @param {String} arch
	 * @api public
	 */
	src(src, os, arch) {
		if (arguments.length === 0) {
			return this._src;
		}

		this._src ||= [];
		this._src.push({url: src, os, arch});

		return this;
	}

	/**
	 * Get or set the destination
	 *
	 * @param {String} dest
	 * @api public
	 */
	dest(dest) {
		if (arguments.length === 0) {
			return this._dest;
		}

		this._dest = dest;
		return this;
	}

	/**
	 * Get or set the binary
	 *
	 * @param {String} bin
	 * @api public
	 */
	use(bin) {
		if (arguments.length === 0) {
			return this._use;
		}

		this._use = bin;
		return this;
	}

	/**
	 * Get or set a semver range to test the binary against
	 *
	 * @param {String} range
	 * @api public
	 */
	version(range) {
		if (arguments.length === 0) {
			return this._version;
		}

		this._version = range;
		return this;
	}

	/**
	 * Get path to the binary
	 *
	 * @api public
	 */
	path() {
		return path.join(this.dest(), this.use());
	}

	/**
	 * Run
	 *
	 * @param {Array} cmd
	 * @api public
	 */
	run(cmd = ['--version']) {
		return this.findExisting().then(() => {
			if (this.options.skipCheck) {
				return;
			}

			return this.runCheck(cmd);
		});
	}

	/**
	 * Run binary check
	 *
	 * @param {Array} cmd
	 * @api private
	 */
	runCheck(cmd) {
		return binCheck(this.path(), cmd).then(works => {
			if (!works) {
				throw new Error(
					`The "${this.path()}" binary doesn't seem to work correctly`,
				);
			}

			if (this.version()) {
				return binVersionCheck(this.path(), this.version());
			}
		});
	}

	/**
	 * Find existing files
	 *
	 * @api private
	 */
	findExisting() {
		return fs.stat(this.path()).catch(error => {
			if (error?.code === 'ENOENT') {
				return this.download();
			}

			throw error;
		});
	}

	/**
	 * Download files
	 *
	 * @api private
	 */
	download() {
		const files = osFilterObject(this.src() || []);

		if (files.length === 0) {
			return Promise.reject(
				new Error(
					'No binary found matching your system. It\'s probably not supported.',
				),
			);
		}

		const urls = [];
		for (const file of files) {
			urls.push(file.url);
		}

		return Promise.all(
			urls.map(url =>
				download(url, this.dest(), {
					extract: true,
					decompress: {
						strip: this.options.strip,
					},
				}),
			),
		).then(result => {
			const resultFiles = result.flatMap((item, index) => {
				if (Array.isArray(item)) {
					return item.map(file => file.path);
				}

				const parsedUrl = new URL(files[index].url);
				const parsedPath = path.parse(parsedUrl.pathname);

				return parsedPath.base;
			});

			return Promise.all(
				resultFiles.map(file => fs.chmod(path.join(this.dest(), file), 0o755)),
			);
		});
	}
}