You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
2.9 KiB
90 lines
2.9 KiB
/**
|
|
* @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
|