feat(medusa-file-local): implement missing streaming methods (#4788)
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import { AbstractFileService, IFileService } from "@medusajs/medusa"
|
||||
import {
|
||||
AbstractFileService,
|
||||
FileServiceGetUploadStreamResult,
|
||||
FileServiceUploadResult,
|
||||
IFileService,
|
||||
} from "@medusajs/medusa"
|
||||
UploadStreamDescriptorType,
|
||||
} from "@medusajs/types"
|
||||
|
||||
import fs from "fs"
|
||||
import { parse } from "path"
|
||||
import path from "path"
|
||||
import stream from "stream"
|
||||
|
||||
class LocalService extends AbstractFileService implements IFileService {
|
||||
protected uploadDir_: string
|
||||
@@ -14,7 +16,7 @@ class LocalService extends AbstractFileService implements IFileService {
|
||||
constructor({}, options) {
|
||||
super({}, options)
|
||||
|
||||
this.uploadDir_ = options.upload_dir || "uploads/images"
|
||||
this.uploadDir_ = options.upload_dir || "uploads"
|
||||
this.backendUrl_ = options.backend_url || "http://localhost:9000"
|
||||
}
|
||||
|
||||
@@ -29,40 +31,91 @@ class LocalService extends AbstractFileService implements IFileService {
|
||||
async uploadFile(
|
||||
file: Express.Multer.File,
|
||||
options = {}
|
||||
): Promise<{ url: string }> {
|
||||
const parsedFilename = parse(file.originalname)
|
||||
): Promise<FileServiceUploadResult> {
|
||||
const parsedFilename = path.parse(file.originalname)
|
||||
|
||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||
if (parsedFilename.dir) {
|
||||
this.ensureDirExists(parsedFilename.dir)
|
||||
}
|
||||
|
||||
const fileKey = path.join(
|
||||
parsedFilename.dir,
|
||||
`${Date.now()}-${parsedFilename.base}`
|
||||
)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.copyFile(file.path, `${this.uploadDir_}/${fileKey}`, (err) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
throw err
|
||||
}
|
||||
|
||||
const fileUrl = `${this.backendUrl_}/${this.uploadDir_}/${fileKey}`
|
||||
|
||||
resolve({ url: fileUrl })
|
||||
resolve({ url: fileUrl, key: fileKey })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async delete(file): Promise<void> {
|
||||
throw Error("Not implemented")
|
||||
const filePath = `${this.uploadDir_}/${file.fileKey}`
|
||||
if (fs.existsSync(filePath)) {
|
||||
fs.unlinkSync(filePath)
|
||||
}
|
||||
}
|
||||
|
||||
async getUploadStreamDescriptor(
|
||||
fileData
|
||||
fileData: UploadStreamDescriptorType
|
||||
): Promise<FileServiceGetUploadStreamResult> {
|
||||
throw Error("Not implemented")
|
||||
const parsedFilename = path.parse(
|
||||
fileData.name + (fileData.ext ? `.${fileData.ext}` : "")
|
||||
)
|
||||
|
||||
if (parsedFilename.dir) {
|
||||
this.ensureDirExists(parsedFilename.dir)
|
||||
}
|
||||
|
||||
const fileKey = path.join(
|
||||
parsedFilename.dir,
|
||||
`${Date.now()}-${parsedFilename.base}`
|
||||
)
|
||||
|
||||
const fileUrl = `${this.backendUrl_}/${this.uploadDir_}/${fileKey}`
|
||||
|
||||
const pass = new stream.PassThrough()
|
||||
const writeStream = fs.createWriteStream(`${this.uploadDir_}/${fileKey}`)
|
||||
|
||||
pass.pipe(writeStream) // for consistency with the IFileService
|
||||
|
||||
const promise = new Promise((res, rej) => {
|
||||
writeStream.on("finish", res)
|
||||
writeStream.on("error", rej)
|
||||
})
|
||||
|
||||
return { url: fileUrl, fileKey, writeStream: pass, promise }
|
||||
}
|
||||
|
||||
async getDownloadStream(fileData): Promise<NodeJS.ReadableStream> {
|
||||
throw Error("Not implemented")
|
||||
const filePath = `${this.uploadDir_}/${fileData.fileKey}`
|
||||
return fs.createReadStream(filePath)
|
||||
}
|
||||
|
||||
async getPresignedDownloadUrl(fileData): Promise<string> {
|
||||
throw Error("Not implemented")
|
||||
return `${this.backendUrl_}/${this.uploadDir_}/${fileData.fileKey}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure `uploadDir_` has nested directories provided as file path
|
||||
*
|
||||
* @param dirPath - file path relative to the base directory
|
||||
* @private
|
||||
*/
|
||||
private ensureDirExists(dirPath: string) {
|
||||
const relativePath = path.join(this.uploadDir_, dirPath)
|
||||
|
||||
if (!fs.existsSync(relativePath)) {
|
||||
fs.mkdirSync(relativePath, { recursive: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user