{"id":21557658,"url":"https://github.com/danielrohers/bory","last_synced_at":"2025-04-10T10:34:16.670Z","repository":{"id":143864439,"uuid":"80938093","full_name":"danielrohers/bory","owner":"danielrohers","description":"Node.js body and query parsing middleware with nesting","archived":false,"fork":false,"pushed_at":"2017-02-06T13:22:51.000Z","size":128,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T09:21:40.274Z","etag":null,"topics":["body","nested","node","parser","query"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/bory","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/danielrohers.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,"governance":null}},"created_at":"2017-02-04T18:11:39.000Z","updated_at":"2017-02-06T13:11:58.000Z","dependencies_parsed_at":"2023-07-16T05:16:17.851Z","dependency_job_id":null,"html_url":"https://github.com/danielrohers/bory","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielrohers%2Fbory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielrohers%2Fbory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielrohers%2Fbory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielrohers%2Fbory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielrohers","download_url":"https://codeload.github.com/danielrohers/bory/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248199245,"owners_count":21063641,"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":["body","nested","node","parser","query"],"created_at":"2024-11-24T08:12:48.409Z","updated_at":"2025-04-10T10:34:16.648Z","avatar_url":"https://github.com/danielrohers.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bory\n\nNode.js **bo**dy and que**ry** parsing middleware with nesting. *Node \u003e= v4.0.0*\n\n**This is a fork of the [body-parser](https://github.com/expressjs/body-parser), but with improvements like nested.**\n\n[![Build Status](https://travis-ci.org/danielrohers/bory.svg?branch=master)](https://travis-ci.org/danielrohers/bory)\n[![Dependency Status](https://david-dm.org/danielrohers/bory/dev-status.svg)](https://david-dm.org/danielrohers/bory#info=dependencies)\n[![devDependency Status](https://david-dm.org/danielrohers/bory/dev-status.svg)](https://david-dm.org/danielrohers/bory#info=devDependencies)\n[![npm download](https://img.shields.io/npm/dt/bory.svg)](https://www.npmjs.com/package/bory)\n[![npm version](https://img.shields.io/npm/v/bory.svg)](https://badge.fury.io/js/bory)\n[![Code Climate](https://codeclimate.com/github/danielrohers/bory/badges/gpa.svg)](https://codeclimate.com/github/danielrohers/bory)\n\nParse incoming request bodies in a middleware before your handlers, available\nunder the `req.body` and `req.query` property.\n\n[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/).\n\n_This does not handle multipart bodies_, due to their complex and typically\nlarge nature. For multipart bodies, you may be interested in the following\nmodules:\n\n  * [busboy](https://www.npmjs.org/package/busboy#readme) and\n    [connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)\n  * [multiparty](https://www.npmjs.org/package/multiparty#readme) and\n    [connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)\n  * [formidable](https://www.npmjs.org/package/formidable#readme)\n  * [multer](https://www.npmjs.org/package/multer#readme)\n\nThis module provides the following parsers:\n\n  * [JSON bory](#boryjsonoptions)\n  * [Raw bory](#boryrawoptions)\n  * [Text bory](#borytextoptions)\n  * [URL-encoded form bory](#boryurlencodedoptions)\n  * [Nested bory](#borynestedoptions)\n  * [Query parser bory](#boryqueryparser)\n  \nExamples:\n\n  * [Node top-level generic](#node-top-level-generic)\n  * [Express / Connect / Restify top-level generic](#express--connect--restify-top-level-generic)\n  * [Express nested](#express-nested)\n  * [Express route-specific](#express-route-specific)\n  * [Change accepted type for parsers](#change-accepted-type-for-parsers)\n\n## Installation\n\n```sh\n$ npm install bory --save\n```\nor\n```sh\n$ yarn add bory\n```\n\n## API\n\n```js\nconst bory = require('bory');\n```\n\nThe `bory` object exposes various factories to create middlewares. All\nmiddlewares will populate the `req.body` or `req.query` property with the parsed body, or an\nempty object (`{}`) if there was no body to parse (or an error was returned).\n\nThe various errors returned by this module are described in the\n[errors section](#errors).\n\n### bory.json(options)\n\nReturns middleware that only parses `json`. This parser accepts any Unicode\nencoding of the body and supports automatic inflation of `gzip` and `deflate`\nencodings.\n\nA new `body` object containing the parsed data is populated on the `request`\nobject after the middleware (i.e. `req.body`).\n\n#### Options\n\nThe `json` function takes an option `options` object that may contain any of\nthe following keys:\n\n##### inflate\n\nWhen set to `true`, then deflated (compressed) bodies will be inflated; when\n`false`, deflated bodies are rejected. Defaults to `true`.\n\n##### limit\n\nControls the maximum request body size. If this is a number, then the value\nspecifies the number of bytes; if it is a string, the value is passed to the\n[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults\nto `'100kb'`.\n\n##### reviver\n\nThe `reviver` option is passed directly to `JSON.parse` as the second\nargument. You can find more information on this argument\n[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).\n\n##### strict\n\nWhen set to `true`, will only accept arrays and objects; when `false` will\naccept anything `JSON.parse` accepts. Defaults to `true`.\n\n##### type\n\nThe `type` option is used to determine what media type the middleware will\nparse. This option can be a function or a string. If a string, `type` option\nis passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)\nlibrary and this can be an extension name (like `json`), a mime type (like\n`application/json`), or a mime type with a wildcard (like `*/*` or `*/json`).\nIf a function, the `type` option is called as `fn(req)` and the request is\nparsed if it returns a truthy value. Defaults to `application/json`.\n\n##### verify\n\nThe `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,\nwhere `buf` is a `Buffer` of the raw request body and `encoding` is the\nencoding of the request. The parsing can be aborted by throwing an error.\n\n### bory.raw(options)\n\nReturns middleware that parses all bodies as a `Buffer`. This parser\nsupports automatic inflation of `gzip` and `deflate` encodings.\n\nA new `body` object containing the parsed data is populated on the `request`\nobject after the middleware (i.e. `req.body`). This will be a `Buffer` object\nof the body.\n\n#### Options\n\nThe `raw` function takes an option `options` object that may contain any of\nthe following keys:\n\n##### inflate\n\nWhen set to `true`, then deflated (compressed) bodies will be inflated; when\n`false`, deflated bodies are rejected. Defaults to `true`.\n\n##### limit\n\nControls the maximum request body size. If this is a number, then the value\nspecifies the number of bytes; if it is a string, the value is passed to the\n[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults\nto `'100kb'`.\n\n##### type\n\nThe `type` option is used to determine what media type the middleware will\nparse. This option can be a function or a string. If a string, `type` option\nis passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)\nlibrary and this can be an extension name (like `bin`), a mime type (like\n`application/octet-stream`), or a mime type with a wildcard (like `*/*` or\n`application/*`). If a function, the `type` option is called as `fn(req)`\nand the request is parsed if it returns a truthy value. Defaults to\n`application/octet-stream`.\n\n##### verify\n\nThe `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,\nwhere `buf` is a `Buffer` of the raw request body and `encoding` is the\nencoding of the request. The parsing can be aborted by throwing an error.\n\n### bory.text(options)\n\nReturns middleware that parses all bodies as a string. This parser supports\nautomatic inflation of `gzip` and `deflate` encodings.\n\nA new `body` string containing the parsed data is populated on the `request`\nobject after the middleware (i.e. `req.body`). This will be a string of the\nbody.\n\n#### Options\n\nThe `text` function takes an option `options` object that may contain any of\nthe following keys:\n\n##### defaultCharset\n\nSpecify the default character set for the text content if the charset is not\nspecified in the `Content-Type` header of the request. Defaults to `utf-8`.\n\n##### inflate\n\nWhen set to `true`, then deflated (compressed) bodies will be inflated; when\n`false`, deflated bodies are rejected. Defaults to `true`.\n\n##### limit\n\nControls the maximum request body size. If this is a number, then the value\nspecifies the number of bytes; if it is a string, the value is passed to the\n[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults\nto `'100kb'`.\n\n##### type\n\nThe `type` option is used to determine what media type the middleware will\nparse. This option can be a function or a string. If a string, `type` option\nis passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)\nlibrary and this can be an extension name (like `txt`), a mime type (like\n`text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`).\nIf a function, the `type` option is called as `fn(req)` and the request is\nparsed if it returns a truthy value. Defaults to `text/plain`.\n\n##### verify\n\nThe `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,\nwhere `buf` is a `Buffer` of the raw request body and `encoding` is the\nencoding of the request. The parsing can be aborted by throwing an error.\n\n### bory.urlencoded(options)\n\nReturns middleware that only parses `urlencoded` bodies. This parser accepts\nonly UTF-8 encoding of the body and supports automatic inflation of `gzip`\nand `deflate` encodings.\n\nA new `body` object containing the parsed data is populated on the `request`\nobject after the middleware (i.e. `req.body`). This object will contain\nkey-value pairs, where the value can be a string or array (when `extended` is\n`false`), or any type (when `extended` is `true`).\n\n#### Options\n\nThe `urlencoded` function takes an option `options` object that may contain\nany of the following keys:\n\n##### extended\n\nThe `extended` option allows to choose between parsing the URL-encoded data\nwith the `querystring` library (when `false`) or the `qs` library (when\n`true`). The \"extended\" syntax allows for rich objects and arrays to be\nencoded into the URL-encoded format, allowing for a JSON-like experience\nwith URL-encoded. For more information, please\n[see the qs library](https://www.npmjs.org/package/qs#readme).\n\nDefaults to `true`, but using the default has been deprecated. Please\nresearch into the difference between `qs` and `querystring` and choose the\nappropriate setting.\n\n##### inflate\n\nWhen set to `true`, then deflated (compressed) bodies will be inflated; when\n`false`, deflated bodies are rejected. Defaults to `true`.\n\n##### limit\n\nControls the maximum request body size. If this is a number, then the value\nspecifies the number of bytes; if it is a string, the value is passed to the\n[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults\nto `'100kb'`.\n\n##### parameterLimit\n\nThe `parameterLimit` option controls the maximum number of parameters that\nare allowed in the URL-encoded data. If a request contains more parameters\nthan this value, a 413 will be returned to the client. Defaults to `1000`.\n\n##### type\n\nThe `type` option is used to determine what media type the middleware will\nparse. This option can be a function or a string. If a string, `type` option\nis passed directly to the [type-is](https://www.npmjs.org/package/type-is#readme)\nlibrary and this can be an extension name (like `urlencoded`), a mime type (like\n`application/x-www-form-urlencoded`), or a mime type with a wildcard (like\n`*/x-www-form-urlencoded`). If a function, the `type` option is called as\n`fn(req)` and the request is parsed if it returns a truthy value. Defaults\nto `application/x-www-form-urlencoded`.\n\n##### verify\n\nThe `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,\nwhere `buf` is a `Buffer` of the raw request body and `encoding` is the\nencoding of the request. The parsing can be aborted by throwing an error.\n\n### bory.nested(options)\n\nReturns middleware that only parses `nested` bodies.\n\nA new `body` and `query` object containing the parsed data is populated on the request object after the middleware (i.e. `req.body`, `req.query`).\n\n#### Options\n\nThe `nested` function takes an option `options` object that may contain\nany of the following keys:\n\n##### body\n\nWhen set to `true`, bodies will be nested; when `false`, the bodies conform to request. The default is `true`.\n\n##### query\n\nWhen set to `true`, bodies will be nested; when `false`, the bodies conform to request. The default is `true`.\n\n\n### bory.queryParser()\n\nReturns the middleware that only parses the query (url).\n\nA new `query` object containing the parsed data is populated on the request object after the middleware (i.e. `req.query`).\n\n## Errors\n\nThe middlewares provided by this module create errors depending on the error\ncondition during parsing. The errors will typically have a `status` property\nthat contains the suggested HTTP response code and a `body` property containing\nthe read body, if available.\n\nThe following are the common errors emitted, though any error can come through\nfor various reasons.\n\n### content encoding unsupported\n\nThis error will occur when the request had a `Content-Encoding` header that\ncontained an encoding but the \"inflation\" option was set to `false`. The\n`status` property is set to `415`.\n\n### request aborted\n\nThis error will occur when the request is aborted by the client before reading\nthe body has finished. The `received` property will be set to the number of\nbytes received before the request was aborted and the `expected` property is\nset to the number of expected bytes. The `status` property is set to `400`.\n\n### request entity too large\n\nThis error will occur when the request body's size is larger than the \"limit\"\noption. The `limit` property will be set to the byte limit and the `length`\nproperty will be set to the request body's length. The `status` property is\nset to `413`.\n\n### request size did not match content length\n\nThis error will occur when the request's length did not match the length from\nthe `Content-Length` header. This typically occurs when the request is malformed,\ntypically when the `Content-Length` header was calculated based on characters\ninstead of bytes. The `status` property is set to `400`.\n\n### stream encoding should not be set\n\nThis error will occur when something called the `req.setEncoding` method prior\nto this middleware. This module operates directly on bytes only and you cannot\ncall `req.setEncoding` when using this module. The `status` property is set to\n`500`.\n\n### unsupported charset \"BOGUS\"\n\nThis error will occur when the request had a charset parameter in the\n`Content-Type` header, but the `iconv-lite` module does not support it OR the\nparser does not support it. The charset is contained in the message as well\nas in the `charset` property. The `status` property is set to `415`.\n\n### unsupported content encoding \"bogus\"\n\nThis error will occur when the request had a `Content-Encoding` header that\ncontained an unsupported encoding. The encoding is contained in the message\nas well as in the `encoding` property. The `status` property is set to `415`.\n\n## Examples\n\n### Node top-level generic\n\nThis example demonstrates adding a generic JSON, URL-encoded, Query and Nested parser as a top-level middleware, which will parse the bodies of all incoming requests. This is the simplest setup.\n\n```js\nconst http = require('http');\nconst async = require('async');\nconst bory = require('bory');\n\nconst hostname = '127.0.0.1';\nconst port = 3000;\n\nconst server = http.createServer((req, res) =\u003e {\n  async.series([\n    // parse application/x-www-form-urlencoded\n    async.apply(bory.urlencoded({ extended: false }), req, res),\n    // parse application/json\n    async.apply(bory.json(), req, res),\n    // parse query\n    async.apply(bory.queryParser(), req, res),\n    // parse nested\n    async.apply(bory.nested(), req, res),\n  ], (err) =\u003e {\n    res.statusCode = 200;\n    res.setHeader('Content-Type', 'text/plain');\n    res.end(req.body.user.first_name);\n  });\n});\n\nserver.listen(port, hostname, () =\u003e {\n  console.log(`Server running at http://${hostname}:${port}/`);\n});\n```\n\n### Express / Connect / Restify top-level generic\n\nThis example demonstrates adding a generic JSON and URL-encoded parser as a\ntop-level middleware, which will parse the bodies of all incoming requests.\nThis is the simplest setup.\n\n```js\nconst express = require('express');\nconst bory = require('bory');\n\nconst app = express();\n\n// parse application/x-www-form-urlencoded\napp.use(bory.urlencoded({ extended: false }));\n\n// parse application/json\napp.use(bory.json());\n\napp.use((req, res) =\u003e {\n  res.setHeader('Content-Type', 'text/plain');\n  res.write('you posted:\\n');\n  res.end(JSON.stringify(req.body, null, 2));\n});\n```\n\n### Express nested\n\nThis example demonstrates the use of nesting, ie when submitted `user.name`.\nWith nesting `req.body.user.name`; without nesting would be `req.body['user.name']`.\n\n```js\nconst express = require('express');\nconst bory = require('bory');\n\nconst app = express();\n\n// parse application/x-www-form-urlencoded\napp.use(bory.urlencoded({ extended: false }));\n\n// parse application/json\napp.use(bory.json());\n\n// parse nested\napp.use(bory.nested());\n\napp.use((req, res) =\u003e {\n  res.send(`welcome, ${req.body.user.name}`);\n})\n```\n\nWhen performing a POST with:\n```js\n{\n  'user.first_name': 'daniel',\n  'user.last_name': 'moura',\n}\n```\n\nWith [body-parser](https://github.com/expressjs/body-parser) you will have:\n```js\nreq.body['user.first_name']; //daniel\nreq.body['user.last_name']; //moura\n```\n\nWith **bory** you will have:\n```js\nreq.body.user.first_name; //daniel\nreq.body.user.last_name; //moura\n```\n\n### Express route-specific\n\nThis example demonstrates adding body parsers specifically to the routes that\nneed them. In general, this is the most recommended way to use bory with\nExpress.\n\n```js\nconst express = require('express');\nconst bory = require('bory');\n\nconst app = express();\n\n// create application/json parser\nconst jsonParser = bory.json();\n\n// create application/x-www-form-urlencoded parser\nconst urlencodedParser = bory.urlencoded({ extended: false });\n\n// POST /login gets urlencoded bodies\napp.post('/login', urlencodedParser, (req, res) =\u003e {\n  if (!req.body) return res.sendStatus(400);\n  res.send(`welcome, ${req.body.username}`);\n})\n\n// POST /api/users gets JSON bodies\napp.post('/api/users', jsonParser, (req, res) =\u003e {\n  if (!req.body) return res.sendStatus(400);\n  // create user in req.body\n})\n```\n\n### Change accepted type for parsers\n\nAll the parsers accept a `type` option which allows you to change the\n`Content-Type` that the middleware will parse.\n\n```js\nconst express = require('express');\nconst bory = require('bory');\n\nconst app = express();\n\n// parse various different custom JSON types as JSON\napp.use(bory.json({ type: 'application/*+json' }));\n\n// parse some custom thing into a Buffer\napp.use(bory.raw({ type: 'application/vnd.custom-type' }));\n\n// parse an HTML body into a string\napp.use(bory.text({ type: 'text/html' }));\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielrohers%2Fbory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielrohers%2Fbory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielrohers%2Fbory/lists"}