/**
* @module flitter-upload/store/FlitterStore
*/
const Store = require('./Store')
const path = require('path')
const mkdirp = require('mkdirp')
const fs = require('fs').promises
const uuid = require('uuid/v4')
/**
* Local filesystem-backed file store provider.
* @extends module:flitter-upload/store/Store~Store
*/
class FlitterStore extends Store {
/**
* The absolute path to the directory where uploads will be stored.
* @type {string}
*/
store_path = ''
/**
* Defines the services required by this store.
* @returns {Array<string>}
*/
static get services() {
return [...super.services, 'utility', 'output', 'models']
}
/**
* Initializes the store. Creates the store upload directory, if it does not already exist.
* @returns {Promise<void>}
*/
async init() {
this.store_path = path.resolve(path.dirname(this.utility.root()), this.config.destination ? this.config.destination : './uploads')
await mkdirp(this.store_path)
this.output.info(`Created ${this.config.name} upload destination: ${this.store_path}`)
}
/**
* Permanently store a temporarily uploaded file in this store.
* @param {object} params
* @param {string} params.temp_path - absolute path to the temporarily uploaded file
* @param {string} params.original_name - the original upload name of the file
* @param {string} params.mime_type - the MIME type of the file.
* @returns {Promise<module:flitter-upload/model/File~File>}
*/
async store({ temp_path, original_name, mime_type }) {
const File = this.models.get('upload::File')
const upload_name = uuid()
await fs.copyFile(temp_path, this.filepath(upload_name))
const f = new File({
original_name,
upload_name,
mime_type,
store: this.config.name,
store_id: upload_name,
})
await f.save()
return f
}
/**
* Send the specified file as the data for the response.
* Sets the appropriate Content-Type and Content-Disposition headers.
* @param {module:flitter-upload/model/File~File} file - the file to send
* @param {express/response} response - the response
* @returns {Promise<void>}
*/
async send_file(file, response) {
const file_path = this.filepath(file.store_id)
response.setHeader('Content-Type', file.mime_type)
response.setHeader('Content-Disposition', `inline; filename="${file.original_name}";`)
response.sendFile(file_path)
}
/**
* Resolve the unique file name of a store file to its absolute path in the store.
* @param {string} file_name - the UUID name of the file
* @returns {string} - absolute path to the stored file
*/
filepath(file_name) {
return path.resolve(this.store_path, file_name)
}
}
module.exports = exports = FlitterStore