UNPKG

3.19 kBPlain TextView Raw
1import { Request as ERequest, Response as EResponse } from "express";
2import AsyncResponse from "./async.response";
3import * as Jimp from "jimp";
4import * as fs from "fs";
5import { app } from "./app";
6
7function fileExsist(path: string): Promise<boolean> {
8 return new Promise<boolean>((res, _) => {
9 fs.exists(path, val => {
10 res(val);
11 });
12 });
13}
14
15function saveToCache(path: string, s: Jimp) {
16 if (!app.config.chachingImages) {
17 return;
18 }
19 s.writeAsync(path).catch(err => console.error(err));
20}
21
22/**
23 * This interface defines the currently available options for files.
24 */
25export interface FileOptions {
26 width: number;
27 height?: number;
28}
29/**
30 * Generation of a File response.
31 */
32export default class FileResponse extends AsyncResponse {
33 private readonly path: string;
34 private _contentType?: string;
35 private _fileName: string;
36 private _options?: FileOptions;
37 constructor(path: string) {
38 super();
39 this.path = path;
40 }
41
42 /**
43 * Set the content type of the response.
44 * @param value the content type
45 */
46 set contentType(value: string) {
47 this._contentType = value;
48 }
49
50 /**
51 * Set the name of the file to download
52 * @param value the name of the file
53 */
54 set fileName(value: string) {
55 this._fileName = value;
56 }
57
58 /**
59 * Set the file options, to correctly generate the response.
60 * @param value the FileOptions
61 */
62 set options(value: FileOptions) {
63 this._options = value;
64 }
65
66 private download(res: EResponse, path: string) {
67 if (this._fileName) {
68 return res.download(path, this._fileName);
69 }
70 res.download(path);
71 }
72 /**
73 * Generation of the response.
74 * This method can eventually perform some transformation on output if a
75 * FileOptions was specified.
76 */
77 async asyncResponse(_: ERequest, res: EResponse): Promise<void> {
78 if (this._contentType) {
79 res.contentType(this._contentType);
80 }
81 let path = await app.config.ufs.getToCache(
82 this.path,
83 app.config.cachePath
84 );
85
86 if (!this._options) {
87 return this.download(res, path);
88 }
89
90 let cachePath = path + "_" + JSON.stringify(this._options);
91 if (await fileExsist(cachePath)) {
92 return this.download(res, cachePath);
93 }
94
95 let img = {} as Jimp;
96 let hasProcessing = false;
97 if (!this._options.height) {
98 img = await Jimp.read(path);
99 img = img.resize(this._options.width, Jimp.AUTO);
100 hasProcessing = true;
101 }
102 if (this._options.width && this._options.height) {
103 hasProcessing = true;
104 img = await Jimp.read(path);
105 img = img.resize(this._options.width, this._options.height);
106
107 }
108 if (hasProcessing) {
109 let buff = await (img as Jimp).getBufferAsync(this._contentType as string);
110 res.send(buff);
111 res.end();
112 saveToCache(cachePath, img);
113 return;
114 }
115 this.download(res, path);
116 }
117}
118
\No newline at end of file