{"id":18317888,"url":"https://github.com/idiocc/busboy","last_synced_at":"2025-04-09T13:51:16.625Z","repository":{"id":57113704,"uuid":"194369085","full_name":"idiocc/busboy","owner":"idiocc","description":"[fork] A Streaming Parser For HTML Form Data For Node.JS.","archived":false,"fork":false,"pushed_at":"2019-12-24T10:33:22.000Z","size":519,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-16T03:17:37.752Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://idio.cc","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idiocc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-29T05:43:38.000Z","updated_at":"2019-12-24T10:33:25.000Z","dependencies_parsed_at":"2022-08-22T05:31:09.392Z","dependency_job_id":null,"html_url":"https://github.com/idiocc/busboy","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fbusboy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fbusboy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fbusboy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idiocc%2Fbusboy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idiocc","download_url":"https://codeload.github.com/idiocc/busboy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054218,"owners_count":21039951,"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-05T18:07:47.132Z","updated_at":"2025-04-09T13:51:16.595Z","avatar_url":"https://github.com/idiocc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @goa/busboy\n\n[![npm version](https://badge.fury.io/js/%40goa%2Fbusboy.svg)](https://www.npmjs.com/package/@goa/busboy)\n\n`@goa/busboy` is a fork of [A Streaming Parser For HTML Form Data For Node.JS](https://github.com/mscdex/busboy) Written In ES6 And Optimised With [JavaScript Compiler](https://compiler.page).\n\n```sh\nyarn add @goa/busboy\n```\n\n## Table Of Contents\n\n- [Table Of Contents](#table-of-contents)\n- [API](#api)\n- [`class Busboy`](#class-busboy)\n  * [File Event](#file-event)\n  * [Field Event](#field-event)\n- [`constructor(conf=: !BusBoyConfig)`](#constructorconf-busboyconfig-busboy)\n  * [`BusBoyConfig`](#type-busboyconfig)\n  * [`BusBoyLimits`](#type-busboylimits)\n- [Copyright](#copyright)\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/0.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## API\n\nThe package is available by importing its default function:\n\n```js\nimport Busboy from '@goa/busboy'\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## `class Busboy`\n\nBusboy is a _Writable_ stream. Emits the following events:\n\n|         Event         |                                                                                             Description                                                                                              |\n| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [file](#file-event)   | Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream. |\n| [field](#field-event) | Emitted for each new non-file field found.                                                                                                                                                           |\n| partsLimit            | Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.                                                              |\n| filesLimit            | Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.                                                                         |\n| fieldsLimit           | Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.                                                                        |\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/2.svg?sanitize=true\" width=\"25\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n### File Event\n\n```ts\nbusboy.on('file',\n  \u003cstring\u003e fieldname,\n  \u003cReadableStream\u003e stream,\n  \u003cstring\u003e filename,\n  \u003cstring\u003e transferEncoding,\n  \u003cstring\u003e mimeType\n)\n```\n\n- Note: if you listen for this event, you should always handle the stream no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume()`; if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).\n- If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/3.svg?sanitize=true\" width=\"25\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n### Field Event\n\n```ts\nbusboy.on('field',\n  \u003cstring\u003e fieldname,\n  \u003cstring\u003e value,\n  \u003cboolean\u003e fieldnameTruncated,\n  \u003cboolean\u003e valueTruncated,\n  \u003cstring\u003e transferEncoding,\n  \u003cstring\u003e mimeType\n)\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/4.svg?sanitize=true\" width=\"25\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## \u003ccode\u003e\u003cins\u003econstructor\u003c/ins\u003e(\u003c/code\u003e\u003csub\u003e\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`conf=: !BusBoyConfig,`\u003cbr/\u003e\u003c/sub\u003e\u003ccode\u003e): \u003ci\u003eBusBoy\u003c/i\u003e\u003c/code\u003e\n\n - \u003ckbd\u003econf\u003c/kbd\u003e \u003cem\u003e\u003ccode\u003e\u003ca href=\"#type-busboyconfig\" title=\"Options for the program.\"\u003e!BusBoyConfig\u003c/a\u003e\u003c/code\u003e\u003c/em\u003e (optional): The configuration.\n\n__\u003ca name=\"type-busboyconfig\"\u003e`BusBoyConfig`\u003c/a\u003e__: Options for the program.\n\n\n|     Name      |                                              Type                                               |                                        Description                                        | Default |\n| ------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------- |\n| headers       | \u003cem\u003e!Object\u003c/em\u003e                                                                                | These are the HTTP headers of the incoming request, which are used by individual parsers. | -       |\n| highWaterMark | \u003cem\u003enumber\u003c/em\u003e                                                                                 | The `highWaterMark` to use for this Busboy instance (Default: WritableStream default).    | -       |\n| fileHwm       | \u003cem\u003enumber\u003c/em\u003e                                                                                 | The `highWaterMark` to use for file streams (Default: ReadableStream default).            | -       |\n| defCharset    | \u003cem\u003estring\u003c/em\u003e                                                                                 | The default character set to use when one isn't defined.                                  | `utf8`  |\n| preservePath  | \u003cem\u003eboolean\u003c/em\u003e                                                                                | If paths in the multipart 'filename' field shall be preserved.                            | `false` |\n| limits        | \u003cem\u003e\u003ca href=\"#type-busboylimits\" title=\"Various limits on incoming data.\"\u003eBusBoyLimits\u003c/a\u003e\u003c/em\u003e | Various limits on incoming data.                                                          | -       |\n\n__\u003ca name=\"type-busboylimits\"\u003e`BusBoyLimits`\u003c/a\u003e__: Various limits on incoming data.\n\n\n|     Name      |      Type       |                                 Description                                  |  Default   |\n| ------------- | --------------- | ---------------------------------------------------------------------------- | ---------- |\n| fieldNameSize | \u003cem\u003enumber\u003c/em\u003e | Max field name size in bytes.                                                | `100`      |\n| fieldSize     | \u003cem\u003enumber\u003c/em\u003e | Max field value size in bytes.                                               | `1024`     |\n| fields        | \u003cem\u003enumber\u003c/em\u003e | Max number of non-file fields.                                               | `Infinity` |\n| fileSize      | \u003cem\u003enumber\u003c/em\u003e | For multipart forms, the max file size in bytes.                             | `Infinity` |\n| files         | \u003cem\u003enumber\u003c/em\u003e | For multipart forms, the max number of file fields.                          | `Infinity` |\n| parts         | \u003cem\u003enumber\u003c/em\u003e | For multipart forms, the max number of parts (fields + files).               | `Infinity` |\n| headerPairs   | \u003cem\u003enumber\u003c/em\u003e | For multipart forms, the max number of header key=\u0026gt; value pairs to parse. | `2000`     |\n\nThe constructor can throw errors:\n\n- Unsupported content type: $type - The Content-Type isn't one Busboy can parse.\n- Missing Content-Type - The provided headers don't include Content-Type at all.\n\n```jsx\nimport idio from '@idio/idio'\nimport render from '@depack/render'\nimport Busboy from '@goa/busboy'\n\n(async () =\u003e {\n  const { app, url } = await idio({\n    async post(ctx, next) {\n      if (ctx.request.method != 'POST') {\n        return await next()\n      }\n      const busboy = new Busboy({ headers: ctx.request.headers })\n\n      busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {\n        console.log(\n          'File [%s]: filename: %s, encoding: %s, mimetype: %s',\n          fieldname, filename, encoding, mimetype)\n        file.on('data', (data) =\u003e {\n          console.log('File [%s] got %s bytes', fieldname, data.length)\n        })\n        file.on('end', () =\u003e {\n          console.log('File [%s] Finished', fieldname)\n        })\n      })\n\n      busboy.on('field', (\n        fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype,\n      ) =\u003e {\n        console.log('Field [%s]: value: %O', fieldname, val)\n      })\n\n      ctx.req.pipe(busboy)\n\n      await new Promise((r, j) =\u003e {\n        busboy.on('finish', () =\u003e {\n          console.log('Done parsing form!')\n          r()\n        }).on('error', j)\n      })\n      ctx.status = 303\n      ctx.body = 'OK'\n      exitExample(app)\n    },\n    get(ctx) {\n      ctx.body = render(\u003chtml\u003e\n        \u003cbody\u003e\n          \u003cform method=\"POST\" encType=\"multipart/form-data\"\u003e\n            \u003cinput type=\"text\" name=\"textfield\" /\u003e\u003cbr /\u003e\n            \u003cinput type=\"file\" name=\"filefield\" /\u003e\u003cbr /\u003e\n            \u003cinput type=\"submit\" /\u003e\n          \u003c/form\u003e\n        \u003c/body\u003e\n      \u003c/html\u003e)\n    },\n  })\n  console.log(url)\n})()\n```\n```\nhttp://localhost:5000\nField [textfield]: value: ''\nFile [filefield]: filename: hi, encoding: 7bit, mimetype: application/octet-stream\nFile [filefield] got 12 bytes\nFile [filefield] Finished\nDone parsing form!\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/5.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Copyright\n\nGNU Affero General Public License v3.0\n\n[Original Work](https://github.com/mscdex/busboy) by Brian White aka mscdex under MIT License found in [COPYING](COPYING).\n\n---\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://artd.eco\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/wrote/wrote/master/images/artdeco.png\"\n          alt=\"Art Deco\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e© \u003ca href=\"https://artd.eco\"\u003eArt Deco\u003c/a\u003e for \u003ca href=\"https://idio.cc\"\u003eIdio\u003c/a\u003e 2019\u003c/th\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://idio.cc\"\u003e\n        \u003cimg src=\"https://avatars3.githubusercontent.com/u/40834161?s=100\" width=\"100\" alt=\"Idio\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://www.technation.sucks\" title=\"Tech Nation Visa\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/idiocc/cookies/master/wiki/arch4.jpg\"\n          alt=\"Tech Nation Visa\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e\u003ca href=\"https://www.technation.sucks\"\u003eTech Nation Visa Sucks\u003c/a\u003e\u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/-1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Fbusboy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidiocc%2Fbusboy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidiocc%2Fbusboy/lists"}