-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add boilerplate s3-client sdk code connected to digital ocean s…
…paces
- Loading branch information
Showing
9 changed files
with
1,448 additions
and
4 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { registerAs } from "@nestjs/config"; | ||
|
||
const DigitalOceanConfig = registerAs("digitalOcean", () => ({ | ||
endpoint: String(process.env.DIGITAL_OCEAN_ENDPOINT ?? "https://sfo3.digitaloceanspaces.com"), | ||
region: String(process.env.DIGITAL_OCEAN_REGION ?? "us-east-1"), | ||
accessKeyId: String(process.env.DIGITAL_OCEAN_ACCESS_KEY_ID ?? ""), | ||
secretAccessKey: String(process.env.DIGITAL_OCEAN_SECRET_ACCESS_KEY ?? ""), | ||
bucketName: String(process.env.DIGITAL_OCEAN_BUCKET_NAME ?? "opengraph-dev"), | ||
})); | ||
|
||
export default DigitalOceanConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import { Module } from "@nestjs/common"; | ||
|
||
import { GithubService } from "./github.service"; | ||
|
||
@Module({ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { Module } from "@nestjs/common"; | ||
|
||
import { S3FileStorageService } from "./s3-file-storage.service"; | ||
|
||
@Module({ | ||
imports: [], | ||
providers: [S3FileStorageService], | ||
exports: [S3FileStorageService], | ||
}) | ||
export class S3FileStorageModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { Injectable, Inject } from "@nestjs/common"; | ||
import { ConfigType } from "@nestjs/config"; | ||
import { S3, HeadObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; | ||
import { createHash } from "node:crypto"; | ||
import { Readable } from "node:stream"; | ||
|
||
import DigitalOceanConfig from "../config/digital-ocean.config"; | ||
|
||
@Injectable() | ||
export class S3FileStorageService { | ||
private s3Client: S3Client; | ||
|
||
constructor ( | ||
@Inject(DigitalOceanConfig.KEY) | ||
private readonly config: ConfigType<typeof DigitalOceanConfig>, | ||
) { | ||
this.s3Client = new S3({ | ||
forcePathStyle: false, | ||
endpoint: config.endpoint, | ||
region: config.region, | ||
credentials: { | ||
accessKeyId: config.accessKeyId, | ||
secretAccessKey: config.secretAccessKey, | ||
}, | ||
}); | ||
} | ||
|
||
async fileExists (hash: string): Promise<boolean> { | ||
try { | ||
await this.s3Client.send( | ||
new HeadObjectCommand({ | ||
Bucket: this.config.bucketName, | ||
Key: hash, | ||
}), | ||
); | ||
return true; | ||
} catch (error) { | ||
console.error(error); | ||
|
||
if (error instanceof Error) { | ||
if (error.name === "ResourceNotFoundException") { | ||
return false; | ||
} | ||
} | ||
|
||
throw error; | ||
} | ||
} | ||
|
||
async getFileLastModified (hash: string): Promise<Date | null> { | ||
try { | ||
const response = await this.s3Client.send( | ||
new HeadObjectCommand({ | ||
Bucket: this.config.bucketName, | ||
Key: hash, | ||
}), | ||
); | ||
|
||
return response.LastModified ?? null; | ||
} catch (error) { | ||
console.error(error); | ||
|
||
if (error instanceof Error) { | ||
if (error.name === "ResourceNotFoundException") { | ||
return null; | ||
} | ||
} | ||
|
||
throw error; | ||
} | ||
} | ||
|
||
async uploadFile ( | ||
fileContent: Buffer | Readable, | ||
hash: string, | ||
contentType: string, | ||
): Promise<void> { | ||
await this.s3Client.send( | ||
new PutObjectCommand({ | ||
Bucket: this.config.bucketName, | ||
Key: hash, | ||
Body: fileContent, | ||
ContentType: contentType, | ||
}), | ||
); | ||
} | ||
|
||
generateHash (content: Buffer): string { | ||
return createHash("sha256").update(content) | ||
.digest("hex"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters