import { Body, Controller, Get, Param, Post, Redirect, Render, Res, UploadedFile, UploadedFiles, UseInterceptors, } from '@nestjs/common'; import { JunkDrawerService } from './junk-drawer.service'; import { ApiConsumes, ApiTags } from '@nestjs/swagger'; import { FilesInterceptor } from '@nestjs/platform-express'; import { generateUniqueSlug } from 'src/utils/slug'; import { JunkDrawerMetadata } from './types'; import { Response } from 'express'; @Controller('junk-drawer') @ApiTags('junk-drawer') export class JunkDrawerController { constructor(private readonly junkDrawerService: JunkDrawerService) {} @Get('') @Render('junk-drawer/upload') generateUploadForm() { return {}; } @Get(':slug.json') async junkDrawerJson( @Param('slug') slug: string, ): Promise { return this.junkDrawerService.getJunkDrawerMetadata(slug); } @Get(':slug') @Render('junk-drawer/view') async viewJunkDrawer(@Param('slug') slug: string): Promise { const metadata = await this.junkDrawerService.getJunkDrawerMetadata(slug); return { ...metadata }; } @Get(':slug/:filename') async downloadJunkDrawerItem( @Param('slug') slug: string, @Param('filename') filename: string, @Res() res: Response, ) { const metadata = await this.junkDrawerService.getJunkDrawerMetadata(slug); if (!metadata) { return res.status(404).send('File not found or expired'); } const item = metadata.items.find((item) => item.filename === filename); if (!item) { return res.status(404).send('File not found or expired'); } const buffer = await this.junkDrawerService.getJunkDrawerItem( slug, filename, ); return res .header('Content-Type', item.mimetype) .header('Content-Disposition', `filename="${item.filename}"`) .send(buffer); } @Post('upload') @Redirect('', 302) @ApiConsumes('multipart/form-data') @UseInterceptors(FilesInterceptor('files')) async handleFileUpload( @UploadedFiles() files: Express.Multer.File[], @Body('description') description: string, @Body('private-ish') privateIsh: boolean, ): Promise { console.log(privateIsh); const uniqueSlug = generateUniqueSlug({ random: privateIsh, }); const metadata: JunkDrawerMetadata = { slug: uniqueSlug, version: '1.0.0', lastModified: new Date(), description, items: files.map((file) => ({ filename: file.originalname, size: file.size, lastModified: new Date(), mimetype: file.mimetype, })), }; for (const file of files) { await this.junkDrawerService.storeJunkDrawerItem( uniqueSlug, file.originalname, file.buffer, ); } await this.junkDrawerService.storeJunkDrawerMetadata(metadata); return { url: `/junk-drawer/${uniqueSlug}` }; } }