feat: implement direct upload (#12328)
* feat: implement direct upload * feat: add direct-upload endpoint * refactor: implement feedback * refactor: have a dedicated endpoint for direct uploads * refactor: convert responses to snakecase * refactor: rename method to createImport * test: add tests for the presigned-urls endpoint
This commit is contained in:
@@ -85,7 +85,9 @@ export class LocalFileService extends AbstractFileProviderService {
|
||||
return
|
||||
}
|
||||
|
||||
async getAsStream(file: FileTypes.ProviderGetFileDTO): Promise<Readable> {
|
||||
async getDownloadStream(
|
||||
file: FileTypes.ProviderGetFileDTO
|
||||
): Promise<Readable> {
|
||||
const baseDir = file.fileKey.startsWith("private-")
|
||||
? this.privateUploadDir_
|
||||
: this.uploadDir_
|
||||
@@ -124,6 +126,47 @@ export class LocalFileService extends AbstractFileProviderService {
|
||||
return this.getUploadFileUrl(file.fileKey)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pre-signed URL that the client (frontend) can use to trigger
|
||||
* a file upload. In this case, the Medusa backend will implement the
|
||||
* "/upload" endpoint to perform the file upload.
|
||||
*
|
||||
* Since, we do not want the client to perform link detection on the frontend
|
||||
* and then prepare a different kind of request for cloud providers and different
|
||||
* request for the local server, we will have to make these URLs self sufficient.
|
||||
*
|
||||
* What is a self sufficient URL
|
||||
*
|
||||
* - There should be no need to specify the MIME type or filename separately in request body (cloud providers don't allow it).
|
||||
* - There should be no need to pass auth headers like cookies. Again cloud providers
|
||||
* won't allow it and will likely result in a CORS error.
|
||||
*/
|
||||
async getPresignedUploadUrl(
|
||||
fileData: FileTypes.ProviderGetPresignedUploadUrlDTO
|
||||
): Promise<FileTypes.ProviderFileResultDTO> {
|
||||
if (!fileData?.filename) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`No filename provided`
|
||||
)
|
||||
}
|
||||
|
||||
const uploadUrl = new URL(
|
||||
"upload",
|
||||
`${this.backendUrl_.replace(/\/$/, "")}/`
|
||||
)
|
||||
|
||||
uploadUrl.searchParams.set("filename", fileData.filename)
|
||||
if (fileData.mimeType) {
|
||||
uploadUrl.searchParams.set("type", fileData.mimeType)
|
||||
}
|
||||
|
||||
return {
|
||||
url: uploadUrl.toString(),
|
||||
key: fileData.filename,
|
||||
}
|
||||
}
|
||||
|
||||
private getUploadFilePath = (baseDir: string, fileKey: string) => {
|
||||
return path.join(baseDir, fileKey)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user