Express middleware for tus resumable upload protocol. Uses abstract-tus-store. Name inspired by busboy.
npm install --save tusboy
Requires Node v6+
See ./test directory for usage examples.
Boilerplate example usage with s3-tus-store:
import tusboy from 'tusboy'
import s3store from 's3-tus-store'
import aws from 'aws-sdk'
import { Passthrough } from 'stream'
import express from 'express'
const bucket = 'my-bucket'
const client = new aws.S3({
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY
})
const store = s3store({ client, bucket })
const app = express()
app
// .use(authenticate)
.use('/:username/avatar', new express.Router({ mergeParams: true })
.get('/', (req, res, next) => {
const key = `users/${req.params.username}/avatar-resized`
const rs = store.createReadStream(key, ({ contentLength, metadata }) => {
res.set('Content-Type', metadata.contentType)
res.set('Content-Length', contentLength)
rs.pipe(res)
}).on('error', next)
})
.use('/upload', tusboy(store, {
getKey: (req) => {
// Always return same key... last successful completed upload
// wins. Can throw here if authz error.
const key = `users/${req.params.username}/avatar`
return key
},
beforeComplete: async (req, upload, uploadId) => {},
afterComplete: async (req, upload, completedUploadId) => {
const key = `users/${req.params.username}/avatar`
console.log(`Completed upload ${completedUploadId}`)
// If you return a promise, the last patch request will
// block until promise is resolved.
// e.g you could resize avatar and write it to .../avatar-resized
const rs = store.createReadStream(key)
// .pipe(resizeImage) actually resize image...
const resizedKey = `users/${req.params.username}/avatar-resized`
const { uploadId } = await store.create(resizedKey, {
metadata: upload.metadata,
uploadLength: upload.uploadLength,
})
await store.append(uploadId, rs)
},
}))
)
app.listen(3000)