UNPKG

chrome-aws-lambda

Version:

Chromium Binary for AWS Lambda and Google Cloud Functions

188 lines 7.56 kB
"use strict"; /// <reference path="../typings/chrome-aws-lambda.d.ts" /> var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const fs_1 = require("fs"); const lambdafs_1 = __importDefault(require("lambdafs")); const path_1 = require("path"); const url_1 = require("url"); if (/^AWS_Lambda_nodejs(?:10|12|14)[.]x$/.test(process.env.AWS_EXECUTION_ENV) === true) { if (process.env.FONTCONFIG_PATH === undefined) { process.env.FONTCONFIG_PATH = '/tmp/aws'; } if (process.env.LD_LIBRARY_PATH === undefined) { process.env.LD_LIBRARY_PATH = '/tmp/aws/lib'; } else if (process.env.LD_LIBRARY_PATH.startsWith('/tmp/aws/lib') !== true) { process.env.LD_LIBRARY_PATH = [...new Set(['/tmp/aws/lib', ...process.env.LD_LIBRARY_PATH.split(':')])].join(':'); } } class Chromium { /** * Downloads or symlinks a custom font and returns its basename, patching the environment so that Chromium can find it. * If not running on AWS Lambda nor Google Cloud Functions, `null` is returned instead. */ static font(input) { if (Chromium.headless !== true) { return null; } if (process.env.HOME === undefined) { process.env.HOME = '/tmp'; } if (fs_1.existsSync(`${process.env.HOME}/.fonts`) !== true) { fs_1.mkdirSync(`${process.env.HOME}/.fonts`); } return new Promise((resolve, reject) => { if (/^https?:[/][/]/i.test(input) !== true) { input = `file://${input}`; } const url = new url_1.URL(input); const output = `${process.env.HOME}/.fonts/${url.pathname.split('/').pop()}`; if (fs_1.existsSync(output) === true) { return resolve(output.split('/').pop()); } if (url.protocol === 'file:') { fs_1.access(url.pathname, (error) => { if (error != null) { return reject(error); } fs_1.symlink(url.pathname, output, (error) => { return error != null ? reject(error) : resolve(url.pathname.split('/').pop()); }); }); } else { let handler = url.protocol === 'http:' ? require('http').get : require('https').get; handler(input, (response) => { if (response.statusCode !== 200) { return reject(`Unexpected status code: ${response.statusCode}.`); } const stream = fs_1.createWriteStream(output); stream.once('error', (error) => { return reject(error); }); response.on('data', (chunk) => { stream.write(chunk); }); response.once('end', () => { stream.end(() => { return resolve(url.pathname.split('/').pop()); }); }); }); } }); } /** * Returns a list of additional Chromium flags recommended for serverless environments. * The canonical list of flags can be found on https://peter.sh/experiments/chromium-command-line-switches/. */ static get args() { const result = [ '--allow-running-insecure-content', '--autoplay-policy=user-gesture-required', '--disable-component-update', '--disable-domain-reliability', '--disable-features=AudioServiceOutOfProcess,IsolateOrigins,site-per-process', '--disable-print-preview', '--disable-setuid-sandbox', '--disable-site-isolation-trials', '--disable-speech-api', '--disable-web-security', '--disk-cache-size=33554432', '--enable-features=SharedArrayBuffer', '--hide-scrollbars', '--ignore-gpu-blocklist', '--in-process-gpu', '--mute-audio', '--no-default-browser-check', '--no-pings', '--no-sandbox', '--no-zygote', '--use-gl=swiftshader', '--window-size=1920,1080', // https://source.chromium.org/search?q=lang:cpp+symbol:kWindowSize&ss=chromium ]; if (Chromium.headless === true) { result.push('--single-process'); // https://source.chromium.org/search?q=lang:cpp+symbol:kSingleProcess&ss=chromium } else { result.push('--start-maximized'); // https://source.chromium.org/search?q=lang:cpp+symbol:kStartMaximized&ss=chromium } return result; } /** * Returns sensible default viewport settings. */ static get defaultViewport() { return { deviceScaleFactor: 1, hasTouch: false, height: 1080, isLandscape: true, isMobile: false, width: 1920, }; } /** * Inflates the current version of Chromium and returns the path to the binary. * If not running on AWS Lambda nor Google Cloud Functions, `null` is returned instead. */ static get executablePath() { if (Chromium.headless !== true) { return Promise.resolve(null); } if (fs_1.existsSync('/tmp/chromium') === true) { for (const file of fs_1.readdirSync('/tmp')) { if (file.startsWith('core.chromium') === true) { fs_1.unlinkSync(`/tmp/${file}`); } } return Promise.resolve('/tmp/chromium'); } const input = path_1.join(__dirname, '..', 'bin'); const promises = [ lambdafs_1.default.inflate(`${input}/chromium.br`), lambdafs_1.default.inflate(`${input}/swiftshader.tar.br`), ]; if (/^AWS_Lambda_nodejs(?:10|12|14)[.]x$/.test(process.env.AWS_EXECUTION_ENV) === true) { promises.push(lambdafs_1.default.inflate(`${input}/aws.tar.br`)); } return Promise.all(promises).then((result) => result.shift()); } /** * Returns a boolean indicating if we are running on AWS Lambda or Google Cloud Functions. * False is returned if Serverless environment variables `IS_LOCAL` or `IS_OFFLINE` are set. */ static get headless() { if (process.env.IS_LOCAL !== undefined || process.env.IS_OFFLINE !== undefined) { return false; } const environments = [ 'AWS_LAMBDA_FUNCTION_NAME', 'FUNCTION_NAME', 'FUNCTION_TARGET', 'FUNCTIONS_EMULATOR', ]; return environments.some((key) => process.env[key] !== undefined); } /** * Overloads puppeteer with useful methods and returns the resolved package. */ static get puppeteer() { for (const overload of ['Browser', 'BrowserContext', 'ElementHandle', 'FrameManager', 'Page']) { require(`${__dirname}/puppeteer/lib/${overload}`); } try { return require('puppeteer'); } catch (error) { if (error.code !== 'MODULE_NOT_FOUND') { throw error; } return require('puppeteer-core'); } } } module.exports = Chromium; //# sourceMappingURL=index.js.map