Gathering detailed insights and metrics for then-busboy
Gathering detailed insights and metrics for then-busboy
npm install then-busboy
Typescript
Module System
Min. Node Version
Node Version
NPM Version
70.6
Supply Chain
97.6
Quality
75.4
Maintenance
50
Vulnerability
99.6
License
TypeScript (99.57%)
JavaScript (0.43%)
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Total Downloads
64,715
Last Day
6
Last Week
52
Last Month
221
Last Year
5,429
MIT License
9 Stars
529 Commits
3 Forks
1 Watchers
3 Branches
4 Contributors
Updated on Oct 25, 2023
Minified
Minified + Gzipped
Latest Version
5.2.1
Package Id
then-busboy@5.2.1
Unpacked Size
76.27 kB
Size
16.42 kB
File Count
80
NPM Version
8.15.0
Node Version
18.7.0
Cumulative downloads
Total Downloads
Last Day
-50%
6
Compared to previous day
Last Week
18.2%
52
Compared to previous week
Last Month
-44.9%
221
Compared to previous month
Last Year
1%
5,429
Compared to previous year
29
Promise-based wrapper around Busboy. Processes multipart/form-data request body and returns it in a single object.
You can install then-busboy
from npm:
npm install --save then-busboy
Or with yarn:
yarn add then-busboy
Because then-busboy can process multipart/form-data
bodies from AsyncIterable sources, you can use it with different HTTP frameworks, or with Node.js http module, or even with Response
object (see the 4th example).
http
module from Node.js.
We'll write a simple server that will parse form-data request, read files content and then send them back as JSON:1import {createServer} from "http" 2import {parse} from "then-busboy" 3 4const handler = (req, res) => parse(req) 5 .then(async body => { 6 const result = [] 7 for (const [path, value] of body) { 8 result.push([path, isFile(value) ? await value.text() : value]) 9 } 10 11 res.setHeader("Content-Type", "application/json") 12 res.end(JSON.stringify(Body.json(result))) 13 }) 14 .catch(error => { 15 res.statusCode = error.status || 500 16 res.end(error.message) 17 }) 18 19createServer(handler) 20 .listen(2319, () => console.log("Server started on http://localhost:2319"))
Note: You can use asynchronous function syntax, because then-busboy always returns a Promise.
1import {parse} from "then-busboy" 2 3async function multipart(ctx, next) { 4 if (["post", "put"].includes(ctx.method.toLowerCase()) === false) { 5 return next() 6 } 7 8 if (ctx.is("multipart/form-data") === false) { 9 return next() 10 } 11 12 const body = await parse(ctx.req) 13 14 ctx.request.body = body.json() 15 16 return next() 17} 18 19export default multipart
AsyncIterable
value as the input. That way you can parse FormData from other that just HTTP requests. Let's take a loook at the example with form-data-encoder
and formdata-node
as the input:1import {fileFromPath} from "formdata-node/file-from-path" 2import {FormDataEncoder} from "form-data-encoder" 3import {FormData} from "formdata-node" 4import {parse} from "then-busboy" 5 6const form = new FormData() 7 8form.set("greeting", "Hello, World!") 9form.set("file", new File(["On Soviet Moon landscape see binoculars through YOU"], "file.txt")) 10form.set("fileFromPath", await fileFromPath("path/to/a/file")) 11 12const encoder = new FormDataEncoder(form) 13 14const body = await parse(encoder, { 15 headers: { 16 "content-type": encoder.contentType 17 } 18}) 19 20console.log(body.json()) // -> {greeting: string, file: BodyFile, fileFromPath: BodyFile}
then-busboy
accepts AsyncIterable as the input, you can also read Response
body like that:1import {Response, FormData} from "node-fetch" 2import {parse} from "then-bosboy" 3const form = new FormData() 4 5form.set("greeting", "Hello, World!") 6form.set("file", new File(["On Soviet Moon landscape see binoculars through YOU"], "file.txt")) 7 8const response = new Respone(form) 9// then-busboy will parse the input and return its own Body instance from which you can create a complete object by calling .json() method or a FormData using .formData() method. 10// The difference with Response.formData() is that then-busboy will save all files to file system and create a *reference* to each of them, 11// while Response (currently) will dump them into RAM, which can be less efficient in some scenarious 12const body = await parse(response.body, { 13 headers: { 14 "content-type": response.headers.get("content-type") 15 } 16}) 17 18body.json() // -> {greeting: string, file: BodyFile} 19body.formData() // -> FormData
parse(source[, options]) -> {Promise<Body>}
class Body
constructor(entries) -> {Body}
Create an object that allows to manipulate FormData fields taken then-busboy
from(entries) -> {Body}
Create a new Body from given entries. An alias of new Body(entries)
then-busboy
json(value) -> {object}
Return an object with data taken from given entries or Body
formData(value) -> {FormData}
Return a FormData instance with data taken from given entries or Body
length -> {number}
Return an amount of entries and files in current Body instance
fields() -> {Body}
Return a new Body that contains fields only
files() -> {Body}
Return a new Body that contains files only
json() -> {object}
Return an object with data taken the current Body instance
formData() -> {FormData}
Return a FormData with data taken the current Body instance
entries() -> {Array<[string[], any]>}
Return an array of entries in current Body instance
values() -> {Iterator}
Return an iterator allows to go through the Body values
keys() -> {Iterator}
Return an iterator allows to go through the Body fields path
interface BodyFile
This interface reflects internal representation of a File. It is not meant to be constructed manually, but since it's compatible with files from the browsers, you can use these in Body if you need to.
name
Contains original name of file taken from the filename property within the form-data.
type
File MIME type
enc
Contains a value from transfer encoding header
path
Path to the file on disk
stream() -> {Readable}
Returns a Readable stream allowing to consume file's content
class BodyField
BodyField class in the internal representation of a regular FormData value.
constructor(value: unknown, name: string[, options]) -> {BodyField}
Creates a new instance of the BodyField class.
name
Returns the name of the field.
fieldnameTruncated
Indicates whether the fieldname was truncated.
valueTruncated
Indicates whether the value was truncated.
enc
Returns a value from Content-Transfer-Encoding header.
type
Returns a value from Content-Type header.
valueOf() -> {unknown}
Returns the value of the BodyField.
toString() -> {string}
Returns string representation of the BodyField value.
then-busboy can restore an object structure from form-data field names if you will follow the naming formats with dots or square brackets:
This notation looks similarly to JS object properties accessiong syntax:
# Flat objects looks the same in both notations
# Note that the following notation examples is just a pseudo code
name = "John Doe"
age = 25
then-busboy will return the this object for an example from above:
1{ 2 name: "John Doe", 3 4 // By default, non-string values will be converted to their initial type. 5 // So, "25" -> 25, "null" -> null, "false" -> false etc. 6 age: 25 7}
For deep objects or collections, use dot or brackets as a separator. But don't mix them.
rootField.nestedField = "Some text here"
1 { 2 rootField: { 3 nestedField: "Some text here" 4 } 5 }
rootField[nestedField] = "I beat Twilight Sparkle and all I got was this lousy t-shirt"
Becomes
1{ 2 rootField: { 3 nestedField: "I beat Twilight Sparkle and all I got was this lousy t-shirt" 4 } 5}
You can also send an arrays and collections using bracket format:
message[sender] = "John Doe"
message[text] = "Some whatever text message."
message[attachments][0][file] = <here is the file content>
message[attachments][0][description] = "Here is a description of the file"
then-busboy returns the following object:
1{ 2 message: { 3 sender: "John Doe", 4 text: "Some whatever text message.", 5 attachments: [ 6 { 7 "file": File, // this field will be represended as a File instance 8 "description": "Here is a description of the file" 9 } 10 ] 11 } 12}
Collections allowed too:
[0][firstName] = "John"
[0][lastName] = "Doe"
[0][dob][day] = "1"
[0][dob][month] = "Jan."
[0][dob][year] = "1989"
[0][skills][0] = "Node.js"
[0][skills][1] = "CoffeeScript"
[0][skills][2] = "JavaScript"
[0][skills][3] = "Babel"
[1][firstName] = "Max"
[1][lastName] = "Doe"
[1][dob][day] = "12"
[1][dob][month] = "Mar."
[1][dob][year] = "1992"
[1][skills][0] = "Python"
[1][skills][1] = "Flask"
[1][skills][2] = "JavaScript"
[1][skills][3] = "Babel"
[1][skills][4] = "React"
[1][skills][5] = "Redux"
Then you will receive:
1[ 2 { 3 firstName: "John", 4 lastName: "Doe", 5 dob: { 6 day: 1, 7 month: "Jan.", 8 year: 1989 9 }, 10 skills: ["Node.js", "CoffeeScript", "JavaScript", "Babel"] 11 }, { 12 firstName: "Max", 13 lastName: "Doe", 14 dob: { 15 day: 12, 16 month: "Mar.", 17 year: 1992 18 }, 19 skills: ["Python", "Flask", "JavaScript", "Babel", "React", "Redux"] 20 } 21]
Whenlimits
options are set, then-busboy
may reject with HTTP 413 error if specified limit(s) exceeded. That will be a regular error from object http-errors
package.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 2/28 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
14 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-03-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More