From e496a15f2d5e8440c026398bde0fb02f4a67bad1 Mon Sep 17 00:00:00 2001 From: Hayden Young Date: Thu, 14 Oct 2021 23:04:03 +0100 Subject: feat: implement an S3-based storage API --- cdn/src/util/Storage.ts | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'cdn/src/util/Storage.ts') diff --git a/cdn/src/util/Storage.ts b/cdn/src/util/Storage.ts index 91f841a6..acef9df3 100644 --- a/cdn/src/util/Storage.ts +++ b/cdn/src/util/Storage.ts @@ -2,6 +2,8 @@ import { FileStorage } from "./FileStorage"; import path from "path"; import fse from "fs-extra"; import { bgCyan, black } from "nanocolors"; +import { S3 } from '@aws-sdk/client-s3'; +import { S3Storage } from "./S3Storage"; process.cwd(); export interface Storage { @@ -10,10 +12,10 @@ export interface Storage { delete(path: string): Promise; } -var storage: Storage; +let storage: Storage; if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) { - var location = process.env.STORAGE_LOCATION; + let location = process.env.STORAGE_LOCATION; if (location) { location = path.resolve(location); } else { @@ -24,6 +26,32 @@ if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) { process.env.STORAGE_LOCATION = location; storage = new FileStorage(); +} else if (process.env.STORAGE_PROVIDER === "s3") { + const + region = process.env.STORAGE_REGION, + bucket = process.env.STORAGE_BUCKET; + + if (!region) { + console.error(`[CDN] You must provide a region when using the S3 storage provider.`); + process.exit(1); + } + + if (!bucket) { + console.error(`[CDN] You must provide a bucket when using the S3 storage provider.`); + process.exit(1); + } + + // in the S3 provider, this should be the root path in the bucket + let location = process.env.STORAGE_LOCATION; + + if (!location) { + console.warn(`[CDN] STORAGE_LOCATION unconfigured for S3 provider, defaulting to '/'...`); + location = "/"; + } + + const client = new S3({ region }); + + storage = new S3Storage(client, location, bucket); } export { storage }; -- cgit 1.5.1 From 3c7b8da9a88df75bbb4f6e63830d63148e543bc6 Mon Sep 17 00:00:00 2001 From: Hayden Young Date: Thu, 14 Oct 2021 23:15:03 +0100 Subject: fix: don't set location by default --- cdn/src/util/S3Storage.ts | 17 ++++++++++++----- cdn/src/util/Storage.ts | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'cdn/src/util/Storage.ts') diff --git a/cdn/src/util/S3Storage.ts b/cdn/src/util/S3Storage.ts index 8c7f7813..df5bc19c 100644 --- a/cdn/src/util/S3Storage.ts +++ b/cdn/src/util/S3Storage.ts @@ -13,14 +13,21 @@ const readableToBuffer = (readable: Readable): Promise => export class S3Storage implements Storage { public constructor( private client: S3, - private basePath: string, - private bucket: string + private bucket: string, + private basePath?: string, ) {} + /** + * Always return a string, to ensure consistency. + */ + get bucketBasePath() { + return this.basePath ?? ''; + } + async set(path: string, data: Buffer): Promise { await this.client.putObject({ Bucket: this.bucket, - Key: `${this.basePath}${path}`, + Key: `${this.bucketBasePath}${path}`, Body: data }); } @@ -29,7 +36,7 @@ export class S3Storage implements Storage { try { const s3Object = await this.client.getObject({ Bucket: this.bucket, - Key: `${this.basePath}${path}` + Key: `${this.bucketBasePath ?? ''}${path}` }); if (!s3Object.Body) return null; @@ -47,7 +54,7 @@ export class S3Storage implements Storage { async delete(path: string): Promise { await this.client.deleteObject({ Bucket: this.bucket, - Key: `${this.basePath}${path}` + Key: `${this.bucketBasePath}${path}` }); } } diff --git a/cdn/src/util/Storage.ts b/cdn/src/util/Storage.ts index acef9df3..3332f21c 100644 --- a/cdn/src/util/Storage.ts +++ b/cdn/src/util/Storage.ts @@ -45,13 +45,13 @@ if (process.env.STORAGE_PROVIDER === "file" || !process.env.STORAGE_PROVIDER) { let location = process.env.STORAGE_LOCATION; if (!location) { - console.warn(`[CDN] STORAGE_LOCATION unconfigured for S3 provider, defaulting to '/'...`); - location = "/"; + console.warn(`[CDN] STORAGE_LOCATION unconfigured for S3 provider, defaulting to the bucket root...`); + location = undefined; } const client = new S3({ region }); - storage = new S3Storage(client, location, bucket); + storage = new S3Storage(client, bucket, location); } export { storage }; -- cgit 1.5.1