UNPKG

@argdown/node

Version:

Async Argdown application for node.js

71 lines (69 loc) 2.37 kB
import { IAsyncArgdownPlugin, IAsyncRequestHandler } from "../IAsyncArgdownPlugin"; import { promisify } from "util"; import imageSize from "image-size"; import { ArgdownPluginError } from "@argdown/core"; import axios from "axios"; import { ISizeCalculationResult } from "image-size/dist/types/interface"; import { constants, promises as fs } from "fs"; import path from "path"; const imageSizeAsync = promisify(imageSize); export class ImageSizePlugin implements IAsyncArgdownPlugin { name = "ImageSizePlugin"; runAsync: IAsyncRequestHandler = async (request, _response, _logger) => { if (!request.images || !request.images.files) { return; } for (let image of Object.values(request.images!.files!)) { if (!image.path) { return; } try { let dimensions: ISizeCalculationResult | undefined; if (image.width && image.height) { // do not overwrite values continue; } if (image.path.startsWith("https:") || image.path.startsWith("http:")) { dimensions = await this.getSizeFromRemoteFile(image.path); } else { try { const baseDir = request.inputPath && !!path.extname(request.inputPath) ? path.dirname(request.inputPath) : request.inputPath || ""; await fs.access( path.resolve(baseDir, image.path), constants.F_OK | constants.R_OK ); dimensions = await imageSizeAsync(image.path); } catch (err) { dimensions = await this.getSizeFromRemoteFile(image.path); } } if (!dimensions) { continue; } image.width = dimensions.width; image.height = dimensions.height; } catch (err) { if (err instanceof Error) { throw new ArgdownPluginError( this.name, "image-size-failed", `'Getting the image size of '${image.path}' failed. ${err.message}` ); } } } }; getSizeFromRemoteFile = async (path: string) => { const response = await axios.get(path, { responseType: "arraybuffer" }); const buffer = Buffer.from(response.data, "binary"); return imageSize(buffer); }; }