I have written a code that should verify and convert every image that passes through it. I made use from nestjs, magic-bytes.js and Sharp. But i get an error that says:
Type 'Promise<Buffer>[]' is missing the following properties from type 'Promise<File | File[]>': then, catch, finally, [Symbol.toStringTag]ts(2739)
Can someone help me fix this?
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";
import { filetypemime } from "magic-bytes.js";
import * as sharp from "sharp";
@Injectable()
export class ParseFile implements PipeTransform {
async transform(
incomingFiles: Express.Multer.File | Express.Multer.File[],
metadata: ArgumentMetadata,
): Promise<Express.Multer.File | Express.Multer.File[]> {
const files = Array.isArray(incomingFiles) ? incomingFiles : [incomingFiles];
const bytes = files.map((file) => new Uint8Array(file.buffer));
const fileMimetype = filetypemime(bytes);
if (fileMimetype) {
console.log(`File type is ${fileMimetype}`);
}
if (incomingFiles === undefined || incomingFiles === null) {
throw new BadRequestException("Validation failed (file expected)");
}
if (Array.isArray(incomingFiles) && incomingFiles.length === 0) {
throw new BadRequestException("Validation failed (files expected)");
}
const compressedFiles: Promise<Express.Multer.File | Express.Multer.File[]> = files.map(
async (file) => await sharp(file.buffer).resize(320, 240).toFormat("webp").toBuffer(),
);
return Array.isArray(incomingFiles) ? compressedFiles : compressedFiles;
}
}
I have tried to remove the type by compressedFiles, but then i got another error that says:
Type 'Promise<Buffer>[]' is not assignable to type 'File | File[]'
I found that this works best for me. Thanks for the help, because i got a lot of inspiration from the answer that i got.
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";
import { filetypemime } from "magic-bytes.js";
import * as sharp from "sharp";
import { Readable } from "stream";
import { randomUUID } from "crypto";
@Injectable()
export class ParseFile implements PipeTransform {
async transform(
incomingFiles: Express.Multer.File | Express.Multer.File[],
metadata: ArgumentMetadata,
): Promise<Express.Multer.File | Express.Multer.File[]> {
const files = Array.isArray(incomingFiles) ? incomingFiles : [incomingFiles];
const bytes = files.map((file) => new Uint8Array(file.buffer));
const mimeTypes = bytes.map((byte) => filetypemime(byte as any));
if (mimeTypes.every((type) => type.includes("image"))) {
throw new BadRequestException(
`Validation failed (file should be an image), mimetype: ${mimeTypes}`,
);
}
if (incomingFiles === undefined || incomingFiles === null) {
throw new BadRequestException("Validation failed (file expected)");
}
if (Array.isArray(incomingFiles) && incomingFiles.length === 0) {
throw new BadRequestException("Validation failed (files expected)");
}
const compressedFiles = await Promise.all(
files.map(async (file) => {
const buffer = await sharp(file.buffer).resize(320, 240).toFormat("webp").toBuffer();
const newFile: Express.Multer.File = {
fieldname: file.fieldname,
originalname: `${randomUUID()}.webp`,
encoding: file.encoding,
mimetype: "image/webp",
buffer: buffer,
size: buffer.length,
destination: "",
stream: new Readable(),
filename: "",
path: "",
};
console.log(newFile);
return newFile;
}),
);
return Array.isArray(incomingFiles) ? compressedFiles : compressedFiles[0];
}
}