Skip to content

Commit

Permalink
Merge pull request #159 from Savio629/minio-multiple1
Browse files Browse the repository at this point in the history
Fix Minio and multiple file upload
  • Loading branch information
techsavvyash authored Jul 9, 2024
2 parents 46a7bab + 94472b6 commit 844c3e5
Show file tree
Hide file tree
Showing 21 changed files with 1,029 additions and 656 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,6 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

data
dist
4 changes: 4 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ yarn-debug.log*
yarn-error.log*

static/**/node_modules/


dist
data
12 changes: 6 additions & 6 deletions packages/common/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ module.exports = {
testMatch: ['**/test/**/*.spec.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json',
},
'^.+\\.(t|j)s$': [
'ts-jest',
{
tsconfig: 'tsconfig.json',
},
],
},
};
1 change: 1 addition & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"dependencies": {
"@nestjs/cache-manager": "^2.1.0",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/platform-fastify": "^10.3.0",
Expand Down
87 changes: 67 additions & 20 deletions packages/common/src/controllers/file-upload.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,43 @@ import {
Controller,
Post,
UploadedFile,
UploadedFiles,
UseInterceptors,
Param,
Get,
Res,
Body,
Query,
Logger,
ValidationPipe,
InternalServerErrorException,
} from '@nestjs/common';
import { FastifyFileInterceptor } from '../interceptors/file-upload.interceptor';
import {
FastifyFilesInterceptor,
FastifyFileInterceptor,
} from '../interceptors/file-upload.interceptor';
import { MultipartFile } from '../interfaces/file-upload.interface';
import { FileUploadService } from '../services/file-upload.service';
import { FastifyReply } from 'fastify';
import {
FileUploadRequestDTO,
MakeBucketRequestDTO,
} from '../services/dto/file-upload.dto';

interface UploadFilesDto {
filename: string[];
}

@Controller('files')
export class FileUploadController {
private readonly logger = new Logger(FileUploadController.name);
constructor(private readonly filesService: FileUploadService) {}

@Post('make-bucket')
async makeBucket(@Body() body: MakeBucketRequestDTO): Promise<string> {
return await this.filesService.makeBucket(body.destination);
}

@Post('upload-file')
@UseInterceptors(FastifyFileInterceptor('file', {}))
async uploadFile(
Expand All @@ -29,11 +51,12 @@ export class FileUploadController {
file?: { url: string } | undefined;
}> {
try {
const directory = await this.filesService.upload(
file,
destination,
filename,
);
const fileUploadRequestDto = new FileUploadRequestDTO();
fileUploadRequestDto.file = file;
fileUploadRequestDto.destination = destination;
fileUploadRequestDto.filename = filename;
console.log(fileUploadRequestDto);
const directory = await this.filesService.upload(fileUploadRequestDto);
return {
message: 'File uploaded successfully',
file: { url: directory },
Expand All @@ -48,22 +71,46 @@ export class FileUploadController {
}
}

@Get('download/:destination')
// @Post('upload-files')
// @UseInterceptors(FastifyFilesInterceptor('file', []))
// async uploadMultipleFiles(
// @UploadedFiles() file: ReadonlyArray<MultipartFile>,
// @Query('destination') destination: string,
// @Body() body: UploadFilesDto,
// ): Promise<{
// statusCode?: number;
// message: string;
// files?: { url: any }[] | undefined;
// }> {
// try {
// const { filename } = body;
// const directories = await this.filesService.uploadMultiple(
// file,
// destination,
// filename,
// );
// return {
// message: 'Files uploaded successfully',
// files: directories.map((directory) => ({ url: directory })),
// };
// } catch (error) {
// this.logger.error(`Error uploading files: ${error.message}`);
// throw new InternalServerErrorException('File upload Failed');
// }
// }

@Get('download')
async downloadFile(
@Param('destination') destination: string,
@Query('destination') destination: string,
@Query('filename') filename: string,
@Res() res: FastifyReply,
): Promise<void> {
try {
const fileStream = await this.filesService.download(destination);
res.headers({
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename=${destination}`,
});
fileStream.pipe(res.raw);
} catch (error) {
console.log('error: ', error);
console.error(`Error downloading file: ${error.message}`);
res.status(500).send('File download failed');
}
const fileStream = await this.filesService.download(destination, filename);

res.headers({
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename=${filename}`,
});
fileStream.pipe(res.raw);
}
}
54 changes: 51 additions & 3 deletions packages/common/src/interceptors/file-upload.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,83 @@ import {
ExecutionContext,
Inject,
mixin,
Logger,
NestInterceptor,
Optional,
Type,
HttpCode,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import FastifyMulter from 'fastify-multer';
import { Options, Multer } from 'multer';
import { InterceptResponseDTO } from './dto/file-upload.dto';

type MulterInstance = Multer;
type MulterInstance = any;

export function FastifyFilesInterceptor(
fieldName: string,
localOptions: Array<Options>,
): Type<NestInterceptor> {
class MixinInterceptor implements NestInterceptor {
protected multer: MulterInstance;
private readonly logger : Logger;
constructor(
@Optional()
@Inject('MULTER_MODULE_OPTIONS')
options: Multer,
) {
this.multer = (FastifyMulter as any)({ ...options, ...localOptions });
this.logger = new Logger(FastifyFilesInterceptor.name);
}

async intercept(
context: ExecutionContext,
next: CallHandler,
): Promise<Observable<InterceptResponseDTO>> {
const ctx = context.switchToHttp();

await new Promise<void>((resolve, reject) =>
this.multer.array(fieldName)(
ctx.getRequest(),
ctx.getResponse(),
(error: any) => {
if (error) {
this.logger.error(`Error uploading files: ${error.message}`, error.stack);
return reject(error);
}
resolve();
},
),
);

return next.handle();
}
}

const Interceptor = mixin(MixinInterceptor);
return Interceptor as Type<NestInterceptor>;
}
export function FastifyFileInterceptor(
fieldName: string,
localOptions: Options,
): Type<NestInterceptor> {
class MixinInterceptor implements NestInterceptor {
protected multer: MulterInstance;
private readonly logger : Logger;

constructor(
@Optional()
@Inject('MULTER_MODULE_OPTIONS')
options: Multer,
) {
this.multer = (FastifyMulter as any)({ ...options, ...localOptions });
this.logger = new Logger(FastifyFileInterceptor.name);
}

async intercept(
context: ExecutionContext,
next: CallHandler,
): Promise<Observable<InterceptResponseDTO>> {
): Promise<Observable<any>> {
const ctx = context.switchToHttp();

await new Promise<void>((resolve, reject) =>
Expand All @@ -41,7 +89,7 @@ export function FastifyFileInterceptor(
(error: any) => {
if (error) {
// const error = transformException(err);
console.log(error);
this.logger.error(`Error uploading files: ${error.message}`, error.stack);
return reject(error);
}
resolve();
Expand Down
8 changes: 6 additions & 2 deletions packages/common/src/modules/file-upload.module.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { Module } from '@nestjs/common';
import { FileUploadController } from '../controllers/file-upload.controller';
import { FileUploadService } from '../services/file-upload.service';

import { ConfigModule } from '@nestjs/config';
@Module({
imports: [],
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
],
controllers: [FileUploadController],
providers: [FileUploadService],
})
Expand Down
31 changes: 18 additions & 13 deletions packages/common/src/services/dto/file-upload.dto.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
import { MultipartFile } from "src/interfaces";
import { MultipartFile } from 'src/interfaces';

export class UploadToMinioRequestDTO {
filename: string;
file: MultipartFile;
filename: string;
destination: string;
file: MultipartFile;
}

export class SaveToLocaleRequestDTO {
destination: string;
filename: string;
file: MultipartFile;
destination: string;
filename: string;
file: MultipartFile;
}

export class FileUploadRequestDTO {
file: MultipartFile
destination: string;
filename: string;
export class FileUploadRequestDTO {
file: MultipartFile;
destination: string;
filename: string;
}

export class FileUploadResponseDTO {
statusCode?: number;
message: string;
file?: {url: string} | undefined;
file?: { url: string } | undefined;
}

export class FileDownloadRequestDTO {
destination: string;
}

export class FileDownloadResponseDTO{
export class FileDownloadResponseDTO {
stream: NodeJS.ReadableStream;
}
}

export class MakeBucketRequestDTO {
destination: string;
}
Loading

0 comments on commit 844c3e5

Please sign in to comment.