zync-nest-library
Version:
NestJS library with database backup and file upload utilities
138 lines (121 loc) • 3.46 kB
text/typescript
import { Injectable } from "@nestjs/common";
import sharp from "sharp";
import { BucketService } from "./bucket";
import { IUpload, IUploadResult } from "./upload.interface";
const SIZE_MAP = {
sm: 433,
md: 640,
lg: 800,
};
()
export class UploadService {
constructor(private readonly bucketSvc: BucketService) {}
public upload = this.bucketSvc;
async saveFiles(
files: any[],
sizes?: Array<"sm" | "md" | "lg">,
type: "stream" | "base64" = "base64"
): Promise<IUploadResult[]> {
let fls = [];
if (files && files.length > 0) {
for await (let file of files) {
const mapedFl = await this._mapFile(file, type);
const uri = await this._saveFile(mapedFl, type);
const fl: Partial<IUploadResult> = {
name: file.filename,
type: file.mimetype,
uri: uri,
};
if (sizes?.length) {
const rs = await Promise.all(
sizes.map(async (size) =>
this._saveFile(
{
file: await this.resize(mapedFl?.file, SIZE_MAP[size]),
filename: file.filename,
filetype: file.filetype,
dir: `${SIZE_MAP[size]}`,
transformName: false,
},
type
)
)
);
sizes.forEach((s, i) => {
fl[`${s}Uri`] = rs[i];
});
}
fls.push(fl);
}
}
return fls;
}
private async _mapFile(file: any, type: "stream" | "base64") {
if (type === "base64")
return {
file: file.file || file.base64Str,
filename: file.filename,
filetype: file.filetype,
};
else {
const { createReadStream, filename, mimetype } = await file;
return {
file:
typeof createReadStream === "function"
? createReadStream()
: createReadStream,
filename: filename,
filetype: mimetype,
};
}
}
private async _saveFile(
upload: IUpload,
type: "stream" | "base64" = "base64"
) {
if (!upload?.file) return null;
return type === "base64"
? await this.upload.uploadBase64(upload)
: await this.upload.uploadStream(upload);
}
public async saveFile(
upload: IUpload,
type: "stream" | "base64" = "base64"
): Promise<IUploadResult> {
const fl = await this._mapFile(upload, type);
return {
uri: await this._saveFile(fl, type),
name: fl.filename,
type: fl.filetype,
};
}
public async deleteFile(uri: string) {
return await this.upload.deleteFile(uri);
}
private async resize(file: any, size: number) {
return new Promise((resolve, reject) => {
// If file is a base64 string, convert it to a Buffer
const buffer =
typeof file === "string" && file.startsWith("data:")
? Buffer.from(file.split(",")[1], "base64")
: Buffer.isBuffer(file)
? file
: file;
sharp(buffer)
.resize({
height: size,
width: size,
fit: sharp.fit.inside,
withoutEnlargement: true,
})
.toBuffer()
.then((resizedBuffer) => {
resolve(resizedBuffer.toString("base64"));
})
.catch((error) => {
console.error("Error occurred while resizing the image:", error);
throw error;
});
});
}
}