{"id":20208411,"url":"https://github.com/fluture-js/fluture-node","last_synced_at":"2025-04-10T12:55:55.027Z","repository":{"id":34397303,"uuid":"177592492","full_name":"fluture-js/fluture-node","owner":"fluture-js","description":"FP-style HTTP and streaming utils for Node based on Fluture","archived":false,"fork":false,"pushed_at":"2024-03-24T14:30:54.000Z","size":165,"stargazers_count":19,"open_issues_count":2,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-26T10:45:15.764Z","etag":null,"topics":["buffer","events","fluture","http","https","nodejs","request","streams","timers"],"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/fluture-js.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-25T13:31:10.000Z","updated_at":"2024-06-21T18:55:09.559Z","dependencies_parsed_at":"2024-06-21T18:55:07.349Z","dependency_job_id":"45b1e3f8-b30b-465f-937f-bc5bdb1ff31c","html_url":"https://github.com/fluture-js/fluture-node","commit_stats":{"total_commits":62,"total_committers":2,"mean_commits":31.0,"dds":0.08064516129032262,"last_synced_commit":"f30d8f08220d1dab6f179fa4f0926e048a9d8549"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluture-js","download_url":"https://codeload.github.com/fluture-js/fluture-node/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248222135,"owners_count":21067720,"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":["buffer","events","fluture","http","https","nodejs","request","streams","timers"],"created_at":"2024-11-14T05:35:28.684Z","updated_at":"2025-04-10T12:55:54.995Z","avatar_url":"https://github.com/fluture-js.png","language":"JavaScript","readme":"# Fluture Node\n\nFP-style HTTP and streaming utils for Node based on [Fluture][].\n\nSkip to the [Http section](#http) for the main code example.\n\n## Usage\n\n```console\n$ npm install --save fluture fluture-node\n```\n\nOn Node 12 and up, this module can be loaded directly with `import` or\n`require`. On Node versions below 12, `require` or the [esm][]-loader can\nbe used.\n\n## API\n\n### EventEmitter\n\n#### \u003ca name=\"once\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L42\"\u003e`once :: String -⁠\u003e EventEmitter -⁠\u003e Future Error a`\u003c/a\u003e\n\nResolve a Future with the first event emitted over\nthe given event emitter under the given event name.\n\nWhen the Future is cancelled, it removes any trace of\nitself from the event emitter.\n\n```js\n\u003e const emitter = new EventEmitter ();\n\u003e setTimeout (() =\u003e emitter.emit ('answer', 42), 100);\n\u003e once ('answer') (emitter);\nFuture.of (42);\n```\n\n### Buffer\n\n#### \u003ca name=\"encode\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L76\"\u003e`encode :: Charset -⁠\u003e Buffer -⁠\u003e Future Error String`\u003c/a\u003e\n\nGiven an encoding and a [Buffer][], returns a Future of the result of\nencoding said buffer using the given encoding. The Future will reject\nwith an Error if the encoding is unknown.\n\n```js\n\u003e encode ('utf8') (Buffer.from ('Hello world!'));\n'Hello world!'\n```\n\n### Stream\n\n#### \u003ca name=\"streamOf\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L93\"\u003e`streamOf :: Buffer -⁠\u003e Future a (Readable Buffer)`\u003c/a\u003e\n\nGiven a [Buffer][], returns a Future of a [Readable][] stream which will\nemit the given Buffer before ending.\n\nThe stream is wrapped in a Future because creation of a stream causes\nside-effects if it's not consumed in time, making it safer to pass it\naround wrapped in a Future.\n\n#### \u003ca name=\"emptyStream\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L109\"\u003e`emptyStream :: Future a (Readable Buffer)`\u003c/a\u003e\n\nA [Readable][] stream which ends after emiting zero bytes. Can be useful\nas an empty [`Request`](#Request) body, for example.\n\n#### \u003ca name=\"buffer\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L115\"\u003e`buffer :: Readable a -⁠\u003e Future Error (Array a)`\u003c/a\u003e\n\nBuffer all data on a [Readable][] stream into a Future of an Array.\n\nWhen the Future is cancelled, it removes any trace of\nitself from the Stream.\n\n```js\n\u003e const stream = new Readable ({read: () =\u003e {}});\n\u003e setTimeout (() =\u003e {\n.   stream.push ('hello');\n.   stream.push ('world');\n.   stream.push (null);\n. }, 100);\n\u003e buffer (stream);\nFuture.of ([Buffer.from ('hello'), Buffer.from ('world')]);\n```\n\n#### \u003ca name=\"bufferString\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L154\"\u003e`bufferString :: Charset -⁠\u003e Readable Buffer -⁠\u003e Future Error String`\u003c/a\u003e\n\nA version of [`buffer`](#buffer) specialized in Strings.\n\nTakes a charset and a [Readable][] stream of [Buffer][]s, and returns\na Future containing a String with the fully buffered and encoded result.\n\n### Event Loop\n\n#### \u003ca name=\"instant\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L166\"\u003e`instant :: b -⁠\u003e Future a b`\u003c/a\u003e\n\nResolves a Future with the given value in the next tick,\nusing [`process.nextTick`][]. The scheduled job cannot be\ncancelled and will run before any other jobs, effectively\nblocking the event loop until it's completed.\n\n```js\n\u003e instant ('noodles')\nFuture.of ('noodles')\n```\n\n#### \u003ca name=\"immediate\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L182\"\u003e`immediate :: b -⁠\u003e Future a b`\u003c/a\u003e\n\nResolves a Future with the given value in the next tick,\nusing [`setImmediate`][]. This job will run as soon as all\nother jobs are completed. When the Future is cancelled, the\njob is unscheduled.\n\n```js\n\u003e immediate ('results')\nFuture.of ('results')\n```\n\n### Http\n\nThe functions below are to be used in compositions such as the one shown\nbelow, in order to cover a wide variety of HTTP-related use cases.\n\n```js\nimport {reject, map, chain, encase, fork} from 'fluture';\nimport {retrieve,\n        matchStatus,\n        followRedirects,\n        autoBufferResponse,\n        responseToError} from 'fluture-node';\n\nconst json = res =\u003e (\n  chain (encase (JSON.parse)) (autoBufferResponse (res))\n);\n\nconst notFound = res =\u003e (\n  chain (({message}) =\u003e reject (new Error (message))) (json (res))\n);\n\nretrieve ('https://api.github.com/users/Avaq') ({'User-Agent': 'Avaq'})\n.pipe (chain (followRedirects (20)))\n.pipe (chain (matchStatus (responseToError) ({200: json, 404: notFound})))\n.pipe (map (avaq =\u003e avaq.name))\n.pipe (fork (console.error) (console.log));\n```\n\nThe example above will either:\n\n1. log `\"Aldwin Vlasblom\"` to the terminal if nothing weird happens; or\n2. Report a 404 error using the message returned from the server; or\n3. log an error to the console if:\n    * a network error occurs;\n    * the response code is not what we expect; or\n    * the JSON is malformed.\n\nNote that we were in control of the following:\n\n- How redirects are followed: We use [`followRedirects`](#followRedirects)\n  with a maxmum of 20 redirects, but we could have used a different\n  redirection function using [`followRedirectsWith`](#followRedirectsWith)\n  with the [`aggressiveRedirectionPolicy`](#aggressiveRedirectionPolicy) or\n  even a fully custom policy.\n\n- How an unexpected status was treated: We passed in a handler to\n  [`matchStatus`](#matchStatus).\n  We used [`responseToError`](#responseToError), conviently provided by\n  this library, but we could have used a custom mechanism.\n\n- How responses with expected status codes are treated:\n  The [`matchStatus`](#matchStatus) function lets us provide a handler\n  based on the status code of the response. Each handler has full control\n  over the response.\n\n- How the response body is buffered and decoded: Our `json` function uses\n  [`autoBufferResponse`](#autoBufferResponse) to buffer and decode the\n  response according to the mime type provided in the headers. However, we\n  could have used lower level functions, such as\n  [`bufferResponse`](#bufferResponse) or even just [`buffer`](#buffer).\n\n- How the response body is parsed: We used [`Fluture.encase`][] with\n  [`JSON.parse`][] to parse JSON with a safe failure path. However, we\n  could have used a more refined approach to parsing the JSON, for\n  example by using [`S.parseJson`][].\n\nThe goal is to give you as much control over HTTP requests and responses\nas possible, while still keeping boilerplate low by leveraging function\ncomposition.\n\nThis contrasts with many of the popular HTTP client libraries out there,\nwhich either make decisions for you, taking away control in an attempt to\nprovide a smoother usage experience, or which take complicated structures\nof interacting options to attempt to cater to as many cases as possible.\n\n#### \u003ca name=\"Request\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L297\"\u003e`Request :: Object -⁠\u003e Url -⁠\u003e Future Error (Readable Buffer) -⁠\u003e Request`\u003c/a\u003e\n\nConstructs a value of type Request to be used as an argument for\nfunctions such as [`sendRequest`](#sendRequest).\n\nTakes the following arguments:\n\n1. An Object containing any [http options][] except: `auth`, `host`,\n   `hostname`, `path`, `port`, and `protocol`; because they are part of\n   the URL, and `signal`; because Fluture handles the cancellation.\n2. A String containing the request URL.\n3. A Future of a [Readable][] stream of [Buffer][]s to be used as the\n   request body. Note that the Future must produce a brand new Stream\n   every time it is forked, or if it can't, it is expected to reject\n   with a value of type Error.\n\nSee [`sendRequest`](#sendRequest) for a usage example.\n\n#### \u003ca name=\"Request.options\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L316\"\u003e`Request.options :: Request -⁠\u003e Object`\u003c/a\u003e\n\nGet the options out of a Request.\n\n#### \u003ca name=\"Request.url\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L321\"\u003e`Request.url :: Request -⁠\u003e Url`\u003c/a\u003e\n\nGet the url out of a Request.\n\n#### \u003ca name=\"Request.body\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L326\"\u003e`Request.body :: Request -⁠\u003e Future Error (Readable Buffer)`\u003c/a\u003e\n\nGet the body out of a Request.\n\n#### \u003ca name=\"Response\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L331\"\u003e`Response :: Request -⁠\u003e IncomingMessage -⁠\u003e Response`\u003c/a\u003e\n\nConstructs a value of type Response. These values are typically created\nfor you by functions such as [`sendRequest`](#sendRequest).\nTakes the following arguments:\n\n1. A [Request](#Request).\n2. An [IncomingMessage][] assumed to belong to the Request.\n\n#### \u003ca name=\"Response.request\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L341\"\u003e`Response.request :: Response -⁠\u003e Request`\u003c/a\u003e\n\nGet the request out of a Response.\n\n#### \u003ca name=\"Response.message\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L346\"\u003e`Response.message :: Response -⁠\u003e IncomingMessage`\u003c/a\u003e\n\nGet the message out of a Response.\n\n#### \u003ca name=\"sendRequest\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L373\"\u003e`sendRequest :: Request -⁠\u003e Future Error Response`\u003c/a\u003e\n\nThis is the \"lowest level\" function for making HTTP requests. It does not\nhandle buffering, encoding, content negotiation, or anything really.\nFor most use cases, you can use one of the more specialized functions:\n\n* [`send`](#send): Make a generic HTTP request.\n* [`retrieve`](#retrieve): Make a GET request.\n\nGiven a [Request](#Request), returns a Future which makes an HTTP request\nand resolves with the resulting [Response](#Response).\nIf the Future is cancelled, the request is aborted.\n\n```js\nimport {attempt} from 'fluture';\nimport {createReadStream} from 'fs';\n\nconst BinaryPostRequest = Request ({\n  method: 'POST',\n  headers: {'Transfer-Encoding': 'chunked'},\n});\n\nconst eventualBody = attempt (() =\u003e createReadStream ('./data.bin'));\n\nsendRequest (BinaryPostRequest ('https://example.com') (eventualBody));\n```\n\nIf you want to use this function to transfer a stream of data, don't forget\nto set the Transfer-Encoding header to \"chunked\".\n\n#### \u003ca name=\"retrieve\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L422\"\u003e`retrieve :: Url -⁠\u003e StrMap String -⁠\u003e Future Error Response`\u003c/a\u003e\n\nA version of [`sendRequest`](#sendRequest) specialized in the `GET` method.\n\nGiven a URL and a StrMap of request headers, returns a Future which\nmakes a GET requests to the given resource.\n\n```js\nretrieve ('https://api.github.com/users/Avaq') ({'User-Agent': 'Avaq'})\n```\n\n#### \u003ca name=\"send\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L436\"\u003e`send :: Mimetype -⁠\u003e Method -⁠\u003e Url -⁠\u003e StrMap String -⁠\u003e Buffer -⁠\u003e Future Error Response`\u003c/a\u003e\n\nA version of [`sendRequest`](#sendRequest) for sending arbitrary data to\na server. There's also more specific versions for sending common types of\ndata:\n\n* [`sendJson`](#sendJson) sends JSON stringified data.\n* [`sendForm`](#sendForm) sends form encoded data.\n\nGiven a MIME type, a request method, a URL, a StrMap of headers, and\nfinally a Buffer, returns a Future which will send the Buffer to the\nserver at the given URL using the given request method, telling it the\nbuffer contains data of the given MIME type.\n\nThis function will always send the Content-Type and Content-Length headers,\nalongside the provided headers. Manually provoding either of these headers\noverride those generated by this function.\n\n#### \u003ca name=\"sendJson\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L461\"\u003e`sendJson :: Method -⁠\u003e String -⁠\u003e StrMap String -⁠\u003e JsonValue -⁠\u003e Future Error Response`\u003c/a\u003e\n\nA version of [`send`](#send) specialized in sending JSON.\n\nGiven a request method, a URL, a StrMap of headers and a JavaScript plain\nobject, returns a Future which sends the object to the server at the\ngiven URL after JSON-encoding it.\n\n```js\nsendJson ('PUT')\n         ('https://example.com/users/bob')\n         ({Authorization: 'Bearer asd123'})\n         ({name: 'Bob', email: 'bob@example.com'});\n```\n\n#### \u003ca name=\"sendForm\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L480\"\u003e`sendForm :: Method -⁠\u003e String -⁠\u003e StrMap String -⁠\u003e JsonValue -⁠\u003e Future Error Response`\u003c/a\u003e\n\nA version of [`send`](#send) specialized in sending form data.\n\nGiven a request method, a URL, a StrMap of headers and a JavaScript plain\nobject, returns a Future which sends the object to the server at the\ngiven URL after www-form-urlencoding it.\n\n```js\nsendForm ('POST')\n         ('https://example.com/users/create')\n         ({})\n         ({name: 'Bob', email: 'bob@example.com'});\n```\n\n#### \u003ca name=\"matchStatus\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L499\"\u003e`matchStatus :: (Response -⁠\u003e a) -⁠\u003e StrMap (Response -⁠\u003e a) -⁠\u003e Response -⁠\u003e a`\u003c/a\u003e\n\nTransform a [`Response`](#Response) based on its status code.\n\n```js\nimport {chain} from 'fluture';\n\nconst processResponse = matchStatus (responseToError) ({\n  200: autoBufferResponse,\n});\n\nchain (processResponse) (retreive ('https://example.com'));\n```\n\nThis is kind of like a `switch` statement on the status code of the\nResponse message. Or, if you will, a pattern match against the\nResponse type if you imagine it being tagged via the status code.\n\nThe first argument is the \"default\" case, and the second argument is a\nmap of status codes to functions that should have the same type as the\nfirst argument.\n\nThe resulting function `Response -\u003e a` has the same signature as the input\nfunctions, meaning you can use `matchStatus` *again* to \"extend\" the\npattern by passing the old pattern as the \"default\" case for the new one:\n\n```js\nimport {reject} from 'fluture';\n\nmatchStatus (processResponse) ({\n  404: () =\u003e reject (new Error ('Example not found!')),\n});\n```\n\n#### \u003ca name=\"redirectAnyRequest\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L569\"\u003e`redirectAnyRequest :: Response -⁠\u003e Request`\u003c/a\u003e\n\nA redirection strategy that simply reissues the original Request to the\nLocation specified in the given Response.\n\nIf the new location is on an external host, then any confidential headers\n(such as the cookie header) will be dropped from the new request.\n\nUsed in the [`defaultRedirectionPolicy`](#defaultRedirectionPolicy) and\nthe [`aggressiveRedirectionPolicy`](#aggressiveRedirectionPolicy).\n\n#### \u003ca name=\"redirectIfGetMethod\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L593\"\u003e`redirectIfGetMethod :: Response -⁠\u003e Request`\u003c/a\u003e\n\nA redirection strategy that simply reissues the original Request to the\nLocation specified in the given Response, but only if the original request\nwas using the GET method.\n\nIf the new location is on an external host, then any confidential headers\n(such as the cookie header) will be dropped from the new request.\n\nUsed in [`followRedirectsStrict`](#followRedirectsStrict).\n\n#### \u003ca name=\"redirectUsingGetMethod\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L612\"\u003e`redirectUsingGetMethod :: Response -⁠\u003e Request`\u003c/a\u003e\n\nA redirection strategy that sends a new GET request based on the original\nrequest to the Location specified in the given Response. If the response\ndoes not contain a valid location, the request is not redirected.\n\nThe original request method and body are discarded, but other options\nare preserved. If the new location is on an external host, then any\nconfidential headers (such as the cookie header) will be dropped from the\nnew request.\n\nUsed in the [`defaultRedirectionPolicy`](#defaultRedirectionPolicy) and\nthe [`aggressiveRedirectionPolicy`](#aggressiveRedirectionPolicy).\n\n#### \u003ca name=\"retryWithoutCondition\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L642\"\u003e`retryWithoutCondition :: Response -⁠\u003e Request`\u003c/a\u003e\n\nA redirection strategy that removes any caching headers if present and\nretries the request, or does nothing if no caching headers were present\non the original request.\n\nUsed in the [`defaultRedirectionPolicy`](#defaultRedirectionPolicy).\n\n#### \u003ca name=\"defaultRedirectionPolicy\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L658\"\u003e`defaultRedirectionPolicy :: Response -⁠\u003e Request`\u003c/a\u003e\n\nCarefully follows redirects in strict accordance with\n[RFC2616 Section 10.3][].\n\nRedirections with status codes 301, 302, and 307 are only followed if the\noriginal request used the GET method, and redirects with status code 304\nare left alone for a caching layer to deal with.\n\nThis redirection policy is used by default in the\n[`followRedirects`](#followRedirects) function. You can extend it, using\n[`matchStatus`](#matchStatus) to create a custom redirection policy, as\nshown in the example:\n\nSee also [`aggressiveRedirectionPolicy`](#aggressiveRedirectionPolicy).\n\n```js\nconst redirectToBestOption = () =\u003e {\n  // Somehow figure out which URL to redirect to.\n};\n\nconst myRedirectionPolicy = matchStatus (defaultRedirectionPolicy) ({\n  300: redirectToBestOption,\n  301: redirectUsingGetMethod,\n});\n\nretrieve ('https://example.com') ({})\n.pipe (chain (followRedirectsWith (myRedirectionPolicy) (10)))\n```\n\n#### \u003ca name=\"aggressiveRedirectionPolicy\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L695\"\u003e`aggressiveRedirectionPolicy :: Response -⁠\u003e Request`\u003c/a\u003e\n\nAggressively follows redirects in mild violation of\n[RFC2616 Section 10.3][]. In particular, anywhere that a redirection\nshould be interrupted for user confirmation or caching, this policy\nfollows the redirection nonetheless.\n\nRedirections with status codes 301, 302, and 307 are always followed\nwithout user intervention, and redirects with status code 304 are\nretried without conditions if the original request had any conditional\nheaders.\n\nSee also [`defaultRedirectionPolicy`](defaultRedirectionPolicy).\n\n```js\nretrieve ('https://example.com') ({})\n.pipe (chain (followRedirectsWith (aggressiveRedirectionPolicy) (10)))\n```\n\n#### \u003ca name=\"followRedirectsWith\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L732\"\u003e`followRedirectsWith :: (Response -⁠\u003e Request) -⁠\u003e Number -⁠\u003e Response -⁠\u003e Future Error Response`\u003c/a\u003e\n\nGiven a function that take a Response and produces a new Request, and a\n\"maximum\" number, recursively keeps resolving new requests until a request\nis encountered that was seen before, or the maximum number is reached.\n\nSee [`followRedirects`](#followRedirects) for an out-of-the-box redirect-\nfollower. See [`aggressiveRedirectionPolicy`](#aggressiveRedirectionPolicy)\nand [`defaultRedirectionPolicy`](defaultRedirectionPolicy) for\nadditional usage examples.\n\n#### \u003ca name=\"followRedirects\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L764\"\u003e`followRedirects :: Number -⁠\u003e Response -⁠\u003e Future Error Response`\u003c/a\u003e\n\nGiven the maximum numbers of redirections, follows redirects according to\nthe [default redirection policy](#defaultRedirectionPolicy).\n\nSee the [Http section](#http) for a usage example.\n\n#### \u003ca name=\"acceptStatus\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L772\"\u003e`acceptStatus :: Number -⁠\u003e Response -⁠\u003e Future Response Response`\u003c/a\u003e\n\nThis function \"tags\" a [Response](#Response) based on a given status code.\nIf the response status matches the given status code, the returned Future\nwill resolve. If it doesn't, the returned Future will reject.\n\nSee also [`matchStatus`](#matchStatus), which will probably be more useful\nin most cases.\n\nThe idea is that you can compose this function with one that returns a\nResponse, and reject any responses that don't meet the expected status\ncode.\n\nIn combination with [`responseToError`](#responseToError), you can then\nflatten it back into the outer Future. The usage example under the\n[Http](#http) section shows this.\n\n#### \u003ca name=\"bufferMessage\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L790\"\u003e`bufferMessage :: Charset -⁠\u003e IncomingMessage -⁠\u003e Future Error String`\u003c/a\u003e\n\nA version of [`buffer`](#buffer) specialized in [IncomingMessage][]s.\n\nSee also [`bufferResponse`](#bufferResponse) and\n[`autoBufferMessage`](#autoBufferMessage).\n\nGiven a charset and an IncomingMessage, returns a Future with the buffered,\nencoded, message body.\n\n#### \u003ca name=\"bufferResponse\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L804\"\u003e`bufferResponse :: Charset -⁠\u003e Response -⁠\u003e Future Error String`\u003c/a\u003e\n\nA composition of [`Response.message`](#Response.message) and\n[`bufferMessage`](#bufferMessage) for your convenience.\n\nSee also [autoBufferResponse](#autoBufferResponse).\n\n#### \u003ca name=\"autoBufferMessage\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L814\"\u003e`autoBufferMessage :: IncomingMessage -⁠\u003e Future Error String`\u003c/a\u003e\n\nGiven an IncomingMessage, buffers and decodes the message body using the\ncharset provided in the message headers. Falls back to UTF-8 if the\ncharset was not provided.\n\nReturns a Future with the buffered, encoded, message body.\n\nSee also [bufferMessage](#bufferMessage).\n\n#### \u003ca name=\"autoBufferResponse\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L830\"\u003e`autoBufferResponse :: Response -⁠\u003e Future Error String`\u003c/a\u003e\n\nA composition of [`Response.message`](#Response.message) and\n[`autoBufferMessage`](#autoBufferMessage) for your convenience.\n\nSee also [bufferResponse](#bufferResponse).\n\n#### \u003ca name=\"responseToError\" href=\"https://github.com/fluture-js/fluture-node/blob/v4.0.3/index.js#L840\"\u003e`responseToError :: Response -⁠\u003e Future Error a`\u003c/a\u003e\n\nGiven a [Response](#Response), returns a *rejected* Future of an instance\nof Error with a message based on the content of the response.\n\n[`process.nextTick`]: https://nodejs.org/api/process.html#process_process_nexttick_callback_args\n[`setImmediate`]: https://nodejs.org/api/timers.html#timers_setimmediate_callback_args\n[`S.parseJson`]: https://sanctuary.js.org/#parseJson\n[`Fluture.encase`]: https://github.com/fluture-js/Fluture#encase\n[`JSON.parse`]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse\n\n[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer\n[Fluture]: https://github.com/fluture-js/Fluture\n[http options]: https://nodejs.org/api/http.html#http_http_request_url_options_callback\n[IncomingMessage]: https://nodejs.org/api/http.html#http_class_http_incomingmessage\n[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable\n\n[RFC2616 Section 10.3]: https://tools.ietf.org/html/rfc2616#section-10.3\n[esm]: https://github.com/standard-things/esm\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluture-js%2Ffluture-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluture-js%2Ffluture-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluture-js%2Ffluture-node/lists"}