Files
lislgosms/api/src/files/client-files.controller.ts
T

56 lines
2.0 KiB
TypeScript

import {
BadRequestException,
Body,
Controller,
Get,
Param,
Post,
Query,
Res,
UploadedFile,
UseInterceptors,
UsePipes,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags } from '@nestjs/swagger';
import { CurrentSessionUserId } from '../auth/current-session-user.decorator';
import { FilesService } from './files.service';
import { strictValidationPipe } from '../common/strict-validation.pipe';
import { ClientFileUploadDto } from './client-files.dto';
type UploadedMultipartFile = { originalname: string; mimetype: string; size: number; buffer: Buffer };
type DownloadResponse = { setHeader(name: string, value: number | string): void; send(content: Buffer): void };
@ApiTags('client-files')
@Controller('client/files')
export class ClientFilesController {
constructor(private readonly files: FilesService) {}
@Post('upload')
@UseInterceptors(FileInterceptor('file', { limits: { fileSize: 10 * 1024 * 1024, files: 1, fields: 4, parts: 5 } }))
@UsePipes(strictValidationPipe)
upload(
@CurrentSessionUserId() userId: string | undefined,
@UploadedFile() file: UploadedMultipartFile,
@Body() body: ClientFileUploadDto,
) {
if (!file) throw new BadRequestException('Upload file is required');
return this.files.uploadForClient(userId, body, file);
}
@Get(':id/download')
async download(
@CurrentSessionUserId() userId: string | undefined,
@Param('id') id: string,
@Query('disposition') disposition: string | undefined,
@Res() response: DownloadResponse,
) {
const { fileObject, content } = await this.files.getClientDownload(userId, id);
const mode = disposition === 'inline' ? 'inline' : 'attachment';
response.setHeader('Content-Type', fileObject.contentType || 'application/octet-stream');
response.setHeader('Content-Length', content.length);
response.setHeader('Content-Disposition', `${mode}; filename*=UTF-8''${encodeURIComponent(fileObject.fileName)}`);
response.send(content);
}
}