{"id":14969169,"url":"https://github.com/fastify/fastify-funky","last_synced_at":"2025-04-04T20:06:27.934Z","repository":{"id":36982568,"uuid":"315070922","full_name":"fastify/fastify-funky","owner":"fastify","description":"Make fastify functional! Plugin, adding support for fastify routes returning functional structures, such as Either, Task or plain parameterless function","archived":false,"fork":false,"pushed_at":"2025-03-07T19:14:28.000Z","size":137,"stargazers_count":84,"open_issues_count":1,"forks_count":6,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-03-28T19:09:40.204Z","etag":null,"topics":["fastify","fastify-plugin","functional-programming"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@fastify/funky","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/fastify.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"fastify","open_collective":"fastify"}},"created_at":"2020-11-22T15:37:19.000Z","updated_at":"2025-03-18T17:21:20.000Z","dependencies_parsed_at":"2023-01-17T11:32:07.024Z","dependency_job_id":"2f0c12b5-b3d6-405f-b2ba-c662816b63fe","html_url":"https://github.com/fastify/fastify-funky","commit_stats":{"total_commits":132,"total_committers":12,"mean_commits":11.0,"dds":"0.49242424242424243","last_synced_commit":"020bfecc6fc5870a1e040a2c7fb17b65173a78e0"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-funky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-funky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-funky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-funky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fastify","download_url":"https://codeload.github.com/fastify/fastify-funky/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242669,"owners_count":20907133,"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":["fastify","fastify-plugin","functional-programming"],"created_at":"2024-09-24T13:41:16.189Z","updated_at":"2025-04-04T20:06:27.892Z","avatar_url":"https://github.com/fastify.png","language":"JavaScript","readme":"# @fastify/funky\n\n[![NPM Version][npm-image]][npm-url]\n[![CI](https://github.com/fastify/fastify-funky/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fastify-funky/actions/workflows/ci.yml)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)\n\nSupport for Fastify routes returning functional structures, such as `fp-ts` Either, Task, TaskEither, or plain JavaScript parameterless functions.\nLet's go funky, let's go functional!\n\n## Getting started\n\nFirst, install the package:\n\n```bash\nnpm i @fastify/funky\n```\n\nNext, set up the plugin:\n\n```js\nconst { fastifyFunky } = require('@fastify/funky')\nconst fastify = require('fastify');\n\nfastify.register(fastifyFunky);\n```\n\n`@fastify/funky` plugin is executed during `preSerialization` response lifecycle phase.\n\n## Supported structures\n\nWhile the most convenient way to use this plugin is with `fp-ts` library, it is not required.\n`@fastify/funky` supports the following data structures:\n\n### Parameterless functions:\n\n```js\napp.get('/', (req, reply) =\u003e {\n  // This will result in a response 200: { id: 1}\n  return () =\u003e { return { id: 1} }\n\n  // Same as above\n  return () =\u003e { return { right:\n  { id: 1 }\n  }}\n\n  // Same as above\n  return () =\u003e { return Promise.resolve({ id: 1 })}\n\n  // Same as above\n  return () =\u003e { return Promise.resolve({ right:\n      { id: 1 }\n  })}\n\n  // Plugin will pass-through this value without doing anything\n  return (id) =\u003e { return Promise.resolve({ id })}\n});\n```\n\nIf the function returns an `Either` object, it will be handled in the same way as if you returned that `Either` object directly.\n\nIf the function returns a Promise, it will be resolved. If Promise resolves to an `Either` object, it will be handled in the same way as if you returned that `Either` object directly.\n\nIf the function directly returns anything else, or if its Promise resolves to anything else, that result is passed further along the chain as the plugin execution result.\n\nNote that functions with parameters will be ignored by the plugin and passed-through as-is.\n\n### `Either` objects:\n\nRight value is passed further along the chain as the plugin execution result:\n\n```js\napp.get('/', (req, reply) =\u003e {\n  // This will result in a response 200: { id: 1}\n  return { right:\n           { id: 1 }\n         }\n});\n```\n\nLeft value is passed to the error handler:\n\n```js\napp.get('/', (req, reply) =\u003e {\n  // This will propagate to fastify error handler, which by default will result in a response 500: Internal server error\n  return { left: new Error('Invalid state') }\n});\n```\n\n## Using with fp-ts\n\nWith the plugin registered, you can start returning entities of type Either, Task, or plain parameterless functions as router method results:\n\n```js\nconst { either, task, taskEither } = require('fp-ts')\n\napp.get('/', (req, reply) =\u003e {\n  // This will result in a response 200: { id: 1}\n  return either.right({ id: 1})\n\n  // Same as above\n  return task.of(Promise.resolve({ id: 1}))\n\n  // Same as above\n  return taskEither.fromEither(either.right({ id: 1}))\n\n  // Same as above\n  return taskEither.fromTask(task.of(Promise.resolve({ id: 1})))\n\n  // Same as above\n  return () =\u003e { return { id: 1} }\n\n  // This will propagate to fastify error handler, which by default will result in a response 500: Internal server error\n  return either.left(new Error('Invalid state'))\n\n  // Same as above\n  return taskEither.fromEither(either.left(new Error('Invalid state')))\n});\n```\n\n## License\n\nLicensed under [MIT](./LICENSE).\n\n[npm-image]: https://img.shields.io/npm/v/@fastify/funky.svg\n[npm-url]: https://npmjs.com/package/@fastify/funky\n[downloads-image]: https://img.shields.io/npm/dm/fastify-funky.svg\n[downloads-url]: https://npmjs.org/package/@fastify/funky\n","funding_links":["https://github.com/sponsors/fastify","https://opencollective.com/fastify"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-funky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffastify%2Ffastify-funky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-funky/lists"}