feat(SPG-521) Base Upload
continuous-integration/drone/tag Build is passing Details

pull/29/head devel_10.6.17
Aswin Ashar Abdullah 2024-07-15 18:09:01 +07:00
parent c2b5f27b3b
commit 75663c4f99
10 changed files with 183 additions and 10 deletions

View File

@ -37,6 +37,7 @@
"@nestjs/schedule": "^4.1.0", "@nestjs/schedule": "^4.1.0",
"@nestjs/swagger": "^7.3.1", "@nestjs/swagger": "^7.3.1",
"@nestjs/typeorm": "^10.0.2", "@nestjs/typeorm": "^10.0.2",
"@types/multer": "^1.4.11",
"algebra.js": "^0.2.6", "algebra.js": "^0.2.6",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"class-transformer": "^0.5.1", "class-transformer": "^0.5.1",

View File

@ -63,6 +63,7 @@ import { TermConditionModule } from './modules/web-information/term-condition/te
import { TermConditionModel } from './modules/web-information/term-condition/data/models/term-condition.model'; import { TermConditionModel } from './modules/web-information/term-condition/data/models/term-condition.model';
import { FaqModel } from './modules/web-information/faq/data/models/faq.model'; import { FaqModel } from './modules/web-information/faq/data/models/faq.model';
import { FaqModule } from './modules/web-information/faq/faq.module'; import { FaqModule } from './modules/web-information/faq/faq.module';
import { UploadModule } from './modules/configuration/upload/upload.module';
@Module({ @Module({
imports: [ imports: [
@ -117,6 +118,7 @@ import { FaqModule } from './modules/web-information/faq/faq.module';
LogModule, LogModule,
MidtransModule, MidtransModule,
SessionModule, SessionModule,
UploadModule,
// user // user
TenantModule, TenantModule,

View File

@ -0,0 +1,39 @@
import * as fs from 'fs';
export function MoveFilePathHelper() {}
// export class MoveFileToDirIdHelper {
// public srcDir: string;
// public fileName: string;
// constructor(private file_url: string = null) {}
// execute(): string {
// try {
// this.getSrcDir();
// this.getFileName();
// const copyFile = `${this.fileName}-copy`;
// fs.mkdirSync(`./uploads/${this.srcDir}`, { recursive: true });
// fs.copyFileSync(
// this.file_url,
// `./uploads/${this.srcDir}/${this.fileName}`,
// );
// fs.unlinkSync(`${this.file_url}`);
// this.file_url = `uploads/${this.srcDir}/${this.fileName}`;
// } catch (error) {
// console.error('Error moving file:', error);
// }
// return this.file_url;
// }
// private getSrcDir(): void {
// this.srcDir = this.file_url.split('/').slice(2, -1).join('/');
// }
// private getFileName(): void {
// this.fileName = this.file_url.split('/').slice(-1).join('/');
// }
// }

View File

@ -0,0 +1,44 @@
import { extname } from 'path';
import { v4 as uuidv4 } from 'uuid';
import { HttpException, HttpStatus } from '@nestjs/common';
import * as fs from 'fs';
import { MulterOptions } from '@nestjs/platform-express/multer/interfaces/multer-options.interface';
import { diskStorage } from 'multer';
const MB = 1024 * 1024;
const fileFilter = (req, file, callback) => {
if (file.mimetype.match(/\/(jpg|jpeg|png)$/)) {
callback(null, true);
} else {
callback(
new HttpException(
`Unsupported file type ${extname(file.originalname)}`,
HttpStatus.BAD_REQUEST,
),
false,
);
}
};
const editFileName = (req, file, callback) => {
const fileExtName = extname(file.originalname);
const randomName = uuidv4();
callback(null, `${randomName}${fileExtName}`);
};
const destinationPath = (req, file, cb) => {
let modulePath = req.body.module;
if (req.body.sub_module) modulePath = `${modulePath}/${req.body.sub_module}`;
fs.mkdirSync(`./uploads/tmp/${modulePath}`, { recursive: true });
cb(null, `./uploads/tmp/${modulePath}`);
};
export const StoreFileConfig: MulterOptions = {
storage: diskStorage({
destination: destinationPath,
filename: editFileName,
}),
fileFilter: fileFilter,
};

View File

@ -1,14 +1,17 @@
import { MigrationInterface, QueryRunner } from "typeorm"; import { MigrationInterface, QueryRunner } from 'typeorm';
export class UpdateRefund1721031712642 implements MigrationInterface { export class UpdateRefund1721031712642 implements MigrationInterface {
name = 'UpdateRefund1721031712642' name = 'UpdateRefund1721031712642';
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "refunds" ADD "refund_sub_total" numeric`); await queryRunner.query(
} `ALTER TABLE "refunds" ADD "refund_sub_total" numeric`,
);
public async down(queryRunner: QueryRunner): Promise<void> { }
await queryRunner.query(`ALTER TABLE "refunds" DROP COLUMN "refund_sub_total"`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "refunds" DROP COLUMN "refund_sub_total"`,
);
}
} }

View File

@ -0,0 +1,5 @@
export interface UploadEntity {
module: string;
sub_module: string;
file: any;
}

View File

@ -0,0 +1,22 @@
import { ApiProperty } from '@nestjs/swagger';
import { UploadEntity } from '../../domain/entities/upload.entity';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
export class UploadDto implements UploadEntity {
@ApiProperty({
type: 'string',
required: true,
default: TABLE_NAME.ITEM,
})
module: string;
@ApiProperty({
type: 'string',
required: false,
default: TABLE_NAME.ITEM,
})
sub_module: string;
@ApiProperty({ type: 'string', format: 'binary', required: true })
file: any;
}

View File

@ -0,0 +1,34 @@
import {
Controller,
Post,
UseInterceptors,
Body,
UploadedFile,
} from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { UploadDto } from './dto/upload.dto';
import { Public } from 'src/core/guards';
import { StoreFileConfig } from 'src/core/helpers/path/upload-store-path.helper';
@ApiTags('uploads')
@Controller('uploads')
@Public(true)
export class UploadController {
constructor(private moduleRef: ModuleRef) {}
@Post()
@ApiConsumes('multipart/form-data')
@ApiBody({ type: UploadDto })
@UseInterceptors(FileInterceptor('file', StoreFileConfig))
async storeFile(
@UploadedFile() file: Express.Multer.File,
@Body() body: UploadDto,
): Promise<any> {
return {
path: file.path,
full_path: `${process.env.ASSETS}${file.path}`,
};
}
}

View File

@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MulterModule } from '@nestjs/platform-express';
import { UploadController } from './infrastructure/upload.controller';
@Module({
imports: [
ConfigModule.forRoot(),
MulterModule.register({
dest: './uploads',
}),
],
controllers: [UploadController],
providers: [],
})
export class UploadModule {}

View File

@ -1081,7 +1081,7 @@
"@types/range-parser" "*" "@types/range-parser" "*"
"@types/send" "*" "@types/send" "*"
"@types/express@^4.17.13": "@types/express@*", "@types/express@^4.17.13":
version "4.17.21" version "4.17.21"
resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d"
integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==
@ -1178,6 +1178,13 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
"@types/multer@^1.4.11":
version "1.4.11"
resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.11.tgz#c70792670513b4af1159a2b60bf48cc932af55c5"
integrity sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==
dependencies:
"@types/express" "*"
"@types/node@*", "@types/node@^20.12.13": "@types/node@*", "@types/node@^20.12.13":
version "20.14.10" version "20.14.10"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a"