Giter Club home page Giter Club logo

express-jsdoc-swagger's Introduction

npm Node.js Package Known Vulnerabilities Maintainability Test Coverage License: MIT npm

express-jsdoc-swagger

With this library, you can document your express endpoints using swagger OpenAPI 3 Specification without writing YAML or JSON. You can write comments similar to jsdoc on each endpoint, and the dependecy is going to create the swagger UI.

Table of Contents

  1. Prerequisites
  2. Installation
  3. Basic Usage
  4. Basic Examples
  5. Validator
  6. VSCode extension

Prerequisites

This library assumes you are using:

  1. NodeJS
  2. Express.js

Installation

npm i express-jsdoc-swagger

Basic Usage

// index.js file
const express = require('express');
const expressJSDocSwagger = require('express-jsdoc-swagger');

const options = {
  info: {
    version: '1.0.0',
    title: 'Albums store',
    license: {
      name: 'MIT',
    },
  },
  security: {
    BasicAuth: {
      type: 'http',
      scheme: 'basic',
    },
  },
  // Base directory which we use to locate your JSDOC files
  baseDir: __dirname,
  // Glob pattern to find your jsdoc files (multiple patterns can be added in an array)
  filesPattern: './**/*.js',
  // URL where SwaggerUI will be rendered
  swaggerUIPath: '/api-docs',
  // Expose OpenAPI UI
  exposeSwaggerUI: true,
  // Expose Open API JSON Docs documentation in `apiDocsPath` path.
  exposeApiDocs: false,
  // Open API JSON Docs endpoint.
  apiDocsPath: '/v3/api-docs',
  // Set non-required fields as nullable by default
  notRequiredAsNullable: false,
  // You can customize your UI options.
  // you can extend swagger-ui-express config. You can checkout an example of this
  // in the `example/configuration/swaggerOptions.js`
  swaggerUiOptions: {},
  // multiple option in case you want more that one instance
  multiple: true,
};

const app = express();
const PORT = 3000;

expressJSDocSwagger(app)(options);

/**
 * GET /api/v1
 * @summary This is the summary of the endpoint
 * @return {object} 200 - success response
 */
app.get('/api/v1', (req, res) => res.json({
  success: true,
}));

app.listen(PORT, () => console.log(`Example app listening at http://localhost:${PORT}`));

Basic Examples

  1. Basic configuration options.
const options = {
  info: {
    version: '1.0.0',
    title: 'Albums store',
    license: {
      name: 'MIT',
    },
  },
  security: {
    BasicAuth: {
      type: 'http',
      scheme: 'basic',
    },
  },
  baseDir: __dirname,
  // Glob pattern to find your jsdoc files (multiple patterns can be added in an array)
  filesPattern: './**/*.js',
};
  1. Components definition
/**
 * A song type
 * @typedef {object} Song
 * @property {string} title.required - The title
 * @property {string} artist - The artist
 * @property {number} year - The year - double
 */
  1. Endpoint which returns a Songs model array in the response.
/**
 * GET /api/v1/albums
 * @summary This is the summary of the endpoint
 * @tags album
 * @return {array<Song>} 200 - success response - application/json
 */
app.get('/api/v1/albums', (req, res) => (
  res.json([{
    title: 'abum 1',
  }])
));
  1. Endpoint PUT with body and path params which returns a Songs model array in the response.
/**
 * PUT /api/v1/albums/{id}
 * @summary Update album
 * @tags album
 * @param {string} name.path - name param description
 * @param {Song} request.body.required - songs info
 * @return {array<Song>} 200 - success response - application/json
 */
app.put('/api/v1/albums/:id', (req, res) => (
  res.json([{
    title: 'abum 1',
  }])
));
  1. Basic endpoint definition with tags, params and basic authentication
/**
 * GET /api/v1/album
 * @summary This is the summary of the endpoint
 * @security BasicAuth
 * @tags album
 * @param {string} name.query.required - name param description
 * @return {object} 200 - success response - application/json
 * @return {object} 400 - Bad request response
 */
app.get('/api/v1/album', (req, res) => (
  res.json({
    title: 'abum 1',
  })
));
  1. Basic endpoint definition with code example for response body
/**
 * GET /api/v1/albums
 * @summary This is the summary of the endpoint
 * @tags album
 * @return {array<Song>} 200 - success response - application/json
 * @example response - 200 - success response example
 * [
 *   {
 *     "title": "Bury the light",
 *     "artist": "Casey Edwards ft. Victor Borba",
 *     "year": 2020
 *   }
 * ]
 */
app.get('/api/v1/albums', (req, res) => (
  res.json([{
    title: 'track 1',
  }])
));

You can find more examples here, or visit our documentation.

Validator

We developed a new package works as a validator of your API endpoints and the documentation you create with this package. This package is express-oas-validator.

Example

Install using the node package registry:

npm install --save express-oas-validator

We have to wait until we have the full swagger schema to initiate the validator.

// validator.js
const { init } = require('express-oas-validator');

const validators = instance => new Promise((resolve, reject) => {
  instance.on('finish', (swaggerDef) => {
    const { validateRequest, validateResponse } = init(swaggerDef);
    resolve({ validateRequest, validateResponse });
  });

  instance.on('error', (error) => {
    reject(error);
  });
});

module.exports = validators;

You can check out this also in our example folder.

// index.js
const express = require('express');
const expressJSDocSwagger = require('express-jsdoc-swagger');
const validator = require('./validator');

const options = {
  info: {
    version: '1.0.0',
    title: 'Albums store',
    license: {
      name: 'MIT',
    },
  },
  filesPattern: './**.js',
  baseDir: __dirname,
};

const app = express();
const instance = expressJSDocSwagger(app)(options);

const serverApp = async () => {
  const { validateRequest, validateResponse } = await validator(instance);
  app.use(express.urlencoded({ extended: true }));
  app.use(express.json());
  /**
   * A song
   * @typedef {object} Song
   * @property {string} title.required - The title
   * @property {string} artist - The artist
   * @property {integer} year - The year
   */

  /**
   * POST /api/v1/songs
   * @param {Song} request.body.required - song info
   * @return {object} 200 - song response
   */
  app.post('/api/v1/songs', validateRequest(), (req, res) => res.send('You save a song!'));

  /**
   * POST /api/v1/name
   * @param {string} request.body.required - name body description
   * @return {object} 200 - song response
   */
  app.post('/api/v1/name', (req, res, next) => {
    try {
      // Validate response
      validateResponse('Error string', req);
      return res.send('Hello World!');
    } catch (error) {
      return next(error);
    }
  });

  /**
   * GET /api/v1/authors
   * @summary This is the summary or description of the endpoint
   * @param {string} name.query.required - name param description - enum:type1,type2
   * @param {array<string>} license.query - name param description
   * @return {object} 200 - success response - application/json
   */
  app.get('/api/v1/authors', validateRequest({ headers: false }), (req, res) => (
    res.json([{
      title: 'album 1',
    }])
  ));

  // eslint-disable-next-line no-unused-vars
  app.use((err, req, res, next) => {
    res.status(err.status).json(err);
  });

  return app;
};

const PORT = process.env.PORT || 4000;

serverApp()
  .then(app => 
    app.listen(PORT, () =>
      console.log(`Listening PORT: ${PORT}`)
    ))
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

You can visit our documentation.

Contributors ✨

Briam Martinez Escobar
Briam Martinez Escobar

💻
Kevin Julián Martínez Escobar
Kevin Julián Martínez Escobar

💻
Heung-yeon Oh
Heung-yeon Oh

💻
Sara Hernández
Sara Hernández

💻
Josep Servat
Josep Servat

💻
Nick Dong
Nick Dong

💻
Aleksander Stós
Aleksander Stós

💻
Kjell Dankert
Kjell Dankert

💻
juliendu11
juliendu11

💻
Mohamed Meabed
Mohamed Meabed

💻
Faruk Aydın
Faruk Aydın

💻
Dahlmo
Dahlmo

💻
Carlos Ravelo
Carlos Ravelo

💻
Paul Ishenin
Paul Ishenin

💻
Sam Bingner
Sam Bingner

💻
Alexander Staroselsky
Alexander Staroselsky

💻
Joel Abrahamsson
Joel Abrahamsson

💻
Markus Moltke
Markus Moltke

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

express-jsdoc-swagger's People

Contributors

alexstaroselsky avatar allcontributors[bot] avatar bri06 avatar dahlmo avatar dependabot[bot] avatar gandazgul avatar hoonga avatar joelabrahamsson avatar juliendu11 avatar kdankert avatar kevinccbsg avatar lonelyprincess avatar makakwastaken avatar matart15 avatar meabed avatar ofarukaydin avatar paulish avatar sbingner avatar servatj avatar snyk-bot avatar stosiu avatar thuydx55 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

express-jsdoc-swagger's Issues

[Enhancement] Components property Array of other components

Is your feature request related to a problem? Please describe.
We fixed the problem with multiple primitive types on one property in this commit b2bd217 but we need to do the same for Components references. It should be similar like we do in schemas

Describe the solution you'd like
We need to display and Album schema with an Array of Songs schemas.

[BUG] @typedef with optional parameters

Hello, i am experiencing this behavior on schemas @typedefs with optional parameters.

Using the following syntax [myparam] to express optional parameter in the @typedef here is an exmaple :

/**
 * @typedef {object} FormMixin
 * @property {string} [id]
 * @property {string} [code]
 * @property {string} [name]
 */

I get the following result in the ui :

Capture

Tried with another syntax with ? character liek this :

/**
 * @typedef {object} FormMixin
 * @property {string?} id
 * @property {string?} code
 * @property {string?} name
 */

This time i get the following error :

(node:38552) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined
    at addTypeApplication (C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:20:25)
    at C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:45:12
    at Array.reduce (<anonymous>)
    at formatProperties (C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:32:21)
    at parseSchema (C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:77:19)
    at C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:85:17
    at Array.reduce (<anonymous>)
    at parseComponents (C:\Project\node_modules\express-jsdoc-swagger\transforms\components\index.js:84:38)
    at C:\Project\node_modules\express-jsdoc-swagger\processSwagger.js:35:23
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Optional parameters may be badly used from my side, or is it a not handled feature ?

Thx in advance 👍

Context:

  • Node.js v12.18.2

Export Swagger definition

Is your feature request related to a problem? Please describe.
I currently use this package for an express API which does not offer a publicly hosted instance so we have nowhere to serve the documentation endpoint from.

Describe the solution you'd like
I would like to be able to export the generated swagger yml file so that I can use it with my CICD to host the docs on GH pages. This repo works for such hosting and only needs the swagger definition.

Describe alternatives you've considered
I'm considering switching to other Swagger jsdoc libraries for this, but I much prefer the format of the docstrings which this project uses.

Use express-jsdoc-swagger behind reverse proxy

I am running express-jsdoc-swagger behind a reverse proxy.
Unfortunately if I access the swagger ui from /api/messages/api-docs it redirects me to /api-docs/, which reaches another service. If I access /api/messages/api-docs/ everything works cause there is no redirect. I know that there are some config paramaters in the express swagger ui package, but I can't get it working by passing parameters to express-jsdoc-swagger. Do you know how this could be achieved? Help would be really appreciated

[Docs] Full API example

We have to complete the documentation of one API with all these features:

  • Basic info
  • Security info
  • Multiple endpoints
  • Tags
  • Multiple responses
  • Components

We have to save them as the other ones described in this README file

Tasks

[BUG] Swagger UI response TYPE is giving html instead of json response

Describe the bug
I wanted to have a documentation for my API. Im doing every thing described in the docs but it is not giving me mty expected result

Expected behavior
the expected output should be a JSON object but it gives me a html markup in response

Screenshots
github SwaggerUI

Desktop (please complete the following information):

  • OS:[ Windows 10 Pro]
  • Version [20H2]

Additional context
Add any other context about the problem here.

Question about using the object notation for @property

Hi! I really appreciate this package that you all created. It's greatly assisting in adding in some automatic documentation.

I had a question though: I'm currently confused about how to use the {object} type on @Property. Right now, I have our cloudOptions parameter declared as an {object}. The layout seems to imply that there's a way to describe the attributes inside this object. Instead, the object opens up empty and just shows the description.

I searched throughout the repo and I didn't see any extra documentation on the {object} type and how to declare inner attributes.

Screen Shot 2021-02-26 at 4 58 42 PM

Could I ask if there is? Thanks!

JSDoc optional syntax instead of `.required`

Is your feature request related to a problem? Please describe.

I mostly noticed the issue when using @typedef, since comments on app.use tend to be quite meaningless when it comes to the IDE type discovery.

Types which uses JSDoc optional syntax aren't shown in the Swagger UI.

Also the current way to define required parameters or properties causes issues with code editor type detection.
When adding .required to the name of the parameter/property VSCode isn't able to detect the property type anymore.

Describe the solution you'd like

A solution would be to use the default JSDoc optional syntax.

The parameter definition would go from @param {number} myNum This is my optional number to @param {number} [myNum] This is my optional number for optional parameters and from @param {number} myNum.required This is my optional number to @param {number} myNum This is my optional number for required parameters.

Describe alternatives you've considered

Currently we're just keeping all the parameters/properties optional (not adding .required) since it would break the type detection.

Additional context

image

As you can see VSCode doesn't detect one of the properties since it think the property name is required.

Example request and response

How to add Example request and response to an endpoint. When writing API documentation, you would usually want to provide your users with sample request body to guide how the request payload should be constructed and formatted and also provide at least a sample returned response to showcase the format of the response

Describe the solution you'd like
/**
*@example {requestBody} - a sample request body
{
"username": "LA-AM-0001",
"password": "PMNmj@123",
"firstName": "segufkn",
"lastName": "IDEklmhj",
"dob": "2000-07-08",
"gender": "Male",
"role": "master-agent",
"phone": {
"code": "234",
"number": "807489388"
}
*@example {responseBody} - a sample request body
{
"status": true,
"message": "user registered successfully",
"data": {
"username": "LA-AM-0001",
"firstName": "segufkn",
"lastName": "IDEklmhj",
"dob": "04-26-202",
"gender": "Male",
"role": "master-agent",
"phone": {
"code": "234",
"number": "807489388"
},
"wallet": {
"balance": 20000,
"ledgerBalance": 20000,
"trust": 0
}
}
}
*/

[BUG] TypeScript typings don't match documentation

Describe the bug

I've just setup the same project as per the docs, but the project fails to compile when using TypeScript. There are multiple issues, but one example:

 Types of property 'servers' are incompatible.
    Type '{ url: string; description: string; }[]' is not assignable to type 'string[]'.
      Type '{ url: string; description: string; }' is not assignable to type 'string'.

To Reproduce

Setup a project from scratch based on the documentation, then try to compile the project with tsc.

Expected behavior

The TypeScript typings match the documentation.

Desktop (please complete the following information):

  • OS: macOS 11.1
  • Node 14.15.3, npm 6.14.10, tsc 3.9.7

Additional context

My tsconfig:

{
	"compilerOptions": {
		"target": "ES2016",
		"module": "commonjs",
		"lib": ["es2015"],
		"strict": true,
		"noImplicitAny": false,
		"esModuleInterop": true,
		"skipLibCheck": true,
		"forceConsistentCasingInFileNames": true,
		"outDir": "dist/",
		"pretty": true,
		"noEmitOnError": true,
		"experimentalDecorators": true,
		"emitDecoratorMetadata": true
	},
	"include": ["src/**/*.ts", "src/**/*.js","src/**/*.json"],
	"exclude": ["node_modules", "src/migrations", "src/db/seeds"]
}

TypeScript support

Any way to get TypeScript working with this?

node_modules/express-jsdoc-swagger/index.js' implicitly has an 'any' type.
Try npm install @types/express-jsdoc-swagger if it exists or add a new declaration (.d.ts) file containing declare module 'express-jsdoc-swagger';ts(7016)

yarn add @types/express-jsdoc-swagger
yarn add v1.22.5
[1/4] Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@types%2fexpress-jsdoc-swagger: Not found".

[BUG] Errors with empty required properties

Describe the bug
When we add a JSON object that we generate with our library into Swagger Editor we see this error.

Screen Shot 2020-07-31 at 19 03 26

This is because we always add required key for components value. This line is the method we need to modify.

https://github.com/BRIKEV/express-jsdoc-swagger/blob/master/transforms/components/index.js#L54

This method needs to be changed to erase the required property when it hasn't values.

To Reproduce
If you want to reproduce this you can use this JSON file in Swagger Editor.

{
  "openapi": "3.0.0",
  "info": {
    "title": "Albums store",
    "description": "Add your description",
    "license": {
      "name": "MIT",
      "url": ""
    },
    "termsOfService": "",
    "version": "1.0.0"
  },
  "servers": [],
  "paths": {},
  "tags": [],
  "components": {
    "schemas": {
      "Song": {
        "description": "A song",
        "required": [
          "title"
        ],
        "type": "object",
        "properties": {
          "title": {
            "description": "The title",
            "type": "string"
          },
          "artist": {
            "description": "The artist",
            "type": "string"
          },
          "year": {
            "description": "The year",
            "type": "number",
            "format": "double"
          }
        }
      },
      "Author": {
        "description": "Author model",
        "required": [
          "name"
        ],
        "type": "object",
        "properties": {
          "name": {
            "description": "Author name",
            "type": "string"
          },
          "age": {
            "description": "Author age",
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "Album": {
        "description": "Album",
        "required": [],
        "type": "object",
        "properties": {
          "firstSong": {
            "description": "",
            "$ref": "#/components/schemas/Song"
          },
          "author": {
            "description": "",
            "$ref": "#/components/schemas/Author"
          }
        }
      }
    }
  }
}

Expected behavior
Not having Swagger Editor errors.

Screenshots
Screen Shot 2020-07-31 at 19 03 26

[BUG] example response not showing line breaks correctly

Describe the bug
Example responses shows line breaks as /n breaking any readability of it

To Reproduce

   * @example response - 200 - example with group-by-day=false
   * [
   *   {
   *     name: 'foo',
   *     bar: 1241
   *   }
   * ]

Expected behavior
Expected "Indentation and breaklines will be preserved in Swagger UI" as described in the docs.

Screenshots
Here's how it looks in UI
image

  • Version 1.1.0

support multiple security annotate

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I want to add multiple security.
for example of my case :
I use two request header strings for authentication. x-access-token and x-refresh-token.
in this case, I cannot implement both authentication in one request.

Describe the solution you'd like
A clear and concise description of what you want to happen.
according to official document of swagger
we can add multiple authentication variable with and or operator.

I can define multiple of security objects in option.

it will be easy if I can add

/**
 * GET /test
 *
 * @summary 
 ...
 * @security accessToken | refreshToken
 ...

for or operator

and

/**
 * GET /test
 *
 * @summary 
 ...
 * @security accessToken & refreshToken
 ...

for and operator I guess.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
or at least availabie multiple annotation for security

/**
 * GET /test
 *
 * @summary 
 ...
 * @security accessToken
 * @security refreshToken
 ...

like this.

Additional context

this is my options settings for security.

{
    info: {
        version: '1.0.0',
        title: 'HR API',
        license: {
            name: 'MIT',
        },
    },
    security: {
        BasicAuth: {
            type: 'http',
            scheme: 'basic',
        },
        accessToken: {
            type: 'apiKey',
            name: 'x-access-token',
            in: 'header'
        },
        refreshToken: {
            type: 'apiKey',
            name: 'x-refresh-token',
            in: 'header'
        }
    },
    filesPattern: [ './routes/*.js' ], // Glob pattern to find your jsdoc files
    swaggerUIPath: `/swagger`, // SwaggerUI will be render in this url. Default: '/api-docs'
    baseDir: __dirname,
    exposeSwaggerUI: true, // Expose OpenAPI UI. Default true
    exposeApiDocs: true, // Expose Open API JSON Docs documentation in `apiDocsPath` path. Default false.
    apiDocsPath: '/v3/api-docs', // Open API JSON Docs endpoint. Default value '/v3/api-docs'.
}

for just in case
Add any other context or screenshots about the feature request here.

I am not sure this is already implemented or not, at least i cannot find any example or issues in here.

[Docs] Update README

We have to complete documentation of the README file with one basic example and a link to our Docs.

One basic example can be when we complete this issue #27.

Tasks

  • complete README.md description

[CodeClimate] `expressJSDocSwagger` has 33 lines of code (exceeds 25 allowed)

There is one issue in our code climate that should be fixed.

Here is the link of this problem.

Tasks

  • Separate in different file this block of code
globFilesMatches(options.baseDir, options.file)
      .then(readFiles)
      .then(getOnlyComments)
      .then(jsdocInfo())
      .then(data => {
        swaggerObject = getPaths(swaggerObject, data);
        swaggerObject = getComponents(swaggerObject, data);
        swaggerObject = getTags(swaggerObject, data);
      })
      .catch(console.log);
  • Add test to the separated function

[Enhancement] Refactor process swagger

Is your feature request related to a problem? Please describe.
We found that we can improve the way we parse our tags to be more performant.

Describe the solution you'd like
We would like to refactor this function, as we are processing all of our JSDoc components for each parser when we should do it once.

Describe alternatives you've considered
These lines https://github.com/BRIKEV/express-jsdoc-swagger/blob/master/processSwagger.js#L33 should be replaced with one method to decide which parser must be used so that we only run once all of our parse methods.

How to use $ref

Is there a way to utilize $ref references to other files when using

 * Album
 * @typedef {object} Album
 * @property {string} title - The title
 * @property {array<number>} years
 */

Extend "options.filesPattern" to support arrays of strings

Is your feature request related to a problem? Please describe.
In my project, we want to generate different definitions based on the files. Currently filesPattern supports only string. We'd love to be able to pass string[] there. express-swagger-generator support files: string[] which is exactly what we need as we want to migrate from this lib to yours as yours it maintained and better documented.

Describe the solution you'd like
Add option to pass either string or string[] in options.filesPattern.

[BUG] Tabstopp in example breaks linebreak output

Describe the bug
If your have the tabstopp character in your example json, it breaks the output, resulting in wrong line breaks.

To Reproduce
Copy this code into your javascript. Note, that the spaces before the json are tabstopps, not whitespaces.

/**
 * GET /server/healthcheck
 *
 * @summary Returns information the healthiness of the server.
 *
 * @return {object} 200 - success response - application/json
 * @example response - 200 - success response example
 * { 
 *  "status": 200,
 *  "message": "healty"
 * }
 */

Expected behavior

Screenshots of the error

Desktop

  • OS: Windows 20H2, Node 15.2.1
  • Version: express-jsdoc-swagger 1.1.3

Additional context
The issue does not happen with whitespaces. It also does not happen in swagger directly (using a yaml file)

Hiding components

Hi! Is there any way currently to hide schemas? My use case is to hide schemas from the general list view (to prevent clutter), but still reference them inside other schemas

intercept request before swagger page load?

Is your feature request related to a problem? Please describe.

Thanks module again,

in current state, whoever got the url path for swagger, they can access freely.

I think that is in-secure, therefore i want to disable access this module in specific case.

Describe the solution you'd like

I want to intercept express's request before swagger route handle requests.

therefore i try code like this.

const expressJSDocSwagger = require('express-jsdoc-swagger');
const swaggerSetting = require('../public/swaggerDefine.json');
const swagger_options = {
    info: {
        version: '1.0.0',
        title: 'HR API',
        license: {
            name: 'MIT',
        },
    },
    security: {
        BasicAuth: {
            type: 'http',
            scheme: 'basic',
        },
    },
    filesPattern: './**/*.js', // Glob pattern to find your jsdoc files
    swaggerUIPath: `/swagger`, // SwaggerUI will be render in this url. Default: '/api-docs'
    baseDir: __dirname,
}
expressJSDocSwagger(app)(swagger_options, swaggerSetting);

...

app.use('/swagger',( req, res ) => {
    // disable it if production mode
    console.log('are you there?');
    if ( Config.mode === ENUM.RUN_MODE.PRODUCTION )
        res.send(404);
})

...

app.listen(PORT);

but seems like swagger module get request first, my route didnt get any log.

Describe alternatives you've considered

not sure.. :/

Additional context

Im new about swagger neither JsDoc, therefore I might approach totally wrong direction, if I did totally wrong, please correct me :>

example for request header

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

so my API is quite lots of required header for each request.
also sometime response have headers too, but this topic is not fit for this thread i guess.

So far I search this repo's example, n I did found how to make request header, luckily.

image

/**
     *
     * POST /board/write
     * @summary 게시판 작성 메소드.
     * @tags board
     * @param {string} x-lang.header.required - ko
     * @param {string} x-access-token.header.required - access토큰
     * @param {string} x-refresh-token.header.required - refresh토큰
     * @param {Req_board_write} request.body.required - song info
     * @return {testType} 200 - success response - application/json
     * @example request - payload example
     * {
     *   "seqUser" : 0,
     *   "boardTitle" : "Hello world",
     *   "boardContext" : "<h1>Hello world</h1>",
     *   "boardType" : 1
     * }
     */

I guess you guys assume that my header's are might be using all of my restAPI's.
yes, those headers are pretty much everywhere in my project.

and its so hard that I have to copy-paste every single try-out. its so painful.

therefore I expect @example for request header also.

Describe the solution you'd like
A clear and concise description of what you want to happen.

add another annotation tag for request header example
eg)

/**
     *
     * POST /board/write
     * @summary 게시판 작성 메소드.
     * @tags board
     * @param {string} x-lang.header.required - ko
     * @param {string} x-access-token.header.required - access토큰
     * @param {string} x-refresh-token.header.required - refresh토큰
     * @param {Req_board_write} request.body.required - song info
     * @return {testType} 200 - success response - application/json
     * @example request.body - payload example
     * {
     *   "seqUser" : 0,
     *   "boardTitle" : "Hello world",
     *   "boardContext" : "<h1>Hello world</h1>",
     *   "boardType" : 1
     * }
     * @example request.header - example headers
     * {
     *   "x-access-token" : "Foo",
     *   "x-refresh-token" : "Bar",
     *   "x-lang" : "Faz"
     * }
     */

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

or extends example for fillable header
eg)

/**
     *
     * POST /board/write
     * @summary 게시판 작성 메소드.
     * @tags board
     * @param {string} x-lang.header.required - ko
     * @param {string} x-access-token.header.required - access토큰
     * @param {string} x-refresh-token.header.required - refresh토큰
     * @param {Req_board_write} request.body.required - song info
     * @return {testType} 200 - success response - application/json
     * @example request - payload example
     * {
     *  "header" : {
     *     "x-access-token" : "Foo",
     *     "x-refresh-token" : "Bar",
     *     "x-lang" : "Faz"
     *   }
     *   "body" : {
     *     "seqUser" : 0,
     *     "boardTitle" : "Hello world",
     *     "boardContext" : "<h1>Hello world</h1>",
     *     "boardType" : 1
     *   }
     * }
     */

Additional context
Add any other context or screenshots about the feature request here.
or maybe there is already reqeust header example,
i dunno where to find.
help me out will ya?

allow examples to be provided for each property in a typedef

When I'm defining a schema consisting of types containing properties, it would be handy to specify the example values which should appear in the request & response examples that reference that type.

Given a type:

/**
 * A song
 * @typedef {object} Song
 * @property {string} title.required - The title
 * @property {string} artist - The artist
 * @property {number} year - The year - double
 */

I'd like some way (if it doesn't already exist) to specify example values of "My Song", "Artist X", and "2021" for the 3 properties.

I may have an API GET /api/songs would automatically have a sample response like

[
  {
    "song": "My Song",
    "artist": "Artist X",
    "year": 2021,
  }
]

instead of

[
  {
    "song": "string",
    "artist": "string",
    "year": 0,
  }
]

Other APIs GET /api/song/:name and PUT /api/song could each benefit from those example values without duplicating those sample values in @example request and @example response blocks.

Eventually, I'd like to have types derived from Song using anyOf which would inherit those sample values for each property.

Add a file upload example

Is your feature request related to a problem? Please describe.
i don't know how to add file upload on a route.

Describe the solution you'd like
Add in documentation a file upload example

Enable CORS for `Try it out`

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I recently made serverless - tiny api server for my project.
therefore i need to make another documentation, but i dont want to separate document projects.
so I made two swagger documentation in one project,
which i used from this topic:Docs/improve multiple instance docs #128
and it working great.

BUT there is another probloms with Try it out on sawggerUI.
this -newly created document- is not a same url as original.
therefore my test result shows CORS error like below

image

i tried to add cors request headers on swagger API like above image,
and enabled cors on express.js like below.
image

Describe the solution you'd like
i see some of difference packages are have enableCORS option on init, or they can just simply enable cors on express.js.

Describe alternatives you've considered
sorry, no idea.

Additional context

First of all, i have no clue that i tried right way or not.
i did enabled cors in my server decade ago, but oddly, cors error has occurred on swaggerUI.

full request and error log of first screenshot is below
request info :

General
- Request URL: http://localhost:7071/api/HttpTrigger1?code=EIfMtpIuZfCUajK4txznaZX/w5JED0ITZjbY/RFUE4KX/MLCbtT4HQ==
- Referrer Policy: strict-origin-when-cross-origin
Header
- accept: */*
- Access-Control-Allow-Headers: Content-Type,api_key,Authorization
- Access-Control-Allow-Methods: *
- Access-Control-Allow-Origin: *
- Content-Type: application/json
- DNT: 1
- Referer: http://192.168.0.4:3000/
- sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
- sec-ch-ua-mobile: ?0
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
General
 - Request URL: http://localhost:7071/api/HttpTrigger1?code=EIfMtpIuZfCUajK4txznaZX/w5JED0ITZjbY/RFUE4KX/MLCbtT4HQ==
 - Request Method: OPTIONS
 - Status Code: 404 Not Found
 - Remote Address: 127.0.0.1:7071
 - Referrer Policy: strict-origin-when-cross-origin

RequestHeader
 - Accept: */*
 - Accept-Encoding: gzip, deflate, br
 - Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
 - Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,content-type
 - Access-Control-Request-Method: POST
 - Connection: keep-alive
 - Host: localhost:7071
 - Origin: http://192.168.0.4:3000
 - Referer: http://192.168.0.4:3000/
 - Sec-Fetch-Dest: empty
 - Sec-Fetch-Mode: cors
 - Sec-Fetch-Site: cross-site
 - User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36

Response Header
 - Content-Length: 0
 - Date: Mon, 29 Mar 2021 04:25:46 GMT
 - Server: Kestrel

ERROR LOG ON CONSOLE

* Access to fetch at 'http://localhost:7071/api/HttpTrigger1?code=EIfMtpIuZfCUajK4txznaZX/w5JED0ITZjbY/RFUE4KX/MLCbtT4HQ==' from origin 'http://192.168.0.4:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
* POST http://localhost:7071/api/HttpTrigger1?code=EIfMtpIuZfCUajK4txznaZX/w5JED0ITZjbY/RFUE4KX/MLCbtT4HQ== net::ERR_FAILED

every jsdoc annotation is being ignored?

every jsdoc annotations are being ignored:

image

/**
 * POST /tag
 *
 * @summary create a tag
 * @param {string} name the name fo the new tag
 * @returns {object} 200 - success response
 * @returns {object} 400 - Bad request response
 * @example response - 200 - success response example
 *   {
 *     "_id": "Bury the light",
 *     "name": "lorem ipsum",
 *   }
 */
router.post('/', [insertNewTag])

config:

const swaggerSettings = {
	info: {
		version: '1.0.0',
		title: 'PetStore',
		license: {
			name: 'MIT',
		},
	},
	security: {
		BasicAuth: {
			type: 'http',
			scheme: 'basic',
		},
	},
	baseDir: __dirname,
	filesPattern: ['./routes/**/*.*'],
	swaggerUIPath: '/api-docs',
	exposeSwaggerUI: true,
	exposeApiDocs: false,
	apiDocsPath: '/v3/api-docs',
	notRequiredAsNullable: false,
	swaggerUiOptions: {},
}

Also notice the filepattern. This works (well nothing really is being rendered from the jsdoc)

./routes/**/*.*

while this one is not:

./**/*.ts

How to add definitions for headers?

I can't seem to find anything in the source/examples with defining a response header

Is this a feature not yet available or have I missed the relevant examples?

[Feature] Allowing `null` as property data type

Is your feature request related to a problem? Please describe.
There can be scenarios on which any of our properties can also take null values, and such case is not considered in the current state of the library. It would be good to modify the library to support this, so we can specify whether our fields are nullable or not.

Describe the solution you'd like
We could add null as a possible data type to specify that a given property can contain null values:

/**
 * @property {string} notNullProp - prop that does not support null values
 * @property {(string | null)} nullableProp - prop that can contain null values
 */

When generating the Swagger UI docs, this null data type would translate to nullable: true.

The syntax used to define multiple types in the example above is based on the specifications found in the official JSDoc website.

[Enhancement] Review test json with Enforcer to omit values

Is your feature request related to a problem? Please describe.
If we use Enforcer we get some warnings. We should review our tests and update those warnings.

One example is allowEmptyValues. We set this as false and Enforcer gave a warning. We should remove from the object when it is false.

[BUG] Example request rendering as string instead of object

What is happening
I try to show an example request body object for a POST request. I use the examples that can be found here. However, the example is shown as a string: "{\n \"title\": \"Bury The Light\",\n \"artist\": \"Casey Edwards ft. Victor Borba\",\n \"year\": 2020\n}"

image

Once I change the selection in the combo box to "other payload example" and back to "payload example" again, it displays the example correctly:

image

When I'm only using one example, there's no way to get it to display properly as in the second screenshot.

To Reproduce
These are the JS Doc Comments, that I'm using:

 * A song
 * @typedef {object} Song
 * @property {string} title.required - The title
 * @property {string} artist - The artist
 * @property {integer} year - The year - int64
 */

/**
 * POST /api/v1/song
 * @param {Song} request.body.required - song info
 * @return {object} 200 - song response
 * @return {object} 400 - Bad request response
 * @example request - payload example
 * {
 *   "title": "Bury The Light",
 *   "artist": "Casey Edwards ft. Victor Borba",
 *   "year": 2020
 * }
 * @example request - other payload example
 * {
 *   "title": "The war we made",
 *   "artist": "Red",
 *   "year": 2020
 * }
 */

this is my environment:
NodeJS v14.10.0
WSL2 Ubuntu

I am using this in a TypeScript app, in case that's of relevance (which I doubt, since everything else is functioning fine).

I don't know if that's a bug, or whether I'm simply oblivious to an error of mine. Any pointers would be greatly appreciated.
THANKS

[BUG] No way to provide empty response body as return example

Describe the bug
When describing an endpoint, there is no way to define an empty response body

To Reproduce

Add a docblock with the following content
/**
 * DELETE /api/v1/products/{id}
 * @summary Delete product with specific ID
 * @tags Products
 * @param {number} id.path.required
 * @return 201 - Success Response
 */

Expected behavior
Produces a swagger response example with an empty body

Actual behavior
Produces example response with a "string" body. In the case of an empty response body, this section should be empty.

Screenshots Screen Shot 2021-06-14 at 5 59 45 PM

The following is an example from another Swagger API doc with an empty response:
Screen Shot 2021-06-14 at 6 08 37 PM

It's worth noting that if you attempt any of the following comments, the Swagger docs fail to render and display an error:

/**
 * fails to build docs:
 * @return {undefined} 201 - Success Response
 * @return {null} 201 - Success Response
 * 
 * displays "string" as body type:
 * @return {void} 201 - Success Response
 * @return 201 - Success Response
 */

[Enhancement] Security configuration in path method

We need to add the feature of the security method for each endpoint. We've already added the configuration and schemas in this PR #18 so we have to add for the endpoint config.

The API for the user can be:

/**
 * POST /api/v1/song
 * @summary Create new song
 * @security BasicAuth
 */

Note: BasicAuth is the name we provide in the security options like in this example.

const options = {
  info: {
    version: '1.0.0',
    title: 'Albums store',
    license: {
      name: 'MIT',
    },
  },
  security: {
    BasicAuth: {
      type: 'http',
      scheme: 'basic',
    },
  },
  file: './basic-auth.js',
  baseDir: __dirname,
};

Expected son should be like this one in each endpoint:

"security": [
  {
     "BasicAuth": []
  }
]

Tasks

  • Include it as an option in this function.

[Enhancement] Improve error message

Is your feature request related to a problem? Please describe.
When I type something wrong I don't have a very useful error. This happens when we miss some of the types in the responses.

Describe alternatives you've considered
Maybe we can show a better error message with chalk.

how to exprot apidocs to postman or like a json file

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

[Enhancement] Merge option

In order to always provide support to any kind of option in swagger. We thought in to provide the option of sending a full swagger JSON as parameter with the options we don't support and merge with the one we generate with jsdoc comments.

In order to get this, we can use the Lodash merge method (I'm not sure about that option) or this package.

This is still needed to be decided so I'll tag as a question.

Import typdef

Describe the bug
I cant import typedef

To Reproduce
/**

  • @Property {import('./myImportedDef.dto').myImportedDef} myImportedDef
    */

Expected behavior
Squema generation for swagger

[Enhancement] Event emitter feature

We want to expose our package as an event emitter so the user can receive events of what is happening in our parse functions.

This will be very useful for the user as we allow them to know what has been processed or not, the final SwaggerObject, or if there was an error.

We started this development in this Branch but it needs to be updated.

The API of this emitter can be something like this.

const swaggerGenerator = require('express-jsdoc-swagger');
const express = require('express');

const options = {
  info: {
    version: '1.0.0',
    title: 'Albums store',
    license: {
      name: 'MIT',
    },
  },
  file: './simple.js',
  baseDir: __dirname,
};

const app = express();
const generator = swaggerGenerator(app)(options);

// Event emitter API
generator.on('error', error => {
  // user can handle errors
});

generator.on('process', ({ entity, swaggerObject }) => {
  // user can handle swaggerObject status and which entity was evaluated
});

generator.on('finish', swaggerObject => {
  // user can handle see swaggerObject final result
});

[Chore] Add Github action to publish package

We need to add Github's actions to publish this repo as an npm package. We will need to set up an npm secret and create workflow YAML.

question

  • which npm account are we going to use? Could we create an organization account? 🤔

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.