Skip to content

Commit

Permalink
lint and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Sparticuz committed Apr 15, 2024
1 parent 1151d3b commit e6f131c
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 175 deletions.
2 changes: 1 addition & 1 deletion _/amazon/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { createHash } = require("node:crypto");
const puppeteer = require("puppeteer-core");
const chromium = require("@sparticuz/chromium");

exports.handler = async (event, context) => {
exports.handler = async (event) => {
let browser = null;

try {
Expand Down
23 changes: 8 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
"@tsconfig/node20": "^20.1.4",
"@tsconfig/strictest": "^2.0.5",
"@types/follow-redirects": "^1.14.4",
"@types/node": "^20.12.3",
"@types/node": "^20.12.7",
"@types/tar-fs": "^2.0.4",
"clean-modules": "^3.0.5",
"typescript": "^5.4.3"
"typescript": "^5.4.5"
},
"engines": {
"node": ">= 16"
Expand Down
23 changes: 11 additions & 12 deletions source/helper.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { unlink } from "node:fs";
import { https } from "follow-redirects";
import { unlink } from "node:fs";
import { tmpdir } from "node:os";
import { type UrlWithStringQuery, parse } from "node:url";
import { extract } from "tar-fs";
import { parse } from "node:url";
import type { UrlWithStringQuery } from "node:url";

interface FollowRedirOptions extends UrlWithStringQuery {
maxBodyLength: number;
Expand All @@ -12,7 +11,7 @@ interface FollowRedirOptions extends UrlWithStringQuery {
export const isValidUrl = (input: string) => {
try {
return !!new URL(input);
} catch (err) {
} catch {
return false;
}
};
Expand Down Expand Up @@ -59,18 +58,18 @@ export const downloadAndExtract = async (url: string) =>
new Promise<string>((resolve, reject) => {
const getOptions = parse(url) as FollowRedirOptions;
getOptions.maxBodyLength = 60 * 1024 * 1024; // 60mb
const destDir = `${tmpdir()}/chromium-pack`;
const extractObj = extract(destDir);
const destinationDirectory = `${tmpdir()}/chromium-pack`;
const extractObject = extract(destinationDirectory);
https
.get(url, (response) => {
response.pipe(extractObj);
extractObj.on("finish", () => {
resolve(destDir);
response.pipe(extractObject);
extractObject.on("finish", () => {
resolve(destinationDirectory);
});
})
.on("error", (err) => {
unlink(destDir, (_) => {
reject(err);
.on("error", (error) => {
unlink(destinationDirectory, () => {
reject(error);
});
});
});
173 changes: 87 additions & 86 deletions source/index.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,53 @@
import { https } from "follow-redirects";
import {
access,
createWriteStream,
existsSync,
mkdirSync,
symlink,
} from "node:fs";
import { https } from "follow-redirects";
import LambdaFS from "./lambdafs";
import { join } from "node:path";
import { URL } from "node:url";

import {
downloadAndExtract,
isRunningInAwsLambda,
isValidUrl,
isRunningInAwsLambdaNode20,
isValidUrl,
} from "./helper";
import { inflate } from "./lambdafs";

/** Viewport taken from https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.viewport.md */
interface Viewport {
/**
* The page width in pixels.
*/
width: number;
/**
* The page height in pixels.
*/
height: number;
/**
* Specify device scale factor.
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio | devicePixelRatio} for more info.
* @default 1
*/
deviceScaleFactor?: number;
/**
* Whether the `meta viewport` tag is taken into account.
* Specify if the viewport supports touch events.
* @default false
*/
isMobile?: boolean;
hasTouch?: boolean;
/**
* The page height in pixels.
*/
height: number;
/**
* Specifies if the viewport is in landscape mode.
* @default false
*/
isLandscape?: boolean;
/**
* Specify if the viewport supports touch events.
* Whether the `meta viewport` tag is taken into account.
* @default false
*/
hasTouch?: boolean;
isMobile?: boolean;
/**
* The page width in pixels.
*/
width: number;
}

if (isRunningInAwsLambda()) {
Expand Down Expand Up @@ -93,71 +94,7 @@ class Chromium {
* If false, webgl will be disabled.
* (If false, the swiftshader.tar.br file will also not extract)
*/
private static graphicsMode: boolean = true;

/**
* Downloads or symlinks a custom font and returns its basename, patching the environment so that Chromium can find it.
*/
static font(input: string): Promise<string> {
if (process.env["HOME"] === undefined) {
process.env["HOME"] = "/tmp";
}

if (existsSync(`${process.env["HOME"]}/.fonts`) !== true) {
mkdirSync(`${process.env["HOME"]}/.fonts`);
}

return new Promise((resolve, reject) => {
if (/^https?:[/][/]/i.test(input) !== true) {
input = `file://${input}`;
}

const url = new URL(input);
const output = `${process.env["HOME"]}/.fonts/${url.pathname
.split("/")
.pop()}`;

if (existsSync(output) === true) {
return resolve(output.split("/").pop() as string);
}

if (url.protocol === "file:") {
access(url.pathname, (error) => {
if (error != null) {
return reject(error);
}

symlink(url.pathname, output, (error) => {
return error != null
? reject(error)
: resolve(url.pathname.split("/").pop() as string);
});
});
} else {
https.get(input, (response) => {
if (response.statusCode !== 200) {
return reject(`Unexpected status code: ${response.statusCode}.`);
}

const stream = 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() as string);
});
});
});
}
});
}
private static graphicsMode = true;

/**
* Returns a list of additional Chromium flags recommended for serverless environments.
Expand Down Expand Up @@ -271,19 +208,19 @@ class Chromium {

// Extract the required files
const promises = [
LambdaFS.inflate(`${input}/chromium.br`),
LambdaFS.inflate(`${input}/fonts.tar.br`),
inflate(`${input}/chromium.br`),
inflate(`${input}/fonts.tar.br`),
];
if (this.graphics) {
// Only inflate graphics stack if needed
promises.push(LambdaFS.inflate(`${input}/swiftshader.tar.br`));
promises.push(inflate(`${input}/swiftshader.tar.br`));
}
if (isRunningInAwsLambda()) {
// If running in AWS Lambda, extract more required files
promises.push(LambdaFS.inflate(`${input}/al2.tar.br`));
promises.push(inflate(`${input}/al2.tar.br`));
}
if (isRunningInAwsLambdaNode20()) {
promises.push(LambdaFS.inflate(`${input}/al2023.tar.br`));
promises.push(inflate(`${input}/al2023.tar.br`));
}

// Await all extractions
Expand All @@ -292,6 +229,70 @@ class Chromium {
return result.shift() as string;
}

/**
* Downloads or symlinks a custom font and returns its basename, patching the environment so that Chromium can find it.
*/
static font(input: string): Promise<string> {
if (process.env["HOME"] === undefined) {
process.env["HOME"] = "/tmp";
}

if (existsSync(`${process.env["HOME"]}/.fonts`) !== true) {
mkdirSync(`${process.env["HOME"]}/.fonts`);
}

return new Promise((resolve, reject) => {
if (/^https?:\/\//i.test(input) !== true) {
input = `file://${input}`;
}

const url = new URL(input);
const output = `${process.env["HOME"]}/.fonts/${url.pathname
.split("/")
.pop()}`;

if (existsSync(output) === true) {
return resolve(output.split("/").pop() as string);
}

if (url.protocol === "file:") {
access(url.pathname, (error) => {
if (error != null) {
return reject(error);
}

symlink(url.pathname, output, (error) => {
return error == null
? resolve(url.pathname.split("/").pop() as string)
: reject(error);
});
});
} else {
https.get(input, (response) => {
if (response.statusCode !== 200) {
return reject(`Unexpected status code: ${response.statusCode}.`);
}

const stream = 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() as string);
});
});
});
}
});
}

/**
* Returns whether the graphics stack is enabled or disabled
* @returns boolean
Expand All @@ -309,7 +310,7 @@ class Chromium {
*/
public static set setGraphicsMode(value: boolean) {
if (typeof value !== "boolean") {
throw new Error(
throw new TypeError(
`Graphics mode must be a boolean, you entered '${value}'`
);
}
Expand Down
Loading

0 comments on commit e6f131c

Please sign in to comment.