Skip to content

Commit

Permalink
apply feedback #1
Browse files Browse the repository at this point in the history
  • Loading branch information
kpazgan committed Oct 7, 2024
1 parent 6d5d383 commit 6a98b4a
Show file tree
Hide file tree
Showing 10 changed files with 35 additions and 224 deletions.

This file was deleted.

This file was deleted.

Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { CommonFile } from "../../common/schemas/common-file.schema";

export abstract class FilesAdapter {
abstract uploadFile(file: Express.Multer.File): Promise<CommonFile>;
abstract uploadFile(
path: string,
file: Express.Multer.File,
): Promise<{ path: string }>;

abstract deleteFile(id: string): Promise<void>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import {
Inject,
Injectable,
InternalServerErrorException,
NotFoundException,
} from "@nestjs/common";
import { Injectable, InternalServerErrorException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { DatabasePg } from "../../common";
import { v7 as uuid } from "uuid";
import { files } from "../../storage/schema";
import { CommonFile } from "../../common/schemas/common-file.schema";
import { eq } from "drizzle-orm";
import * as fs from "node:fs";
import * as path from "node:path";
import { FilesAdapter } from "./files.adapter";
Expand All @@ -25,68 +16,37 @@ export class LocalFilesAdapter extends FilesAdapter {
"..",
this.configService.getOrThrow<string>("localFile.uploadDir"),
);
constructor(
private configService: ConfigService,
@Inject("DB") private readonly db: DatabasePg,
) {
constructor(private configService: ConfigService) {
super();
}

async uploadFile(file: Express.Multer.File) {
async uploadFile(directory: string, file: Express.Multer.File) {
try {
const key = `${uuid()}-${file.originalname}`;
const key = `${directory}/${uuid()}-${file.originalname}`;
fs.writeFile(path.join(this.uploadsDir, key), file.buffer, (err) => {
if (err) {
throw new InternalServerErrorException("Failed to upload file");
}
});

const [savedFile] = await this.db
.insert(files)
.values({
url: key,
filename: file.originalname,
mimetype: file.mimetype,
size: file.size,
})
.returning();

return savedFile as CommonFile;
return { path: key };
} catch (error) {
throw new InternalServerErrorException("Failed to upload file");
}
}

async getFileUrl(id: string): Promise<{ url: string }> {
async getFileUrl(path: string): Promise<{ url: string }> {
try {
const file = await this.db.query.files.findFirst({
where: eq(files.id, id),
});

if (!file) {
throw new NotFoundException("File not found");
}

const url = `https://storage.guidebook.localhost/${file.url}`;
const url = `https://storage.guidebook.localhost/${path}`;
return { url: url };
} catch (error) {
throw new InternalServerErrorException("Failed to get file");
}
}

async deleteFile(id: string): Promise<void> {
async deleteFile(url: string): Promise<void> {
try {
const file = await this.db.query.files.findFirst({
where: eq(files.id, id),
});

if (!file) {
throw new NotFoundException("File not found");
}

fs.unlinkSync(path.join(this.uploadsDir, file.url));

await this.db.delete(files).where(eq(files.id, id)).execute();
fs.unlinkSync(path.join(this.uploadsDir, url));
} catch (error) {
throw new InternalServerErrorException("Failed to delete file");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import {
Inject,
Injectable,
InternalServerErrorException,
NotFoundException,
} from "@nestjs/common";
import { Injectable, InternalServerErrorException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { DatabasePg } from "../../common";
import {
GetObjectCommand,
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
import { v7 as uuid } from "uuid";
import { files } from "../../storage/schema";
import { CommonFile } from "../../common/schemas/common-file.schema";
import { eq } from "drizzle-orm";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { FilesAdapter } from "./files.adapter";

Expand All @@ -23,14 +14,13 @@ export class S3FileAdapter extends FilesAdapter {
private client: S3Client;
private bucketName = this.configService.getOrThrow<string>("aws.BUCKET_NAME");

constructor(
private configService: ConfigService,
@Inject("DB") private readonly db: DatabasePg,
) {
constructor(private configService: ConfigService) {
super();
const region = this.configService.getOrThrow<string>("aws.AWS_REGION");
const endpoint = `https://s3.${region}.amazonaws.com`;
this.client = new S3Client({
region: this.configService.getOrThrow<string>("aws.AWS_REGION"),
endpoint: this.configService.getOrThrow<string>("aws.AWS_ENDPOINT"),
region,
endpoint,
credentials: {
accessKeyId: this.configService.getOrThrow<string>(
"aws.AWS_ACCESS_KEY_ID",
Expand All @@ -43,9 +33,9 @@ export class S3FileAdapter extends FilesAdapter {
});
}

async uploadFile(file: Express.Multer.File) {
async uploadFile(path: string, file: Express.Multer.File) {
try {
const key = `${uuid()}-${file.originalname}`;
const key = `${path}/${uuid()}-${file.originalname}`;
const command = new PutObjectCommand({
Bucket: this.bucketName,
Key: key,
Expand All @@ -55,7 +45,6 @@ export class S3FileAdapter extends FilesAdapter {
originalname: file.originalname,
},
});
console.log(this.client);

const uploadResult = await this.client.send(command);

Expand All @@ -66,55 +55,27 @@ export class S3FileAdapter extends FilesAdapter {
throw new InternalServerErrorException("Failed to upload file");
}

const [savedFile] = await this.db
.insert(files)
.values({
url: key,
filename: file.originalname,
mimetype: file.mimetype,
size: file.size,
})
.returning();

return savedFile as CommonFile;
return { path: key };
} catch (error) {
throw new InternalServerErrorException("Failed to upload file");
}
}

async getFileUrl(id: string): Promise<{ url: string }> {
async getFileUrl(path: string): Promise<{ url: string }> {
try {
const file = await this.db.query.files.findFirst({
where: eq(files.id, id),
});

if (!file) {
throw new NotFoundException("File not found");
}

return this.getPublicUrl(file.url);
return this.getPublicUrl(path);
} catch (error) {
throw new InternalServerErrorException("Failed to get file");
}
}

async deleteFile(id: string): Promise<void> {
async deleteFile(path: string): Promise<void> {
try {
const file = await this.db.query.files.findFirst({
where: eq(files.id, id),
});

if (!file) {
throw new NotFoundException("File not found");
}

const command = new GetObjectCommand({
Bucket: this.bucketName,
Key: file.url,
Key: path,
});
await this.client.send(command);

await this.db.delete(files).where(eq(files.id, id)).execute();
} catch (error) {
throw new InternalServerErrorException("Failed to delete file");
}
Expand Down

This file was deleted.

17 changes: 9 additions & 8 deletions examples/common_nestjs_remix/apps/api/src/files/file.service.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import { Inject, Injectable } from "@nestjs/common";
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { S3FileAdapter } from "./adapters";
import { LocalFilesAdapter } from "./adapters";
import { DatabasePg } from "../common";
import { CommonFile } from "../common/schemas/common-file.schema";

@Injectable()
export class FileService {
private storageAdapter: LocalFilesAdapter | S3FileAdapter;

constructor(configService: ConfigService, @Inject("DB") db: DatabasePg) {
constructor(configService: ConfigService) {
if (configService.get("ENVIRONMENT") === "development") {
this.storageAdapter = new LocalFilesAdapter(configService, db);
this.storageAdapter = new LocalFilesAdapter(configService);
} else {
this.storageAdapter = new S3FileAdapter(configService, db);
this.storageAdapter = new S3FileAdapter(configService);
}
}

async uploadFile(file: Express.Multer.File): Promise<CommonFile> {
return await this.storageAdapter.uploadFile(file);
async uploadFile(
directory: string,
file: Express.Multer.File,
): Promise<{ path: string }> {
return await this.storageAdapter.uploadFile(directory, file);
}

async deleteFile(key: string): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Module } from "@nestjs/common";
import { FileService } from "./file.service";
import { FileController } from "./api/file.controller";

@Module({
providers: [FileService],
controllers: [FileController],
})
export class FilesModule {}

This file was deleted.

0 comments on commit 6a98b4a

Please sign in to comment.