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:
@@ -27,6 +27,15 @@ export class FileProviderServiceFixtures extends AbstractFileProviderService {
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
async getPresignedUploadUrl(
|
||||
fileData: FileTypes.ProviderGetPresignedUploadUrlDTO
|
||||
): Promise<FileTypes.ProviderFileResultDTO> {
|
||||
return {
|
||||
url: "presigned-url/" + fileData.filename,
|
||||
key: fileData.filename,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const services = [FileProviderServiceFixtures]
|
||||
|
||||
@@ -63,6 +63,31 @@ moduleIntegrationTestRunner<IFileModuleService>({
|
||||
const downloadUrl = await service.retrieveFile("test.jpg")
|
||||
expect(await new Response(downloadUrl.url).text()).toEqual("test")
|
||||
})
|
||||
|
||||
it("generates a presigned upload URL", async () => {
|
||||
const res = await service.getUploadFileUrls({
|
||||
filename: "test.jpg",
|
||||
mimeType: "image/jpeg",
|
||||
})
|
||||
|
||||
expect(res).toEqual({
|
||||
url: "presigned-url/test.jpg",
|
||||
key: "test.jpg",
|
||||
})
|
||||
})
|
||||
|
||||
it("fails to get a presigned upload URL if a filename isn't provided", async () => {
|
||||
const err = await service
|
||||
.getUploadFileUrls({
|
||||
filename: "",
|
||||
mimeType: "image/jpeg",
|
||||
})
|
||||
.catch((err) => err)
|
||||
|
||||
expect(err.message).toEqual(
|
||||
"File name is required to get a presigned upload URL"
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import {
|
||||
Context,
|
||||
CreateFileDTO,
|
||||
GetUploadFileUrlDTO,
|
||||
FileDTO,
|
||||
UploadFileUrlDTO,
|
||||
FileTypes,
|
||||
FilterableFileProps,
|
||||
FindConfig,
|
||||
@@ -49,6 +51,27 @@ export default class FileModuleService implements FileTypes.IFileModuleService {
|
||||
return Array.isArray(data) ? result : result[0]
|
||||
}
|
||||
|
||||
getUploadFileUrls(
|
||||
data: GetUploadFileUrlDTO[],
|
||||
sharedContext?: Context
|
||||
): Promise<UploadFileUrlDTO[]>
|
||||
getUploadFileUrls(
|
||||
data: GetUploadFileUrlDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<UploadFileUrlDTO>
|
||||
|
||||
async getUploadFileUrls(
|
||||
data: GetUploadFileUrlDTO[] | GetUploadFileUrlDTO
|
||||
): Promise<UploadFileUrlDTO[] | UploadFileUrlDTO> {
|
||||
const input = Array.isArray(data) ? data : [data]
|
||||
|
||||
const result = await Promise.all(
|
||||
input.map((file) => this.fileProviderService_.getPresignedUploadUrl(file))
|
||||
)
|
||||
|
||||
return Array.isArray(data) ? result : result[0]
|
||||
}
|
||||
|
||||
async deleteFiles(ids: string[], sharedContext?: Context): Promise<void>
|
||||
async deleteFiles(id: string, sharedContext?: Context): Promise<void>
|
||||
async deleteFiles(ids: string[] | string): Promise<void> {
|
||||
|
||||
@@ -48,4 +48,24 @@ export default class FileProviderService {
|
||||
): Promise<string> {
|
||||
return this.fileProvider_.getPresignedDownloadUrl(fileData)
|
||||
}
|
||||
|
||||
getPresignedUploadUrl(
|
||||
fileData: FileTypes.ProviderGetPresignedUploadUrlDTO
|
||||
): Promise<FileTypes.ProviderFileResultDTO> {
|
||||
if (!this.fileProvider_.getPresignedUploadUrl) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Provider does not support presigned upload URLs"
|
||||
)
|
||||
}
|
||||
|
||||
if (!fileData.filename) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"File name is required to get a presigned upload URL"
|
||||
)
|
||||
}
|
||||
|
||||
return this.fileProvider_.getPresignedUploadUrl(fileData)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user