Gathering detailed insights and metrics for @goodrequest/express-joi-to-swagger
Gathering detailed insights and metrics for @goodrequest/express-joi-to-swagger
npm install @goodrequest/express-joi-to-swagger
Typescript
Module System
Min. Node Version
Node Version
NPM Version
45.2
Supply Chain
66.4
Quality
85.8
Maintenance
100
Vulnerability
98.9
License
TypeScript (93.86%)
JavaScript (5.71%)
HTML (0.32%)
Shell (0.11%)
Total Downloads
41,711
Last Day
47
Last Week
256
Last Month
1,139
Last Year
16,184
20 Stars
214 Commits
7 Forks
9 Watching
18 Branches
21 Contributors
Latest Version
2.0.4
Package Id
@goodrequest/express-joi-to-swagger@2.0.4
Unpacked Size
146.23 kB
Size
32.90 kB
File Count
48
NPM Version
8.19.4
Node Version
16.20.2
Publised On
09 Jan 2025
Cumulative downloads
Total Downloads
Last day
-17.5%
47
Compared to previous day
Last week
18.5%
256
Compared to previous week
Last month
12.4%
1,139
Compared to previous month
Last year
17.2%
16,184
Compared to previous year
15
Solution that generates beatiful Swagger API documentation from code. 💻
It lists all of endpoints registred within app with their routes, methods, relevant middlewares.
When it comes to generating 📑Swagger documentation, you have two options. Generate Swagger UI that can be served as a static file within your application, or keep documentation as data.json file within defined 📁location.
For more information see Config parameters bellow ⬇.
This simple tool does not require you to write any more code that necessary. Documentation is generated from source code itself without using annotations or separate doc files.
Use the package manager (npm or yarn) to install dependencies.
1npm install @goodrequest/express-joi-to-swagger 2or 3yarn add @goodrequest/express-joi-to-swagger
✖ This solution is suitable for everybody who uses Express in a combination with Joi to build application's API. This 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 use Typescipt version 3.7.5 and higher.
✖ As mentioned before, it is not needed to use annotations in your code, however to make this tool works properly you need to obey some coding practices. You need define at least one router in your application. If you want to include request and response Joi schemas in a documentation they need to be named the same and exported.
✖ If you are using middleware for user authorization and wish to include endpoint permissions in the documentation as well you need to name the function responsible for handling this and provide permissions array as its input parameter.
You can find simple examples of all mentioned in the demo folder of this repository. Quick usage example can also be found below ⬇.
Name | Type | Required | Description |
---|---|---|---|
outputPath | string | ✅ | Path to directory where output JSON file should be created. |
generateUI | boolean | ✅ | Whether Swagger UI should be generated. |
middlewares | object | ❌ | Configuration parameters for parsing middlewares. |
middlewares.formatter | function | ❌ | Custom formatter function for middleware. If not provided, the default one will be used. |
middlewares.middlewareName | string | ✅ | Name of the middleware. |
middlewares.closure | string | ✅ | Name of the middleware closure. |
middlewares.maxParamDepth | number | ❌ | Max depth of middleware parameter. Default value is 5. |
requestSchemaName | string | ❌ | Name of the Joi schema object defining request structure. |
responseSchemaName | string | ❌ | Name of the Joi schema object defining response structure. |
requestSchemaParams | any[] | ❌ | Param for ability to pass mock params for requestSchema. |
responseSchemaParams | any[] | ❌ | Param for ability to pass mock params for responseSchema. |
errorResponseSchemaName | string | ❌ | Name of the Joi schema object defining error responses structure. |
businessLogicName | string | ✅ | Name of the function responsible for handling business logic of the request. |
swaggerInitInfo | ISwaggerInit | ❌ | Swagger initial information. |
swaggerInitInfo.servers | IServer[] | ❌ | List of API servers. |
swaggerInitInfo.servers.url | string | ❌ | API server URL. |
swaggerInitInfo.info | IInfo | ❌ | Basic API information. |
swaggerInitInfo.info.description | string | ❌ | API description. |
swaggerInitInfo.info.version | string | ❌ | API version. |
swaggerInitInfo.info.title | string | ❌ | API title. |
swaggerInitInfo.info.termsOfService | string | ❌ | Link to terms of service. |
swaggerInitInfo.info.contact | IContact | ❌ | Swagger initial information. |
swaggerInitInfo.info.contact.email | string | ✅ | Contact email. |
swaggerInitInfo.info.license | ILicense | ❌ | Swagger initial information. |
swaggerInitInfo.info.license.name | string | ✅ | License name. |
swaggerInitInfo.info.license.url | string | ✅ | License url. |
tags | string | ❌ | Configuration parameters for parsing tags. |
tags.baseUrlSegmentsLength | number | ❌ | Number of base URL segments. |
tags.joinTags | boolean | ❌ | If set to true, array of parsed tags will be joined to string by tagSeparator, otherwise array of tags is returned. |
tags.tagSeparator | string | ❌ | String used to join parsed tags. |
tags.versioning | boolean | ❌ | 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". |
tags.versionSeparator | string | ❌ | String used to separate parsed tags from API version tag is versioning == true. |
deprecationPathPattern | string | ❌ | If provided, all versions of endpoints except latest will be marked as deprecated. Pattern needs to specify api route from start segment to version segment, which have to be specified as "v*". 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 |
1// imports 2import getSwagger from '@goodrequest/express-joi-to-swagger' 3import path from 'path' 4import app from './your-path-to-express-app' 5 6// Config example 7const config: IConfig = { 8 outputPath: path.join(__dirname, 'dist'), 9 generateUI: true, 10 middlewares: [ 11 { 12 middlewareName: 'permission', 13 closure: 'permissionMiddleware', 14 formatter: basicArrayFormatter, 15 maxParamDepth: 3 16 }, 17 { 18 middlewareName: 'validate', 19 closure: 'validationMiddleware' 20 } 21 ], 22 requestSchemaName: 'requestSchema', 23 requestSchemaParams: [mockFn], 24 responseSchemaName: 'responseSchema', 25 errorResponseSchemaName: 'errorResponseSchemas', 26 businessLogicName: 'businessLogic', 27 swaggerInitInfo: { 28 info: { 29 description: 'Generated Store', 30 title: 'Test app' 31 } 32 }, 33 tags: {} 34} 35 36// Use case example 37function workflow() { 38 getSwagger(app, config).then(() => { 39 console.log('Apidoc was successfully generated') 40 }).catch((e) => { 41 console.log(`Unable to generate apidoc: ${err}`) 42 }) 43} 44 45// Start script 46workflow()
Middlewares and router implementation.
1router.get( 2 '/users/:userID', 3 4 // permissionMiddleware 5 permissionMiddleware(['SUPERADMIN', 'TEST']), 6 7 validationMiddleware(requestSchema), 8 9 // businessLogic 10 businessLogic 11 ) 12 13//permissions middleware implementation 14export const permissionMiddleware = (allowPermissions: string[]) => function permission(req: Request, res: Response, next: NextFunction) { 15 ... 16}
Adding description for endpoints.
1const userEndpointDesc = 'This is how to add swagger description for this endpoint'
2
3export const requestSchema = Joi.object({
4 params: Joi.object({
5 userID: Joi.number()
6 }),
7 query: Joi.object({
8 search: Joi.string().required()
9 }),
10 body: Joi.object({
11 name: Joi.string().required()
12 })
13}).description(userEndpointDesc)
Top level request .alternatives() or .alternatives().try()..
1export const requestSchema = Joi.object({
2 params: Joi.object(),
3 query: Joi.object(),
4 body: Joi.alternatives().try(
5 Joi.object().keys({
6 a: Joi.string(),
7 b: Joi.number()
8 }),
9 Joi.object().keys({
10 c: Joi.boolean(),
11 d: Joi.date()
12 })
13 )
14})
..displays request example as:
1{ 2 "warning": ".alternatives() object - select 1 option only", 3 "option_0": { 4 "a": "string", 5 "b": 0 6 }, 7 "option_1": { 8 "c": true, 9 "d": "2021-01-01T00:00:00.001Z" 10 } 11}
Marking endpoint as deprecated (by adding the @deprecated
flag to the beginning of the description in the request schema).
1export const requestSchema = Joi.object({
2 params: Joi.object({
3 userID: Joi.number()
4 }),
5 query: Joi.object({
6 search: Joi.string().required()
7 }),
8 body: Joi.object({
9 name: Joi.string().required()
10 })
11}).description('@deprecated Endpoint returns list of users.')
Using shared schema by calling .meta
and specifying schema name in className
property.
Shared schemas can be used inside requestSchema body or anywhere in responseSchema or errorResponseSchema
1export const userSchema = Joi.object({
2 id: Joi.number(),
3 name: Joi.string(),
4 surname: Joi.string()
5}).meta({ className: 'User' })
6
7export const responseSchema = Joi.object({
8 user: userSchema
9})
Setting custom http status code for response (both responseSchema and errorResponseSchema) by setting it in description of schema.
1export const responseSchema = Joi.object({ 2 id: Joi.number().integer().required() 3}).description('201') 4 5export const errorResponseSchemas = [ 6 Joi.object({ 7 messages: Joi.array().items( 8 Joi.object({ 9 type: Joi.string().required(), 10 message: Joi.string().required().example('Not found') 11 }) 12 ) 13 }).description('404') 14]
Implementing custom formatter example.
1/** 2 * Custom formatter 3 * @param {string} middlewareName 4 * @param {{ 5 closure: string 6 isUsed: boolean 7 middlewareArguments: { 8 argumentName: string 9 value: any 10 }[] 11}} middleware object containing all necessary information about actual middleware 12 * @return { string } middleware's description 13 * */ 14export const defaultFormatter = (middlewareName: string, middleware: IMiddleware) => { 15 return `${middlewareName}: ${middleware.isUsed}` 16}
Generated SwaggerUI
Swagger bug reports shows inconsistency error in the schema and/or your route definition.
orderBy: Joi.string().lowercase()
.valid('name', 'duration', 'calories', 'views')
.empty(['', null]).default('order'),
//route with id as parameter
router.put('/:id',
schema definition
//joi schema that does not include definition for id param
params: Joi.object()
Any 👐 contributions, 🐛 issues and 🌟 feature requests are welcome!
Feel free to check following #TODO ideas we have:
#ID | Filename | Description |
---|---|---|
#1 | @all | create tests |
#2 | @all | update to new Open API after release 3.1.0 fix issue https://github.com/OAI/OpenAPI-Specification/pull/2117 |
#3 | @all | sync with branch v14 |
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
packaging workflow detected
Details
Reason
2 existing vulnerabilities detected
Details
Reason
4 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 3
Reason
Found 1/14 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
license file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More