{"id":20208378,"url":"https://github.com/fluture-js/fluture-express","last_synced_at":"2025-07-18T04:36:26.808Z","repository":{"id":52291816,"uuid":"117820838","full_name":"fluture-js/fluture-express","owner":"fluture-js","description":":steam_locomotive: Create Express middleware using Futures","archived":false,"fork":false,"pushed_at":"2021-05-01T08:31:55.000Z","size":243,"stargazers_count":29,"open_issues_count":1,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-23T11:18:32.671Z","etag":null,"topics":["express","express-middleware","fluture","functional-programming"],"latest_commit_sha":null,"homepage":null,"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}},"created_at":"2018-01-17T10:24:57.000Z","updated_at":"2021-05-03T02:49:56.000Z","dependencies_parsed_at":"2022-08-30T00:11:08.325Z","dependency_job_id":null,"html_url":"https://github.com/fluture-js/fluture-express","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/fluture-js/fluture-express","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-express","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-express/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-express/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-express/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluture-js","download_url":"https://codeload.github.com/fluture-js/fluture-express/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluture-js%2Ffluture-express/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265701129,"owners_count":23813751,"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":["express","express-middleware","fluture","functional-programming"],"created_at":"2024-11-14T05:35:21.084Z","updated_at":"2025-07-18T04:36:26.789Z","avatar_url":"https://github.com/fluture-js.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fluture Express\n\n[![NPM Version](https://badge.fury.io/js/fluture-express.svg)](https://www.npmjs.com/package/fluture-express)\n[![Dependencies](https://david-dm.org/fluture-js/fluture-express.svg)](https://david-dm.org/fluture-js/fluture-express)\n[![Code Coverage](https://codecov.io/gh/fluture-js/fluture-express/branch/master/graph/badge.svg)](https://codecov.io/gh/fluture-js/fluture-express)\n\nCreate Express middleware using Futures from [Fluture][].\n\nAllows for the definition of pure functions to be used as Express\nmiddleware. This has benefits for testing and developer sanity.\nAnother benefit of this particular approach, where every middleware is\nwrapped individually, is that it plays nicely with existing Express\nmiddleware, and they can be used interchangably.\n\n## Usage\n\n### Node\n\n```console\n$ npm install --save fluture-express\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### Deno and Modern Browsers\n\nYou can load the EcmaScript module from various content delivery networks:\n\n- [Skypack](https://cdn.skypack.dev/fluture-express@6.0.1)\n- [JSPM](https://jspm.dev/fluture-express@6.0.1)\n- [jsDelivr](https://cdn.jsdelivr.net/npm/fluture-express@6.0.1/+esm)\n\n### Usage Example\n\n```js\n// index.js\n\nconst {dispatcher} = require ('fluture-express');\nconst app = require ('express') ();\nconst dispatch = dispatcher ('./actions');\n\napp.use (dispatch ('welcome'));\napp.listen (3000);\n```\n\n```js\n// actions/welcome.js\n\nconst {Json} = require ('fluture-express');\nconst Future = require ('fluture');\n\nmodule.exports = locals =\u003e req =\u003e Future.go (function* () {\n  const user = yield locals.database.find ('sessions', locals.session.id);\n  return withStatus (418) (Json ({welcome: user.name}));\n});\n```\n\nFor a more in-depth example, see the `example` directory.\n\n## Documentation\n\n### Pseudo types\n\n#### `Req`\n\nThe Express Request object.\n\n#### `Res a`\n\nThe Express Response object with a `locals` property of type `a`.\n\n### The Response type\n\nFluture-Express mutates the response object for you, based on a\nspecification of what the response should be. This specification is\ncaptured by the Response sum-type.\n\n#### \u003ca name=\"Response\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L164\"\u003e`Response :: Type`\u003c/a\u003e\n\nThe Response sum type encoded with [daggy][]. You probably don't need to\nuse this directly.\n\n```hs\ndata Response a b = Respond (Array Head) (Body a)\n                  | Next b\n```\n\n#### \u003ca name=\"Head\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L180\"\u003e`Head :: Type`\u003c/a\u003e\n\nThe Head sum type encoded with [daggy][]. You probably don't need to\nuse this directly.\n\n```hs\ndata Head = Status Number\n          | Type String\n          | Location String\n          | Links (StrMap String)\n          | Cookie String String Object\n          | ClearCookie String Object\n          | HeaderPart String String\n          | Header String String\n```\n\n#### \u003ca name=\"Body\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L208\"\u003e`Body :: Type`\u003c/a\u003e\n\nThe Body sum type encoded with [daggy][]. You probably don't need to\nuse this directly.\n\n```hs\ndata Body a = None\n            | Send Any\n            | Json JsonValue\n            | Stream (Future a Readable)\n            | Render String Object\n```\n\n#### \u003ca name=\"Stream -\u003e Future a Readable -\u003e Response a b\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L238\"\u003e`Stream -⁠\u003e Future a Readable -⁠\u003e Response a b`\u003c/a\u003e\n\nCreates a streamed response given a mime type and a Future that produces\na Readable Stream when consumed. The Future is expected to produce a new\nStream every time it's consumed, or if it can't, reject with a value that\nyour Express error handler can handle.\n\nUses a Content-Type of `application/octet-stream` unless overridden by\n[`withType`](#withType), [`withHeader`](#withHeader),\nor [`withoutHeader`](#withoutHeader).\n\n#### \u003ca name=\"Text\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L253\"\u003e`Text :: String -⁠\u003e Response a b`\u003c/a\u003e\n\nIndicates a textual response.\n\nUses a Content-Type of `text/plain` unless overridden by\n[`withType`](#withType), [`withHeader`](#withHeader),\nor [`withoutHeader`](#withoutHeader).\n\n#### \u003ca name=\"Json\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L265\"\u003e`Json :: JsonValue -⁠\u003e Response a b`\u003c/a\u003e\n\nIndicates a JSON response.\n\nUses a Content-Type of `application/json` unless overridden by\n[`withType`](#withType), [`withHeader`](#withHeader).\n\n#### \u003ca name=\"Render\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L276\"\u003e`Render :: String -⁠\u003e Object -⁠\u003e Response a b`\u003c/a\u003e\n\nIndicates a response to be rendered using a template. The first argument\nis the path to the template file, and the second is the data to inject into\nthe template. This uses Express' render method under the hood, so you can\nconfigure it globally with `app.set ('view engine', engine)` and\n`app.set ('views', path)`.\n\n#### \u003ca name=\"Redirect\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L288\"\u003e`Redirect :: String -⁠\u003e Response a b`\u003c/a\u003e\n\nIndicates a redirection. The first argument will be the response status\ncode, and the second will be the value of the Location header.\n\nUnless overridden by [`withStatus`](#withStatus), the status code will be\nset to 301 (Moved Permanently).\n\n#### \u003ca name=\"Empty\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L300\"\u003e`Empty :: Response a b`\u003c/a\u003e\n\nIndicates an empty response. The response status will be set to 204, and\nno response body or Content-Type header will be sent.\n\n#### \u003ca name=\"Next\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L309\"\u003e`Next :: b -⁠\u003e Response a b`\u003c/a\u003e\n\nIndicates that this middleware does not form a response. The supplied value\nwill be assigned to `res.locals` and the next middleware will be called.\n\n#### \u003ca name=\"withStatus\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L315\"\u003e`withStatus :: Number -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the status code by setting up a call to [`res.status`][].\n\n#### \u003ca name=\"withType\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L326\"\u003e`withType :: String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the Content-Type by setting up a call to [`res.type`][].\n\n#### \u003ca name=\"withLocation\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L337\"\u003e`withLocation :: String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the Location header by setting up a call to [`res.location`][].\n\n#### \u003ca name=\"withLinks\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L348\"\u003e`withLinks :: StrMap String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the Link header by setting up a call to [`res.links`][].\n\n#### \u003ca name=\"withCookie\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L359\"\u003e`withCookie :: CookieOptions -⁠\u003e String -⁠\u003e String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the Set-Cookie header by setting up a call to [`res.cookie`][].\n\n#### \u003ca name=\"withClearCookie\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L370\"\u003e`withClearCookie :: CookieOptions -⁠\u003e String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure the Set-Cookie header by setting up a call to\n[`res.clearCookie`][].\n\n#### \u003ca name=\"withHeaderPart\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L382\"\u003e`withHeaderPart :: String -⁠\u003e String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nAppend to a header by setting up a call to [`res.append`][].\n\n#### \u003ca name=\"withHeader\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L393\"\u003e`withHeader :: String -⁠\u003e String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nConfigure a header by setting up a call to [`res.set`][].\n\n#### \u003ca name=\"withoutHeader\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L404\"\u003e`withoutHeader :: String -⁠\u003e Response a b -⁠\u003e Response a b`\u003c/a\u003e\n\nRemoves a header from the Response. Also removes headers that would be\nset by functions like [`withType`](#withType). For example:\n\n```js\n\u003e withoutHeader ('Content-Type') (withType ('json') (Empty))\nEmpty\n```\n\n### Middleware creation utilities\n\n#### \u003ca name=\"middleware\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L429\"\u003e`middleware :: (b -⁠\u003e Req -⁠\u003e Future a (Response a c)) -⁠\u003e (Req, Res b, (a -⁠\u003e Undefined)) -⁠\u003e Undefined`\u003c/a\u003e\n\nConverts an action to an Express middleware.\n\nTakes a function that returns a [Future][] of a [Response][], and returns\nan Express middleware that uses the returned structure to make the\nappropriate mutations to the [`res`][].\n\nIf the Future rejects, the rejection reason is passed into `next` for\nfurther [error handling with Express][].\n\n#### \u003ca name=\"dispatcher\" href=\"https://github.com/fluture-js/fluture-express/blob/v6.0.1/index.js#L443\"\u003e`dispatcher :: String -⁠\u003e String -⁠\u003e (Req, Res a, (Any -⁠\u003e Undefined)) -⁠\u003e Promise Undefined`\u003c/a\u003e\n\nCreates middleware that uses the export from the given file in the given\ndirectory as an \"action\".\n\nIt takes the file in two steps for convenience. You are encouraged to use\nthe first parameter to set up a sub-directory where all your actions live.\n\nThe exported value should be a function of the same signature as given to\n[`middleware`][].\n\n[Fluture]: https://github.com/fluture-js/Fluture\n[Future]: https://github.com/fluture-js/Fluture#future\n[Response]: #the-response-type\n[`middleware`]: #middleware\n[`res`]: #res-a\n[error handling with Express]: https://expressjs.com/en/guide/error-handling.html\n[daggy]: https://github.com/fantasyland/daggy\n[esm]: https://github.com/standard-things/esm\n\n[`res.status`]: https://expressjs.com/en/4x/api.html#res.status\n[`res.type`]: https://expressjs.com/en/4x/api.html#res.type\n[`res.location`]: https://expressjs.com/en/4x/api.html#res.location\n[`res.links`]: https://expressjs.com/en/4x/api.html#res.links\n[`res.cookie`]: https://expressjs.com/en/4x/api.html#res.cookie\n[`res.clearCookie`]: https://expressjs.com/en/4x/api.html#res.clearCookie\n[`res.append`]: https://expressjs.com/en/4x/api.html#res.append\n[`res.set`]: https://expressjs.com/en/4x/api.html#res.set\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluture-js%2Ffluture-express","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluture-js%2Ffluture-express","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluture-js%2Ffluture-express/lists"}