chore: uploader service
This commit is contained in:
@@ -29,8 +29,10 @@
|
||||
"prepare": "husky || true"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.735.0",
|
||||
"@fastify/static": "^7.0.4",
|
||||
"@keyv/redis": "^4.2.0",
|
||||
"@nest-lab/fastify-multer": "^1.3.0",
|
||||
"@nest-lab/throttler-storage-redis": "^1.0.0",
|
||||
"@nestjs-modules/mailer": "^2.0.2",
|
||||
"@nestjs/axios": "^4.0.0",
|
||||
|
||||
Generated
+1274
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
import { FastifyMulterModule } from "@nest-lab/fastify-multer";
|
||||
import { CacheModule } from "@nestjs/cache-manager";
|
||||
import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
@@ -12,6 +13,7 @@ import { AnnoucementsModule } from "./modules/announcements/announcement.module"
|
||||
import { AuthModule } from "./modules/auth/auth.module";
|
||||
import { DanakServicesModule } from "./modules/danak-services/danak-services.module";
|
||||
import { TicketsModule } from "./modules/tickets/tickets.module";
|
||||
import { UploaderModule } from "./modules/uploader/uploader.module";
|
||||
import { UsersModule } from "./modules/users/users.module";
|
||||
|
||||
@Module({
|
||||
@@ -20,11 +22,13 @@ import { UsersModule } from "./modules/users/users.module";
|
||||
ConfigModule.forRoot({ cache: true, isGlobal: true }),
|
||||
CacheModule.registerAsync(cacheConfig()),
|
||||
TypeOrmModule.forRootAsync(databaseConfigs()),
|
||||
FastifyMulterModule,
|
||||
UsersModule,
|
||||
TicketsModule,
|
||||
AuthModule,
|
||||
DanakServicesModule,
|
||||
AnnoucementsModule,
|
||||
UploaderModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [],
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
|
||||
export function S3Configs() {
|
||||
return {
|
||||
inject: [ConfigService],
|
||||
useFactory(configService: ConfigService) {
|
||||
return {
|
||||
accessKeyId: configService.getOrThrow<string>("BUCKET_ACCESS_KEY"),
|
||||
secretAccessKey: configService.getOrThrow<string>("BUCKET_SECRET_KEY"),
|
||||
endpoint: configService.getOrThrow<string>("BUCKET_URL"),
|
||||
region: configService.getOrThrow<string>("BUCKET_REGION"),
|
||||
bucket: configService.getOrThrow<string>("BUCKET_NAME"),
|
||||
url: configService.getOrThrow<string>("BUCKET_UPLOAD_URL"),
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export interface IS3Configs {
|
||||
accessKeyId: string;
|
||||
secretAccessKey: string;
|
||||
endpoint: string;
|
||||
region: string;
|
||||
bucket: string;
|
||||
url: string;
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import { getSwaggerDocument } from "./configs/swagger.config";
|
||||
import { HttpExceptionFilter } from "./core/exceptions/http.exceptions";
|
||||
import { PaginationInterceptor } from "./core/interceptors/pagination.interceptor";
|
||||
import { ResponseInterceptor } from "./core/interceptors/response.interceptor";
|
||||
|
||||
async function bootstrap() {
|
||||
const logger = new Logger("APP");
|
||||
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
|
||||
@@ -22,7 +21,6 @@ async function bootstrap() {
|
||||
credentials: true,
|
||||
optionsSuccessStatus: 204,
|
||||
});
|
||||
|
||||
const configService = app.get<ConfigService>(ConfigService);
|
||||
|
||||
getSwaggerDocument(app);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { FileInterceptor } from "@nest-lab/fastify-multer";
|
||||
import { Controller, Post, UploadedFile, UseInterceptors } from "@nestjs/common";
|
||||
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
|
||||
import { UploaderService } from "./uploader.service";
|
||||
import { IFile } from "../utils/interfaces/IFile";
|
||||
|
||||
@ApiTags("Uploader")
|
||||
@Controller("uploader")
|
||||
export class UploaderController {
|
||||
constructor(private readonly uploaderService: UploaderService) {}
|
||||
|
||||
@ApiOperation({ summary: "Uploads a single file" })
|
||||
@ApiConsumes("multipart/form-data")
|
||||
@UseInterceptors(FileInterceptor("file"))
|
||||
@ApiBody({
|
||||
required: true,
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
file: {
|
||||
type: "string",
|
||||
format: "binary",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@Post("single-file")
|
||||
async uploadFile(@UploadedFile() file: IFile) {
|
||||
console.log(file);
|
||||
return await this.uploaderService.upload(file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
import { UploaderController } from "./uploader.controller";
|
||||
import { UploaderService } from "./uploader.service";
|
||||
import { S3Service } from "../utils/providers/s3.service";
|
||||
import { UtilsModule } from "../utils/utils.module";
|
||||
|
||||
@Module({
|
||||
imports: [UtilsModule],
|
||||
providers: [UploaderService, S3Service],
|
||||
controllers: [UploaderController],
|
||||
exports: [UploaderService],
|
||||
})
|
||||
export class UploaderModule {}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
import { S3Service } from "../utils/providers/s3.service";
|
||||
|
||||
@Injectable()
|
||||
export class UploaderService {
|
||||
constructor(private s3Service: S3Service) {}
|
||||
|
||||
async upload(file: any) {
|
||||
return await this.s3Service.upload(file);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { Role } from "./entities/role.entity";
|
||||
import { UserGroup } from "./entities/user-group.entity";
|
||||
import { User } from "./entities/user.entity";
|
||||
import { RoleRepository } from "./providers/roles.repository";
|
||||
import { UserGroupRepository } from "./providers/user-group.repository";
|
||||
import { UsersService } from "./providers/users.service";
|
||||
import { RoleRepository } from "./repositories/roles.repository";
|
||||
import { UserGroupRepository } from "./repositories/user-group.repository";
|
||||
import { UserRepository } from "./repositories/users.repository";
|
||||
import { UsersController } from "./users.controller";
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export const SMS_CONFIG = "SMS_CONFIG";
|
||||
export const S3_CONFIG = "S3_CONFIG";
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface IFile {
|
||||
fieldname: string;
|
||||
originalname: string;
|
||||
encoding: string;
|
||||
mimetype: string;
|
||||
buffer: Buffer;
|
||||
size: number;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { extname } from "node:path";
|
||||
|
||||
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
|
||||
import { IS3Configs } from "../../../configs/s3.config";
|
||||
import { S3_CONFIG } from "../constants";
|
||||
import { IFile } from "../interfaces/IFile";
|
||||
|
||||
@Injectable()
|
||||
export class S3Service {
|
||||
private client: S3Client;
|
||||
constructor(@Inject(S3_CONFIG) private s3Configs: IS3Configs) {
|
||||
this.client = new S3Client({
|
||||
endpoint: this.s3Configs.endpoint,
|
||||
region: this.s3Configs.region,
|
||||
credentials: {
|
||||
accessKeyId: this.s3Configs.accessKeyId,
|
||||
secretAccessKey: this.s3Configs.secretAccessKey,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async upload(file: IFile) {
|
||||
const extName = extname(file.originalname);
|
||||
const params = {
|
||||
Body: file.buffer,
|
||||
Bucket: this.s3Configs.bucket,
|
||||
Key: "images/" + randomUUID() + Date.now() + extName,
|
||||
};
|
||||
await this.client.send(new PutObjectCommand(params));
|
||||
const url = `${this.s3Configs.url}/${params.Key}`;
|
||||
return {
|
||||
url,
|
||||
originalname: file.originalname,
|
||||
size: file.size,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Module } from "@nestjs/common";
|
||||
|
||||
import { SMS_CONFIG } from "./constants";
|
||||
import { S3_CONFIG, SMS_CONFIG } from "./constants";
|
||||
import { CacheService } from "./providers/cache.service";
|
||||
import { OTPService } from "./providers/otp.service";
|
||||
import { PasswordService } from "./providers/password.service";
|
||||
import { S3Service } from "./providers/s3.service";
|
||||
import { SmsService } from "./providers/sms.service";
|
||||
import { S3Configs } from "../../configs/s3.config";
|
||||
import { smsConfigs } from "../../configs/sms.config";
|
||||
|
||||
@Module({
|
||||
@@ -13,12 +15,18 @@ import { smsConfigs } from "../../configs/sms.config";
|
||||
PasswordService,
|
||||
CacheService,
|
||||
SmsService,
|
||||
S3Service,
|
||||
{
|
||||
provide: SMS_CONFIG,
|
||||
useFactory: smsConfigs().useFactory,
|
||||
inject: smsConfigs().inject,
|
||||
},
|
||||
{
|
||||
provide: S3_CONFIG,
|
||||
useFactory: S3Configs().useFactory,
|
||||
inject: S3Configs().inject,
|
||||
},
|
||||
],
|
||||
exports: [SMS_CONFIG, OTPService, PasswordService, CacheService, SmsService],
|
||||
exports: [SMS_CONFIG, S3_CONFIG, S3Service, OTPService, PasswordService, CacheService, SmsService],
|
||||
})
|
||||
export class UtilsModule {}
|
||||
|
||||
Reference in New Issue
Block a user