Skip to content

Instantly share code, notes, and snippets.

@izaakwalz
Created December 20, 2023 08:31
Show Gist options
  • Save izaakwalz/748d73a69d058ac1faec3a95f70f8ba6 to your computer and use it in GitHub Desktop.
Save izaakwalz/748d73a69d058ac1faec3a95f70f8ba6 to your computer and use it in GitHub Desktop.
Multer upload Middleware
import { Request } from 'express';
import multer, { FileFilterCallback } from 'multer';
import { AppStatusCode, ErrorResponse } from '../helpers/errorResponse';
type processType = 'image' | 'video';
type maxSizeType = '10MB' | '50MB' | '100MB' | '1GB';
const storage = multer.memoryStorage(); // multer storage path
const videoFilter = (request: Request, file: any, callback: FileFilterCallback): void => {
//Accepted file types
const mimeTypes = ['video/mp4', 'video/3gp', 'video/mkv', 'video/mov', 'video/webm'];
if (mimeTypes.includes(file.mimetype)) {
callback(null, true);
} else {
callback(new ErrorResponse(AppStatusCode.FAILURE, 'Invalid file format!', 409));
}
};
const imageFilter = (request: Request, file: any, callback: FileFilterCallback): void => {
//Accepted file types
const mimeTypes = ['image/jpeg', 'image/png']; // ...rest;
if (mimeTypes.includes(file.mimetype)) {
callback(null, true);
} else {
callback(new ErrorResponse(AppStatusCode.FAILURE, 'Invalid file format!', 409));
}
};
/**
* Custom Multer Upload midddleware
*
* @param filterType should be - `image` - or - `video`
* @returns Multer instance that provides several methods for Uploading files
*/
export default function upload(limtType: maxSizeType, filterType: processType) {
const filterFor = { image: imageFilter, video: videoFilter }; // filter type function
// limist type for file
const maxSizeForLimit = {
'10MB': { fileSize: 10 * 10024 * 1024 },
'50MB': { fileSize: 50 * 10024 * 1024 },
'100MB': { fileSize: 100 * 1024 * 1025 },
'1GB': { fileSize: 1024 * 10024 * 1024 },
};
return multer({ storage, limits: maxSizeForLimit[limtType], fileFilter: filterFor[filterType] });
}
import { File, Web3Storage } from 'web3.storage';
import { WEB3STORAGE_TOKEN } from '../constants';
import { customAlphabet } from 'nanoid';
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 8);
function getAccessToken() {
return WEB3STORAGE_TOKEN;
}
export async function makeStorageClient() {
return new Web3Storage({ token: getAccessToken() });
}
export function makeFileObjects(object: object) {
const obj = object;
const blob = new Blob([JSON.stringify(obj)], { type: 'application/json' });
const fileName = `${nanoid()}_${new Date().toString()}.txt`;
const file = new File([blob], fileName);
return file;
}
export default async function (file: any, name?: string) {
const assetName = name ? name : file.originalname;
try {
const files = [
new File([file.buffer], assetName, {
type: file.mimetype,
}),
];
const client = await makeStorageClient();
const cid = await client.put(files);
// e.g
// upload user avatart
export const updateAvatar = asyncHandler(
async (req: Request, res: Response) => {
const user = res.locals.user;
const id = new Types.ObjectId(user._id);
if (!req.file)
throw new ErrorResponse(
AppStatusCode.FAILURE,
'No file found!',
StatusCodes.NOT_FOUND,
);
const name = user.username;
const avatarId = await ipfsUtils(req.file, name);
await updateUserParams({ _id: id }, avatarId && { avatar: avatarId });
return res
.status(StatusCodes.OK)
.send(apiResponse(200, 'user avatar updated', avatarId));
},
);
return cid;
} catch (error: any) {
if (error.code == 'LIMIT_FILE_SIZE') {
console.log(error.message)
}
if (error.code == 'MISSING_FIELD_NAME'){
console.log(error.message)
}
if (error.code == 'LIMIT_UNEXPECTED_FILE') {
console.log(error.message)
}
console.log(error.message)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment