Add enable_pdf to chromium build and add build to git folder for installing via npm on git
This commit is contained in:
parent
74283507ac
commit
ae70d74c68
|
|
@ -3,7 +3,6 @@
|
|||
*.pem.pub
|
||||
*.zip
|
||||
bin/chromium-*.br
|
||||
build
|
||||
node_modules
|
||||
nodejs
|
||||
_/amazon/samconfig.toml
|
||||
|
|
@ -12,3 +11,6 @@ _/amazon/.aws-sam
|
|||
*.tgz
|
||||
examples/**/package-lock.json
|
||||
examples/**/.serverless
|
||||
chromium/
|
||||
_/ansible/bin
|
||||
_/ansible/lib
|
||||
|
|
@ -64,12 +64,12 @@
|
|||
|
||||
- name: Registering Host
|
||||
add_host:
|
||||
hostname: "{{ ec2.instances[0].public_ip_address }}"
|
||||
hostname: "{{ ec2.instances[0]['public_ip_address'] }}"
|
||||
groupname: aws
|
||||
|
||||
- name: Waiting for SSH
|
||||
wait_for:
|
||||
host: "{{ ec2.instances[0].public_ip_address }}"
|
||||
host: "{{ ec2.instances[0]['public_ip_address'] }}"
|
||||
port: 22
|
||||
timeout: 240
|
||||
state: started
|
||||
|
|
@ -251,6 +251,7 @@
|
|||
disable_histogram_support = false
|
||||
enable_basic_print_dialog = false
|
||||
enable_basic_printing = true
|
||||
enable_pdf = true
|
||||
enable_keystone_registration_framework = false
|
||||
enable_linux_installer = false
|
||||
enable_media_remoting = false
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,9 @@
|
|||
export declare const isValidUrl: (input: string) => boolean;
|
||||
/**
|
||||
* Determines if the running instance is inside an AWS Lambda container.
|
||||
* AWS_EXECUTION_ENV is for native Lambda instances
|
||||
* AWS_LAMBDA_JS_RUNTIME is for netlify instances
|
||||
* @returns boolean indicating if the running instance is inside a Lambda container
|
||||
*/
|
||||
export declare const isRunningInAwsLambda: () => boolean;
|
||||
export declare const downloadAndExtract: (url: string) => Promise<string>;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.downloadAndExtract = exports.isRunningInAwsLambda = exports.isValidUrl = void 0;
|
||||
const node_fs_1 = require("node:fs");
|
||||
const follow_redirects_1 = require("follow-redirects");
|
||||
const node_os_1 = require("node:os");
|
||||
const tar_fs_1 = require("tar-fs");
|
||||
const node_url_1 = require("node:url");
|
||||
const isValidUrl = (input) => {
|
||||
try {
|
||||
return !!new URL(input);
|
||||
}
|
||||
catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
exports.isValidUrl = isValidUrl;
|
||||
/**
|
||||
* Determines if the running instance is inside an AWS Lambda container.
|
||||
* AWS_EXECUTION_ENV is for native Lambda instances
|
||||
* AWS_LAMBDA_JS_RUNTIME is for netlify instances
|
||||
* @returns boolean indicating if the running instance is inside a Lambda container
|
||||
*/
|
||||
const isRunningInAwsLambda = () => {
|
||||
if (process.env["AWS_EXECUTION_ENV"] &&
|
||||
/^AWS_Lambda_nodejs/.test(process.env["AWS_EXECUTION_ENV"]) === true) {
|
||||
return true;
|
||||
}
|
||||
else if (process.env["AWS_LAMBDA_JS_RUNTIME"] &&
|
||||
/^nodejs/.test(process.env["AWS_LAMBDA_JS_RUNTIME"]) === true) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
exports.isRunningInAwsLambda = isRunningInAwsLambda;
|
||||
const downloadAndExtract = async (url) => new Promise((resolve, reject) => {
|
||||
const getOptions = (0, node_url_1.parse)(url);
|
||||
getOptions.maxBodyLength = 60 * 1024 * 1024; // 60mb
|
||||
const destDir = `${(0, node_os_1.tmpdir)()}/chromium-pack`;
|
||||
const extractObj = (0, tar_fs_1.extract)(destDir);
|
||||
follow_redirects_1.https
|
||||
.get(url, (response) => {
|
||||
response.pipe(extractObj);
|
||||
extractObj.on("finish", () => {
|
||||
resolve(destDir);
|
||||
});
|
||||
})
|
||||
.on("error", (err) => {
|
||||
(0, node_fs_1.unlink)(destDir, (_) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
exports.downloadAndExtract = downloadAndExtract;
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/** 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.
|
||||
* @default false
|
||||
*/
|
||||
isMobile?: boolean;
|
||||
/**
|
||||
* Specifies if the viewport is in landscape mode.
|
||||
* @default false
|
||||
*/
|
||||
isLandscape?: boolean;
|
||||
/**
|
||||
* Specify if the viewport supports touch events.
|
||||
* @default false
|
||||
*/
|
||||
hasTouch?: boolean;
|
||||
}
|
||||
declare class Chromium {
|
||||
/**
|
||||
* Determines the headless mode that chromium will run at
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @values true or "new"
|
||||
*/
|
||||
private static headlessMode;
|
||||
/**
|
||||
* If true, the graphics stack and webgl is enabled,
|
||||
* If false, webgl will be disabled.
|
||||
* (If false, the swiftshader.tar.br file will also not extract)
|
||||
*/
|
||||
private static graphicsMode;
|
||||
/**
|
||||
* 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>;
|
||||
/**
|
||||
* 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(): string[];
|
||||
/**
|
||||
* Returns sensible default viewport settings for serverless environments.
|
||||
*/
|
||||
static get defaultViewport(): Required<Viewport>;
|
||||
/**
|
||||
* Inflates the included version of Chromium
|
||||
* @param input The location of the `bin` folder
|
||||
* @returns The path to the `chromium` binary
|
||||
*/
|
||||
static executablePath(input?: string): Promise<string>;
|
||||
/**
|
||||
* Returns the headless mode.
|
||||
* `true` means the 'old' (legacy, chromium < 112) headless mode.
|
||||
* "new" means the 'new' headless mode.
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @returns true | "new"
|
||||
*/
|
||||
static get headless(): true | "new";
|
||||
/**
|
||||
* Sets the headless mode.
|
||||
* `true` means the 'old' (legacy, chromium < 112) headless mode.
|
||||
* "new" means the 'new' headless mode.
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @default "new"
|
||||
*/
|
||||
static set setHeadlessMode(value: true | "new");
|
||||
/**
|
||||
* Returns whether the graphics stack is enabled or disabled
|
||||
* @returns boolean
|
||||
*/
|
||||
static get graphics(): boolean;
|
||||
/**
|
||||
* Sets whether the graphics stack is enabled or disabled.
|
||||
* @param true means the stack is enabled. WebGL will work.
|
||||
* @param false means that the stack is disabled. WebGL will not work.
|
||||
* `false` will also skip the extract of the graphics driver, saving about a second during initial extract
|
||||
* @default true
|
||||
*/
|
||||
static set setGraphicsMode(value: boolean);
|
||||
}
|
||||
export = Chromium;
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
const node_fs_1 = require("node:fs");
|
||||
const follow_redirects_1 = require("follow-redirects");
|
||||
const lambdafs_1 = __importDefault(require("./lambdafs"));
|
||||
const node_path_1 = require("node:path");
|
||||
const node_url_1 = require("node:url");
|
||||
const helper_1 = require("./helper");
|
||||
if ((0, helper_1.isRunningInAwsLambda)()) {
|
||||
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.
|
||||
*/
|
||||
static font(input) {
|
||||
if (process.env["HOME"] === undefined) {
|
||||
process.env["HOME"] = "/tmp";
|
||||
}
|
||||
if ((0, node_fs_1.existsSync)(`${process.env["HOME"]}/.fonts`) !== true) {
|
||||
(0, node_fs_1.mkdirSync)(`${process.env["HOME"]}/.fonts`);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (/^https?:[/][/]/i.test(input) !== true) {
|
||||
input = `file://${input}`;
|
||||
}
|
||||
const url = new node_url_1.URL(input);
|
||||
const output = `${process.env["HOME"]}/.fonts/${url.pathname
|
||||
.split("/")
|
||||
.pop()}`;
|
||||
if ((0, node_fs_1.existsSync)(output) === true) {
|
||||
return resolve(output.split("/").pop());
|
||||
}
|
||||
if (url.protocol === "file:") {
|
||||
(0, node_fs_1.access)(url.pathname, (error) => {
|
||||
if (error != null) {
|
||||
return reject(error);
|
||||
}
|
||||
(0, node_fs_1.symlink)(url.pathname, output, (error) => {
|
||||
return error != null
|
||||
? reject(error)
|
||||
: resolve(url.pathname.split("/").pop());
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
follow_redirects_1.https.get(input, (response) => {
|
||||
if (response.statusCode !== 200) {
|
||||
return reject(`Unexpected status code: ${response.statusCode}.`);
|
||||
}
|
||||
const stream = (0, node_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() {
|
||||
/**
|
||||
* These are the default args in puppeteer.
|
||||
* https://github.com/puppeteer/puppeteer/blob/3a31070d054fa3cd8116ca31c578807ed8d6f987/packages/puppeteer-core/src/node/ChromeLauncher.ts#L185
|
||||
*/
|
||||
const puppeteerFlags = [
|
||||
"--allow-pre-commit-input",
|
||||
"--disable-background-networking",
|
||||
"--disable-background-timer-throttling",
|
||||
"--disable-backgrounding-occluded-windows",
|
||||
"--disable-breakpad",
|
||||
"--disable-client-side-phishing-detection",
|
||||
"--disable-component-extensions-with-background-pages",
|
||||
"--disable-component-update",
|
||||
"--disable-default-apps",
|
||||
"--disable-dev-shm-usage",
|
||||
"--disable-extensions",
|
||||
"--disable-hang-monitor",
|
||||
"--disable-ipc-flooding-protection",
|
||||
"--disable-popup-blocking",
|
||||
"--disable-prompt-on-repost",
|
||||
"--disable-renderer-backgrounding",
|
||||
"--disable-sync",
|
||||
"--enable-automation",
|
||||
// TODO(sadym): remove '--enable-blink-features=IdleDetection' once
|
||||
// IdleDetection is turned on by default.
|
||||
"--enable-blink-features=IdleDetection",
|
||||
"--export-tagged-pdf",
|
||||
"--force-color-profile=srgb",
|
||||
"--metrics-recording-only",
|
||||
"--no-first-run",
|
||||
"--password-store=basic",
|
||||
"--use-mock-keychain",
|
||||
];
|
||||
const puppeteerDisableFeatures = [
|
||||
"Translate",
|
||||
"BackForwardCache",
|
||||
// AcceptCHFrame disabled because of crbug.com/1348106.
|
||||
"AcceptCHFrame",
|
||||
"MediaRouter",
|
||||
"OptimizationHints",
|
||||
];
|
||||
const puppeteerEnableFeatures = ["NetworkServiceInProcess2"];
|
||||
const chromiumFlags = [
|
||||
"--disable-domain-reliability",
|
||||
"--disable-print-preview",
|
||||
"--disable-speech-api",
|
||||
"--disk-cache-size=33554432",
|
||||
"--mute-audio",
|
||||
"--no-default-browser-check",
|
||||
"--no-pings",
|
||||
"--single-process", // Needs to be single-process to avoid `prctl(PR_SET_NO_NEW_PRIVS) failed` error
|
||||
];
|
||||
const chromiumDisableFeatures = [
|
||||
"AudioServiceOutOfProcess",
|
||||
"IsolateOrigins",
|
||||
"site-per-process",
|
||||
];
|
||||
const chromiumEnableFeatures = ["SharedArrayBuffer"];
|
||||
const graphicsFlags = [
|
||||
"--hide-scrollbars",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--in-process-gpu",
|
||||
"--window-size=1920,1080", // https://source.chromium.org/search?q=lang:cpp+symbol:kWindowSize&ss=chromium
|
||||
];
|
||||
// https://chromium.googlesource.com/chromium/src/+/main/docs/gpu/swiftshader.md
|
||||
this.graphics
|
||||
? graphicsFlags.push("--use-gl=angle", "--use-angle=swiftshader")
|
||||
: graphicsFlags.push("--disable-webgl");
|
||||
const insecureFlags = [
|
||||
"--allow-running-insecure-content",
|
||||
"--disable-setuid-sandbox",
|
||||
"--disable-site-isolation-trials",
|
||||
"--disable-web-security",
|
||||
"--no-sandbox",
|
||||
"--no-zygote", // https://source.chromium.org/search?q=lang:cpp+symbol:kNoZygote&ss=chromium
|
||||
];
|
||||
const headlessFlags = [
|
||||
this.headless === "new" ? "--headless='new'" : "--headless",
|
||||
];
|
||||
return [
|
||||
...puppeteerFlags,
|
||||
...chromiumFlags,
|
||||
`--disable-features=${[
|
||||
...puppeteerDisableFeatures,
|
||||
...chromiumDisableFeatures,
|
||||
].join(",")}`,
|
||||
`--enable-features=${[
|
||||
...puppeteerEnableFeatures,
|
||||
...chromiumEnableFeatures,
|
||||
].join(",")}`,
|
||||
...graphicsFlags,
|
||||
...insecureFlags,
|
||||
...headlessFlags,
|
||||
];
|
||||
}
|
||||
/**
|
||||
* Returns sensible default viewport settings for serverless environments.
|
||||
*/
|
||||
static get defaultViewport() {
|
||||
return {
|
||||
deviceScaleFactor: 1,
|
||||
hasTouch: false,
|
||||
height: 1080,
|
||||
isLandscape: true,
|
||||
isMobile: false,
|
||||
width: 1920,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Inflates the included version of Chromium
|
||||
* @param input The location of the `bin` folder
|
||||
* @returns The path to the `chromium` binary
|
||||
*/
|
||||
static async executablePath(input) {
|
||||
/**
|
||||
* If the `chromium` binary already exists in /tmp/chromium, return it.
|
||||
*/
|
||||
if ((0, node_fs_1.existsSync)("/tmp/chromium") === true) {
|
||||
return Promise.resolve("/tmp/chromium");
|
||||
}
|
||||
/**
|
||||
* If input is a valid URL, download and extract the file. It will extract to /tmp/chromium-pack
|
||||
* and executablePath will be recursively called on that location, which will then extract
|
||||
* the brotli files to the correct locations
|
||||
*/
|
||||
if (input && (0, helper_1.isValidUrl)(input)) {
|
||||
return this.executablePath(await (0, helper_1.downloadAndExtract)(input));
|
||||
}
|
||||
/**
|
||||
* If input is defined, use that as the location of the brotli files,
|
||||
* otherwise, the default location is ../bin.
|
||||
* A custom location is needed for workflows that using custom packaging.
|
||||
*/
|
||||
input ??= (0, node_path_1.join)(__dirname, "..", "bin");
|
||||
/**
|
||||
* If the input directory doesn't exist, throw an error.
|
||||
*/
|
||||
if (!(0, node_fs_1.existsSync)(input)) {
|
||||
throw new Error(`The input directory "${input}" does not exist.`);
|
||||
}
|
||||
// Extract the required files
|
||||
const promises = [lambdafs_1.default.inflate(`${input}/chromium.br`)];
|
||||
if (this.graphics) {
|
||||
// Only inflate graphics stack if needed
|
||||
promises.push(lambdafs_1.default.inflate(`${input}/swiftshader.tar.br`));
|
||||
}
|
||||
if ((0, helper_1.isRunningInAwsLambda)()) {
|
||||
// If running in AWS Lambda, extract more required files
|
||||
promises.push(lambdafs_1.default.inflate(`${input}/aws.tar.br`));
|
||||
}
|
||||
// Await all extractions
|
||||
const result = await Promise.all(promises);
|
||||
// Returns the first result of the promise, which is the location of the `chromium` binary
|
||||
return result.shift();
|
||||
}
|
||||
/**
|
||||
* Returns the headless mode.
|
||||
* `true` means the 'old' (legacy, chromium < 112) headless mode.
|
||||
* "new" means the 'new' headless mode.
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @returns true | "new"
|
||||
*/
|
||||
static get headless() {
|
||||
return this.headlessMode;
|
||||
}
|
||||
/**
|
||||
* Sets the headless mode.
|
||||
* `true` means the 'old' (legacy, chromium < 112) headless mode.
|
||||
* "new" means the 'new' headless mode.
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @default "new"
|
||||
*/
|
||||
static set setHeadlessMode(value) {
|
||||
if ((typeof value === "string" && value !== "new") ||
|
||||
(typeof value === "boolean" && value !== true)) {
|
||||
throw new Error(`Headless mode must be either \`true\` or 'new', you entered '${value}'`);
|
||||
}
|
||||
this.headlessMode = value;
|
||||
}
|
||||
/**
|
||||
* Returns whether the graphics stack is enabled or disabled
|
||||
* @returns boolean
|
||||
*/
|
||||
static get graphics() {
|
||||
return this.graphicsMode;
|
||||
}
|
||||
/**
|
||||
* Sets whether the graphics stack is enabled or disabled.
|
||||
* @param true means the stack is enabled. WebGL will work.
|
||||
* @param false means that the stack is disabled. WebGL will not work.
|
||||
* `false` will also skip the extract of the graphics driver, saving about a second during initial extract
|
||||
* @default true
|
||||
*/
|
||||
static set setGraphicsMode(value) {
|
||||
if (typeof value !== "boolean") {
|
||||
throw new Error(`Graphics mode must be a boolean, you entered '${value}'`);
|
||||
}
|
||||
this.graphicsMode = value;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Determines the headless mode that chromium will run at
|
||||
* https://developer.chrome.com/articles/new-headless/#try-out-the-new-headless
|
||||
* @values true or "new"
|
||||
*/
|
||||
Chromium.headlessMode = "new";
|
||||
/**
|
||||
* If true, the graphics stack and webgl is enabled,
|
||||
* If false, webgl will be disabled.
|
||||
* (If false, the swiftshader.tar.br file will also not extract)
|
||||
*/
|
||||
Chromium.graphicsMode = true;
|
||||
module.exports = Chromium;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
declare class LambdaFS {
|
||||
/**
|
||||
* Decompresses a (tarballed) Brotli or Gzip compressed file and returns the path to the decompressed file/folder.
|
||||
*
|
||||
* @param filePath Path of the file to decompress.
|
||||
*/
|
||||
static inflate(filePath: string): Promise<string>;
|
||||
}
|
||||
export = LambdaFS;
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
"use strict";
|
||||
const node_fs_1 = require("node:fs");
|
||||
const node_os_1 = require("node:os");
|
||||
const node_path_1 = require("node:path");
|
||||
const tar_fs_1 = require("tar-fs");
|
||||
const node_zlib_1 = require("node:zlib");
|
||||
class LambdaFS {
|
||||
/**
|
||||
* Decompresses a (tarballed) Brotli or Gzip compressed file and returns the path to the decompressed file/folder.
|
||||
*
|
||||
* @param filePath Path of the file to decompress.
|
||||
*/
|
||||
static inflate(filePath) {
|
||||
const output = filePath.includes("swiftshader")
|
||||
? (0, node_os_1.tmpdir)()
|
||||
: (0, node_path_1.join)((0, node_os_1.tmpdir)(), (0, node_path_1.basename)(filePath).replace(/[.](?:t(?:ar(?:[.](?:br|gz))?|br|gz)|br|gz)$/i, ""));
|
||||
return new Promise((resolve, reject) => {
|
||||
if (filePath.includes("swiftshader")) {
|
||||
if ((0, node_fs_1.existsSync)(`${output}/libGLESv2.so`)) {
|
||||
return resolve(output);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((0, node_fs_1.existsSync)(output) === true) {
|
||||
return resolve(output);
|
||||
}
|
||||
}
|
||||
let source = (0, node_fs_1.createReadStream)(filePath, { highWaterMark: 2 ** 23 });
|
||||
let target = null;
|
||||
if (/[.](?:t(?:ar(?:[.](?:br|gz))?|br|gz))$/i.test(filePath) === true) {
|
||||
target = (0, tar_fs_1.extract)(output);
|
||||
target.once("finish", () => {
|
||||
return resolve(output);
|
||||
});
|
||||
}
|
||||
else {
|
||||
target = (0, node_fs_1.createWriteStream)(output, { mode: 0o700 });
|
||||
}
|
||||
source.once("error", (error) => {
|
||||
return reject(error);
|
||||
});
|
||||
target.once("error", (error) => {
|
||||
return reject(error);
|
||||
});
|
||||
target.once("close", () => {
|
||||
return resolve(output);
|
||||
});
|
||||
if (/(?:br|gz)$/i.test(filePath) === true) {
|
||||
source
|
||||
.pipe(/br$/i.test(filePath)
|
||||
? (0, node_zlib_1.createBrotliDecompress)({ chunkSize: 2 ** 21 })
|
||||
: (0, node_zlib_1.createUnzip)({ chunkSize: 2 ** 21 }))
|
||||
.pipe(target);
|
||||
}
|
||||
else {
|
||||
source.pipe(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
module.exports = LambdaFS;
|
||||
Loading…
Reference in New Issue