71 lines
1.7 KiB
JavaScript
71 lines
1.7 KiB
JavaScript
import fs from 'fs'
|
|
import { GraphQLUpload } from 'graphql-upload'
|
|
import lowdb from 'lowdb'
|
|
import FileSync from 'lowdb/adapters/FileSync'
|
|
import mkdirp from 'mkdirp'
|
|
import promisesAll from 'promises-all'
|
|
import shortid from 'shortid'
|
|
|
|
const UPLOAD_DIR = './uploads'
|
|
const db = lowdb(new FileSync('db.json'))
|
|
|
|
// Seed an empty DB
|
|
db.defaults({ uploads: [] }).write()
|
|
|
|
// Ensure upload directory exists
|
|
mkdirp.sync(UPLOAD_DIR)
|
|
|
|
const storeFS = ({ stream, filename }) => {
|
|
const id = shortid.generate()
|
|
const path = `${UPLOAD_DIR}/${id}-${filename}`
|
|
return new Promise((resolve, reject) =>
|
|
stream
|
|
.on('error', error => {
|
|
if (stream.truncated)
|
|
// Delete the truncated file
|
|
fs.unlinkSync(path)
|
|
reject(error)
|
|
})
|
|
.pipe(fs.createWriteStream(path))
|
|
.on('error', error => reject(error))
|
|
.on('finish', () => resolve({ id, path }))
|
|
)
|
|
}
|
|
|
|
const storeDB = file =>
|
|
db
|
|
.get('uploads')
|
|
.push(file)
|
|
.last()
|
|
.write()
|
|
|
|
const processUpload = async upload => {
|
|
const { createReadStream, filename, mimetype } = await upload
|
|
const stream = createReadStream()
|
|
const { id, path } = await storeFS({ stream, filename })
|
|
return storeDB({ id, filename, mimetype, path })
|
|
}
|
|
|
|
export default {
|
|
Upload: GraphQLUpload,
|
|
Query: {
|
|
uploads: () => db.get('uploads').value()
|
|
},
|
|
Mutation: {
|
|
singleUpload: (obj, { file }) => processUpload(file),
|
|
async multipleUpload(obj, { files }) {
|
|
const { resolve, reject } = await promisesAll.all(
|
|
files.map(processUpload)
|
|
)
|
|
|
|
if (reject.length)
|
|
reject.forEach(({ name, message }) =>
|
|
// eslint-disable-next-line no-console
|
|
console.error(`${name}: ${message}`)
|
|
)
|
|
|
|
return resolve
|
|
}
|
|
}
|
|
}
|