feat: Add support for uploading a file directly to the file provider from the client (#12224)
* feat: Add support for uploading a file directly to the file provider from the client * fix: Add missing types and add a couple of module tests * fix: Allow nested routes, add test for it
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
DeleteObjectCommand,
|
||||
GetObjectCommand,
|
||||
ObjectCannedACL,
|
||||
PutObjectCommand,
|
||||
S3Client,
|
||||
S3ClientConfigType,
|
||||
@@ -36,6 +37,8 @@ interface S3FileServiceConfig {
|
||||
additionalClientConfig?: Record<string, any>
|
||||
}
|
||||
|
||||
const DEFAULT_UPLOAD_EXPIRATION_DURATION_SECONDS = 60 * 60
|
||||
|
||||
export class S3FileService extends AbstractFileProviderService {
|
||||
static identifier = "s3"
|
||||
protected config_: S3FileServiceConfig
|
||||
@@ -175,4 +178,41 @@ export class S3FileService extends AbstractFileProviderService {
|
||||
expiresIn: this.config_.downloadFileDuration,
|
||||
})
|
||||
}
|
||||
|
||||
// Note: Some providers (eg. AWS S3) allows IAM policies to further restrict what can be uploaded.
|
||||
async getPresignedUploadUrl(
|
||||
fileData: FileTypes.ProviderGetPresignedUploadUrlDTO
|
||||
): Promise<FileTypes.ProviderFileResultDTO> {
|
||||
if (!fileData?.filename) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`No filename provided`
|
||||
)
|
||||
}
|
||||
|
||||
const fileKey = `${this.config_.prefix}${fileData.filename}`
|
||||
|
||||
let acl: ObjectCannedACL | undefined
|
||||
if (fileData.access) {
|
||||
acl = fileData.access === "public" ? "public-read" : "private"
|
||||
}
|
||||
|
||||
// Using content-type, acl, etc. doesn't work with all providers, and some simply ignore it.
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: this.config_.bucket,
|
||||
ContentType: fileData.mimeType,
|
||||
ACL: acl,
|
||||
Key: fileKey,
|
||||
})
|
||||
|
||||
const signedUrl = await getSignedUrl(this.client_, command, {
|
||||
expiresIn:
|
||||
fileData.expiresIn ?? DEFAULT_UPLOAD_EXPIRATION_DURATION_SECONDS,
|
||||
})
|
||||
|
||||
return {
|
||||
url: signedUrl,
|
||||
key: fileKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user