{"id":20766997,"url":"https://github.com/binded/tusboy","last_synced_at":"2025-05-11T08:34:04.516Z","repository":{"id":57382405,"uuid":"68335088","full_name":"binded/tusboy","owner":"binded","description":"Express middleware for the Tus resumable upload protocol","archived":true,"fork":false,"pushed_at":"2016-10-28T04:15:50.000Z","size":1180,"stargazers_count":5,"open_issues_count":1,"forks_count":1,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-27T12:02:17.319Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/binded.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-09-15T22:08:15.000Z","updated_at":"2025-03-11T07:58:55.000Z","dependencies_parsed_at":"2022-09-26T16:50:20.820Z","dependency_job_id":null,"html_url":"https://github.com/binded/tusboy","commit_stats":null,"previous_names":["blockai/tusboy"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binded%2Ftusboy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binded%2Ftusboy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binded%2Ftusboy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binded%2Ftusboy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binded","download_url":"https://codeload.github.com/binded/tusboy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253540462,"owners_count":21924522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T11:27:10.145Z","updated_at":"2025-05-11T08:34:04.221Z","avatar_url":"https://github.com/binded.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tusboy\n\n[![Build Status](https://travis-ci.org/blockai/tusboy.svg?branch=master)](https://travis-ci.org/blockai/tusboy)\n\nExpress middleware for [tus resumable upload protocol](http://tus.io/).\nUses [abstract-tus-store](https://github.com/blockai/abstract-tus-store).\nName inspired by [busboy](https://github.com/mscdex/busboy).\n\n[![tus-store-compatible](https://github.com/blockai/abstract-tus-store/raw/master/badge.png)](https://github.com/blockai/abstract-tus-store)\n\n## Install\n\n```bash\nnpm install --save tusboy\n```\n\nRequires Node v6+\n\n## Usage\n\nSee [./test](./test) directory for usage examples.\n\nBoilerplate example usage with s3-tus-store:\n\n```javascript\nimport tusboy from 'tusboy'\nimport s3store from 's3-tus-store'\nimport aws from 'aws-sdk'\nimport { Passthrough } from 'stream'\n\nimport express from 'express'\n\nconst bucket = 'my-bucket'\nconst client = new aws.S3({\n  accessKeyId: process.env.S3_ACCESS_KEY,\n  secretAccessKey: process.env.S3_SECRET_KEY\n})\nconst store = s3store({ client, bucket })\n\nconst app = express()\napp\n  // .use(authenticate)\n  .use('/:username/avatar', new express.Router({ mergeParams: true })\n    .get('/', (req, res, next) =\u003e {\n      const key = `users/${req.params.username}/avatar-resized`\n      const rs = store.createReadStream(key, ({ contentLength, metadata }) =\u003e {\n        res.set('Content-Type', metadata.contentType)\n        res.set('Content-Length', contentLength)\n        rs.pipe(res)\n      }).on('error', next)\n    })\n    .use('/upload', tusboy(store, {\n      getKey: (req) =\u003e {\n        // Always return same key... last successful completed upload\n        // wins. Can throw here if authz error.\n        const key = `users/${req.params.username}/avatar`\n        return key\n      },\n      beforeComplete: async (req, upload, uploadId) =\u003e {},\n      afterComplete: async (req, upload, completedUploadId) =\u003e {\n        const key = `users/${req.params.username}/avatar`\n        console.log(`Completed upload ${completedUploadId}`)\n        // If you return a promise, the last patch request will\n        // block until promise is resolved.\n        // e.g you could resize avatar and write it to .../avatar-resized\n        const rs = store.createReadStream(key)\n          // .pipe(resizeImage) actually resize image...\n        const resizedKey = `users/${req.params.username}/avatar-resized`\n        const { uploadId } = await store.create(resizedKey, {\n          metadata: upload.metadata,\n          uploadLength: upload.uploadLength,\n        })\n        await store.append(uploadId, rs)\n      },\n    }))\n  )\n\napp.listen(3000)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinded%2Ftusboy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinded%2Ftusboy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinded%2Ftusboy/lists"}