chrome-aws-lambda
Version:
Chromium Binary for AWS Lambda and Google Cloud Functions
188 lines • 7.56 kB
JavaScript
/// <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
;