lint and cleanup
This commit is contained in:
parent
1151d3bc96
commit
e6f131ca70
|
|
@ -3,7 +3,7 @@ const { createHash } = require("node:crypto");
|
||||||
const puppeteer = require("puppeteer-core");
|
const puppeteer = require("puppeteer-core");
|
||||||
const chromium = require("@sparticuz/chromium");
|
const chromium = require("@sparticuz/chromium");
|
||||||
|
|
||||||
exports.handler = async (event, context) => {
|
exports.handler = async (event) => {
|
||||||
let browser = null;
|
let browser = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -13,25 +13,18 @@
|
||||||
"tar-fs": "^3.0.5"
|
"tar-fs": "^3.0.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node16": "^16.1.3",
|
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@tsconfig/strictest": "^2.0.5",
|
"@tsconfig/strictest": "^2.0.5",
|
||||||
"@types/follow-redirects": "^1.14.4",
|
"@types/follow-redirects": "^1.14.4",
|
||||||
"@types/node": "^20.12.3",
|
"@types/node": "^20.12.7",
|
||||||
"@types/tar-fs": "^2.0.4",
|
"@types/tar-fs": "^2.0.4",
|
||||||
"clean-modules": "^3.0.5",
|
"clean-modules": "^3.0.5",
|
||||||
"typescript": "^5.4.3"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tsconfig/node16": {
|
|
||||||
"version": "16.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-16.1.3.tgz",
|
|
||||||
"integrity": "sha512-9nTOUBn+EMKO6rtSZJk+DcqsfgtlERGT9XPJ5PRj/HNENPCBY1yu/JEj5wT6GLtbCLBO2k46SeXDaY0pjMqypw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@tsconfig/node20": {
|
"node_modules/@tsconfig/node20": {
|
||||||
"version": "20.1.4",
|
"version": "20.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
|
||||||
|
|
@ -54,9 +47,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "20.12.3",
|
"version": "20.12.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||||
"integrity": "sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw==",
|
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
|
|
@ -306,9 +299,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.4.3",
|
"version": "5.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.4",
|
||||||
"@tsconfig/strictest": "^2.0.5",
|
"@tsconfig/strictest": "^2.0.5",
|
||||||
"@types/follow-redirects": "^1.14.4",
|
"@types/follow-redirects": "^1.14.4",
|
||||||
"@types/node": "^20.12.3",
|
"@types/node": "^20.12.7",
|
||||||
"@types/tar-fs": "^2.0.4",
|
"@types/tar-fs": "^2.0.4",
|
||||||
"clean-modules": "^3.0.5",
|
"clean-modules": "^3.0.5",
|
||||||
"typescript": "^5.4.3"
|
"typescript": "^5.4.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 16"
|
"node": ">= 16"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { unlink } from "node:fs";
|
|
||||||
import { https } from "follow-redirects";
|
import { https } from "follow-redirects";
|
||||||
|
import { unlink } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
|
import { type UrlWithStringQuery, parse } from "node:url";
|
||||||
import { extract } from "tar-fs";
|
import { extract } from "tar-fs";
|
||||||
import { parse } from "node:url";
|
|
||||||
import type { UrlWithStringQuery } from "node:url";
|
|
||||||
|
|
||||||
interface FollowRedirOptions extends UrlWithStringQuery {
|
interface FollowRedirOptions extends UrlWithStringQuery {
|
||||||
maxBodyLength: number;
|
maxBodyLength: number;
|
||||||
|
|
@ -12,7 +11,7 @@ interface FollowRedirOptions extends UrlWithStringQuery {
|
||||||
export const isValidUrl = (input: string) => {
|
export const isValidUrl = (input: string) => {
|
||||||
try {
|
try {
|
||||||
return !!new URL(input);
|
return !!new URL(input);
|
||||||
} catch (err) {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -59,18 +58,18 @@ export const downloadAndExtract = async (url: string) =>
|
||||||
new Promise<string>((resolve, reject) => {
|
new Promise<string>((resolve, reject) => {
|
||||||
const getOptions = parse(url) as FollowRedirOptions;
|
const getOptions = parse(url) as FollowRedirOptions;
|
||||||
getOptions.maxBodyLength = 60 * 1024 * 1024; // 60mb
|
getOptions.maxBodyLength = 60 * 1024 * 1024; // 60mb
|
||||||
const destDir = `${tmpdir()}/chromium-pack`;
|
const destinationDirectory = `${tmpdir()}/chromium-pack`;
|
||||||
const extractObj = extract(destDir);
|
const extractObject = extract(destinationDirectory);
|
||||||
https
|
https
|
||||||
.get(url, (response) => {
|
.get(url, (response) => {
|
||||||
response.pipe(extractObj);
|
response.pipe(extractObject);
|
||||||
extractObj.on("finish", () => {
|
extractObject.on("finish", () => {
|
||||||
resolve(destDir);
|
resolve(destinationDirectory);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.on("error", (err) => {
|
.on("error", (error) => {
|
||||||
unlink(destDir, (_) => {
|
unlink(destinationDirectory, () => {
|
||||||
reject(err);
|
reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
173
source/index.ts
173
source/index.ts
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { https } from "follow-redirects";
|
||||||
import {
|
import {
|
||||||
access,
|
access,
|
||||||
createWriteStream,
|
createWriteStream,
|
||||||
|
|
@ -5,27 +6,19 @@ import {
|
||||||
mkdirSync,
|
mkdirSync,
|
||||||
symlink,
|
symlink,
|
||||||
} from "node:fs";
|
} from "node:fs";
|
||||||
import { https } from "follow-redirects";
|
|
||||||
import LambdaFS from "./lambdafs";
|
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { URL } from "node:url";
|
import { URL } from "node:url";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
downloadAndExtract,
|
downloadAndExtract,
|
||||||
isRunningInAwsLambda,
|
isRunningInAwsLambda,
|
||||||
isValidUrl,
|
|
||||||
isRunningInAwsLambdaNode20,
|
isRunningInAwsLambdaNode20,
|
||||||
|
isValidUrl,
|
||||||
} from "./helper";
|
} from "./helper";
|
||||||
|
import { inflate } from "./lambdafs";
|
||||||
|
|
||||||
/** Viewport taken from https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.viewport.md */
|
/** Viewport taken from https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.viewport.md */
|
||||||
interface Viewport {
|
interface Viewport {
|
||||||
/**
|
|
||||||
* The page width in pixels.
|
|
||||||
*/
|
|
||||||
width: number;
|
|
||||||
/**
|
|
||||||
* The page height in pixels.
|
|
||||||
*/
|
|
||||||
height: number;
|
|
||||||
/**
|
/**
|
||||||
* Specify device scale factor.
|
* Specify device scale factor.
|
||||||
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio | devicePixelRatio} for more info.
|
* See {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio | devicePixelRatio} for more info.
|
||||||
|
|
@ -33,20 +26,28 @@ interface Viewport {
|
||||||
*/
|
*/
|
||||||
deviceScaleFactor?: number;
|
deviceScaleFactor?: number;
|
||||||
/**
|
/**
|
||||||
* Whether the `meta viewport` tag is taken into account.
|
* Specify if the viewport supports touch events.
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
isMobile?: boolean;
|
hasTouch?: boolean;
|
||||||
|
/**
|
||||||
|
* The page height in pixels.
|
||||||
|
*/
|
||||||
|
height: number;
|
||||||
/**
|
/**
|
||||||
* Specifies if the viewport is in landscape mode.
|
* Specifies if the viewport is in landscape mode.
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
isLandscape?: boolean;
|
isLandscape?: boolean;
|
||||||
/**
|
/**
|
||||||
* Specify if the viewport supports touch events.
|
* Whether the `meta viewport` tag is taken into account.
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
hasTouch?: boolean;
|
isMobile?: boolean;
|
||||||
|
/**
|
||||||
|
* The page width in pixels.
|
||||||
|
*/
|
||||||
|
width: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRunningInAwsLambda()) {
|
if (isRunningInAwsLambda()) {
|
||||||
|
|
@ -93,71 +94,7 @@ class Chromium {
|
||||||
* If false, webgl will be disabled.
|
* If false, webgl will be disabled.
|
||||||
* (If false, the swiftshader.tar.br file will also not extract)
|
* (If false, the swiftshader.tar.br file will also not extract)
|
||||||
*/
|
*/
|
||||||
private static graphicsMode: boolean = true;
|
private static graphicsMode = 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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of additional Chromium flags recommended for serverless environments.
|
* Returns a list of additional Chromium flags recommended for serverless environments.
|
||||||
|
|
@ -271,19 +208,19 @@ class Chromium {
|
||||||
|
|
||||||
// Extract the required files
|
// Extract the required files
|
||||||
const promises = [
|
const promises = [
|
||||||
LambdaFS.inflate(`${input}/chromium.br`),
|
inflate(`${input}/chromium.br`),
|
||||||
LambdaFS.inflate(`${input}/fonts.tar.br`),
|
inflate(`${input}/fonts.tar.br`),
|
||||||
];
|
];
|
||||||
if (this.graphics) {
|
if (this.graphics) {
|
||||||
// Only inflate graphics stack if needed
|
// Only inflate graphics stack if needed
|
||||||
promises.push(LambdaFS.inflate(`${input}/swiftshader.tar.br`));
|
promises.push(inflate(`${input}/swiftshader.tar.br`));
|
||||||
}
|
}
|
||||||
if (isRunningInAwsLambda()) {
|
if (isRunningInAwsLambda()) {
|
||||||
// If running in AWS Lambda, extract more required files
|
// 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()) {
|
if (isRunningInAwsLambdaNode20()) {
|
||||||
promises.push(LambdaFS.inflate(`${input}/al2023.tar.br`));
|
promises.push(inflate(`${input}/al2023.tar.br`));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Await all extractions
|
// Await all extractions
|
||||||
|
|
@ -292,6 +229,70 @@ class Chromium {
|
||||||
return result.shift() as string;
|
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 whether the graphics stack is enabled or disabled
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
|
|
@ -309,7 +310,7 @@ class Chromium {
|
||||||
*/
|
*/
|
||||||
public static set setGraphicsMode(value: boolean) {
|
public static set setGraphicsMode(value: boolean) {
|
||||||
if (typeof value !== "boolean") {
|
if (typeof value !== "boolean") {
|
||||||
throw new Error(
|
throw new TypeError(
|
||||||
`Graphics mode must be a boolean, you entered '${value}'`
|
`Graphics mode must be a boolean, you entered '${value}'`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,73 @@
|
||||||
import { createReadStream, createWriteStream, existsSync } from "node:fs";
|
import { createReadStream, createWriteStream, existsSync } from "node:fs";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { basename, join } from "node:path";
|
import { basename, join } from "node:path";
|
||||||
import { extract } from "tar-fs";
|
|
||||||
import { createBrotliDecompress, createUnzip } from "node:zlib";
|
import { createBrotliDecompress, createUnzip } from "node:zlib";
|
||||||
|
import { extract } from "tar-fs";
|
||||||
|
|
||||||
class LambdaFS {
|
/**
|
||||||
/**
|
* Decompresses a (tarballed) Brotli or Gzip compressed file and returns the path to the decompressed file/folder.
|
||||||
* 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.
|
||||||
* @param filePath Path of the file to decompress.
|
*/
|
||||||
*/
|
export const inflate = (filePath: string): Promise<string> => {
|
||||||
static inflate(filePath: string): Promise<string> {
|
const output = filePath.includes("swiftshader")
|
||||||
const output = filePath.includes("swiftshader")
|
? tmpdir()
|
||||||
? tmpdir()
|
: join(
|
||||||
: join(
|
tmpdir(),
|
||||||
tmpdir(),
|
basename(filePath).replace(
|
||||||
basename(filePath).replace(
|
/\.(?:t(?:ar(?:\.(?:br|gz))?|br|gz)|br|gz)$/i,
|
||||||
/[.](?:t(?:ar(?:[.](?:br|gz))?|br|gz)|br|gz)$/i,
|
""
|
||||||
""
|
)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (filePath.includes("swiftshader")) {
|
if (filePath.includes("swiftshader")) {
|
||||||
if (existsSync(`${output}/libGLESv2.so`)) {
|
if (existsSync(`${output}/libGLESv2.so`)) {
|
||||||
return resolve(output);
|
return resolve(output);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (existsSync(output) === true) {
|
|
||||||
return resolve(output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
let source = createReadStream(filePath, { highWaterMark: 2 ** 23 });
|
if (existsSync(output) === true) {
|
||||||
let target = null;
|
return resolve(output);
|
||||||
|
|
||||||
if (/[.](?:t(?:ar(?:[.](?:br|gz))?|br|gz))$/i.test(filePath) === true) {
|
|
||||||
target = extract(output);
|
|
||||||
|
|
||||||
target.once("finish", () => {
|
|
||||||
return resolve(output);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
target = createWriteStream(output, { mode: 0o700 });
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
source.once("error", (error: Error) => {
|
const source = createReadStream(filePath, { highWaterMark: 2 ** 23 });
|
||||||
return reject(error);
|
let target = null;
|
||||||
});
|
|
||||||
|
|
||||||
target.once("error", (error: Error) => {
|
if (/\.t(?:ar(?:\.(?:br|gz))?|br|gz)$/i.test(filePath) === true) {
|
||||||
return reject(error);
|
target = extract(output);
|
||||||
});
|
|
||||||
|
|
||||||
target.once("close", () => {
|
target.once("finish", () => {
|
||||||
return resolve(output);
|
return resolve(output);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
target = createWriteStream(output, { mode: 0o700 });
|
||||||
|
}
|
||||||
|
|
||||||
if (/(?:br|gz)$/i.test(filePath) === true) {
|
source.once("error", (error: Error) => {
|
||||||
source
|
return reject(error);
|
||||||
.pipe(
|
|
||||||
/br$/i.test(filePath)
|
|
||||||
? createBrotliDecompress({ chunkSize: 2 ** 21 })
|
|
||||||
: createUnzip({ chunkSize: 2 ** 21 })
|
|
||||||
)
|
|
||||||
.pipe(target);
|
|
||||||
} else {
|
|
||||||
source.pipe(target);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LambdaFS;
|
target.once("error", (error: Error) => {
|
||||||
|
return reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
target.once("close", () => {
|
||||||
|
return resolve(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (/(?:br|gz)$/i.test(filePath) === true) {
|
||||||
|
source
|
||||||
|
.pipe(
|
||||||
|
/br$/i.test(filePath)
|
||||||
|
? createBrotliDecompress({ chunkSize: 2 ** 21 })
|
||||||
|
: createUnzip({ chunkSize: 2 ** 21 })
|
||||||
|
)
|
||||||
|
.pipe(target);
|
||||||
|
} else {
|
||||||
|
source.pipe(target);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default inflate;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue