Files
medusa-store/packages/medusa-file-s3/src/services/s3.js
T

139 lines
3.0 KiB
JavaScript

import fs from "fs"
import aws from "aws-sdk"
import { AbstractFileService } from "@medusajs/medusa"
import stream from "stream"
class S3Service extends AbstractFileService {
// eslint-disable-next-line no-empty-pattern
constructor({}, options) {
super({}, options)
this.bucket_ = options.bucket
this.s3Url_ = options.s3_url
this.accessKeyId_ = options.access_key_id
this.secretAccessKey_ = options.secret_access_key
this.region_ = options.region
this.endpoint_ = options.endpoint
}
upload(file) {
this.updateAwsConfig()
return this.uploadFile(file)
}
uploadProtected(file) {
this.updateAwsConfig()
return this.uploadFile(file, { acl: "private" })
}
uploadFile(file, options = { isProtected: false, acl: undefined }) {
const s3 = new aws.S3()
const params = {
ACL: options.acl ?? (options.isProtected ? "private" : "public-read"),
Bucket: this.bucket_,
Body: fs.createReadStream(file.path),
Key: `${file.originalname}`,
}
return new Promise((resolve, reject) => {
s3.upload(params, (err, data) => {
if (err) {
reject(err)
return
}
resolve({ url: data.Location, key: data.Key })
})
})
}
async delete(file) {
this.updateAwsConfig()
const s3 = new aws.S3()
const params = {
Bucket: this.bucket_,
Key: `${file}`,
}
return new Promise((resolve, reject) => {
s3.deleteObject(params, (err, data) => {
if (err) {
reject(err)
return
}
resolve(data)
})
})
}
async getUploadStreamDescriptor(fileData) {
this.updateAwsConfig()
const pass = new stream.PassThrough()
const fileKey = `${fileData.name}.${fileData.ext}`
const params = {
ACL: fileData.acl ?? "private",
Bucket: this.bucket_,
Body: pass,
Key: fileKey,
}
const s3 = new aws.S3()
return {
writeStream: pass,
promise: s3.upload(params).promise(),
url: `${this.s3Url_}/${fileKey}`,
fileKey,
}
}
async getDownloadStream(fileData) {
this.updateAwsConfig()
const s3 = new aws.S3()
const params = {
Bucket: this.bucket_,
Key: `${fileData.fileKey}`,
}
return s3.getObject(params).createReadStream()
}
async getPresignedDownloadUrl(fileData) {
this.updateAwsConfig({
signatureVersion: "v4",
})
const s3 = new aws.S3()
const params = {
Bucket: this.bucket_,
Key: `${fileData.fileKey}`,
Expires: this.downloadUrlDuration,
}
return await s3.getSignedUrlPromise("getObject", params)
}
updateAwsConfig(additionalConfiguration = {}) {
aws.config.setPromisesDependency(null)
aws.config.update(
{
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
...additionalConfiguration,
},
true
)
}
}
export default S3Service