import { StorageDriver , DiskOptions , FileOptions , StorageDriver$FileMetadataResponse , StorageDriver$PutFileResponse , StorageDriver$RenameFileResponse , } from "../interfaces" ; import { S3 , SharedIniFileCredentials } from "aws-sdk" ; import { getMimeFromExtension } from "../helpers" ; import { HeadObjectRequest , PutObjectRequest } from "aws-sdk/clients/s3" ; export class S3Storage implements StorageDriver { private readonly disk : string ; private config : DiskOptions ; private client : S3 ; constructor ( disk , config ) { this . disk = disk ; this . config = config ; const options = { signatureVersion : "v4" , region : this . config . region , } as Record < string , any > ; if ( config . profile ) { options [ "credentials" ] = new SharedIniFileCredentials ( { profile : config . profile , } ) ; } this . client = new S3 ( options ) ; } param path param fileContent async put ( path , fileContent , options ? ) { const { mimeType } = options || { } ; let params = { Bucket : this . config . bucket , Key : path , Body : fileContent , ContentType : mimeType ? mimeType : getMimeFromExtension ( path ) , } as PutObjectRequest ; const res = await this . client . upload ( params ) . promise ( ) ; return { url : this . url ( path ) , path } ; } param path signedUrl ( path , expireInMinutes = 20 ) { const params = { Bucket : this . config . bucket , Key : path , Expires : 60 * expireInMinutes , } ; const signedUrl = this . client . getSignedUrl ( "getObject" , params ) ; return signedUrl ; } param path async get ( path ) { try { const params = { Bucket : this . config . bucket || "" , Key : path } ; const res = await this . client . getObject ( params ) . promise ( ) ; return res . Body as Buffer ; } catch ( e ) { return null ; } } param path async exists ( path ) { const meta = await this . meta ( path ) ; return Object . keys ( meta ) . length > 0 ? true : false ; } param path async meta ( path ) { const params = { Bucket : this . config . bucket , Key : path , } ; try { const res = await this . client . headObject ( params as HeadObjectRequest ) . promise ( ) ; return { path : path , contentType : res . ContentType , contentLength : res . ContentLength , lastModified : res . LastModified , } ; } catch ( e ) { return { } ; } } param path async missing ( path ) { const meta = await this . meta ( path ) ; return Object . keys ( meta ) . length === 0 ? true : false ; } param path url ( path ) { const url = this . signedUrl ( path , 20 ) . split ( "?" ) [ 0 ] ; return url ; } param path async delete ( path ) { const params = { Bucket : this . config . bucket || "" , Key : path } ; try { await this . client . deleteObject ( params ) . promise ( ) ; return true ; } catch ( err ) { return false ; } } param path param newPath async copy ( path , newPath ) { this . client . copyObject ( { Bucket : this . config . bucket || "" , CopySource : this . config . bucket + "/" + path , Key : newPath , } ) . promise ( ) ; return { path : newPath , url : this . url ( newPath ) } ; } param path param newPath async move ( path , newPath ) { await this . copy ( path , newPath ) ; await this . delete ( path ) ; return { path : newPath , url : this . url ( newPath ) } ; } /**
     * Get instance of driver's client.
     */ getClient ( ) { return this . client ; } /**
     * Get config of the driver's instance.
     */ getConfig ( ) { return this . config ; } }