{"id":28732337,"url":"https://github.com/goodrequest/express-joi-to-swagger","last_synced_at":"2026-05-11T07:31:47.845Z","repository":{"id":45959775,"uuid":"341833905","full_name":"GoodRequest/express-joi-to-swagger","owner":"GoodRequest","description":"Simple tool for generating swagger API documentation from source code.","archived":false,"fork":false,"pushed_at":"2025-01-09T07:58:11.000Z","size":2195,"stargazers_count":21,"open_issues_count":1,"forks_count":7,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-13T14:21:49.302Z","etag":null,"topics":["backend","express","nodejs","swagger","typescript","web-utils"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoodRequest.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-02-24T08:41:51.000Z","updated_at":"2025-03-04T19:45:53.000Z","dependencies_parsed_at":"2023-09-28T18:48:15.607Z","dependency_job_id":"fdd64f1e-d3b7-4576-8719-de9ce30075cf","html_url":"https://github.com/GoodRequest/express-joi-to-swagger","commit_stats":{"total_commits":103,"total_committers":6,"mean_commits":"17.166666666666668","dds":"0.27184466019417475","last_synced_commit":"4824a12c5ffd6b646043f6cbfa25750f557212f7"},"previous_names":[],"tags_count":61,"template":false,"template_full_name":null,"purl":"pkg:github/GoodRequest/express-joi-to-swagger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodRequest%2Fexpress-joi-to-swagger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodRequest%2Fexpress-joi-to-swagger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodRequest%2Fexpress-joi-to-swagger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodRequest%2Fexpress-joi-to-swagger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoodRequest","download_url":"https://codeload.github.com/GoodRequest/express-joi-to-swagger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodRequest%2Fexpress-joi-to-swagger/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260046683,"owners_count":22950894,"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":["backend","express","nodejs","swagger","typescript","web-utils"],"created_at":"2025-06-15T20:42:04.435Z","updated_at":"2026-05-11T07:31:47.812Z","avatar_url":"https://github.com/GoodRequest.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Welcome to express-joi-to-swagger\n\n## Description\nSolution that generates beatiful Swagger API documentation from code. 💻\n\nIt lists all of endpoints registred within [app](https://expressjs.com/) with their routes, [methods](https://expressjs.com/en/guide/routing.html), relevant middlewares.\n\nWhen it comes to generating 📑**Swagger documentation**, you have two options. Generate [Swagger UI](https://swagger.io/tools/swagger-ui/) that can be served as a static file within your application,\nor keep documentation as **data.json** file within defined  📁location.\n\nFor more information see **Config parameters** bellow ⬇.\n\nThis simple tool does not require you to write any more code that necessary. Documentation is generated from source code itself\nwithout using annotations or separate doc files.\n\n## Migration guides\n\n- [Middlewares migration from v1 to v2](docs/middlewaresMigration.md) \n\n## Installation\n\nUse the package manager (*npm* or *yarn*) to install dependencies.\n\n```bash\nnpm install @goodrequest/express-joi-to-swagger\nor\nyarn add @goodrequest/express-joi-to-swagger\n```\n\n## Requirements\n✖ This solution is suitable for everybody who uses [Express](http://expressjs.com/) in a combination with [Joi](https://joi.dev/) to build application's API.\nThis version was developed and tested on versions 17.x.x of Joi. For version 14.x.x we have parallel branch **v14**. For proper functioning it is also necessary to \nuse Typescipt version 3.7.5 and higher. \n\n✖ As mentioned before, it is not needed to use annotations in your code, however to make this tool works properly you need to\nobey some coding practices. You need define at least one [router](https://expressjs.com/en/guide/routing.html) in your application. If you want to include\nrequest and response Joi schemas in a documentation they need to be named the same and exported.\n\n✖ If you are using [middleware](https://expressjs.com/en/guide/using-middleware.html) for user authorization and wish to include\nendpoint permissions in the documentation as well you need to name the function responsible for handling this and provide permissions\narray as its input parameter.\n\nYou can find simple examples of all mentioned in the demo folder of this repository. Quick usage example can also be found below ⬇.\n\n\n## Config parameters\n\n| Name\t\t\t\t\t\t\t\t\t\t                            | Type\t\t\t       | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |\n|-------------------------------------------|---------------|:--------:|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **outputPath**\t\t\t\t\t\t\t                     | string\t\t      | \t✅\t| Path to directory where output JSON file should be created.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |\n| **generateUI**\t\t\t\t\t\t\t                     | boolean\t\t     | \t✅\t| Whether [Swagger UI](https://swagger.io/tools/swagger-ui/) should be generated.                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| **middlewares**\t\t\t\t\t\t\t                    | object\t\t      | \t❌\t| Configuration parameters for parsing middlewares.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |\n| **middlewares**.formatter\t\t\t\t\t            | function\t\t    | \t❌\t| Custom formatter function for middleware. If not provided, the default one will be used.                                                                                                                                                                                                                                                                                                                                                                                                                                   |\n| **middlewares**.middlewareName\t\t\t         | string\t\t      | \t✅\t| Name of the middleware.                                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| **middlewares**.closure\t\t\t\t\t              | string\t\t      | \t✅\t| Name of the middleware closure.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |\n| **middlewares**.maxParamDepth\t\t\t\t\t              | number\t\t      | \t❌\t| Max depth of middleware parameter. Default value is 5.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |\n| **requestSchemaName**\t\t\t\t\t\t               | string\t\t      | \t❌\t| Name of the Joi schema object defining request structure.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| **responseSchemaName**\t\t\t\t\t               | string\t\t      | \t❌\t| Name of the Joi schema object defining response structure.                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |\n| **requestSchemaParams**\t\t\t\t\t              | any[]\t\t\t      | \t❌\t| Param for ability to pass mock params for requestSchema.                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |\n| **responseSchemaParams**\t\t\t\t\t             | any[]\t\t\t      | \t❌\t| Param for ability to pass mock params for responseSchema.                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| **errorResponseSchemaName**\t\t\t\t           | string\t\t      | \t❌\t| Name of the Joi schema object defining error responses structure.                                                                                                                                                                                                                                                                                                                                                                                                                                                          |\n| **businessLogicName**\t\t\t\t\t\t               | string\t\t      | \t✅\t| Name of the function responsible for handling business logic of the request.                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **swaggerInitInfo**\t\t\t\t\t\t                 | ISwaggerInit\t | \t❌\t| Swagger initial information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **swaggerInitInfo**.servers\t\t\t\t           | IServer[]\t\t   | \t❌\t| List of API servers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |\n| **swaggerInitInfo**.servers.url\t\t\t        | string\t\t      | \t❌\t| API server URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| **swaggerInitInfo**.info\t\t\t\t\t             | IInfo\t\t\t      | \t❌\t| Basic API information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |\n| **swaggerInitInfo**.info.description\t\t    | string\t\t      | \t❌\t| API description.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| **swaggerInitInfo**.info.version\t\t\t       | string\t\t      | \t❌\t| API version.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **swaggerInitInfo**.info.title\t\t\t         | string\t\t      | \t❌\t| API title.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |\n| **swaggerInitInfo**.info.termsOfService \t | string\t\t      | \t❌\t| Link to terms of service.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| **swaggerInitInfo**.info.contact\t\t\t       | IContact\t\t    | \t❌\t| Swagger initial information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **swaggerInitInfo**.info.contact.email\t   | string\t\t      | \t✅\t| Contact email.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |\n| **swaggerInitInfo**.info.license\t\t\t       | ILicense\t\t    | \t❌\t| Swagger initial information.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **swaggerInitInfo**.info.license.name\t\t   | string\t\t      | \t✅\t| License name.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |\n| **swaggerInitInfo**.info.license.url\t\t    | string\t\t      | \t✅\t| License url.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **tags**\t\t\t\t\t\t\t\t\t                         | string\t\t      | \t❌\t| Configuration parameters for parsing [tags](https://swagger.io/docs/specification/grouping-operations-with-tags/).                                                                                                                                                                                                                                                                                                                                                                                                         |\n| **tags**.baseUrlSegmentsLength \t\t\t        | number\t\t      | \t❌\t| Number of base URL segments.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| **tags**.joinTags \t\t\t\t\t\t                  | boolean\t\t     | \t❌\t| If set to true, array of parsed tags will be joined to string by **tagSeparator**, otherwise array of tags is returned.                                                                                                                                                                                                                                                                                                                                                                                                    |\n| **tags**.tagSeparator \t\t\t\t\t               | string\t\t      | \t❌\t| String used to join parsed tags.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| **tags**.versioning \t\t\t\t\t\t                | boolean\t\t     | \t❌\t| If you are using multiple versions of API, you can separate endpoints also by API version. In this case it is necessary to define param **\"baseUrlSegmentsLength\"**.                                                                                                                                                                                                                                                                                                                                                       |\n| **tags**.versionSeparator \t\t\t\t            | string\t\t      | \t❌\t| String used to separate parsed tags from API version tag is versioning == true.                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| **deprecationPathPattern**\t\t\t\t            | string\t\t      | \t❌\t| If provided, all versions of endpoints except latest will be marked as deprecated. \u003cbr\u003e Pattern needs to specify api route from start segment to version segment, which have to be specified as **\"v\\***\". \u003cbr\u003e For example if we have **api/v1/users** and **api/v2/users** endpoints and we set **deprecationPathPattern='/api/v\\*/'**, **api/v1/users** endpoint will be automatically marked as deprecated. For complex route schemas use pattern like **deprecationPathPattern='/api/.+/v\\*/'**, **api/b2b/v1/users** |\n\n\n## Usage example\n\n```Typescript\n// imports\nimport getSwagger from '@goodrequest/express-joi-to-swagger'\nimport path from 'path'\nimport app from './your-path-to-express-app'\n\n// Config example\nconst config: IConfig = {\n\toutputPath: path.join(__dirname, 'dist'),\n\tgenerateUI: true,\n\tmiddlewares: [\n\t\t{\n\t\t\tmiddlewareName: 'permission',\n\t\t\tclosure: 'permissionMiddleware',\n\t\t\tformatter: basicArrayFormatter,\n\t\t\tmaxParamDepth: 3\n\t\t},\n\t\t{\n\t\t\tmiddlewareName: 'validate',\n\t\t\tclosure: 'validationMiddleware'\n\t\t}\n\t],\n\trequestSchemaName: 'requestSchema',\n\trequestSchemaParams: [mockFn],\n\tresponseSchemaName: 'responseSchema',\n\terrorResponseSchemaName: 'errorResponseSchemas',\n\tbusinessLogicName: 'businessLogic',\n\tswaggerInitInfo: {\n\t\tinfo: {\n\t\t\tdescription: 'Generated Store',\n\t\t\ttitle: 'Test app'\n\t\t}\n\t},\n\ttags: {}\n}\n\n// Use case example\nfunction workflow() {\n\tgetSwagger(app, config).then(() =\u003e {\n\t\tconsole.log('Apidoc was successfully generated')\n\t}).catch((e) =\u003e {\n\t\tconsole.log(`Unable to generate apidoc: ${err}`)\n\t})\n}\n\n// Start script\nworkflow()\n```\n\n\nMiddlewares and router implementation.\n```Typescript\nrouter.get(\n\t\t'/users/:userID',\n\t\t\n\t\t// permissionMiddleware\n\t\tpermissionMiddleware(['SUPERADMIN', 'TEST']),\n\t\t\n\t\tvalidationMiddleware(requestSchema),\n\t\t\n\t\t// businessLogic\n\t\tbusinessLogic\n\t)\n\n//permissions middleware implementation\nexport const permissionMiddleware = (allowPermissions: string[]) =\u003e function permission(req: Request, res: Response, next: NextFunction) {\n\t...\n}\n```\n\nAdding description for endpoints.\n```Typescript\nconst userEndpointDesc = 'This is how to add swagger description for this endpoint'\n\nexport const requestSchema = Joi.object({\n\tparams: Joi.object({\n\t\tuserID: Joi.number()\n\t}),\n\tquery: Joi.object({\n\t\tsearch: Joi.string().required()\n\t}),\n\tbody: Joi.object({\n\t\tname: Joi.string().required()\n\t})\n}).description(userEndpointDesc)\n```\n\nTop level request .alternatives() or .alternatives().try()..\n```Typescript\nexport const requestSchema = Joi.object({\n    params: Joi.object(),\n    query: Joi.object(),\n    body: Joi.alternatives().try(\n        Joi.object().keys({\n            a: Joi.string(),\n            b: Joi.number()\n        }),\n        Joi.object().keys({\n            c: Joi.boolean(),\n            d: Joi.date()\n        })\n    )\n})\n```\n..displays request example as:\n```JSON\n{\n  \"warning\": \".alternatives() object - select 1 option only\",\n  \"option_0\": {\n    \"a\": \"string\",\n    \"b\": 0\n  },\n  \"option_1\": {\n    \"c\": true,\n    \"d\": \"2021-01-01T00:00:00.001Z\"\n  }\n}\n```\n\nMarking endpoint as **deprecated** (by adding the `@deprecated` flag to the beginning of the description in the request schema).\n```Typescript\nexport const requestSchema = Joi.object({\n\tparams: Joi.object({\n\t\tuserID: Joi.number()\n\t}),\n\tquery: Joi.object({\n\t\tsearch: Joi.string().required()\n\t}),\n\tbody: Joi.object({\n\t\tname: Joi.string().required()\n\t})\n}).description('@deprecated Endpoint returns list of users.')\n```\n\nUsing shared schema by calling `.meta` and specifying schema name in `className` property.\nShared schemas can be used inside requestSchema body or anywhere in responseSchema or errorResponseSchema\n\n```Typescript\nexport const userSchema = Joi.object({\n\tid: Joi.number(),\n\tname: Joi.string(),\n\tsurname: Joi.string()\n}).meta({ className: 'User' })\n\nexport const responseSchema = Joi.object({\n\tuser: userSchema\n})\n```\n\nSetting custom **http status code** for response (both responseSchema and errorResponseSchema) by setting it in description of schema.\n```Typescript\nexport const responseSchema = Joi.object({\n\tid: Joi.number().integer().required()\n}).description('201')\n\nexport const errorResponseSchemas = [\n\tJoi.object({\n\t\tmessages: Joi.array().items(\n\t\t\tJoi.object({\n\t\t\t\ttype: Joi.string().required(),\n\t\t\t\tmessage: Joi.string().required().example('Not found')\n\t\t\t})\n\t\t)\n\t}).description('404')\n]\n```\n\nImplementing custom formatter example.\n```typescript\n/**\n * Custom formatter\n * @param {string} middlewareName\n * @param {{\n\tclosure: string\n\tisUsed: boolean\n\tmiddlewareArguments: {\n\t\targumentName: string\n\t\tvalue: any\n\t}[]\n}} middleware object containing all necessary information about actual middleware\n * @return { string } middleware's description\n * */\nexport const defaultFormatter = (middlewareName: string, middleware: IMiddleware) =\u003e {\n\treturn `${middlewareName}: ${middleware.isUsed}`\n}\n```\n\n## Result\n\nGenerated SwaggerUI\n\n![Generated SwaggerUI](demo/example.png)\n\n\n## Extra Benefits\nSwagger bug reports shows inconsistency error in the schema and/or your route definition.\n\n1. In this case the default value is not present in valid values.\n```\norderBy: Joi.string().lowercase()\n.valid('name', 'duration', 'calories', 'views')\n.empty(['', null]).default('order'),\n```\n2. If you defined id as parameter within route but forgot to define it the schema Swagger will report error.\n```\n//route with id as parameter\n\nrouter.put('/:id',\n```\nschema definition\n```\n//joi schema that does not include definition for id param\n\nparams: Joi.object()\n```\n## Contribution\nAny 👐 contributions, 🐛 issues and 🌟 feature requests are welcome!\n\nFeel free to check following #TODO ideas we have:\n\n\n| #ID\t| Filename\t    | Description\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  \t\t\t\t\t\t|\n| ------|:---------------:|-------------------------------------------------------------------------------------------------------- \t\t\t|\n| #1\t|      @all \t| create tests\t\t\t\t\t\t\t\t\t\t\t\t\t\t                      \t\t\t\t\t\t|\n| #2\t|      @all\t\t| update to new Open API after release 3.1.0 fix issue https://github.com/OAI/OpenAPI-Specification/pull/2117\t\t\t\t\t\t\t\t                                                  \t\t\t\t\t\t|\n| #3\t|      @all  \t| sync with branch v14 \t\t\t\t\t\t\t\t\t\t\t\t\t                              \t\t\t\t\t\t|\n\n\n## Credits\n*  [Express endpoint parser](https://github.com/AlbertoFdzM/express-list-endpoints) to retrieve a list of the passed router with the set verbs.\n*  [Conversion library](https://github.com/Twipped/joi-to-swagger#readme) for transforming [Joi](https://www.npmjs.com/package/joi) schema objects into [Swagger](https://swagger.io/) schema definitions.\n*  A simple [tool](https://github.com/midrissi/func-loc) that help you to retrieve the function location from its reference.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodrequest%2Fexpress-joi-to-swagger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodrequest%2Fexpress-joi-to-swagger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodrequest%2Fexpress-joi-to-swagger/lists"}