UNPKG

zync-nest-library

Version:

NestJS library with database backup and file upload utilities

138 lines (121 loc) 3.46 kB
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, }; @Injectable() 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; }); }); } }