139 lines
3.0 KiB
JavaScript
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
|