[
  {
    "path": ".all-contributorsrc",
    "content": "{\n  \"files\": [\n    \"README.md\"\n  ],\n  \"imageSize\": 100,\n  \"commit\": false,\n  \"contributors\": [\n    {\n      \"login\": \"bri06\",\n      \"name\": \"Briam Martinez Escobar\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/24435223?v=4\",\n      \"profile\": \"https://github.com/bri06\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"kevinccbsg\",\n      \"name\": \"Kevin Julián Martínez Escobar\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/12685053?v=4\",\n      \"profile\": \"https://twitter.com/kjmesc\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"hoonga\",\n      \"name\": \"Heung-yeon Oh\",\n      \"avatar_url\": \"https://avatars3.githubusercontent.com/u/10708927?v=4\",\n      \"profile\": \"https://github.com/hoonga\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"LonelyPrincess\",\n      \"name\": \"Sara Hernández\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/17673317?v=4\",\n      \"profile\": \"https://github.com/LonelyPrincess\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"servatj\",\n      \"name\": \"Josep Servat\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/3521485?v=4\",\n      \"profile\": \"http://servatj.me\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"thuydx55\",\n      \"name\": \"Nick Dong\",\n      \"avatar_url\": \"https://avatars2.githubusercontent.com/u/1469984?v=4\",\n      \"profile\": \"https://github.com/thuydx55\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"Stosiu\",\n      \"name\": \"Aleksander Stós\",\n      \"avatar_url\": \"https://avatars1.githubusercontent.com/u/10252063?v=4\",\n      \"profile\": \"https://github.com/Stosiu\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"kdankert\",\n      \"name\": \"Kjell Dankert\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/46489624?v=4\",\n      \"profile\": \"https://github.com/kdankert\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"juliendu11\",\n      \"name\": \"juliendu11\",\n      \"avatar_url\": \"https://avatars0.githubusercontent.com/u/18739442?v=4\",\n      \"profile\": \"https://github.com/juliendu11\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"meabed\",\n      \"name\": \"Mohamed Meabed\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/45731?v=4\",\n      \"profile\": \"https://me.io\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"ofarukaydin\",\n      \"name\": \"Faruk Aydın\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/32788963?v=4\",\n      \"profile\": \"https://github.com/ofarukaydin\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"dahlmo\",\n      \"name\": \"Dahlmo\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/23076026?v=4\",\n      \"profile\": \"https://github.com/dahlmo\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"gandazgul\",\n      \"name\": \"Carlos Ravelo\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/108850?v=4\",\n      \"profile\": \"https://github.com/gandazgul\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"paulish\",\n      \"name\": \"Paul Ishenin\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/1762032?v=4\",\n      \"profile\": \"https://github.com/paulish\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"sbingner\",\n      \"name\": \"Sam Bingner\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/354533?v=4\",\n      \"profile\": \"https://github.com/sbingner\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"alexstaroselsky\",\n      \"name\": \"Alexander Staroselsky\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/34102969?v=4\",\n      \"profile\": \"https://stackoverflow.com/users/5059657/alexander-staroselsky\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"joelabrahamsson\",\n      \"name\": \"Joel Abrahamsson\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/218986?v=4\",\n      \"profile\": \"http://joelabrahamsson.com\",\n      \"contributions\": [\n        \"code\"\n      ]\n    },\n    {\n      \"login\": \"MakakWasTaken\",\n      \"name\": \"Markus Moltke\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/11789635?v=4\",\n      \"profile\": \"https://github.com/MakakWasTaken\",\n      \"contributions\": [\n        \"code\"\n      ]\n    }\n  ],\n  \"contributorsPerLine\": 7,\n  \"projectName\": \"express-jsdoc-swagger\",\n  \"projectOwner\": \"BRIKEV\",\n  \"repoType\": \"github\",\n  \"repoHost\": \"https://github.com\",\n  \"skipCi\": true,\n  \"commitType\": \"docs\",\n  \"commitConvention\": \"angular\"\n}\n"
  },
  {
    "path": ".eslintignore",
    "content": ".nyc_output\ncoverage\ntest-results.xml\nnode_modules\n.github\nexamples\n"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"env\": {\n    \"commonjs\": true,\n    \"es6\": true,\n    \"node\": true,\n    \"jest/globals\": true\n  },\n  \"extends\": [\n    \"airbnb-base\"\n  ],\n  \"plugins\": [\"jest\"],\n  \"globals\": {\n    \"Atomics\": \"readonly\",\n    \"SharedArrayBuffer\": \"readonly\"\n  },\n  \"parserOptions\": {\n    \"ecmaVersion\": 11\n  },\n  \"rules\": {\n    \"arrow-parens\": [\n      \"error\",\n      \"as-needed\",\n      {\n        \"requireForBlockBody\": false\n      }\n    ],\n    \"jest/no-disabled-tests\": \"warn\",\n    \"jest/no-focused-tests\": \"error\",\n    \"jest/no-identical-title\": \"error\",\n    \"jest/prefer-to-have-length\": \"warn\",\n    \"jest/valid-expect\": \"error\",\n    \"max-len\": [\"error\", {\n      \"ignoreComments\": true,\n      \"code\": 130\n    }]\n  }\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: brikev\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"[BUG]\"\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nPlease share your JSDoc comments or your configuration so that we can reproduce the bug\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "### What kind of change does this PR introduce? (check at least one)\n - [ ] Bugfix\n - [ ] Feature\n - [ ] Test\n - [ ] Docs\n - [ ] Refactor\n - [ ] Build-related changes\n - [ ] Other, please describe:\n\n### Description:"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "content": "name: Publish\n\non:\n  release:\n    types: [published]\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v1\n      - uses: actions/setup-node@v1\n        with:\n          node-version: 18\n          registry-url: https://registry.npmjs.org/\n      - run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}\n"
  },
  {
    "path": ".github/workflows/runTests.yml",
    "content": "# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created\n# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages\n\nname: Build\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: [master]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version: [18.x, 20.x]\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v1\n        with:\n          node-version: ${{ matrix.node-version }}\n      - run: npm ci\n      - run: npm run lint -- --fix\n      - run: npm test\n  coverage:\n    name: coverage\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@master\n    - uses: actions/setup-node@master\n      with:\n        node-version: '20'\n    - run: npm ci\n    - uses: paambaati/codeclimate-action@v2.6.0\n      env:\n        CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}\n      with:\n        coverageCommand: npm test -- --coverage\n        coverageLocations: |\n          ${{github.workspace}}/coverage/lcov.info:lcov\n"
  },
  {
    "path": ".gitignore",
    "content": "\n# Created by https://www.gitignore.io/api/node,linux,macos,windows\n# Edit at https://www.gitignore.io/?templates=node,linux,macos,windows\n\n### Linux ###\n*~\n.vscode\n# temporary files which can be created if a process still has a handle open of a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n### macOS ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### Node ###\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# TypeScript cache\n*.tsbuildinfo\nbuild\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n.env.test\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# rollup.js default build output\ndist/\n\n# Uncomment the public line if your project uses Gatsby\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# https://create-react-app.dev/docs/using-the-public-folder/#docsNav\n# public\n\n# Storybook build outputs\n.out\n.storybook-out\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# Temporary folders\ntmp/\ntemp/\n\n### Windows ###\n# Windows thumbnail cache files\nThumbs.db\nThumbs.db:encryptable\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n# End of https://www.gitignore.io/api/node,linux,macos,windows\n.idea\n"
  },
  {
    "path": ".npmignore",
    "content": ".DS_Store\nnpm-debug.log\nexamples\ntest\n.github\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at hello.brikev@gmail.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to express-jsdoc-swagger\n\nThanks for your interest in express-jsdoc-swagger. Our goal is to provide an easy Swagger OpenAPI 3.x generator using simple JSDoc comments.\n\n## Contributions\n\nexpress-jsdoc-swagger welcomes contributions from everyone.\n\nContributions to express-jsdoc-swagger should be made in the form of GitHub pull requests. Each pull request will\nbe reviewed by a core contributor ([@bri06](https://github.com/bri06) or [@kevinccbsg](https://github.com/kevinccbsg)) and either landed in the\nmain tree or given feedback for changes that would be required.\n\n## Getting Started\n\nexpress-jsdoc-swagger's [open issues are here](https://github.com/BRIKEV/express-jsdoc-swagger/issues).\n\nexpress-jsdoc-swagger's [docs are here](https://brikev.github.io/express-jsdoc-swagger-docs/#/).\n\nYou can clone this repository and run this command to start using developing this package.\n\n```\nnpm install\n```\n\nIf you want to test it you can add a new test in [this folder](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/test) or you can create a new example [here](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples).\n\nTo execute package's tests you have run this command:\n\n```\nnpm test\n```\n\nPlease also ensure linting is correct while you're developing by running this command:\n\n```\nnpm run lint\n```\n\n## Pull Request Checklist\n\n- [Check validations](https://github.com/BRIKEV/express-jsdoc-swagger/actions?query=workflow%3ABuild) should pass. This one includes linting and testing.\n\n- Commits should be as small as possible, while ensuring that each commit is\n  correct independently (i.e., each commit should compile and pass tests). \n\n- If your patch is not getting reviewed or you need a specific person to review\n  it, you can @-reply a reviewer asking for a review in the pull request or a\n  comment.\n\n\n## Conduct\n\nWe follow the [express-jsdoc-swagger Code of Conduct](https://github.com/BRIKEV/express-jsdoc-swagger/blob/master/CODE_OF_CONDUCT.md).\n\nAll code in this repository is under [MIT License](https://github.com/BRIKEV/express-jsdoc-swagger/blob/master/LICENSE.md).\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 BRIKEV\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "![npm](https://img.shields.io/npm/v/express-jsdoc-swagger)\n![Node.js Package](https://github.com/BRIKEV/express-jsdoc-swagger/workflows/Build/badge.svg)\n[![Known Vulnerabilities](https://snyk.io/test/github/BRIKEV/express-jsdoc-swagger/badge.svg)](https://snyk.io/test/github/BRIKEV/express-jsdoc-swagger)\n[![Maintainability](https://api.codeclimate.com/v1/badges/6d5565df0c9c10e75b59/maintainability)](https://codeclimate.com/github/BRIKEV/express-jsdoc-swagger/maintainability)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/6d5565df0c9c10e75b59/test_coverage)](https://codeclimate.com/github/BRIKEV/express-jsdoc-swagger/test_coverage)\n![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)\n![npm](https://img.shields.io/npm/dm/express-jsdoc-swagger)\n\n# express-jsdoc-swagger\n\nWith this library, you can document your express endpoints using swagger [OpenAPI 3 Specification](https://swagger.io/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.\n\n## Table of Contents\n\n1. [Prerequisites](#Prerequisites)\n2. [Installation](#Installation)\n3. [Basic Usage](#Basic-Usage)\n4. [Basic Examples](#Basic-Examples)\n\t- [Advanced examples](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples)\n\t- [Official docs](https://brikev.github.io/express-jsdoc-swagger-docs/#/)\n5. [Validator](#Validator)\n6. [VSCode extension](https://marketplace.visualstudio.com/items?itemName=brikev.express-jsdoc-swagger-snippets)\n\n## Prerequisites\n\nThis library assumes you are using:\n\n1. [NodeJS](https://nodejs.org)\n2. [Express.js](http://www.expressjs.com)\n\n## Installation\n\n```\nnpm i express-jsdoc-swagger\n```\n\n## Basic Usage\n\n```javascript\n// index.js file\nconst express = require('express');\nconst expressJSDocSwagger = require('express-jsdoc-swagger');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  security: {\n    BasicAuth: {\n      type: 'http',\n      scheme: 'basic',\n    },\n  },\n  // Base directory which we use to locate your JSDOC files\n  baseDir: __dirname,\n  // Glob pattern to find your jsdoc files (multiple patterns can be added in an array)\n  filesPattern: './**/*.js',\n  // URL where SwaggerUI will be rendered\n  swaggerUIPath: '/api-docs',\n  // Expose OpenAPI UI\n  exposeSwaggerUI: true,\n  // Expose Open API JSON Docs documentation in `apiDocsPath` path.\n  exposeApiDocs: false,\n  // Open API JSON Docs endpoint.\n  apiDocsPath: '/v3/api-docs',\n  // Set non-required fields as nullable by default\n  notRequiredAsNullable: false,\n  // You can customize your UI options.\n  // you can extend swagger-ui-express config. You can checkout an example of this\n  // in the `example/configuration/swaggerOptions.js`\n  swaggerUiOptions: {},\n  // multiple option in case you want more that one instance\n  multiple: true,\n};\n\nconst app = express();\nconst PORT = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @return {object} 200 - success response\n */\napp.get('/api/v1', (req, res) => res.json({\n  success: true,\n}));\n\napp.listen(PORT, () => console.log(`Example app listening at http://localhost:${PORT}`));\n```\n\n## Basic Examples\n\n1. Basic configuration options.\n\n```javascript\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  security: {\n    BasicAuth: {\n      type: 'http',\n      scheme: 'basic',\n    },\n  },\n  baseDir: __dirname,\n  // Glob pattern to find your jsdoc files (multiple patterns can be added in an array)\n  filesPattern: './**/*.js',\n};\n```\n\n2. Components definition\n\n```javascript\n/**\n * A song type\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {number} year - The year - double\n */\n```\n\n3. Endpoint which returns a `Songs` model array in the response.\n\n```javascript\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @tags album\n * @return {array<Song>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n```\n\n3. Endpoint PUT with body and path params which returns a `Songs` model array in the response.\n\n```javascript\n/**\n * PUT /api/v1/albums/{id}\n * @summary Update album\n * @tags album\n * @param {string} name.path - name param description\n * @param {Song} request.body.required - songs info\n * @return {array<Song>} 200 - success response - application/json\n */\napp.put('/api/v1/albums/:id', (req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n```\n\n4. Basic endpoint definition with tags, params and basic authentication\n\n```javascript\n/**\n * GET /api/v1/album\n * @summary This is the summary of the endpoint\n * @security BasicAuth\n * @tags album\n * @param {string} name.query.required - name param description\n * @return {object} 200 - success response - application/json\n * @return {object} 400 - Bad request response\n */\napp.get('/api/v1/album', (req, res) => (\n  res.json({\n    title: 'abum 1',\n  })\n));\n```\n\n5. Basic endpoint definition with code example for response body\n\n```javascript\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @tags album\n * @return {array<Song>} 200 - success response - application/json\n * @example response - 200 - success response example\n * [\n *   {\n *     \"title\": \"Bury the light\",\n *     \"artist\": \"Casey Edwards ft. Victor Borba\",\n *     \"year\": 2020\n *   }\n * ]\n */\napp.get('/api/v1/albums', (req, res) => (\n  res.json([{\n    title: 'track 1',\n  }])\n));\n```\n\nYou can find more examples [here](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples), or visit our [documentation](https://brikev.github.io/express-jsdoc-swagger-docs/#/).\n\n\n## Validator\n\nWe 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](https://github.com/BRIKEV/express-oas-validator).\n\n**Example**\n\nInstall using the node package registry:\n\n```\nnpm install --save express-oas-validator\n```\n\nWe have to wait until we have the full swagger schema to initiate the validator.\n\n```js\n// validator.js\nconst { init } = require('express-oas-validator');\n\nconst validators = instance => new Promise((resolve, reject) => {\n  instance.on('finish', (swaggerDef) => {\n    const { validateRequest, validateResponse } = init(swaggerDef);\n    resolve({ validateRequest, validateResponse });\n  });\n\n  instance.on('error', (error) => {\n    reject(error);\n  });\n});\n\nmodule.exports = validators;\n\n```\n\nYou can check out this also in our [example folder](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/validator).\n\n```js\n// index.js\nconst express = require('express');\nconst expressJSDocSwagger = require('express-jsdoc-swagger');\nconst validator = require('./validator');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './**.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst instance = expressJSDocSwagger(app)(options);\n\nconst serverApp = async () => {\n  const { validateRequest, validateResponse } = await validator(instance);\n  app.use(express.urlencoded({ extended: true }));\n  app.use(express.json());\n  /**\n   * A song\n   * @typedef {object} Song\n   * @property {string} title.required - The title\n   * @property {string} artist - The artist\n   * @property {integer} year - The year\n   */\n\n  /**\n   * POST /api/v1/songs\n   * @param {Song} request.body.required - song info\n   * @return {object} 200 - song response\n   */\n  app.post('/api/v1/songs', validateRequest(), (req, res) => res.send('You save a song!'));\n\n  /**\n   * POST /api/v1/name\n   * @param {string} request.body.required - name body description\n   * @return {object} 200 - song response\n   */\n  app.post('/api/v1/name', (req, res, next) => {\n    try {\n      // Validate response\n      validateResponse('Error string', req);\n      return res.send('Hello World!');\n    } catch (error) {\n      return next(error);\n    }\n  });\n\n  /**\n   * GET /api/v1/authors\n   * @summary This is the summary or description of the endpoint\n   * @param {string} name.query.required - name param description - enum:type1,type2\n   * @param {array<string>} license.query - name param description\n   * @return {object} 200 - success response - application/json\n   */\n  app.get('/api/v1/authors', validateRequest({ headers: false }), (req, res) => (\n    res.json([{\n      title: 'album 1',\n    }])\n  ));\n\n  // eslint-disable-next-line no-unused-vars\n  app.use((err, req, res, next) => {\n    res.status(err.status).json(err);\n  });\n\n  return app;\n};\n\nconst PORT = process.env.PORT || 4000;\n\nserverApp()\n  .then(app => \n    app.listen(PORT, () =>\n      console.log(`Listening PORT: ${PORT}`)\n    ))\n  .catch((err) => {\n    console.error(err);\n    process.exit(1);\n  });\n```\n\nYou can visit our [documentation](https://brikev.github.io/express-jsdoc-swagger-docs/#/validator).\n\n## Contributors ✨\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tbody>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/bri06\"><img src=\"https://avatars0.githubusercontent.com/u/24435223?v=4?s=100\" width=\"100px;\" alt=\"Briam Martinez Escobar\"/><br /><sub><b>Briam Martinez Escobar</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=bri06\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://twitter.com/kjmesc\"><img src=\"https://avatars2.githubusercontent.com/u/12685053?v=4?s=100\" width=\"100px;\" alt=\"Kevin Julián Martínez Escobar\"/><br /><sub><b>Kevin Julián Martínez Escobar</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=kevinccbsg\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/hoonga\"><img src=\"https://avatars3.githubusercontent.com/u/10708927?v=4?s=100\" width=\"100px;\" alt=\"Heung-yeon Oh\"/><br /><sub><b>Heung-yeon Oh</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=hoonga\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/LonelyPrincess\"><img src=\"https://avatars1.githubusercontent.com/u/17673317?v=4?s=100\" width=\"100px;\" alt=\"Sara Hernández\"/><br /><sub><b>Sara Hernández</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=LonelyPrincess\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://servatj.me\"><img src=\"https://avatars0.githubusercontent.com/u/3521485?v=4?s=100\" width=\"100px;\" alt=\"Josep Servat\"/><br /><sub><b>Josep Servat</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=servatj\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/thuydx55\"><img src=\"https://avatars2.githubusercontent.com/u/1469984?v=4?s=100\" width=\"100px;\" alt=\"Nick Dong\"/><br /><sub><b>Nick Dong</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=thuydx55\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/Stosiu\"><img src=\"https://avatars1.githubusercontent.com/u/10252063?v=4?s=100\" width=\"100px;\" alt=\"Aleksander Stós\"/><br /><sub><b>Aleksander Stós</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=Stosiu\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/kdankert\"><img src=\"https://avatars0.githubusercontent.com/u/46489624?v=4?s=100\" width=\"100px;\" alt=\"Kjell Dankert\"/><br /><sub><b>Kjell Dankert</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=kdankert\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/juliendu11\"><img src=\"https://avatars0.githubusercontent.com/u/18739442?v=4?s=100\" width=\"100px;\" alt=\"juliendu11\"/><br /><sub><b>juliendu11</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=juliendu11\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://me.io\"><img src=\"https://avatars.githubusercontent.com/u/45731?v=4?s=100\" width=\"100px;\" alt=\"Mohamed Meabed\"/><br /><sub><b>Mohamed Meabed</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=meabed\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/ofarukaydin\"><img src=\"https://avatars.githubusercontent.com/u/32788963?v=4?s=100\" width=\"100px;\" alt=\"Faruk Aydın\"/><br /><sub><b>Faruk Aydın</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=ofarukaydin\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/dahlmo\"><img src=\"https://avatars.githubusercontent.com/u/23076026?v=4?s=100\" width=\"100px;\" alt=\"Dahlmo\"/><br /><sub><b>Dahlmo</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=dahlmo\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/gandazgul\"><img src=\"https://avatars.githubusercontent.com/u/108850?v=4?s=100\" width=\"100px;\" alt=\"Carlos Ravelo\"/><br /><sub><b>Carlos Ravelo</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=gandazgul\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/paulish\"><img src=\"https://avatars.githubusercontent.com/u/1762032?v=4?s=100\" width=\"100px;\" alt=\"Paul Ishenin\"/><br /><sub><b>Paul Ishenin</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=paulish\" title=\"Code\">💻</a></td>\n    </tr>\n    <tr>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/sbingner\"><img src=\"https://avatars.githubusercontent.com/u/354533?v=4?s=100\" width=\"100px;\" alt=\"Sam Bingner\"/><br /><sub><b>Sam Bingner</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=sbingner\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://stackoverflow.com/users/5059657/alexander-staroselsky\"><img src=\"https://avatars.githubusercontent.com/u/34102969?v=4?s=100\" width=\"100px;\" alt=\"Alexander Staroselsky\"/><br /><sub><b>Alexander Staroselsky</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=alexstaroselsky\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"http://joelabrahamsson.com\"><img src=\"https://avatars.githubusercontent.com/u/218986?v=4?s=100\" width=\"100px;\" alt=\"Joel Abrahamsson\"/><br /><sub><b>Joel Abrahamsson</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=joelabrahamsson\" title=\"Code\">💻</a></td>\n      <td align=\"center\" valign=\"top\" width=\"14.28%\"><a href=\"https://github.com/MakakWasTaken\"><img src=\"https://avatars.githubusercontent.com/u/11789635?v=4?s=100\" width=\"100px;\" alt=\"Markus Moltke\"/><br /><sub><b>Markus Moltke</b></sub></a><br /><a href=\"https://github.com/BRIKEV/express-jsdoc-swagger/commits?author=MakakWasTaken\" title=\"Code\">💻</a></td>\n    </tr>\n  </tbody>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n"
  },
  {
    "path": "commitlint.config.js",
    "content": "/* Examples\n  * chore: run tests on travis ci\n  * fix(server): send cors headers\n  * feat(blog): add comment section\n */\n/* Common Errors\n  * subject must not be sentence-case, start-case, pascal-case, upper-case [subject-case]\n  * type must be lower-case [type-case]\n  * type must be one of\n  *   [build, chore, ci, docs, feat, fix, improvement, perf, refactor, revert, style, test]\n */\n/*\n  * docs - Add or edit documentation.\n  * feat - Implementation of new feature.\n  * improvement - Enhancements on existing features.\n  * fix - Changes that solve existing bugs in the application.\n  * perf - Changes to improve the application's performance.\n  * refactor - Code enhancements that do not alter the functionality.\n  * style - Fix front end styles\n  * test - Add or edit tests\n */\nmodule.exports = {\n  extends: ['@commitlint/config-conventional'],\n};\n"
  },
  {
    "path": "config/default.js",
    "content": "const expressJSDocSwaggerOptions = {\n  // Absolute path of the application\n  baseDir: __dirname,\n  // Glob pattern to find your jsdoc files (multiple patterns can be added in an array)\n  filesPattern: './**/*.js',\n  // URL where SwaggerUI will be rendered\n  swaggerUIPath: '/api-docs',\n  // Expose OpenAPI UI\n  exposeSwaggerUI: true,\n  // Expose Open API JSON Docs documentation in `apiDocsPath` path.\n  exposeApiDocs: false,\n  // Open API JSON Docs endpoint.\n  apiDocsPath: '/v3/api-docs',\n  // Set non-required fields as nullable by default\n  notRequiredAsNullable: false,\n};\n\nmodule.exports = expressJSDocSwaggerOptions;\n"
  },
  {
    "path": "config/swaggerEvents.js",
    "content": "const swaggerEvents = options => ({\n  multiple: options.multiple !== undefined ? options.multiple : false,\n});\n\nmodule.exports = swaggerEvents;\n"
  },
  {
    "path": "consumers/getOnlyComments.js",
    "content": "const getComments = require('./utils/getComments');\n\nconst flat = array => [].concat(...array);\n\nconst trimComment = comment => comment.trim();\n\nconst removeSimpleComments = comment => (comment[0] === '/' && comment[1] !== '/');\n\nconst processComments = comment => {\n  const trimedComments = trimComment(comment);\n  return getComments(trimedComments);\n};\n\nconst getOnlyComments = (files = []) => {\n  if (!Array.isArray(files)) return [];\n  const comments = files\n    .map(processComments);\n  return flat(comments).filter(removeSimpleComments);\n};\n\nmodule.exports = getOnlyComments;\n"
  },
  {
    "path": "consumers/globFilesMatches.js",
    "content": "const glob = require('glob');\nconst path = require('path');\n\nconst DEFAULT_EXCLUDED_FOLDER = 'node_modules';\nconst DEFAULT_GLOB_OPTIONS = { ignore: '**/node_modules/**' };\n\nconst globFilesMatches = (baseDir, filesPattern, excludedFolder = DEFAULT_EXCLUDED_FOLDER) => (\n  new Promise((resolve, reject) => {\n    if (!baseDir || !filesPattern) {\n      const error = new Error('baseDir and filePath are required');\n      return reject(error);\n    }\n\n    if (!Array.isArray(filesPattern) && typeof filesPattern !== 'string') {\n      const error = new Error('files pattern has to be a type of string');\n      return reject(error);\n    }\n\n    if (Array.isArray(filesPattern)) {\n      if (filesPattern.length === 0) {\n        const error = new Error('if you submit an array of filesPattern it must contain at least one pattern');\n        return reject(error);\n      }\n\n      if (filesPattern.some(pattern => typeof pattern !== 'string')) {\n        const error = new Error('all file patterns have to be strings');\n        return reject(error);\n      }\n    }\n\n    try {\n      let files;\n      if (!Array.isArray(filesPattern)) {\n        files = glob.sync(path.resolve(baseDir, filesPattern), DEFAULT_GLOB_OPTIONS);\n      } else {\n        files = filesPattern\n          .map(pattern => glob.sync(path.resolve(baseDir, pattern), DEFAULT_EXCLUDED_FOLDER))\n          .reduce((memo, it) => memo.concat(it), [])\n          .filter((value, index, self) => self.indexOf(value) === index);\n      }\n\n      const filteredFiles = files.filter(file => !file.includes(excludedFolder));\n      return resolve(filteredFiles);\n    } catch (error) {\n      return reject(error);\n    }\n  })\n);\n\nmodule.exports = globFilesMatches;\n"
  },
  {
    "path": "consumers/jsdocInfo.js",
    "content": "const doctrine = require('doctrine');\n\nconst jsdocInfo = (options = { unwrap: true }) => comments => {\n  if (!comments || !Array.isArray(comments)) return [];\n  return comments.map(comment => {\n    const parsedValue = doctrine.parse(comment, options);\n    const tags = parsedValue.tags.map(tag => ({\n      ...tag,\n      description: tag.description ? tag.description.replace('\\n/', '').replace(/\\/$/, '') : tag.description,\n    }));\n    const description = parsedValue.description.replace('/**\\n', '').replace('\\n/', '');\n    return {\n      ...parsedValue,\n      tags,\n      description,\n    };\n  });\n};\n\nmodule.exports = jsdocInfo;\n"
  },
  {
    "path": "consumers/readFiles.js",
    "content": "const readFile = require('./utils/readFile');\n\nconst readFiles = files => {\n  if (!files || !Array.isArray(files)) return Promise.resolve([]);\n  const filesInfo = files.map(file => readFile(file));\n  return Promise.all(filesInfo);\n};\n\nmodule.exports = readFiles;\n"
  },
  {
    "path": "consumers/utils/getComments.js",
    "content": "const COMMENTS_PATTERN = /((\\/\\*\\*+[\\s\\S]*?\\*\\/)|(\\/\\*+.*\\*\\/)|^\\/\\/.*?[\\r\\n])[\\r\\n]*/gm;\nconst BREAK_LINE = /\\n/g;\n\nconst getComments = text => {\n  const comments = text.match(COMMENTS_PATTERN);\n  if (comments) {\n    const filterComments = comments.filter(comment => comment.match(BREAK_LINE));\n    return filterComments.map(comment => comment.trim());\n  }\n  return [];\n};\n\nmodule.exports = getComments;\n"
  },
  {
    "path": "consumers/utils/readFile.js",
    "content": "const fs = require('fs');\n\nconst readFile = path => (\n  new Promise((resolve, reject) => {\n    let data = '';\n    const readStream = fs.createReadStream(path, 'utf8');\n    readStream.on('data', chunk => {\n      data += chunk;\n    })\n      .on('end', () => resolve(data))\n      .on('error', error => reject(error));\n  })\n);\n\nmodule.exports = readFile;\n"
  },
  {
    "path": "examples/README.md",
    "content": "# express-jsdoc-swagger examples\n\nThis page will includes some examples on how to use this package.\n\n- [configuration](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/configuration)\n- [responses](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/responses)\n- [components](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/components)\n- [request body](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/requestBody)\n- [parameters](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/parameters)\n- [security](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/security)\n- [tags](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/tags)\n- [Combine schemas](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/combineSchemas)\n- [Event Emitter example](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/eventEmitter)\n- [Merge option](https://github.com/BRIKEV/express-jsdoc-swagger/tree/master/examples/merge)\n- albumAPI - WIP\n\n\n## Run examples\n\nYou can run this examples in your machine following these steps.\n\n1. Install dependencies inside examples folder\n\n```\nnpm install\n```\n\n2. You can run every example if you execute\n\n```\nnpm run <FOLDER>:<FILE_NAME>\n\nnpm run responses:simple\n```\n\nThen you can go to the [Docs generated page](http://localhost:3000/api-docs).\n"
  },
  {
    "path": "examples/combineSchemas/index.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './index.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} IntrumentalSong\n * @property {string} title.required - The title\n * @property {string} band - The band\n * @property {number} year - The year - double\n */\n\n/**\n * A song\n * @typedef {object} PopSong\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * GET /api/v1/song/{id}\n * @summary This is the summary of the endpoint\n * @tags album\n * @param {number} id.path - song id\n * @return {oneOf|IntrumentalSong|PopSong} 200 - success response - application/json\n */\napp.get('/api/v1/song/:id', (_req, res) => (\n  res.json({\n    title: 'abum 1',\n  })\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/components/enum.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './enum.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {number} artist - The artist - double\n * @property {string} license - The year - enum:ISC,MIT\n */\n\n/**\n * Author model\n * @typedef {object} Author\n * @property {string} name.required - Author name\n * @property {string} role - enum:singer,guitarrist - The author role\n * @property {integer} age - Author age - int64\n */\n\n/**\n * Album\n * @typedef {object} Album\n * @property {Song} firstSong\n * @property {Author} author\n */\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/components/simple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * Author model\n * @typedef {object} Author\n * @property {string} name.required - Author name\n * @property {number} age - Author age - double\n */\n\n/**\n * Album\n * @typedef {object} Album\n * @property {Song} firstSong\n * @property {Author} author\n */\n\n/**\n * Album\n * @typedef {object} Album\n * @property {string} title - The title\n * @property {array<number>} years\n */\n\n/**\n * Album\n * @typedef {object} Album\n * @property {array<Song>} Songs\n */\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/configuration/index.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst app = express();\nconst port = 3000;\n\n// It is a fictitious configuration\nconst optionsClientAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Client API',\n    description: 'For client',\n  },\n  filesPattern: '../client-v1-docs.js',\n  swaggerUIPath: '/api/v1/client/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/client/api-docs',\n};\n\n// It is a fictitious configuration\nconst optionsAdminAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Admin API',\n    description: 'Only admin accounts authorized to use this API',\n  },\n  security: {\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n      bearerFormat: 'JWT',\n    },\n  },\n  filesPattern: './admin-v1-docs.js',\n  swaggerUIPath: '/api/v1/admin/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/admin/api-docs',\n};\n\nexpressJSDocSwagger(app)(optionsClientAPIInstance);\nexpressJSDocSwagger(app)(optionsAdminAPIInstance);\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/configuration/main.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\n// This is a full set of options\n// It is not neccesary to complete every option\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  servers: [\n    {\n      url: 'https://{username}.gigantic-server.com:{port}/{basePath}',\n      description: 'The production API server',\n      variables: {\n        username: {\n          default: 'demo',\n          description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',\n        },\n        port: {\n          enum: [\n            '8443',\n            '443',\n          ],\n          default: '8443',\n        },\n        basePath: {\n          default: 'v2',\n        },\n      },\n    },\n  ],\n  filesPattern: './main.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/configuration/multiple-files.txt",
    "content": "/**\n * GET /api/v2\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */"
  },
  {
    "path": "examples/configuration/multipleFiles.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\n// This is a full set of options\n// It is not neccesary to complete every option\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  servers: [\n    {\n      url: 'https://{username}.gigantic-server.com:{port}/{basePath}',\n      description: 'The production API server',\n      variables: {\n        username: {\n          default: 'demo',\n          description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',\n        },\n        port: {\n          enum: [\n            '8443',\n            '443',\n          ],\n          default: '8443',\n        },\n        basePath: {\n          default: 'v2',\n        },\n      },\n    },\n  ],\n  filesPattern: ['./multipleFiles.js', './multiple-files.txt'],\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/configuration/multipleInstance/admin-v1-docs.js",
    "content": "/**\n * GET /api/admin/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "examples/configuration/multipleInstance/client-v1-docs.js",
    "content": "/**\n * GET /api/client/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "examples/configuration/multipleInstance/index.js",
    "content": "const express = require('express');\n\nconst logger = require('../../utils/logger');\nconst expressJSDocSwagger = require('../../..');\n\nconst app = express();\nconst port = 3000;\n\n// It is a fictitious configuration\nconst optionsClientAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Client API',\n    description: 'For client',\n  },\n  filesPattern: './client-v1-docs.js',\n  swaggerUIPath: '/api/v1/client/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/client/api-docs',\n  multiple: true,\n};\n\n// It is a fictitious configuration\nconst optionsAdminAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Admin API',\n    description: 'Only admin accounts authorized to use this API',\n  },\n  security: {\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n      bearerFormat: 'JWT',\n    },\n  },\n  filesPattern: './admin-v1-docs.js',\n  swaggerUIPath: '/api/v1/admin/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/admin/api-docs',\n  multiple: true,\n};\n\nconst instance = expressJSDocSwagger(app)(optionsClientAPIInstance);\nconst instance2 = expressJSDocSwagger(app)(optionsAdminAPIInstance);\n\ninstance.on('finish', data => {\n  console.log(data);\n})\n\ninstance2.on('finish', data => {\n  console.log(data);\n})\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/configuration/swaggerOptions.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\n// This is a full set of options\n// It is not neccesary to complete every option\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  servers: [],\n  filesPattern: './main.js',\n  baseDir: __dirname,\n  swaggerUiOptions: {\n    swaggerOptions: {\n      // This one removes the modals spec\n      // You can checkout more config info here: https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md\n      defaultModelsExpandDepth: -1,\n    },\n  },\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song type\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @return {array<Song>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => res.json([]));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/eventEmitter/index.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nconst listener = expressJSDocSwagger(app)(options);\n\n// Event emitter API\nlistener.on('error', error => {\n  logger.error(`Error: ${error}`);\n});\n\nlistener.on('process', ({ entity, swaggerObject }) => {\n  logger.info(`entity: ${entity}`);\n  logger.info('swaggerObject');\n  logger.info(swaggerObject);\n});\n\nlistener.on('finish', swaggerObject => {\n  logger.info('Finish');\n  logger.info(swaggerObject);\n});\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/eventEmitter/multipleInstance.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst app = express();\nconst port = 3000;\n\n// It is a fictitious configuration\nconst optionsClientAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Client API',\n    description: 'For client',\n  },\n  filesPattern: '../api/client/v1/*.js',\n  swaggerUIPath: '/api/v1/client/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/client/api-docs',\n};\n\n// It is a fictitious configuration\nconst optionsAdminAPIInstance = {\n  info: {\n    version: '1.0.0',\n    title: 'Admin API',\n    description: 'Only admin accounts authorized to use this API',\n  },\n  security: {\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n      bearerFormat: 'JWT',\n    },\n  },\n  filesPattern: '../api/admin/v1/*.js',\n  swaggerUIPath: '/api/v1/admin/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/admin/api-docs',\n};\n\nconst clientAPIInstance = expressJSDocSwagger(app)(optionsClientAPIInstance);\nconst adminAPIInstance = expressJSDocSwagger(app)(optionsAdminAPIInstance);\n\nclientAPIInstance.on('error', error => {\n  console.error(`[CLIENT]Error: ${error}`);\n});\n\nclientAPIInstance.on('process', ({ entity, swaggerObject }) => {\n  console.log(`[CLIENT]entity: ${entity}`);\n  console.log('[CLIENT]swaggerObject');\n  console.log(swaggerObject);\n});\n\nclientAPIInstance.on('finish', swaggerObject => {\n  console.log('[CLIENT]Finish');\n  console.log(swaggerObject);\n});\n\nadminAPIInstance.on('error', error => {\n  console.error(`[ADMIN]Error: ${error}`);\n});\n\nadminAPIInstance.on('process', ({ entity, swaggerObject }) => {\n  console.log(`[ADMIN]entity: ${entity}`);\n  console.log('[ADMIN]swaggerObject');\n  console.log(swaggerObject);\n});\n\nadminAPIInstance.on('finish', swaggerObject => {\n  console.log('[ADMIN]Finish');\n  console.log(swaggerObject);\n});\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));"
  },
  {
    "path": "examples/merge/simple.js",
    "content": "const express = require('express');\nconst userSwagger = require('./swagger');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n    info: {\n      version: '1.0.0',\n      title: 'Albums store',\n      license: {\n        name: 'MIT',\n        url: 'http://example.com',\n      },\n      description: 'API desctiption',\n      contact: {\n        name: 'contact name',\n        url: 'http://example.com',\n        email: 'test@test.com',\n      },\n      termsOfService: 'http://example.com',\n    },\n    filesPattern: './simple.js',\n    baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options, userSwagger);\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @param {array<object>} name.query.required - name param description\n * @return {array<object>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/merge/swagger.js",
    "content": "const userSwagger = {\n  openapi: '3.0.0',\n  info: {\n    title: 'Albums store',\n    description: 'Add your description',\n    contact: {},\n    license: {\n      name: 'MIT',\n      url: ''\n    },\n    termsOfService: '',\n    version: '1.0.0'\n  },\n  servers: [],\n  components: {\n    schemas: {}\n  },\n  paths: {\n    '/users/{id}': {\n      parameters: [\n        {\n          in: 'path',\n          name: 'id',\n          schema: {\n            type: 'integer'\n          },\n          required: true,\n          description: 'The user ID.'\n        }\n      ],\n      delete: {\n        summary: 'Deletes the user with the specified ID.',\n        responses: {\n          204: {\n            description: 'User was deleted.'\n          }\n        }\n      },\n      get: {\n        summary: 'Gets one or more users by ID.',\n        parameters: [\n          {\n            in: 'path',\n            name: 'id',\n            required: true,\n            description: 'A comma-separated list of user IDs.',\n            schema: {\n              type: 'array',\n              items: {\n                type: 'integer'\n              },\n              minItems: 1\n            },\n            explode: false,\n            style: 'simple'\n          }\n        ],\n        responses: {\n          200: {\n            description: 'OK'\n          }\n        }\n      }\n    }\n  },\n  tags: []\n}\n\nmodule.exports = userSwagger;\n"
  },
  {
    "path": "examples/nullableFields/explicitNullable.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    description: 'Example where we define which specific properties are nullable',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './index.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * @typedef {object} Song\n * @property {number} id.required - Id\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n * @property {oneOf|string|null} album - The album to which the song belongs (if any)\n * @property {(string[]|null)} tags - Associate tags (if any)\n */\n\n/**\n * POST /api/v1/songs\n * @summary Nullable props in request body\n * @param {Song} request.body.required - Song to add\n * @return {string} 200 - Success message\n */\n app.post('/api/v1/songs', (_req, res) => res.send('You saved a song!'));\n\n/**\n * GET /api/v1/song\n * @summary Nullable props in response\n * @return {array<Song>} 200 - List of songs\n */\napp.get('/api/v1/song', (_req, res) => res.json([\n  {\n    id: 1,\n    title: 'Song from album',\n    album: 'Collection',\n  },\n  {\n    id: 2,\n    title: 'Song with no album',\n    album: null,\n  },\n]));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/nullableFields/nullableByDefault.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    description: 'Example where non-required fields are nullable by default',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './index.js',\n  baseDir: __dirname,\n  notRequiredAsNullable: true,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * @typedef {object} Song\n * @property {number} id.required - Id\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * POST /api/v1/songs\n * @summary Adds a new song\n * @param {Song} request.body.required - Song to add\n * @return {string} 200 - Success message\n */\napp.post('/api/v1/songs', (_req, res) => res.send('You saved a song!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/package.json",
    "content": "{\n  \"name\": \"express-jsdoc-swagger-examples\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A set of examples of the package\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"configuration:main\": \"node configuration/main.js\",\n    \"configuration:multipleFiles\": \"node configuration/multipleFiles.js\",\n    \"configuration:swaggerOptions\": \"node configuration/swaggerOptions.js\",\n    \"configuration:multipleInstance\": \"node configuration/multipleInstance/index.js\",\n    \"parameters:simple\": \"node parameters/simple.js\",\n    \"parameters:headers\": \"node parameters/headers.js\",\n    \"parameters:multiple\": \"node parameters/multiple.js\",\n    \"parameters:components\": \"node parameters/components.js\",\n    \"parameters:enum\": \"node parameters/enum.js\",\n    \"responses:simple\": \"node responses/simple.js\",\n    \"responses:multiple\": \"node responses/multiple.js\",\n    \"responses:components\": \"node responses/components.js\",\n    \"responses:full-example\": \"node responses/full-example.js\",\n    \"responses:withExamples\": \"node responses/withExamples.js\",\n    \"requestBody:simple\": \"node requestBody/simple.js\",\n    \"requestBody:multiple\": \"node requestBody/multiple.js\",\n    \"requestBody:components\": \"node requestBody/components.js\",\n    \"requestBody:formdata\": \"node requestBody/formdata.js\",\n    \"requestBody:formParameters\": \"node requestBody/formParameters.js\",\n    \"requestBody:formUrlencoded\": \"node requestBody/formUrlencoded.js\",\n    \"requestBody:withExamples\": \"node requestBody/withExamples.js\",\n    \"security:basic-auth\": \"node security/basic-auth.js\",\n    \"security:basic-oauth2\": \"node security/basic-oauth2.js\",\n    \"components:simple\": \"node components/simple.js\",\n    \"components:enum\": \"node components/enum.js\",\n    \"tags:simple\": \"node tags/simple.js\",\n    \"combineSchemas\": \"node combineSchemas/index.js\",\n    \"eventEmitter\": \"node eventEmitter/index.js\",\n    \"validator\": \"node validator/index.js\",\n    \"eventEmitter:multipleInstance\": \"node eventEmitter/multipleInstance.js\",\n    \"merge\": \"node merge/simple.js\",\n    \"nullableFields:explicit\": \"node nullableFields/explicitNullable.js\",\n    \"nullableFields:byDefault\": \"node nullableFields/nullableByDefault.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"express\": \"^4.18.2\",\n    \"express-oas-validator\": \"^3.0.0\",\n    \"winston\": \"^3.2.1\"\n  }\n}\n"
  },
  {
    "path": "examples/parameters/components.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './components.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song type\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @param {array<Song>} name.query.required - name param description\n * @return {array<Song>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/parameters/enum.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './enum.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @param {string} name.query.required - name param description - enum:type1,type2\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @param {string} name.query.required - name param description - enum:type1,type2\n * @param {string} license.query - enum:MIT,ISC - name param description\n * @return {object} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/parameters/headers.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './headers.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @param {string} name.header.required - name param description\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/parameters/multiple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './multiple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1/{id}\n * @summary This is the summary of the endpoint\n * @param {string} name.query.required - name param description\n * @param {number} id.path - phone number\n * @return {string} 200 - success response\n */\napp.get('/api/v1/:id', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v1/albums/{id}\n * @summary This is the summary of the endpoint\n * @param {array<string>} name.query.required.deprecated - name param description\n * @param {number} id.path\n * @return {object} 200 - success response - application/json\n */\napp.get('/api/v1/albums/:id', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/parameters/simple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @param {string} name.query.required - name param description\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @param {array<string>} name.query.required.deprecated - name param description\n * @return {object} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/components.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './components.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n * @property {string} createdAt - created - date\n */\n\n/**\n * POST /api/v1/song\n * @param {Song} request.body.required - song info\n * @return {object} 200 - song response\n */\napp.post('/api/v1/songs', (_req, res) => res.send('You save a song!'));\n\n/**\n * POST /api/v1/album\n * @param {array<Song>} request.body.required - songs info\n * @return {object} 200 - album response\n */\napp.post('/api/v1/album', (_req, res) => res.send('You save a song!'));\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/formParameters.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './formParameters.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n// To use form params it is neccesary to provide a description\n\n/**\n * POST /api/v1/song\n * @param {string} id.form.required - This is the song id - application/x-www-form-urlencoded\n * @param {string} title.form.required - This is the song title - application/x-www-form-urlencoded\n * @return {object} 200 - song response\n */\napp.post('/api/v1/songs', (_req, res) => res.json({}));\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/formUrlencoded.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './formUrlencoded.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * POST /api/v1/song\n * @param {Song} request.body.required - song info - application/x-www-form-urlencoded\n * @return {object} 200 - song response\n */\napp.post('/api/v1/songs', (_req, res) => res.send('You save a song!'));\n\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/formdata.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './formdata.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {string} cover - image cover - binary\n * @property {integer} year - The year - int64\n */\n\n/**\n * POST /api/v1/album\n * @param {Song} request.body.required - songs info - multipart/form-data\n * @return {object} 200 - Album created\n */\napp.post('/api/v1/album', (_req, res) => res.send('You save a song!'));\n\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/multiple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './multiple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n// This one includes a mix of params and requestBody\n\n/**\n * POST /api/v1/album\n * @param {number} body.query\n * @param {array<string>} request.body.required - name body description\n * @return {object} 200 - album response\n */\napp.post('/api/v1/album', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/simple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * POST /api/v1/songs\n * @param {string} request.body.required - name body description\n * @return {object} 200 - song response\n */\napp.post('/api/v1/songs', (_req, res) => res.send('Hello World!'));\n\n/**\n * POST /api/v1/albums\n * @param {array<object>} request.body.required\n * @return {object} 200 - song response\n */\napp.post('/api/v1/albums', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/requestBody/withExamples.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './withExamples.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * POST /api/v1/song\n * @param {Song} request.body.required - song info\n * @return {object} 200 - song response\n * @return {object} 400 - Bad request response\n * @example request - payload example\n * {\n *   \"title\": \"Bury The Light\",\n *   \"artist\": \"Casey Edwards ft. Victor Borba\",\n *   \"year\": 2020\n * }\n * @example request - other payload example\n * {\n *   \"title\": \"The war we made\",\n *   \"artist\": \"Red\",\n *   \"year\": 2020\n * }\n */\napp.post('/api/v1/song', (_req, res) => res.send({\n  message: 'You added a song!',\n}));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/responses/components.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './components.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song type\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {integer} year - The year - int64\n */\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @return {array<Song>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/responses/full-example.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './full-example.js',\n  baseDir: __dirname,\n  security: {\n    BasicAuth: {\n      type: 'http',\n      scheme: 'basic',\n    },\n  },\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A song type\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {array<number>} year\n */\n\n/**\n * GET /api/v2/album\n * @summary This is the summary of the endpoint\n * @tags album\n * @security BasicAuth\n * @return {object} 200 - success response - application/json\n * @return {object} 400 - Bad request response\n */\napp.get('/api/v2/album', (_req, res) => (\n  res.json({\n    title: 'abum 1',\n  })\n));\n\n/**\n * GET /api/v1/album\n * @summary This is the summary of the endpoint\n * @tags album\n * @deprecated\n * @return {object} 200 - success response - application/json\n * @return {object} 400 - Bad request response\n */\napp.get('/api/v1/album', (_req, res) => (\n  res.json({\n    title: 'abum 1',\n  })\n));\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @tags album\n * @return {array<Song>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/responses/multiple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './multiple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1/album\n * @summary This is the summary of the endpoint\n * @return {object} 200 - success response - application/json\n * @return {object} 400 - Bad request response\n */\napp.get('/api/v1/album', (_req, res) => (\n  res.json({\n    title: 'abum 1',\n  })\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/responses/simple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @return {object} 200 - success response - application/json\n * @return {array<object>} 200 - success response - application/json\n */\napp.get('/api/v1/albums', (_req, res) => (\n  res.json([{\n    title: 'abum 1',\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/responses/withExamples.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Pet store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './withExamples.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * A pet\n * @typedef {object} Pet\n * @property {string} name.required - The name\n * @property {string} type.required - The type of pet\n * @property {string} breed - The breed\n */\n\n/**\n * GET /api/v1/pet\n * @return {array<Pet>} 200 - success response\n * @return {object} 403 - forbidden request response\n * @example response - 200 - example success response\n * [\n *   {\n *     \"name\": \"Blaze\",\n *     \"type\": \"Dog\",\n *     \"breed\": \"Siberian husky\"\n *   },\n *   {\n *     \"name\": \"Luna\",\n *     \"type\": \"Cat\"\n *   }\n * ]\n * @example response - 200 - second example success response\n * [\n *   {\n *     \"name\": \"Hachiko\",\n *     \"type\": \"Dog\",\n *     \"breed\": \"Akita Inu\"\n *   }\n * ]\n * @example response - 403 - example error response\n * {\n *   \"message\": \"you cannot access pet data\"\n * }\n */\napp.get('/api/v1/pet', (_req, res) => (\n  res.json([{\n    name: 'Hachiko',\n    type: 'Dog',\n    breed: 'Akita Inu'\n  }])\n));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/security/basic-auth.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  security: {\n    BasicAuth: {\n      type: 'http',\n      scheme: 'basic',\n    },\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n    },\n  },\n  filesPattern: './basic-auth.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1\n * @summary Endpoint with security info\n * @return {string} 200 - success response\n * @security BasicAuth\n */\napp.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v2\n * @summary Endpoint with multiple security configuration (AND logic)\n * @return {string} 200 - success response\n * @security BasicAuth & BearerAuth\n */\napp.get('/api/v2', (_req, res) => res.send('Hello World!'));\n\n/**\n * GET /api/v3\n * @summary Endpoint with multiple security configuration (OR logic)\n * @return {string} 200 - success response\n * @security BasicAuth | BearerAuth\n */\napp.get('/api/v3', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/security/basic-oauth2.js",
    "content": "const express = require('express');\nconst oauthDetails = require('./swagger');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  security: {\n    oAuthSample: [\n      'write_pets',\n      'read_pets',\n    ]\n  },\n  filesPattern: './basic-oauth2.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options, oauthDetails);\n\n/**\n * GET /api/v1/oauth\n * @summary Endpoint with security info\n * @return {string} 200 - success response\n * @security oAuthSample\n */\n app.get('/api/v1', (_req, res) => res.send('Hello World!'));\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/security/swagger.json",
    "content": "{\n  \"components\": {\n    \"securitySchemes\": {\n      \"oAuthSample\": {\n        \"type\": \"oauth2\",\n        \"description\": \"This API uses OAuth 2 with the implicit grant flow. [More info](https://api.example.com/docs/auth)\",\n        \"flows\": {\n          \"implicit\": {\n            \"authorizationUrl\": \"https://api.example.com/oauth2/authorize\",\n            \"scopes\": {\n              \"read_pets\": \"read your pets\",\n              \"write_pets\": \"modify pets in your account\"\n            }\n          }\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "examples/tags/simple.js",
    "content": "const express = require('express');\n\nconst logger = require('../utils/logger');\nconst expressJSDocSwagger = require('../..');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './simple.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst port = 3000;\n\nexpressJSDocSwagger(app)(options);\n\n/**\n * GET /api/v1/album\n * @tags Album\n * @return {object} 200 - album response\n */\n\n/**\n * GET /api/v1/songs\n * @tags Album\n * @tags Songs\n * @return {object} 200 - album response\n */\n\n/**\n * POST /api/v1/song\n * @summary Create new song\n * @tags Songs - everything about songs\n * @return {object} 200 - album response\n */\n\n/**\n * PUT /api/v1/song/{songId}\n * @param {number} songId.path.required - song id\n * @summary Edit song\n * @tags Songs\n * @return {object} 200 - album response\n */\n\n/**\n * DELETE /api/v1/song/{songId}\n * @param {number} songId.path.required - song id\n * @summary Delete song\n * @tags Songs\n * @return {object} 200 - album response\n */\n\n/**\n * GET /api/v1/song/{songId}\n * @param {number} songId.path.required - song id\n * @summary Get song detail\n * @tags Songs\n * @return {object} 200 - album response\n */\n\napp.listen(port, () => logger.info(`Example app listening at http://localhost:${port}`));\n"
  },
  {
    "path": "examples/ts-example/README.md",
    "content": "# TS-Example\n\nThis folder includes a simple TS example. It is important that in the config you add both extensions `ts,js` because when you are running the app using `ts-node` you will watch `ts` files but when it is build you need to watch `js`.\n\n## Install dependencies\n\n```\nnpm i\n```\n\n## Execute\n\n```\n// Execute dev mode\nnpm run dev\n// Build TS file in build/simple.js\nnpm run tsc:build\n// Execute ts-node app\nnpm run start\n// execute build app\nnpm run start:prod\n```\n"
  },
  {
    "path": "examples/ts-example/nodemon.json",
    "content": "{\n  \"ignore\": [\"**/*.test.ts\", \"**/*.spec.ts\", \"node_modules\"],\n  \"watch\": [\"simple.ts\"],\n  \"exec\": \"npm start\",\n  \"ext\": \"ts\"\n}\n"
  },
  {
    "path": "examples/ts-example/package.json",
    "content": "{\n  \"name\": \"ts-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"simple.js\",\n  \"scripts\": {\n    \"dev\": \"nodemon\",\n    \"tsc:build\": \"tsc\",\n    \"start\": \"ts-node simple.ts\",\n    \"start:prod\": \"node build/simple.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"nodemon\": \"^2.0.7\",\n    \"ts-node\": \"^9.1.1\",\n    \"typescript\": \"^4.0.5\"\n  },\n  \"dependencies\": {\n    \"@types/express\": \"^4.17.8\",\n    \"express\": \"^4.17.1\",\n    \"express-jsdoc-swagger\": \"^1.6.0\"\n  }\n}\n"
  },
  {
    "path": "examples/ts-example/simple.ts",
    "content": "import express from 'express';\nimport expressJSDocSwagger from 'express-jsdoc-swagger';\n\nconst port = 3000;\n// Create a new express app instance\nconst app: express.Application = express();\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  servers: [\n    {\n      url: 'https://{username}.gigantic-server.com:{port}/{basePath}',\n      description: 'The production API server',\n      variables: {\n        username: {\n          default: 'demo',\n          description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',\n        },\n        port: {\n          enum: [\n            '8443',\n            '443',\n          ],\n          default: '8443',\n        },\n        basePath: {\n          default: 'v2',\n        },\n      },\n    },\n  ],\n  security: {\n    BasicAuth: {\n      type: 'http',\n      scheme: 'basic',\n    },\n  },\n  filesPattern: './simple.{ts,js}',\n  baseDir: __dirname,\n};\n\n\nexpressJSDocSwagger(app)(options);\n/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\napp.get('/api/v1', (_req, res) => {\n  res.send('Hello World!');\n});\n\n/**\n * POST /tag\n *\n * @summary create a tag\n * @param {string} name the name fo the new tag\n * @returns {object} 200 - success response\n * @returns {object} 400 - Bad request response\n * @example response - 200 - success response example\n *   {\n *     \"_id\": \"Bury the light\",\n *     \"name\": \"lorem ipsum\",\n *   }\n */\napp.listen(port, () => {\n  console.log('App is listening on port 3000!');\n});\n\n"
  },
  {
    "path": "examples/ts-example/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n\n    /* Basic Options */\n    // \"incremental\": true,                   /* Enable incremental compilation */\n    \"target\": \"es5\",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */\n    \"module\": \"commonjs\",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */\n    // \"lib\": [],                             /* Specify library files to be included in the compilation. */\n    // \"allowJs\": true,                       /* Allow javascript files to be compiled. */\n    // \"checkJs\": true,                       /* Report errors in .js files. */\n    // \"jsx\": \"preserve\",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */\n    // \"declaration\": true,                   /* Generates corresponding '.d.ts' file. */\n    // \"declarationMap\": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */\n    // \"sourceMap\": true,                     /* Generates corresponding '.map' file. */\n    // \"outFile\": \"./\",                       /* Concatenate and emit output to single file. */\n    \"outDir\": \"./build\",                        /* Redirect output structure to the directory. */\n    // \"rootDir\": \"./\",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n    // \"composite\": true,                     /* Enable project compilation */\n    // \"tsBuildInfoFile\": \"./\",               /* Specify file to store incremental compilation information */\n    // \"removeComments\": true,                /* Do not emit comments to output. */\n    // \"noEmit\": true,                        /* Do not emit outputs. */\n    // \"importHelpers\": true,                 /* Import emit helpers from 'tslib'. */\n    // \"downlevelIteration\": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n    // \"isolatedModules\": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n\n    /* Strict Type-Checking Options */\n    \"strict\": true,                           /* Enable all strict type-checking options. */\n    // \"noImplicitAny\": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,              /* Enable strict null checks. */\n    // \"strictFunctionTypes\": true,           /* Enable strict checking of function types. */\n    // \"strictBindCallApply\": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */\n    // \"strictPropertyInitialization\": true,  /* Enable strict checking of property initialization in classes. */\n    // \"noImplicitThis\": true,                /* Raise error on 'this' expressions with an implied 'any' type. */\n    // \"alwaysStrict\": true,                  /* Parse in strict mode and emit \"use strict\" for each source file. */\n\n    /* Additional Checks */\n    // \"noUnusedLocals\": true,                /* Report errors on unused locals. */\n    // \"noUnusedParameters\": true,            /* Report errors on unused parameters. */\n    // \"noImplicitReturns\": true,             /* Report error when not all code paths in function return a value. */\n    // \"noFallthroughCasesInSwitch\": true,    /* Report errors for fallthrough cases in switch statement. */\n\n    /* Module Resolution Options */\n    // \"moduleResolution\": \"node\",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */\n    // \"baseUrl\": \"./\",                       /* Base directory to resolve non-absolute module names. */\n    // \"paths\": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n    // \"rootDirs\": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */\n    // \"typeRoots\": [],                       /* List of folders to include type definitions from. */\n    // \"types\": [],                           /* Type declaration files to be included in compilation. */\n    // \"allowSyntheticDefaultImports\": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n    \"esModuleInterop\": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */\n    // \"preserveSymlinks\": true,              /* Do not resolve the real path of symlinks. */\n    // \"allowUmdGlobalAccess\": true,          /* Allow accessing UMD globals from modules. */\n\n    /* Source Map Options */\n    // \"sourceRoot\": \"\",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */\n    // \"mapRoot\": \"\",                         /* Specify the location where debugger should locate map files instead of generated locations. */\n    // \"inlineSourceMap\": true,               /* Emit a single file with source maps instead of having a separate file. */\n    // \"inlineSources\": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */\n\n    /* Experimental Options */\n    // \"experimentalDecorators\": true,        /* Enables experimental support for ES7 decorators. */\n    // \"emitDecoratorMetadata\": true,         /* Enables experimental support for emitting type metadata for decorators. */\n\n    /* Advanced Options */\n    \"skipLibCheck\": true,                     /* Skip type checking of declaration files. */\n    \"forceConsistentCasingInFileNames\": true  /* Disallow inconsistently-cased references to the same file. */\n  }\n}\n"
  },
  {
    "path": "examples/utils/logger.js",
    "content": "const winston = require('winston');\n\nconst logger = winston.createLogger({\n  transports: [\n    new winston.transports.Console(),\n  ],\n});\n\nmodule.exports = logger;\n"
  },
  {
    "path": "examples/validator/app.js",
    "content": "const express = require('express');\nconst expressJSDocSwagger = require('../..');\nconst validator = require('./validator');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './**.js',\n  baseDir: __dirname,\n};\n\nconst app = express();\nconst instance = expressJSDocSwagger(app)(options);\n\nconst serverApp = async () => {\n  const { validateRequest, validateResponse } = await validator(instance);\n  app.use(express.urlencoded({ extended: true }));\n  app.use(express.json());\n  /**\n   * A song\n   * @typedef {object} Song\n   * @property {string} title.required - The title\n   * @property {string} artist - The artist\n   * @property {integer} year - The year\n   */\n\n  /**\n   * POST /api/v1/songs\n   * @param {Song} request.body.required - song info\n   * @return {object} 200 - song response\n   */\n  app.post('/api/v1/songs', validateRequest(), (_req, res) => res.send('You save a song!'));\n\n  /**\n   * POST /api/v1/name\n   * @param {string} request.body.required - name body description\n   * @return {object} 200 - song response\n   */\n  app.post('/api/v1/name', (_req, res, next) => {\n    try {\n      // Validate response\n      validateResponse('Error string', req);\n      return res.send('Hello World!');\n    } catch (error) {\n      return next(error);\n    }\n  });\n\n  /**\n   * GET /api/v1/authors\n   * @summary This is the summary or description of the endpoint\n   * @param {string} name.query.required - name param description - enum:type1,type2\n   * @param {array<string>} license.query - name param description\n   * @return {object} 200 - success response - application/json\n   */\n  app.get('/api/v1/authors', validateRequest({ headers: false }), (_req, res) => (\n    res.json([{\n      title: 'album 1',\n    }])\n  ));\n\n\n  // eslint-disable-next-line no-unused-vars\n  app.use((err, _req, res, _next) => {\n    res.status(err.status).json(err);\n  });\n\n  return app;\n};\n\nmodule.exports = serverApp;\n"
  },
  {
    "path": "examples/validator/index.js",
    "content": "const serverApp = require('./app')\nconst logger = require('../utils/logger');\n\nconst PORT = process.env.PORT || 4000;\n\nserverApp()\n  .then(app => \n    app.listen(PORT, () =>\n      logger.info(`Listening PORT: ${PORT}`)\n    ))\n  .catch((err) => {\n    logger.error(err);\n    process.exit(1);\n  });\n"
  },
  {
    "path": "examples/validator/validator.js",
    "content": "const { init } = require('express-oas-validator');\n\nconst validators = instance => new Promise((resolve, reject) => {\n  instance.on('finish', (swaggerDef) => {\n    const { validateRequest, validateResponse } = init(swaggerDef);\n    resolve({ validateRequest, validateResponse });\n  });\n\n  instance.on('error', (error) => {\n    reject(error);\n  });\n});\n\nmodule.exports = validators;\n"
  },
  {
    "path": "index.d.ts",
    "content": "// Type definitions for express-jsdoc-swagger\n// Project: https://github.com/BRIKEV/express-jsdoc-swagger\n// Definitions by: Kevin MArtínez <https://github.com/kevinccbsg>\n// Definitions: https://github.com/BRIKEV/express-jsdoc-swagger/index.d.ts\n// TypeScript Version: 3.9.7\n\nimport { EventEmitter } from \"events\";\nimport express from \"express\";\nimport { SwaggerUiOptions } from \"swagger-ui-express\";\n\ninterface ContactObject {\n  name: string;\n  url?: string;\n  email?: string;\n}\n\ninterface LicenseObject {\n  name: string;\n  url?: string;\n  email?: string;\n}\n\ninterface InfoObject {\n  title: string;\n  version: string;\n  description?: string;\n  termsOfService?: string;\n  contact?: ContactObject;\n  license?: LicenseObject;\n}\n\n\ninterface FlowObjectDefaults {\n  refreshUrl?: string\n  scopes: { [key: string]: string }\n}\ntype SecurityObject =\n  | {\n      description?: string\n    } & (\n      | {\n          type: \"mutualTLS\"\n        }\n      | {\n          type: \"apiKey\"\n          name: string\n          in: \"query\" | \"header\" | \"cookie\"\n        }\n      | {\n          type: \"http\"\n          scheme:\n            | \"basic\"\n            | \"digest\"\n            | \"dpop\"\n            | \"hoba\"\n            | \"mutual\"\n            | \"negotiate\"\n            | \"oauth\"\n            | \"scram-sha-1\"\n            | \"scram-sha-256\"\n            | \"vapid\"\n        }\n      | {\n          type: \"http\"\n          scheme: \"bearer\"\n          bearerFormat: string\n        }\n      | {\n          type: \"oauth2\"\n          flows: {\n            implicit?: FlowObjectDefaults & {\n              authorizationUrl: string\n            }\n            password?: FlowObjectDefaults & {\n              tokenUrl: string\n            }\n            clientCredentials?: FlowObjectDefaults & {\n              tokenUrl: string\n            }\n            authorizationCode?: FlowObjectDefaults & {\n              authorizationUrl: string\n              tokenUrl: string\n            }\n          }\n        }\n      | {\n          type: \"openIdConnect\"\n          openIdConnectUrl: string\n        }\n    )\n\n\n\ninterface Security {\n  [key: string]: SecurityObject;\n}\n\ninterface Servers {\n  url: string;\n  description: string;\n  variables?: object;\n}\n\ninterface Options {\n  info: InfoObject;\n  baseDir: string;\n  filesPattern: string | string[];\n  security?: Security;\n  servers?: string[] | Servers[];\n  exposeSwaggerUI?: boolean;\n  swaggerUIPath?: string;\n  exposeApiDocs?: boolean;\n  apiDocsPath?: string;\n  swaggerUiOptions?: SwaggerUiOptions;\n  notRequiredAsNullable?: boolean;\n}\n\ntype UserSwagger = Record<string, unknown>;\n\ntype EventEmiterHandler = (options: Options, userSwagger?: UserSwagger) => EventEmitter;\n\nexport default function expressJSDocSwagger(app: express.Application): EventEmiterHandler;\n"
  },
  {
    "path": "index.js",
    "content": "const swaggerUi = require('swagger-ui-express');\nconst merge = require('merge');\n\nconst defaultOptions = require('./config/default');\nconst swaggerEventsOptions = require('./config/swaggerEvents');\nconst processSwagger = require('./processSwagger');\nconst swaggerEvents = require('./swaggerEvents');\n\nconst expressJSDocSwagger = app => (userOptions = {}, userSwagger = {}) => {\n  const events = swaggerEvents(swaggerEventsOptions(userOptions));\n  const { instance } = events;\n  let swaggerObject = {};\n\n  const options = {\n    ...defaultOptions,\n    ...userOptions,\n  };\n\n  processSwagger(options, events.processFile)\n    .then(result => {\n      swaggerObject = {\n        ...swaggerObject,\n        ...result.swaggerObject,\n      };\n      swaggerObject = merge.recursive(true, swaggerObject, userSwagger);\n      events.finish(swaggerObject, {\n        jsdocInfo: result.jsdocInfo,\n        getPaths: result.getPaths,\n        getComponents: result.getComponents,\n        getTags: result.getTags,\n      });\n    })\n    .catch(events.error);\n\n  if (options.exposeSwaggerUI) {\n    app.use(options.swaggerUIPath, (req, res, next) => {\n      swaggerObject = {\n        ...swaggerObject,\n        host: req.get('host'),\n      };\n      req.swaggerDoc = swaggerObject;\n      next();\n    }, swaggerUi.serve, swaggerUi.setup(undefined, options.swaggerUiOptions));\n  }\n\n  if (options.exposeApiDocs) {\n    app.get(options.apiDocsPath, (req, res) => {\n      res.json({\n        ...swaggerObject,\n        // we skipped this as is not a valid prop in OpenAPI\n        // This is only being used in the SwaggerUI Library\n        host: undefined,\n      });\n    });\n  }\n\n  return instance;\n};\n\nmodule.exports = expressJSDocSwagger;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"express-jsdoc-swagger\",\n  \"version\": \"1.8.1\",\n  \"description\": \"Swagger OpenAPI 3.x generator\",\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"chalk\": \"^4.1.0\",\n    \"doctrine\": \"^3.0.0\",\n    \"express\": \"^4.17.3\",\n    \"glob\": \"^7.1.6\",\n    \"merge\": \"^2.1.1\",\n    \"swagger-ui-express\": \"^4.3.0\"\n  },\n  \"devDependencies\": {\n    \"@commitlint/cli\": \"^17.6.1\",\n    \"@commitlint/config-conventional\": \"^11.0.0\",\n    \"eslint\": \"^7.19.0\",\n    \"eslint-config-airbnb-base\": \"^14.2.1\",\n    \"eslint-plugin-import\": \"^2.22.1\",\n    \"eslint-plugin-jest\": \"^24.1.3\",\n    \"husky\": \"^8.0.3\",\n    \"jest\": \"^26.6.3\"\n  },\n  \"engines\": {\n    \"node\": \">= 14.0.0\"\n  },\n  \"scripts\": {\n    \"test\": \"jest\",\n    \"lint\": \"./node_modules/.bin/eslint .\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"commit-msg\": \"commitlint -E HUSKY_GIT_PARAMS\",\n      \"pre-commit\": \"npm run lint\",\n      \"pre-push\": \"npm run test\"\n    }\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/brikev/express-jsdoc-swagger.git\"\n  },\n  \"keywords\": [\n    \"swagger\",\n    \"swagger-generator\",\n    \"express\",\n    \"jsdoc\",\n    \"node\",\n    \"docs\",\n    \"documentation\",\n    \"swagger-ui\",\n    \"OpenAPI\"\n  ],\n  \"author\": \"BRIKEV (https://github.com/brikev)\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/brikev/express-jsdoc-swagger/issues\"\n  },\n  \"homepage\": \"https://brikev.github.io/express-jsdoc-swagger-docs/#/\"\n}\n"
  },
  {
    "path": "processSwagger.js",
    "content": "const readFiles = require('./consumers/readFiles');\nconst globFilesMatches = require('./consumers/globFilesMatches');\nconst getOnlyComments = require('./consumers/getOnlyComments');\nconst jsdocInfo = require('./consumers/jsdocInfo');\nconst {\n  getBasicInfo,\n  getSecuritySchemes,\n  getPaths,\n  getComponents,\n  getTags,\n} = require('./transforms');\n\nconst defaultLogger = () => null;\n\nconst processSwagger = (options, logger = defaultLogger) => {\n  let swaggerObject = {\n    openapi: '3.0.0',\n    info: options.info,\n    servers: options.servers,\n    security: options.security,\n  };\n\n  swaggerObject = getBasicInfo(swaggerObject);\n  logger({ entity: 'basicInfo', swaggerObject });\n  swaggerObject = getSecuritySchemes(swaggerObject);\n  logger({ entity: 'securitySchemas', swaggerObject });\n\n  return globFilesMatches(options.baseDir, options.filesPattern)\n    .then(readFiles)\n    .then(getOnlyComments)\n    .then(jsdocInfo())\n    .then(data => {\n      swaggerObject = getPaths(swaggerObject, data);\n      logger({ entity: 'paths', swaggerObject });\n      swaggerObject = getComponents(swaggerObject, data, options);\n      logger({ entity: 'components', swaggerObject });\n      swaggerObject = getTags(swaggerObject, data);\n      logger({ entity: 'tags', swaggerObject });\n      return {\n        swaggerObject, jsdocInfo, getPaths, getComponents, getTags,\n      };\n    });\n};\n\nmodule.exports = processSwagger;\n"
  },
  {
    "path": "swaggerEvents.js",
    "content": "const { EventEmitter } = require('events');\n\nconst ERROR_EVENT_NAME = 'error';\nconst PROCESS_EVENT_NAME = 'process';\nconst FINISH_EVENT_NAME = 'finish';\n\nlet api = null;\n\nconst error = eventEmitter => errorInfo => (\n  eventEmitter.emit(ERROR_EVENT_NAME, errorInfo)\n);\n\nconst processFile = eventEmitter => info => (\n  eventEmitter.emit(PROCESS_EVENT_NAME, info)\n);\n\nconst finish = eventEmitter => (info, methods) => (\n  eventEmitter.emit(FINISH_EVENT_NAME, info, methods)\n);\n\nconst swaggerEvents = ({ multiple } = {}) => {\n  if (api && !multiple) return api;\n  const instance = new EventEmitter();\n\n  api = {\n    instance,\n    error: error(instance),\n    processFile: processFile(instance),\n    finish: finish(instance),\n  };\n\n  return api;\n};\n\nmodule.exports = swaggerEvents;\n"
  },
  {
    "path": "test/consumers/getOnlyComments/index.test.js",
    "content": "const getOnlyComments = require('../../../consumers/getOnlyComments');\n\ndescribe('get only comments consumer method', () => {\n  it('should return empty array with not params', () => {\n    const input = undefined;\n    const expected = [];\n    const result = getOnlyComments(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array with not an array as parameter', () => {\n    const input = 2;\n    const expected = [];\n    const result = getOnlyComments(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array when there is no comments', () => {\n    const input = [`\n      This is a piece of text\n        with no\n          comments\n    `];\n    const expected = [];\n    const result = getOnlyComments(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array for simple comments', () => {\n    const input = [`\n    // this is a comment\n      This is a piece of text\n        with\n        // This is a second comment\n          comment\n    // second comment\n    `];\n    const expected = [];\n    const result = getOnlyComments(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return array with multiline comments', () => {\n    const input = [`\n    /* this is a comment */\n      This is a piece of text\n        with\n        /* This is a second comment */\n          comments\n    `];\n    const expected = ['/* this is a comment */', '/* This is a second comment */'];\n    const result = getOnlyComments(input);\n    expect(result).toHaveLength(2);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return JSdoc comment', () => {\n    const input = [`\n    /**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */\n    \n    // simple comment\n    `];\n    const expected = [`/**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */`];\n    const result = getOnlyComments(input);\n    expect(result).toHaveLength(1);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return only the JSdoc comment when we add a regex in the file pattern', () => {\n    const input = [`\n    const pattern = './*.js';\n    /**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */\n\n    `];\n    const expected = [`/**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */`];\n    const result = getOnlyComments(input);\n    expect(result).toHaveLength(1);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return multiline and JSdoc comment', () => {\n    const input = [`\n    /* this is a comment */\n      This is a piece of text\n      // simple comment\n        with\n        /* This is a second comment */\n          comments\n    `, `\n    /**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */\n    \n    // simple comment\n    `];\n    const expected = ['/* this is a comment */', '/* This is a second comment */', `/**\n     * @param  {[type]}\n     * @param  {[type]}\n     * @return {[type]}\n     */`];\n    const result = getOnlyComments(input);\n    expect(result).toHaveLength(3);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return JSdoc comment that is not at the begining of the line', () => {\n    const input = [`\n      File with comments with tabulation\n    \n      /**\n       * @param  {[type]}\n       * @param  {[type]}\n       * @return {[type]}\n       */\n    `];\n    const expected = [`/**\n       * @param  {[type]}\n       * @param  {[type]}\n       * @return {[type]}\n       */`];\n    const result = getOnlyComments(input);\n    expect(result).toHaveLength(1);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/consumers/globFilesMatches/fixtures/example.txt",
    "content": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  },
  {
    "path": "test/consumers/globFilesMatches/fixtures/excluded/example.txt",
    "content": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  },
  {
    "path": "test/consumers/globFilesMatches/index.test.js",
    "content": "const globFilesMatches = require('../../../consumers/globFilesMatches');\n\ndescribe('glob Files matches method', () => {\n  it('should return error when required param is not send', done => {\n    globFilesMatches()\n      .catch(error => {\n        expect(error.message).toEqual('baseDir and filePath are required');\n        done();\n      });\n  });\n\n  it('should return error when baseDir is undefined', done => {\n    const baseDir = undefined;\n    const filePath = './**/**.txt';\n    globFilesMatches(baseDir, filePath)\n      .catch(error => {\n        expect(error.message).toEqual('baseDir and filePath are required');\n        done();\n      });\n  });\n\n  it('should return error when filePath is not a string', done => {\n    const baseDir = __dirname;\n    const filePath = 3;\n    globFilesMatches(baseDir, filePath)\n      .catch(error => {\n        expect(error.message).toEqual('files pattern has to be a type of string');\n        done();\n      });\n  });\n\n  it('should return error when glob method not receives a string type', done => {\n    const baseDir = 2; // This forces error in glob method\n    const filePath = './**/**.txt';\n    globFilesMatches(baseDir, filePath)\n      .catch(error => {\n        expect(error.message).toEqual('The \"paths[0]\" argument must be of type string. Received type number (2)');\n        done();\n      });\n  });\n\n  it('should return example.txt and excluded/example.txt file', done => {\n    const baseDir = __dirname;\n    const filePath = './**/**.txt';\n    globFilesMatches(baseDir, filePath)\n      .then(files => {\n        const [exampleFile, excludedFile] = files;\n        expect(exampleFile.includes('example.txt')).toBe(true);\n        expect(excludedFile.includes('excluded/example.txt')).toBe(true);\n        expect(files).toHaveLength(2);\n        done();\n      });\n  });\n\n  it('should return only example.txt file when we add exclude condition', done => {\n    const baseDir = __dirname;\n    const filePath = './**/**.txt';\n    const excludedFolder = 'excluded';\n    globFilesMatches(baseDir, filePath, excludedFolder)\n      .then(files => {\n        const [exampleFile] = files;\n        expect(exampleFile.includes('example.txt')).toBe(true);\n        expect(files).toHaveLength(1);\n        done();\n      });\n  });\n\n  describe('Array of file paths', () => {\n    it('should return error when passed empty array', done => {\n      const baseDir = __dirname;\n      const filePath = [];\n      globFilesMatches(baseDir, filePath)\n        .catch(error => {\n          expect(error.message).toEqual('if you submit an array of filesPattern it must contain at least one pattern');\n          done();\n        });\n    });\n\n    it('should return error when one of the array parameters is not a string', done => {\n      const baseDir = __dirname;\n      const filePath = ['a', 'b', 'c', 2];\n      globFilesMatches(baseDir, filePath)\n        .catch(error => {\n          expect(error.message).toEqual('all file patterns have to be strings');\n          done();\n        });\n    });\n\n    it('should return example.txt and excluded/example.txt file', done => {\n      const baseDir = __dirname;\n      const filePath = ['./**/**.txt'];\n      globFilesMatches(baseDir, filePath)\n        .then(files => {\n          const [exampleFile, excludedFile] = files;\n          expect(exampleFile.includes('example.txt')).toBe(true);\n          expect(excludedFile.includes('excluded/example.txt')).toBe(true);\n          expect(files).toHaveLength(2);\n          done();\n        });\n    });\n\n    it('should return example.txt and excluded/example.txt file if multiple paths were passed', done => {\n      const baseDir = __dirname;\n      const filePath = ['./fixtures/example.txt', './fixtures/excluded/example.txt'];\n      globFilesMatches(baseDir, filePath)\n        .then(files => {\n          const [exampleFile, excludedFile] = files;\n          expect(exampleFile.includes('example.txt')).toBe(true);\n          expect(excludedFile.includes('excluded/example.txt')).toBe(true);\n          expect(files).toHaveLength(2);\n          done();\n        });\n    });\n\n    it('should not return duplicated paths', done => {\n      const baseDir = __dirname;\n      const filePath = ['./**/**.txt', './**/**.txt', './fixtures/example.txt'];\n      globFilesMatches(baseDir, filePath)\n        .then(files => {\n          const [exampleFile, excludedFile] = files;\n          expect(exampleFile.includes('example.txt')).toBe(true);\n          expect(excludedFile.includes('excluded/example.txt')).toBe(true);\n          expect(files).toHaveLength(2);\n          done();\n        });\n    });\n\n    it('should return only example.txt file when we add exclude condition', done => {\n      const baseDir = __dirname;\n      const filePath = ['./**/**.txt'];\n      const excludedFolder = 'excluded';\n      globFilesMatches(baseDir, filePath, excludedFolder)\n        .then(files => {\n          const [exampleFile] = files;\n          expect(exampleFile.includes('example.txt')).toBe(true);\n          expect(files).toHaveLength(1);\n          done();\n        });\n    });\n  });\n});\n"
  },
  {
    "path": "test/consumers/jsdocInfo/index.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\n\ndescribe('jsdocInfo method', () => {\n  it('should return function instance', () => {\n    const result = jsdocInfo();\n    expect(result).toBeInstanceOf(Function);\n  });\n\n  it('should return empty array when we do not send params', () => {\n    const input = undefined;\n    const expected = [];\n    const result = jsdocInfo()(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array when we do not send array as param', () => {\n    const input = 3;\n    const expected = [];\n    const result = jsdocInfo()(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return jsdoc parsed', () => {\n    const input = [`\n    /**\n     * @param  {string} param1\n     * @param  {string} param2\n     * @return {string} result\n     */\n    \n    // simple comment\n    `];\n    const result = jsdocInfo()(input);\n    expect(result).toHaveLength(1);\n    const NUMBER_TAGS = 3;\n    expect(result[0].tags).toHaveLength(NUMBER_TAGS);\n  });\n});\n"
  },
  {
    "path": "test/consumers/readFiles/fixtures/example-2.txt",
    "content": "goodbye world"
  },
  {
    "path": "test/consumers/readFiles/fixtures/example.txt",
    "content": "hello world"
  },
  {
    "path": "test/consumers/readFiles/index.test.js",
    "content": "const readFiles = require('../../../consumers/readFiles');\n\ndescribe('readFiles', () => {\n  it('should return empty array when we do not send params', done => {\n    const input = undefined;\n    const expected = [];\n    readFiles(input)\n      .then(result => {\n        expect(result).toEqual(expected);\n        done();\n      })\n      .catch(done);\n  });\n\n  it('should throw an error when file is not found', done => {\n    const input = [\n      `${__dirname}/fixtures/not-found.txt`,\n    ];\n    readFiles(input)\n      .catch(error => {\n        expect(error.message).toMatch(/ENOENT: no such file or directory, open/);\n        done();\n      });\n  });\n\n  it('should return empty array when we do not send array as param', done => {\n    const input = [\n      `${__dirname}/fixtures/example.txt`,\n      `${__dirname}/fixtures/example-2.txt`,\n    ];\n    readFiles(input)\n      .then(result => {\n        const [firstFile, secondFile] = result;\n        expect(firstFile).toEqual('hello world');\n        expect(secondFile).toEqual('goodbye world');\n        expect(result).toHaveLength(2);\n        done();\n      })\n      .catch(done);\n  });\n});\n"
  },
  {
    "path": "test/e2e/components/components.test.js",
    "content": "const processSwagger = require('../../../processSwagger');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './jsdoc-example.js',\n  baseDir: __dirname,\n};\n\ntest('should parse components jsdoc from jsdoc-example', async () => {\n  const expected = {\n    openapi: '3.0.0',\n    info: {\n      title: 'Albums store',\n      description: 'Add your description',\n      license: { name: 'MIT', url: '' },\n      termsOfService: '',\n      version: '1.0.0',\n    },\n    servers: [],\n    security: undefined,\n    paths: {},\n    tags: [],\n    components: {\n      schemas: {\n        Song: {\n          description: 'A song',\n          required: [\n            'title',\n          ],\n          type: 'object',\n          properties: {\n            title: {\n              description: 'The title',\n              type: 'string',\n            },\n            artist: {\n              description: 'The artist',\n              type: 'string',\n            },\n            year: {\n              description: 'The year',\n              type: 'number',\n              format: 'double',\n            },\n          },\n        },\n        Author: {\n          description: 'Author model',\n          required: [\n            'name',\n          ],\n          type: 'object',\n          properties: {\n            name: {\n              description: 'Author name',\n              type: 'string',\n            },\n            age: {\n              description: 'Author age',\n              type: 'integer',\n              format: 'int64',\n            },\n          },\n        },\n        Album: {\n          description: 'Album',\n          type: 'object',\n          properties: {\n            firstSong: {\n              description: '',\n              $ref: '#/components/schemas/Song',\n            },\n            author: {\n              description: '',\n              $ref: '#/components/schemas/Author',\n            },\n          },\n        },\n      },\n    },\n  };\n  const result = await processSwagger(options);\n  expect(result.swaggerObject).toEqual(expected);\n});\n"
  },
  {
    "path": "test/e2e/components/jsdoc-example.js",
    "content": "/**\n * A song\n * @typedef {object} Song\n * @property {string} title.required - The title\n * @property {string} artist - The artist\n * @property {number} year - The year - double\n */\n\n/**\n * Author model\n * @typedef {object} Author\n * @property {string} name.required - Author name\n * @property {integer} age - Author age - int64\n */\n\n/**\n * Album\n * @typedef {object} Album\n * @property {Song} firstSong\n * @property {Author} author\n */\n"
  },
  {
    "path": "test/e2e/configuration/configuration.test.js",
    "content": "const processSwagger = require('../../../processSwagger');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  servers: [\n    {\n      url: 'https://{username}.gigantic-server.com:{port}/{basePath}',\n      description: 'The production API server',\n      variables: {\n        username: {\n          default: 'demo',\n          description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',\n        },\n        port: {\n          enum: [\n            '8443',\n            '443',\n          ],\n          default: '8443',\n        },\n        basePath: {\n          default: 'v2',\n        },\n      },\n    },\n  ],\n  security: {\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n      bearerFormat: 'JWT',\n    },\n  },\n  filesPattern: './main.js',\n  baseDir: __dirname,\n};\n\ntest('should parse basic info', async () => {\n  const expected = {\n    openapi: '3.0.0',\n    info: {\n      version: '1.0.0',\n      title: 'Albums store',\n      license: {\n        name: 'MIT',\n        url: 'http://example.com',\n      },\n      description: 'API desctiption',\n      contact: {\n        name: 'contact name',\n        url: 'http://example.com',\n        email: 'test@test.com',\n      },\n      termsOfService: 'http://example.com',\n    },\n    servers: [\n      {\n        url: 'https://{username}.gigantic-server.com:{port}/{basePath}',\n        description: 'The production API server',\n        variables: {\n          username: {\n            default: 'demo',\n            description: 'this value is assigned by the service provider, in this example `gigantic-server.com`',\n          },\n          port: {\n            enum: [\n              '8443',\n              '443',\n            ],\n            default: '8443',\n          },\n          basePath: {\n            default: 'v2',\n          },\n        },\n      },\n    ],\n    security: [\n      {\n        BearerAuth: [],\n      },\n    ],\n    paths: {},\n    tags: [],\n    components: {\n      schemas: {},\n      securitySchemes: {\n        BearerAuth: {\n          bearerFormat: 'JWT',\n          scheme: 'bearer',\n          type: 'http',\n        },\n      },\n    },\n  };\n  const result = await processSwagger(options);\n  expect(result.swaggerObject).toEqual(expected);\n});\ntest('should get transforms(jsdocInfo, getPaths, getComponents, getTags) methods', async () => {\n  const result = await processSwagger(options);\n  expect(result).toHaveProperty('jsdocInfo');\n  expect(result).toHaveProperty('getPaths');\n  expect(result).toHaveProperty('getComponents');\n  expect(result).toHaveProperty('getTags');\n});\n"
  },
  {
    "path": "test/e2e/errors/errors.test.js",
    "content": "/* eslint-disable no-console */\nconst chalk = require('chalk');\nconst processSwagger = require('../../../processSwagger');\n\ntest('should give a nice error message for parameters', async () => {\n  const options = {\n    info: {\n      version: '1.0.0',\n      title: 'Albums store',\n      license: {\n        name: 'MIT',\n      },\n    },\n    filesPattern: './jsdoc-parameter-error.js',\n    baseDir: __dirname,\n  };\n  global.console = { ...global.console, warn: jest.fn() };\n  await processSwagger(options);\n  expect(console.warn).toHaveBeenCalledTimes(2);\n  expect(console.warn).toHaveBeenNthCalledWith(\n    1,\n    chalk.yellow('[express-jsdoc-swagger] Entity: @param could not be parsed. Value: \"name.query.required\" is wrong'),\n  );\n  expect(console.warn).toHaveBeenNthCalledWith(\n    2,\n    chalk.yellow('[express-jsdoc-swagger] Entity: @param could not be parsed. Value: \"phone.param\" is wrong'),\n  );\n});\n\ntest('should give a nice error message for requestBody', async () => {\n  const options = {\n    info: {\n      version: '1.0.0',\n      title: 'Albums store',\n      license: {\n        name: 'MIT',\n      },\n    },\n    filesPattern: './jsdoc-requestBody-error.js',\n    baseDir: __dirname,\n  };\n  global.console = { ...global.console, warn: jest.fn() };\n  await processSwagger(options);\n  expect(console.warn).toHaveBeenCalledTimes(1);\n  expect(console.warn).toHaveBeenNthCalledWith(\n    1,\n    chalk.yellow(\n      // eslint-disable-next-line max-len\n      '[express-jsdoc-swagger] If you want to add one @param as body you must provide \"request.body\" instead of body.body.required',\n    ),\n  );\n});\n"
  },
  {
    "path": "test/e2e/errors/jsdoc-parameter-error.js",
    "content": "/**\n * GET /api/v1/album\n * @summary This is the summary of the endpoint\n * @param name.query.required - name param description\n * @param phone.param - phone number\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "test/e2e/errors/jsdoc-requestBody-error.js",
    "content": "/**\n * GET /api/v1/album\n * @summary This is the summary of the endpoint\n * @param {object} body.body.required - name param description\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "test/e2e/logger/logger.test.js",
    "content": "const processSwagger = require('../../../processSwagger');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n      url: 'http://example.com',\n    },\n    description: 'API desctiption',\n    contact: {\n      name: 'contact name',\n      url: 'http://example.com',\n      email: 'test@test.com',\n    },\n    termsOfService: 'http://example.com',\n  },\n  filesPattern: './main.js',\n  baseDir: __dirname,\n};\n\ntest('should called logger method', async () => {\n  const spy = jest.fn();\n  const expected = {\n    openapi: '3.0.0',\n    info: {\n      version: '1.0.0',\n      title: 'Albums store',\n      license: {\n        name: 'MIT',\n        url: 'http://example.com',\n      },\n      description: 'API desctiption',\n      contact: {\n        name: 'contact name',\n        url: 'http://example.com',\n        email: 'test@test.com',\n      },\n      termsOfService: 'http://example.com',\n    },\n    servers: [],\n    security: undefined,\n  };\n  await processSwagger(options, spy);\n  expect(spy).toHaveBeenCalledTimes(5);\n  expect(spy).toHaveBeenNthCalledWith(1, {\n    entity: 'basicInfo',\n    swaggerObject: expected,\n  });\n  expect(spy).toHaveBeenNthCalledWith(2, {\n    entity: 'securitySchemas',\n    swaggerObject: {\n      ...expected,\n      components: {},\n    },\n  });\n  expect(spy).toHaveBeenNthCalledWith(3, {\n    entity: 'paths',\n    swaggerObject: {\n      ...expected,\n      components: {},\n      paths: {},\n    },\n  });\n  expect(spy).toHaveBeenNthCalledWith(4, {\n    entity: 'components',\n    swaggerObject: {\n      ...expected,\n      components: {\n        schemas: {},\n      },\n      paths: {},\n    },\n  });\n  expect(spy).toHaveBeenNthCalledWith(5, {\n    entity: 'tags',\n    swaggerObject: {\n      ...expected,\n      components: {\n        schemas: {},\n      },\n      paths: {},\n      tags: [],\n    },\n  });\n});\n"
  },
  {
    "path": "test/e2e/multipleInstance/admin-v1-docs.js",
    "content": "/**\n * GET /api/admin/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "test/e2e/multipleInstance/client-v1-docs.js",
    "content": "/**\n * GET /api/client/v1\n * @summary This is the summary of the endpoint\n * @return {string} 200 - success response\n */\n"
  },
  {
    "path": "test/e2e/multipleInstance/index.js",
    "content": "const express = require('express');\nconst expressJSDocSwagger = require('../../..');\n\nconst app = express();\n\nconst setupInstance = options => new Promise(resolve => {\n  const instance = expressJSDocSwagger(app)(options);\n  instance.on('finish', data => {\n    resolve(data);\n  });\n});\n\nmodule.exports = setupInstance;\n"
  },
  {
    "path": "test/e2e/multipleInstance/multipleInstance.test.js",
    "content": "const multipleInstance = require('.');\n\nconst instance1Options = {\n  info: {\n    version: '1.0.0',\n    title: 'Admin API',\n    description: 'Only admin accounts authorized to use this API',\n  },\n  security: {\n    BearerAuth: {\n      type: 'http',\n      scheme: 'bearer',\n      bearerFormat: 'JWT',\n    },\n  },\n  filesPattern: './admin-v1-docs.js',\n  swaggerUIPath: '/api/v1/admin/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/admin/api-docs',\n};\n\nconst instance2Options = {\n  info: {\n    version: '1.0.0',\n    title: 'Client API',\n    description: 'For client',\n  },\n  filesPattern: './client-v1-docs.js',\n  swaggerUIPath: '/api/v1/client/docs',\n  baseDir: __dirname,\n  exposeSwaggerUI: true,\n  exposeApiDocs: true,\n  apiDocsPath: '/api/v1/client/api-docs',\n};\n\ndescribe('multipleInstance test', () => {\n  it('multipleInstance should be different when multiple option is \"true\"', async () => {\n    const instance1Data = await multipleInstance({\n      ...instance1Options,\n      multiple: true,\n    });\n    const instance2Data = await multipleInstance({\n      ...instance2Options,\n      multiple: true,\n    });\n    expect(instance1Data).not.toEqual(instance2Data);\n  });\n});\n"
  },
  {
    "path": "test/e2e/parameters/jsdoc-example.js",
    "content": "/**\n * GET /api/v1\n * @summary This is the summary of the endpoint\n * @param {string} name.path.required - name param description\n * @param {number} phone.path.required - phone number\n * @return {string} 200 - success response\n */\n\n/**\n * GET /api/v1/albums\n * @summary This is the summary of the endpoint\n * @param {array<string>} name.path.required - name param description\n * @param {number} phone.path.required\n * @return {object} 200 - success response - application/json\n */\n"
  },
  {
    "path": "test/e2e/parameters/parameters.test.js",
    "content": "const processSwagger = require('../../../processSwagger');\n\nconst options = {\n  info: {\n    version: '1.0.0',\n    title: 'Albums store',\n    license: {\n      name: 'MIT',\n    },\n  },\n  filesPattern: './jsdoc-example.js',\n  baseDir: __dirname,\n};\n\ntest('should parse parameters from jsdoc-example', async () => {\n  const expected = {\n    openapi: '3.0.0',\n    info: {\n      title: 'Albums store',\n      description: 'Add your description',\n      license: { name: 'MIT', url: '' },\n      termsOfService: '',\n      version: '1.0.0',\n    },\n    servers: [],\n    security: undefined,\n    paths: {\n      '/api/v1': {\n        get: {\n          deprecated: false,\n          description: undefined,\n          security: [],\n          summary: 'This is the summary of the endpoint',\n          responses: {\n            200: {\n              description: 'success response',\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'string',\n                  },\n                },\n              },\n            },\n          },\n          parameters: [\n            {\n              name: 'name',\n              in: 'path',\n              description: 'name param description',\n              required: true,\n              deprecated: false,\n              schema: {\n                type: 'string',\n              },\n            },\n            {\n              name: 'phone',\n              in: 'path',\n              description: 'phone number',\n              required: true,\n              deprecated: false,\n              schema: {\n                type: 'number',\n              },\n            },\n          ],\n          tags: [],\n        },\n      },\n      '/api/v1/albums': {\n        get: {\n          deprecated: false,\n          description: undefined,\n          security: [],\n          summary: 'This is the summary of the endpoint',\n          responses: {\n            200: {\n              description: 'success response',\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                  },\n                },\n              },\n            },\n          },\n          parameters: [\n            {\n              name: 'name',\n              in: 'path',\n              description: 'name param description',\n              required: true,\n              deprecated: false,\n              schema: {\n                type: 'array',\n                items: {\n                  type: 'string',\n                },\n              },\n            },\n            {\n              name: 'phone',\n              in: 'path',\n              description: '',\n              required: true,\n              deprecated: false,\n              schema: {\n                type: 'number',\n              },\n            },\n          ],\n          tags: [],\n        },\n      },\n    },\n    tags: [],\n    components: {\n      schemas: {},\n    },\n  };\n  const result = await processSwagger(options);\n  expect(result.swaggerObject).toEqual(expected);\n});\n"
  },
  {
    "path": "test/events/events.test.js",
    "content": "const swaggerEvents = require('../../swaggerEvents');\n\ndescribe('swaggerEvents event emitter', () => {\n  it('should return one instance', () => {\n    const instance = swaggerEvents();\n    const newInstance = swaggerEvents();\n    expect(instance).toEqual(newInstance);\n  });\n\n  it('should handle error events', done => {\n    const events = swaggerEvents();\n\n    const error = 'Example error';\n\n    events.instance.on('error', errorInfo => {\n      expect(errorInfo).toEqual(error);\n      done();\n    });\n\n    events.error(error);\n  });\n\n  it('should handle process info events', done => {\n    const events = swaggerEvents();\n\n    const message = 'Example message';\n\n    events.instance.on('process', errorInfo => {\n      expect(errorInfo).toEqual(message);\n      done();\n    });\n\n    events.processFile(message);\n  });\n\n  it('should handle finish info events', done => {\n    const events = swaggerEvents();\n\n    const message = 'Example message';\n\n    events.instance.on('finish', errorInfo => {\n      expect(errorInfo).toEqual(message);\n      done();\n    });\n\n    events.finish(message);\n  });\n});\n"
  },
  {
    "path": "test/transforms/basic/index.test.js",
    "content": "const getBasicInfo = require('../../../transforms/basic');\n\ndescribe('basic transform method', () => {\n  it('should not allow empty configuration', () => {\n    const input = undefined;\n    expect(() => {\n      getBasicInfo(input);\n    }).toThrow('Key title is required in item {}');\n  });\n\n  it('should return error as version is required', () => {\n    const input = {\n      info: {\n        title: 'API 1',\n      },\n      servers: [],\n    };\n    expect(() => {\n      getBasicInfo(input);\n    }).toThrow('Key version is required in item {\"title\":\"API 1\"} for Entity info');\n  });\n\n  it('should return info object', () => {\n    const input = {\n      extra: 'extra info',\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n      },\n    };\n    const expected = {\n      extra: 'extra info',\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n        termsOfService: '',\n        description: 'Add your description',\n      },\n      servers: [],\n    };\n    const result = getBasicInfo(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('should send warn type when type is not correct', () => {\n    global.console = { ...global.console, warn: jest.fn() };\n    const input = {\n      extra: 'extra info',\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n        description: false,\n      },\n    };\n    const expected = {\n      extra: 'extra info',\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n        termsOfService: '',\n        description: false,\n      },\n      servers: [],\n    };\n    const result = getBasicInfo(input);\n    expect(result).toEqual(expected);\n    // eslint-disable-next-line\n    expect(console.warn).toHaveBeenCalled();\n  });\n\n  it('should throw error for invalid server', () => {\n    const input = {\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n      },\n      servers: [{ invalid: 'example' }],\n    };\n    expect(() => {\n      getBasicInfo(input);\n    }).toThrow('Key url is required in item {\"invalid\":\"example\"} for Entity servers');\n  });\n\n  it('should return valid configuration', () => {\n    const input = {\n      info: {\n        title: 'API 1',\n        version: '1.0.0',\n      },\n      servers: [{\n        url: 'https://url.com',\n        variables: {\n          enum: ['300', '200'],\n          default: 200,\n        },\n      }],\n    };\n    const expected = {\n      info: {\n        title: 'API 1',\n        description: 'Add your description',\n        termsOfService: '',\n        version: '1.0.0',\n      },\n      servers: [\n        {\n          url: 'https://url.com',\n          description: '',\n          variables: {\n            enum: ['300', '200'],\n            default: 200,\n          },\n        },\n      ],\n    };\n    const result = getBasicInfo(input);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/components/index.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst parseComponents = require('../../../transforms/components');\n\ndescribe('parseComponents method', () => {\n  it('should return empty array with not params', () => {\n    const initialState = {};\n    const components = undefined;\n    const expected = {\n      components: {\n        schemas: {},\n      },\n    };\n    const result = parseComponents(initialState, components);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array with not an array as parameter', () => {\n    const initialState = {};\n    const components = 2;\n    const expected = {\n      components: {\n        schemas: {},\n      },\n    };\n    const result = parseComponents(initialState, components);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc and return default value when there is no typedef', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @property {string} title - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {},\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with basic properties', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with enum properties', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title - The title\n       * @property {string} artist - The artist - enum:value1,value2\n       * @property {number} year - The year - int64\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n                enum: [\n                  'value1',\n                  'value2',\n                ],\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with enum properties in different order', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title - The title\n       * @property {string} artist - enum:value1,value2 - The artist\n       * @property {number} year - The year - int64\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n                enum: [\n                  'value1',\n                  'value2',\n                ],\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with json options', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title - The title\n       * @property {string} artist - The artist - json:{\"maxLength\": 300}\n       * @property {number} year - The year - int64 - json:{\"minimum\": 2000}\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n                maxLength: 300,\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n                minimum: 2000,\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with require and format properties', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year - int64\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse two jsdoc components', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year - int64\n       */\n    `,\n    `\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {string} name.required - Album name\n       * @property {number} length\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n          Album: {\n            type: 'object',\n            required: [\n              'name',\n            ],\n            description: 'Album',\n            properties: {\n              name: {\n                type: 'string',\n                description: 'Album name',\n              },\n              length: {\n                type: 'number',\n                description: '',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse one reference between two jsdoc components', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year - int64\n       */\n    `,\n    `\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {Song} firstSong\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              firstSong: {\n                $ref: '#/components/schemas/Song',\n                description: '',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse empty string when description is not defined', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required\n       * @property {string} artist\n       * @property {number} year\n       */\n    `,\n    `\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {Song} firstSong\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: '',\n              },\n              artist: {\n                type: 'string',\n                description: '',\n              },\n              year: {\n                type: 'number',\n                description: '',\n              },\n            },\n          },\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              firstSong: {\n                $ref: '#/components/schemas/Song',\n                description: '',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse two reference for one jsdoc component', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year - int64\n       */\n    `,\n    `\n      /**\n       * Author model\n       * @typedef {object} Author\n       * @property {string} name.required - Author name\n       * @property {number} age - Author age - int64\n       */\n    `,\n    `\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {Song} firstSong\n       * @property {Author} author\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n              },\n            },\n          },\n          Author: {\n            type: 'object',\n            required: [\n              'name',\n            ],\n            description: 'Author model',\n            properties: {\n              name: {\n                type: 'string',\n                description: 'Author name',\n              },\n              age: {\n                type: 'number',\n                description: 'Author age',\n                format: 'int64',\n              },\n            },\n          },\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              firstSong: {\n                $ref: '#/components/schemas/Song',\n                description: '',\n              },\n              author: {\n                $ref: '#/components/schemas/Author',\n                description: '',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec when songs property is an array of strings', () => {\n    const jsodInput = [`\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {string} title - The title\n       * @property {array<string>} songs - songs array\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              songs: {\n                type: 'array',\n                description: 'songs array',\n                items: {\n                  type: 'string',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec when songs property is an array of numbers', () => {\n    const jsodInput = [`\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {string} title - The title\n       * @property {array<number>} years - years description\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              years: {\n                type: 'array',\n                description: 'years description',\n                items: {\n                  type: 'number',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec when songs property is an array of numbers with empty description', () => {\n    const jsodInput = [`\n      /**\n       * Album\n       * @typedef {object} Album\n       * @property {string} title - The title\n       * @property {array<number>} years\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              years: {\n                type: 'array',\n                description: '',\n                items: {\n                  type: 'number',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse an album schema with an array of Songs schemas.', () => {\n    const jsodInput = [\n      [`\n        /**\n         * Album\n         * @typedef {object} Album\n         * @property {array<Song>} Songs\n         */\n      `],\n      [`\n        /**\n         * Album\n         * @typedef {object} Album\n         * @property {Array<Song>} Songs\n         */\n      `],\n      [`\n        /**\n         * Album\n         * @typedef {object} Album\n         * @property {Song[]} Songs\n         */\n      `],\n    ];\n    const expected = {\n      components: {\n        schemas: {\n          Album: {\n            type: 'object',\n            description: 'Album',\n            properties: {\n              Songs: {\n                type: 'array',\n                description: '',\n                items: {\n                  $ref: '#/components/schemas/Song',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    jsodInput.forEach(jsod => {\n      const parsedJSDocs = jsdocInfo()(jsod);\n      const result = parseComponents({}, parsedJSDocs);\n      expect(result).toEqual(expected);\n    });\n  });\n\n  it('Should parse a SingleAlbum schema with allOf reference of Song.', () => {\n    const jsodInput = [`\n      /**\n       * SingleAlbum\n       * @typedef {allOf|Song} SingleAlbum\n       * @property {array<Song>} Songs\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          SingleAlbum: {\n            allOf: [\n              {\n                $ref: '#/components/schemas/Song',\n              },\n            ],\n            type: 'object',\n            description: 'SingleAlbum',\n            properties: {\n              Songs: {\n                type: 'array',\n                description: '',\n                items: {\n                  $ref: '#/components/schemas/Song',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse a SongOrAlbum schema with oneOf reference of Song and Album.', () => {\n    const jsodInput = [`\n      /**\n       * SongOrAlbum\n       * @typedef {oneOf|Song|Album} SongOrAlbum\n       * @property {array<Song>} Songs\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          SongOrAlbum: {\n            oneOf: [\n              {\n                $ref: '#/components/schemas/Song',\n              },\n              {\n                $ref: '#/components/schemas/Album',\n              },\n            ],\n            type: 'object',\n            description: 'SongOrAlbum',\n            properties: {\n              Songs: {\n                type: 'array',\n                description: '',\n                items: {\n                  $ref: '#/components/schemas/Song',\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with optional properties nullable by default', () => {\n    const jsdocInput = [`\n      /**\n       * A song\n       * @typedef {object} Song\n       * @property {string} title.required - The title\n       * @property {string} artist - The artist\n       * @property {number} year - The year - int64\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'object',\n            required: [\n              'title',\n            ],\n            description: 'A song',\n            properties: {\n              title: {\n                type: 'string',\n                description: 'The title',\n              },\n              artist: {\n                type: 'string',\n                description: 'The artist',\n                nullable: true,\n              },\n              year: {\n                type: 'number',\n                description: 'The year',\n                format: 'int64',\n                nullable: true,\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = parseComponents({}, parsedJSDocs, { notRequiredAsNullable: true });\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with string type', () => {\n    const jsodInput = [`\n      /**\n       * A song\n       * @typedef {string} Song\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'string',\n            description: 'A song',\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec with string type and a format', () => {\n    const jsodInput = [`\n      /**\n       * A song - enum:value1,value2\n       * @typedef {string} Song\n       */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Song: {\n            type: 'string',\n            description: 'A song',\n            enum: [\n              'value1',\n              'value2',\n            ],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec dictionary', () => {\n    const jsodInput = [`\n       /**\n        * Profile\n        * @typedef {object} Profile\n        *\n        * @property {string} email\n        */\n      `,\n    `\n       /**\n        * Profiles dict\n        * @typedef {Dictionary<Profile>} Profiles\n        */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Profile: {\n            type: 'object',\n            description: 'Profile',\n            properties: {\n              email: {\n                type: 'string',\n                description: '',\n              },\n            },\n          },\n          Profiles: {\n            type: 'object',\n            description: 'Profiles dict',\n            properties: {},\n            additionalProperties: {\n              $ref: '#/components/schemas/Profile',\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc component spec record type', () => {\n    const jsodInput = [`\n      /**\n      * Records dict\n      * @typedef {Dictionary<string>} Records map\n      */\n    `];\n    const expected = {\n      components: {\n        schemas: {\n          Records: {\n            type: 'object',\n            description: 'Records dict',\n            properties: {},\n            additionalProperties: {\n              type: 'string',\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseComponents({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/__snapshots__/validStatusCodes.test.js.snap",
    "content": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`Valid status codes snapshot 1`] = `\nObject {\n  \"100\": \"Continue\",\n  \"101\": \"Switching Protocols\",\n  \"102\": \"Processing\",\n  \"1XX\": \"1XX Range\",\n  \"200\": \"OK\",\n  \"201\": \"Created\",\n  \"202\": \"Accepted\",\n  \"203\": \"Non Authoritative Information\",\n  \"204\": \"No Content\",\n  \"205\": \"Reset Content\",\n  \"206\": \"Partial Content\",\n  \"207\": \"Multi-Status\",\n  \"2XX\": \"2XX Range\",\n  \"300\": \"Multiple Choices\",\n  \"301\": \"Moved Permanently\",\n  \"302\": \"Moved Temporarily\",\n  \"303\": \"See Other\",\n  \"304\": \"Not Modified\",\n  \"305\": \"Use Proxy\",\n  \"307\": \"Temporary Redirect\",\n  \"308\": \"Permanent Redirect\",\n  \"3XX\": \"3XX Range\",\n  \"400\": \"Bad Request\",\n  \"401\": \"Unauthorized\",\n  \"402\": \"Payment Required\",\n  \"403\": \"Forbidden\",\n  \"404\": \"Not Found\",\n  \"405\": \"Method Not Allowed\",\n  \"406\": \"Not Acceptable\",\n  \"407\": \"Proxy Authentication Required\",\n  \"408\": \"Request Timeout\",\n  \"409\": \"Conflict\",\n  \"410\": \"Gone\",\n  \"411\": \"Length Required\",\n  \"412\": \"Precondition Failed\",\n  \"413\": \"Request Entity Too Large\",\n  \"414\": \"Request-URI Too Long\",\n  \"415\": \"Unsupported Media Type\",\n  \"416\": \"Requested Range Not Satisfiable\",\n  \"417\": \"Expectation Failed\",\n  \"418\": \"I'm a teapot\",\n  \"419\": \"Insufficient Space on Resource\",\n  \"420\": \"Method Failure\",\n  \"422\": \"Unprocessable Entity\",\n  \"423\": \"Locked\",\n  \"424\": \"Failed Dependency\",\n  \"428\": \"Precondition Required\",\n  \"429\": \"Too Many Requests\",\n  \"431\": \"Request Header Fields Too Large\",\n  \"4XX\": \"4XX Range\",\n  \"500\": \"Server Error\",\n  \"501\": \"Not Implemented\",\n  \"502\": \"Bad Gateway\",\n  \"503\": \"Service Unavailable\",\n  \"504\": \"Gateway Timeout\",\n  \"505\": \"HTTP Version Not Supported\",\n  \"507\": \"Insufficient Storage\",\n  \"511\": \"Network Authentication Required\",\n  \"5XX\": \"5XX Range\",\n  \"default\": \"Default response\",\n}\n`;\n"
  },
  {
    "path": "test/transforms/paths/combineSchemas.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\nconst parseComponents = require('../../../transforms/components');\n\ntest('should parse jsdoc path response with oneOf keyword', () => {\n  const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {oneOf|Song|Album} 200 - success response - application/json\n       */\n    `];\n  const expected = {\n    paths: {\n      '/api/v1': {\n        get: {\n          deprecated: false,\n          description: undefined,\n          summary: 'This is the summary of the endpoint',\n          parameters: [],\n          tags: [],\n          security: [],\n          responses: {\n            200: {\n              description: 'success response',\n              content: {\n                'application/json': {\n                  schema: {\n                    oneOf: [\n                      {\n                        $ref: '#/components/schemas/Song',\n                      },\n                      {\n                        $ref: '#/components/schemas/Album',\n                      },\n                    ],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = setPaths({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n\ntest('should parse component with anyOf keyword', () => {\n  const jsodInput = [`\n    /**\n     * A song\n     * @typedef {object} Song\n     * @property {string} title.required\n     * @property {string} artist\n     * @property {number} year\n     */\n  `,\n  `\n    /**\n     * Album\n     * @typedef {object} Album\n     * @property {anyOf|Song|Album} firstSong\n     */\n  `];\n  const expected = {\n    components: {\n      schemas: {\n        Song: {\n          type: 'object',\n          required: [\n            'title',\n          ],\n          description: 'A song',\n          properties: {\n            title: {\n              type: 'string',\n              description: '',\n            },\n            artist: {\n              type: 'string',\n              description: '',\n            },\n            year: {\n              type: 'number',\n              description: '',\n            },\n          },\n        },\n        Album: {\n          type: 'object',\n          description: 'Album',\n          properties: {\n            firstSong: {\n              description: '',\n              anyOf: [\n                {\n                  $ref: '#/components/schemas/Song',\n                },\n                {\n                  $ref: '#/components/schemas/Album',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = parseComponents({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n\ntest('should parse jsdoc path reference params with allOf keyword', () => {\n  const jsodInput = [`\n    /**\n     * GET /api/v1\n     * @param {allOf|Song|Album} name.query.required - name param description\n     */\n  `];\n  const expected = {\n    paths: {\n      '/api/v1': {\n        get: {\n          deprecated: false,\n          description: undefined,\n          summary: '',\n          responses: {},\n          security: [],\n          tags: [],\n          parameters: [{\n            deprecated: false,\n            description: 'name param description',\n            in: 'query',\n            name: 'name',\n            required: true,\n            schema: {\n              allOf: [\n                {\n                  $ref: '#/components/schemas/Song',\n                },\n                {\n                  $ref: '#/components/schemas/Album',\n                },\n              ],\n            },\n          }],\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = setPaths({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n\ntest('should parse component with anyOf array keyword', () => {\n  const jsodInput = [`\n    /**\n     * A song\n     * @typedef {object} Song\n     * @property {string} title.required\n     * @property {string} artist\n     * @property {number} year\n     */\n  `,\n  `\n    /**\n     * Album\n     * @typedef {object} Album\n     * @property {anyOf|Song[]|Album|string|string[]|null} firstSong\n     */\n  `];\n  const expected = {\n    components: {\n      schemas: {\n        Song: {\n          type: 'object',\n          required: [\n            'title',\n          ],\n          description: 'A song',\n          properties: {\n            title: {\n              type: 'string',\n              description: '',\n            },\n            artist: {\n              type: 'string',\n              description: '',\n            },\n            year: {\n              type: 'number',\n              description: '',\n            },\n          },\n        },\n        Album: {\n          type: 'object',\n          description: 'Album',\n          properties: {\n            firstSong: {\n              description: '',\n              anyOf: [\n                {\n                  type: 'array',\n                  items: {\n                    $ref: '#/components/schemas/Song',\n                  },\n                },\n                {\n                  $ref: '#/components/schemas/Album',\n                },\n                {\n                  type: 'string',\n                },\n                {\n                  type: 'array',\n                  items: {\n                    type: 'string',\n                  },\n                },\n              ],\n              nullable: true,\n            },\n          },\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = parseComponents({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n\ntest('should parse component with jsdoc syntax for multiple data types', () => {\n  const jsodInput = [`\n    /**\n     * A song\n     * @typedef {object} Song\n     * @property {string} title.required\n     * @property {string} artist\n     * @property {number} year\n     * @property {(string|null)} album\n     * @property {object|number} releaseDate\n     */\n  `];\n  const expected = {\n    components: {\n      schemas: {\n        Song: {\n          type: 'object',\n          required: [\n            'title',\n          ],\n          description: 'A song',\n          properties: {\n            title: {\n              type: 'string',\n              description: '',\n            },\n            artist: {\n              type: 'string',\n              description: '',\n            },\n            year: {\n              type: 'number',\n              description: '',\n            },\n            album: {\n              type: 'string',\n              description: '',\n              nullable: true,\n            },\n            releaseDate: {\n              description: '',\n              oneOf: [\n                {\n                  type: 'object',\n                },\n                {\n                  type: 'number',\n                },\n              ],\n            },\n          },\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = parseComponents({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/transforms/paths/formParameters.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('form requestBody tests', () => {\n  it('should add request body using form examples', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       * @param {string} id.form.required - id description\n       * @param {string} title.form.required - title description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      id: {\n                        type: 'string',\n                        description: 'id description',\n                      },\n                      title: {\n                        type: 'string',\n                        description: 'title description',\n                      },\n                    },\n                    required: ['id', 'title'],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should add request body using form examples with params', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       * @param {string} name.path.required - name param description\n       * @param {string} id.form.required - id description\n       * @param {string} title.form.required - title description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            summary: '',\n            responses: {},\n            tags: [],\n            security: [],\n            parameters: [\n              {\n                deprecated: false,\n                description: 'name param description',\n                in: 'path',\n                name: 'name',\n                required: true,\n                schema: {\n                  type: 'string',\n                },\n              },\n            ],\n            requestBody: {\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      id: {\n                        type: 'string',\n                        description: 'id description',\n                      },\n                      title: {\n                        type: 'string',\n                        description: 'title description',\n                      },\n                    },\n                    required: ['id', 'title'],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should not fail when a request.body is sent', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       * @param {string} request.body.required - name body description\n       * @param {string} id.form.required - id description\n       * @param {string} title.form.required - title description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      id: {\n                        type: 'string',\n                        description: 'id description',\n                      },\n                      title: {\n                        type: 'string',\n                        description: 'title description',\n                      },\n                    },\n                    required: ['id', 'title'],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should add request body for different application content type', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       * @param {string} name.path.required - name param description\n       * @param {string} id.form.required - id description - application/x-www-form-urlencoded\n       * @param {string} title.form.required - title description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            security: [],\n            parameters: [\n              {\n                deprecated: false,\n                description: 'name param description',\n                in: 'path',\n                name: 'name',\n                required: true,\n                schema: {\n                  type: 'string',\n                },\n              },\n            ],\n            requestBody: {\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      title: {\n                        type: 'string',\n                        description: 'title description',\n                      },\n                    },\n                    required: ['title'],\n                  },\n                },\n                'application/x-www-form-urlencoded': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      id: {\n                        type: 'string',\n                        description: 'id description',\n                      },\n                    },\n                    required: ['id'],\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should add request body for different application content type with an example', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       * @param {string} name.path.required - name param description\n       * @param {string} id.form.required - id description - application/x-www-form-urlencoded\n       * @param {string} title.form.required - title description\n       * @example request - example payload\n       * sample input string\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [\n              {\n                deprecated: false,\n                description: 'name param description',\n                in: 'path',\n                name: 'name',\n                required: true,\n                schema: {\n                  type: 'string',\n                },\n              },\n            ],\n            requestBody: {\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      title: {\n                        type: 'string',\n                        description: 'title description',\n                      },\n                    },\n                    required: ['title'],\n                  },\n                  examples: {\n                    example1: {\n                      summary: 'example payload',\n                      value: 'sample input string',\n                    },\n                  },\n                },\n                'application/x-www-form-urlencoded': {\n                  schema: {\n                    type: 'object',\n                    properties: {\n                      id: {\n                        type: 'string',\n                        description: 'id description',\n                      },\n                    },\n                    required: ['id'],\n                  },\n                  examples: {\n                    example1: {\n                      summary: 'example payload',\n                      value: 'sample input string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/index.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('setPaths method', () => {\n  it('should return empty array with not params', () => {\n    const initialState = {};\n    const paths = undefined;\n    const expected = {\n      paths: {},\n    };\n    const result = setPaths(initialState, paths);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty array with not an array as parameter', () => {\n    const initialState = {};\n    const paths = 2;\n    const expected = {\n      paths: {},\n    };\n    const result = setPaths(initialState, paths);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with one response, summary, description and endpoint info', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @description This is the description of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            summary: 'This is the summary of the endpoint',\n            description: 'This is the description of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with deprecated value', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @deprecated\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: true,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with multiple endpoints', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @deprecated\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/songs\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: true,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n        '/api/v1/songs': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with multiple methods for one endpoint', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @deprecated\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `,\n    `\n      /**\n       * POST /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: true,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            security: [],\n            tags: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/parameters.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('params tests', () => {\n  it('should parse jsdoc path params', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {string} name.query.required - name param description\n       * @operationId getInfo\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            operationId: 'getInfo',\n            parameters: [{\n              deprecated: false,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'string',\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should not parse jsdoc path params with malformed info', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {string} name param description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path params with array type', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {array<string>} name.query.required.deprecated - name param description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: true,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'array',\n                items: {\n                  type: 'string',\n                },\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path multiple params', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {array<string>} name.query.required.deprecated - name param description\n       * @param {number} phone.param\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: true,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'array',\n                items: {\n                  type: 'string',\n                },\n              },\n            }, {\n              deprecated: false,\n              description: '',\n              in: 'param',\n              name: 'phone',\n              required: false,\n              schema: {\n                type: 'number',\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path reference params', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {Song} name.query.required - name param description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: false,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                $ref: '#/components/schemas/Song',\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path params with array of references', () => {\n    const jsodInput = [\n      [`\n        /**\n         * GET /api/v1\n         * @param {array<Song>} name.query.required.deprecated - name param description\n         */\n      `],\n      [`\n        /**\n         * GET /api/v1\n         * @param {Array<Song>} name.query.required.deprecated - name param description\n         */\n      `],\n      [`\n        /**\n         * GET /api/v1\n         * @param {Song[]} name.query.required.deprecated - name param description\n         */\n      `],\n    ];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: true,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'array',\n                items: {\n                  $ref: '#/components/schemas/Song',\n                },\n              },\n            }],\n          },\n        },\n      },\n    };\n    jsodInput.forEach(jsod => {\n      const parsedJSDocs = jsdocInfo()(jsod);\n      const result = setPaths({}, parsedJSDocs);\n      expect(result).toEqual(expected);\n    });\n  });\n\n  it('should parse jsdoc path params with enum values', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {string} name.query.required - name param description - enum:value1,value2\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: false,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'string',\n                enum: [\n                  'value1',\n                  'value2',\n                ],\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path params with enum values in diferent order', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @param {string} name.query.required - enum:value1,value2 - name param description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            security: [],\n            tags: [],\n            parameters: [{\n              deprecated: false,\n              description: 'name param description',\n              in: 'query',\n              name: 'name',\n              required: true,\n              schema: {\n                type: 'string',\n                enum: [\n                  'value1',\n                  'value2',\n                ],\n              },\n            }],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n\nit('should parse jsdoc path params with json options', () => {\n  const jsodInput = [`\n    /**\n     * GET /api/v1\n     * @param {string} name.query.required - name param description - enum:value1,value2 - json:{\"minLength\": 6}\n     * @param {integer} age.query - age param description - json:{\"minimum\": 0, \"maximum\": 130}\n     */\n  `];\n  const expected = {\n    paths: {\n      '/api/v1': {\n        get: {\n          deprecated: false,\n          description: undefined,\n          summary: '',\n          responses: {},\n          security: [],\n          tags: [],\n          parameters: [{\n            deprecated: false,\n            description: 'name param description',\n            in: 'query',\n            name: 'name',\n            required: true,\n            schema: {\n              type: 'string',\n              enum: [\n                'value1',\n                'value2',\n              ],\n              minLength: 6,\n            },\n          }, {\n            deprecated: false,\n            description: 'age param description',\n            in: 'query',\n            name: 'age',\n            required: false,\n            schema: {\n              type: 'integer',\n              minimum: 0,\n              maximum: 130,\n            },\n          }],\n        },\n      },\n    },\n  };\n  const parsedJSDocs = jsdocInfo()(jsodInput);\n  const result = setPaths({}, parsedJSDocs);\n  expect(result).toEqual(expected);\n});\n"
  },
  {
    "path": "test/transforms/paths/requestBody.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('request body tests', () => {\n  it('should not add requestBody when there is no body params', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {string} request.body.required - name body description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'string',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body with array type and no description', () => {\n    const jsodInput = [\n      `\n      /**\n       * POST /api/v1/albums\n       * @param {array<object>} request.body.required\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/albums': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: '',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body with array type', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {array<string>} request.body.required - name body description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      type: 'string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body for delete request', () => {\n    const jsdocInput = [`\n      /**\n       * DELETE /message\n       * @summary Delete messages listed under the specified tags\n       * @param {array<string>} request.body.required - Tags of the messages to delete\n       */\n    `];\n    const expected = {\n      paths: {\n        '/message': {\n          delete: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Delete messages listed under the specified tags',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'Tags of the messages to delete',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      type: 'string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path multiple bodys', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {number} body\n       * @param {array<string>} request.body.required - name body description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      type: 'string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc path reference bodys', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {Song} request.body.required - name body description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    $ref: '#/components/schemas/Song',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body with array of references', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {array<Song>} request.body.required - name body description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body with array of references for different content type', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1\n       * @param {array<Song>} request.body.required - name body description\n       * @param {Song} request.body.required - name body description - application/xml\n       * @param {object} request.body.required - name body description - application/x-www-form-urlencoded\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'array',\n                    items: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                  },\n                },\n                'application/xml': {\n                  schema: {\n                    $ref: '#/components/schemas/Song',\n                  },\n                },\n                'application/x-www-form-urlencoded': {\n                  schema: {\n                    type: 'object',\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should parse jsdoc request body with examples', () => {\n    const jsdocInput = [`\n      /**\n       * POST /api/v1\n       * @param {string} request.body.required - name body description\n       * @example request - example payload\n       * sample input string\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            responses: {},\n            tags: [],\n            parameters: [],\n            security: [],\n            requestBody: {\n              description: 'name body description',\n              required: true,\n              content: {\n                'application/json': {\n                  schema: {\n                    type: 'string',\n                  },\n                  examples: {\n                    example1: {\n                      summary: 'example payload',\n                      value: 'sample input string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/responses.test.js",
    "content": "const chalk = require('chalk');\nconst jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('response tests', () => {\n  it('should parse jsdoc path spec with more than one response without type', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return 200 - success response - application/json\n       * @return 400 - Bad request response\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n              },\n              400: {\n                description: 'Bad request response',\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with more than one response', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       * @return {object} 400 - Bad request response\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n              400: {\n                description: 'Bad request response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc with responses, whether @return or @returns tags are used', () => {\n    const jsdocInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       * @returns {object} 400 - Bad request response\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n              400: {\n                description: 'Bad request response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should not parse jsdoc with wrong info and return warning in the console', () => {\n    global.console = {\n      ...global.console,\n      warn: jest.fn(),\n    };\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            responses: {},\n            parameters: [],\n            tags: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n    // eslint-disable-next-line\n    expect(console.warn)\n      .toHaveBeenCalled();\n  });\n\n  it('should parse jsdoc with wrong info and return warning in the console', () => {\n    global.console = {\n      ...global.console,\n      warn: jest.fn(),\n    };\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} default - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              default: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n    // eslint-disable-next-line\n    expect(console.warn)\n      .not\n      .toHaveBeenCalled();\n  });\n\n  it('should parse jsdoc path response with array type', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {array<integer>} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'array',\n                      items: {\n                        type: 'integer',\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc path response with components', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {Song} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc path response with array of components', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {array<Song>} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'array',\n                      items: {\n                        $ref: '#/components/schemas/Song',\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc path spec with more than one response and multiple content types', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {object} 200 - success response - application/json\n       * @return {object} 400 - Bad request response\n       * @return {string} 400 - Bad request response - application/xml\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n              400: {\n                description: 'Bad request response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                  'application/xml': {\n                    schema: {\n                      type: 'string',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should parse jsdoc path response with examples', () => {\n    const jsdocInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {Song} 200 - success response - application/json\n       * @return {object} 403 - forbidden response - application/json\n       * @example response - 200 - example success response\n       * {\n       *   \"title\": \"untitled song\",\n       *   \"artist\": \"anonymous\"\n       * }\n       * @example response - 403 - example error response\n       * {\n       *   \"error\": \"failed to retrieve results\"\n       * }\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                    examples: {\n                      example1: {\n                        summary: 'example success response',\n                        value: {\n                          title: 'untitled song',\n                          artist: 'anonymous',\n                        },\n                      },\n                    },\n                  },\n                },\n              },\n              403: {\n                description: 'forbidden response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                    examples: {\n                      example2: {\n                        summary: 'example error response',\n                        value: {\n                          error: 'failed to retrieve results',\n                        },\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should not parse jsdoc path response with examples when an application/json example is malformed', () => {\n    const jsdocInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {Song} 200 - success response - application/json\n       * @return {object} 403 - forbidden response - application/json\n       * @example response - 200 - example success response\n       * {\n       *   \"title\": \"untitled song\",\n       *   \"artist\": \"anonymous\"\n       * }\n       * @example response - 403 - example error response\n       * {\n       *   \"error\": \"failed to retrieve results\",\n       * }\n       */\n    `];\n    global.console = {\n      ...global.console,\n      warn: jest.fn(),\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    setPaths({}, parsedJSDocs);\n    // eslint-disable-next-line\n    expect(console.warn)\n      .toHaveBeenCalledTimes(1);\n    // eslint-disable-next-line\n    expect(console.warn)\n      .toHaveBeenNthCalledWith(\n        1,\n        chalk.yellow('[express-jsdoc-swagger] response example for status 403 with content-type application/json malformed'),\n      );\n  });\n\n  it('should parse undefined if example has no valid types (request or response)', () => {\n    const jsdocInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {Song} 200 - success response - application/json\n       * @return {object} 403 - forbidden response - application/json\n       * @example response - 200 - example success response\n       * {\n       *   \"title\": \"untitled song\",\n       *   \"artist\": \"anonymous\"\n       * }\n       * @example res - 403 - example error response\n       * {\n       *   \"error\": \"failed to retrieve results\"\n       * }\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                    examples: {\n                      example1: {\n                        summary: 'example success response',\n                        value: {\n                          title: 'untitled song',\n                          artist: 'anonymous',\n                        },\n                      },\n                    },\n                  },\n                },\n              },\n              403: {\n                description: 'forbidden response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                    examples: undefined,\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n\n  it('should not parse an example if has no valid status', () => {\n    const jsdocInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {Song} 200 - success response - application/json\n       * @return {object} 403 - forbidden response - application/json\n       * @example response - 200 - example success response\n       * {\n       *   \"title\": \"untitled song\",\n       *   \"artist\": \"anonymous\"\n       * }\n       * @example response - 333 - example error response\n       * {\n       *   \"error\": \"failed to retrieve results\"\n       * }\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      $ref: '#/components/schemas/Song',\n                    },\n                    examples: {\n                      example1: {\n                        summary: 'example success response',\n                        value: {\n                          title: 'untitled song',\n                          artist: 'anonymous',\n                        },\n                      },\n                    },\n                  },\n                },\n              },\n              403: {\n                description: 'forbidden response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'object',\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsdocInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n  it('should parse jsdoc path spec with more than multiple response and multiple content types', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @summary This is the summary of the endpoint\n       * @return {array<Song|Song>} 200 - success response - application/json\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: 'This is the summary of the endpoint',\n            parameters: [],\n            tags: [],\n            security: [],\n            responses: {\n              200: {\n                description: 'success response',\n                content: {\n                  'application/json': {\n                    schema: {\n                      type: 'array',\n                      items: {\n                        anyOf: [\n                          {\n                            $ref: '#/components/schemas/Song',\n                          },\n                          {\n                            $ref: '#/components/schemas/Song',\n                          },\n                        ],\n                      },\n                    },\n                  },\n                },\n              },\n            },\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result)\n      .toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/security.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('Paths - security', () => {\n  it('Should parse jsdoc security params into security array with each security type', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       * @security BasicAuth\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            security: [\n              {\n                BasicAuth: [],\n              },\n            ],\n            tags: [],\n            responses: {},\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc multiple security params into security array with each security type', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       * @security BasicAuth\n       * @security BearerAuth\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            security: [\n              {\n                BasicAuth: [],\n              },\n              {\n                BearerAuth: [],\n              },\n            ],\n            tags: [],\n            responses: {},\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc multiple security with \"and\" configuration', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       * @security BasicAuth & BearerAuth\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            security: [\n              {\n                BasicAuth: [],\n                BearerAuth: [],\n              },\n            ],\n            tags: [],\n            responses: {},\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc multiple security with \"or\" configuration', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       * @security BasicAuth & BearerAuth | Oauth2\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            security: [\n              {\n                BasicAuth: [],\n                BearerAuth: [],\n              },\n              {\n                Oauth2: [],\n              },\n            ],\n            tags: [],\n            responses: {},\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc empty security tag into empty array', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       * @security\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            security: [],\n            tags: [],\n            responses: {},\n            parameters: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc with no security tag and not include security in the swagger object', () => {\n    const jsodInput = [`\n      /**\n       * POST /api/v1/song\n       * @summary Create new song\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1/song': {\n          post: {\n            deprecated: false,\n            description: undefined,\n            summary: 'Create new song',\n            tags: [],\n            responses: {},\n            parameters: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/tags.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst setPaths = require('../../../transforms/paths');\n\ndescribe('Paths - tags', () => {\n  it('Should parse jsdoc tags params into array with tag name', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @tags album\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            tags: [\n              'album',\n            ],\n            responses: {},\n            parameters: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc multiple tags params into array of tags', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @tags album\n       * @tags Years\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            tags: [\n              'album',\n              'Years',\n            ],\n            responses: {},\n            parameters: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc multiple tags params into array of tags without description', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1\n       * @tags album\n       * @tags Years - tag description\n       */\n    `];\n    const expected = {\n      paths: {\n        '/api/v1': {\n          get: {\n            deprecated: false,\n            description: undefined,\n            summary: '',\n            tags: [\n              'album',\n              'Years',\n            ],\n            responses: {},\n            parameters: [],\n            security: [],\n          },\n        },\n      },\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = setPaths({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/paths/validStatusCodes.test.js",
    "content": "const validStatusCodes = require('../../../transforms/paths/validStatusCodes');\n\ntest('Valid status codes snapshot', () => {\n  expect(validStatusCodes).toMatchSnapshot();\n});\n"
  },
  {
    "path": "test/transforms/security/index.test.js",
    "content": "const parseSecuritySchemas = require('../../../transforms/security');\n\ndescribe('Transform security schemas', () => {\n  it('Should return a empty object with not securitySchemes', () => {\n    const input = undefined;\n    const expected = {\n      components: {},\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return a empty components object with not securitySchemes when security was not set', () => {\n    const input = {\n      info: {\n        version: '1.0.0',\n        title: 'Albums store',\n        license: {\n          name: 'MIT',\n        },\n      },\n    };\n    const expected = {\n      info: {\n        version: '1.0.0',\n        title: 'Albums store',\n        license: {\n          name: 'MIT',\n        },\n      },\n      components: {},\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return a security array and securitySchemes within components field for http', () => {\n    const input = {\n      security: {\n        BasicAuth: {\n          type: 'http',\n          scheme: 'basic',\n        },\n      },\n    };\n    const expected = {\n      security: [\n        {\n          BasicAuth: [],\n        },\n      ],\n      components: {\n        securitySchemes: {\n          BasicAuth: {\n            type: 'http',\n            scheme: 'basic',\n          },\n        },\n      },\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return a security array and securitySchemes within components field for http (bearer format)', () => {\n    const input = {\n      security: {\n        HTTPAuth: {\n          type: 'http',\n          scheme: 'basic',\n          bearerFormat: 'JWT',\n        },\n      },\n    };\n    const expected = {\n      security: [\n        {\n          HTTPAuth: [],\n        },\n      ],\n      components: {\n        securitySchemes: {\n          HTTPAuth: {\n            type: 'http',\n            scheme: 'basic',\n            bearerFormat: 'JWT',\n          },\n        },\n      },\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return a security array and securitySchemes within components field for apiKey', () => {\n    const input = {\n      security: {\n        ApiKeyAuth: {\n          type: 'apiKey',\n          in: 'header',\n          name: 'api_key',\n        },\n      },\n    };\n    const expected = {\n      security: [\n        {\n          ApiKeyAuth: [],\n        },\n      ],\n      components: {\n        securitySchemes: {\n          ApiKeyAuth: {\n            type: 'apiKey',\n            in: 'header',\n            name: 'api_key',\n          },\n        },\n      },\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return a security array and securitySchemes, both with each security type', () => {\n    const input = {\n      security: {\n        BasicAuth: {\n          type: 'http',\n          scheme: 'basic',\n        },\n        bearerAuth: {\n          type: 'http',\n          scheme: 'bearer',\n          bearerFormat: 'JWT',\n        },\n      },\n    };\n    const expected = {\n      security: [\n        {\n          BasicAuth: [],\n        },\n        {\n          bearerAuth: [],\n        },\n      ],\n      components: {\n        securitySchemes: {\n          BasicAuth: {\n            type: 'http',\n            scheme: 'basic',\n          },\n          bearerAuth: {\n            type: 'http',\n            scheme: 'bearer',\n            bearerFormat: 'JWT',\n          },\n        },\n      },\n    };\n    const result = parseSecuritySchemas(input);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/tags/index.test.js",
    "content": "const jsdocInfo = require('../../../consumers/jsdocInfo');\nconst parseTags = require('../../../transforms/tags');\n\ndescribe('parseTags method', () => {\n  it('should return empty tags array with not params', () => {\n    const initialState = {};\n    const tags = undefined;\n    const expected = {\n      tags: [],\n    };\n    const result = parseTags(initialState, tags);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should not parse params that aren\\'t tags', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1/album\n       * @summary example of no summary\n       */\n    `];\n    const expected = {\n      tags: [],\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseTags({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('should return empty tags array with not an array as parameter', () => {\n    const initialState = {};\n    const tags = 2;\n    const expected = {\n      tags: [],\n    };\n    const result = parseTags(initialState, tags);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc tags into tags array with name and description', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1/album\n       * @tags album - album tag description\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/artists\n       * @tags artist - artist tag description\n       */\n    `];\n    const expected = {\n      tags: [\n        {\n          name: 'album',\n          description: 'album tag description',\n        },\n        {\n          name: 'artist',\n          description: 'artist tag description',\n        },\n      ],\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseTags({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should parse jsdoc tags into tags array without duplicate tags', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1/album\n       * @tags album - album tag description\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/years\n       * @tags artist - artist tag description\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/artists\n       * @tags artist - artist tag description\n       */\n    `];\n    const expected = {\n      tags: [\n        {\n          name: 'album',\n          description: 'album tag description',\n        },\n        {\n          name: 'artist',\n          description: 'artist tag description',\n        },\n      ],\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseTags({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return an empty string if the tag has no description', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1/album\n       * @tags album - album tag description\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/years\n       * @tags artist\n       */\n    `];\n    const expected = {\n      tags: [\n        {\n          name: 'album',\n          description: 'album tag description',\n        },\n        {\n          name: 'artist',\n          description: '',\n        },\n      ],\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseTags({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n\n  it('Should return one tag with its description', () => {\n    const jsodInput = [`\n      /**\n       * GET /api/v1/album\n       * @tags album\n       */\n    `,\n    `\n      /**\n       * GET /api/v1/years\n       * @tags album - album tag description\n       */\n    `];\n    const expected = {\n      tags: [\n        {\n          name: 'album',\n          description: 'album tag description',\n        },\n      ],\n    };\n    const parsedJSDocs = jsdocInfo()(jsodInput);\n    const result = parseTags({}, parsedJSDocs);\n    expect(result).toEqual(expected);\n  });\n});\n"
  },
  {
    "path": "test/transforms/utils/index.test.js",
    "content": "const setProperty = require('../../../transforms/utils/setProperty');\n\ndescribe('setProperty method', () => {\n  it('should not allow empty configuration', () => {\n    expect(() => {\n      setProperty()();\n    }).toThrow('item, key and options para are required');\n  });\n});\n"
  },
  {
    "path": "transforms/basic/contact.js",
    "content": "const setProperty = require('../utils/setProperty')('contact');\n\nconst getContact = (options = {}) => ({\n  name: setProperty(options, 'name', {\n    type: 'string',\n    required: true,\n  }),\n  url: setProperty(options, 'url', {\n    type: 'string',\n    defaultValue: '',\n  }),\n  email: setProperty(options, 'email', {\n    type: 'string',\n    defaultValue: '',\n  }),\n});\n\nmodule.exports = getContact;\n"
  },
  {
    "path": "transforms/basic/index.js",
    "content": "const info = require('./info');\nconst servers = require('./servers');\n\nconst getBasicInfo = (swaggerObjet = {}) => ({\n  ...swaggerObjet,\n  info: { ...info(swaggerObjet.info) },\n  servers: servers(swaggerObjet.servers),\n});\n\nmodule.exports = getBasicInfo;\n"
  },
  {
    "path": "transforms/basic/info.js",
    "content": "const setProperty = require('../utils/setProperty')('info');\nconst getContact = require('./contact');\nconst license = require('./license');\n\nconst getInfo = (options = {}) => ({\n  title: setProperty(options, 'title', {\n    type: 'string',\n    required: true,\n  }),\n  description: setProperty(options, 'description', {\n    type: 'string',\n    defaultValue: 'Add your description',\n  }),\n  ...(options.contact ? { contact: getContact(options.contact) } : {}),\n  ...(options.license ? { license: license(options.license) } : {}),\n  termsOfService: setProperty(options, 'termsOfService', {\n    type: 'string',\n    defaultValue: '',\n  }),\n  version: setProperty(options, 'version', {\n    type: 'string',\n    required: true,\n  }),\n});\n\nmodule.exports = getInfo;\n"
  },
  {
    "path": "transforms/basic/license.js",
    "content": "const setProperty = require('../utils/setProperty')('license');\n\nconst getContact = (options = {}) => ({\n  name: setProperty(options, 'name', {\n    type: 'string',\n    required: true,\n  }),\n  url: setProperty(options, 'url', {\n    type: 'string',\n    defaultValue: '',\n  }),\n});\n\nmodule.exports = getContact;\n"
  },
  {
    "path": "transforms/basic/servers.js",
    "content": "const setProperty = require('../utils/setProperty')('servers');\n\nconst setServer = (server = {}) => ({\n  url: setProperty(server, 'url', {\n    type: 'string',\n    required: true,\n  }),\n  description: setProperty(server, 'description', {\n    type: 'string',\n    defaultValue: '',\n  }),\n  ...(server.variables ? { variables: server.variables } : {}),\n});\n\nconst setServers = (servers = []) => {\n  if (!servers || !Array.isArray(servers)) return [];\n  return servers.map(setServer);\n};\n\nmodule.exports = setServers;\n"
  },
  {
    "path": "transforms/components/index.js",
    "content": "const { getTagInfo, getTagsInfo } = require('../utils/tags');\nconst mapDescription = require('../utils/mapDescription');\nconst { refSchema, formatRefSchema } = require('../utils/refSchema');\nconst addEnumValues = require('../utils/enumValues');\nconst formatDescription = require('../utils/formatDescription');\nconst combineSchema = require('../utils/combineSchema');\nconst validateTypes = require('../utils/validateTypes');\n\nconst REQUIRED = 'required';\n\nconst getPropertyName = ({ name: propertyName }) => {\n  const [name] = propertyName.split('.');\n  return name;\n};\n\nconst addTypeApplication = (applications, expression) => {\n  if (!applications && !expression) return {};\n  return {\n    type: expression.name.toLowerCase(),\n    items: {\n      type: applications[0].name,\n    },\n  };\n};\n\nconst addRefSchema = (typeName, applications, elements) => {\n  if (!typeName && !elements) return { items: formatRefSchema(applications) };\n  return {};\n};\n\nconst formatProperties = (properties, options = {}) => {\n  if (!properties || !Array.isArray(properties)) return {};\n  return properties.reduce((acum, property) => {\n    const name = getPropertyName(property);\n    const isRequired = property.name.includes(REQUIRED);\n    const {\n      name: typeName, applications, expression, elements,\n    } = property.type;\n    const [descriptionValue, enumValues, jsonOptions] = formatDescription(property.description);\n    const [description, format] = mapDescription(descriptionValue);\n    return {\n      ...acum,\n      [name]: {\n        description,\n        ...refSchema(typeName),\n        ...combineSchema(elements),\n        ...addTypeApplication(applications, expression),\n        ...addRefSchema(typeName, applications, elements),\n        ...(format ? { format } : {}),\n        ...addEnumValues(enumValues),\n\n        // Add nullable to non-required fields if option to do that is enabled\n        ...(options.notRequiredAsNullable && !isRequired ? {\n          nullable: true,\n        } : {}),\n        ...(jsonOptions || {}),\n      },\n    };\n  }, {});\n};\n\nconst getRequiredProperties = properties => (\n  properties.filter(({ name }) => name.includes(REQUIRED))\n);\n\nconst formatRequiredProperties = requiredProperties => requiredProperties.map(getPropertyName);\n\nconst addDictionaryAdditionalProperties = typedef => {\n  if (\n    typedef.type.expression\n    && typedef.type.expression.name === 'Dictionary'\n  ) {\n    const typeName = typedef.type.applications[0].name;\n    const isPrimitive = validateTypes(typeName);\n\n    return {\n      additionalProperties: {\n        ...(isPrimitive ? { type: typeName } : { $ref: `#/components/schemas/${typeName}` }),\n      },\n    };\n  }\n\n  return {};\n};\n\nconst parseSchema = (schema, options = {}) => {\n  const typedef = getTagInfo(schema.tags, 'typedef');\n  const propertyValues = getTagsInfo(schema.tags, 'property');\n  const requiredProperties = getRequiredProperties(propertyValues);\n  const [descriptionValue, enumValues, jsonOptions] = formatDescription(schema.description);\n  const [description, format] = mapDescription(descriptionValue);\n  if (!typedef || !typedef.name) return {};\n  const {\n    elements,\n  } = typedef.type;\n  const type = typedef.type.name || 'object';\n  return {\n    [typedef.name]: {\n      ...combineSchema(elements),\n      description,\n      ...(requiredProperties.length ? {\n        required: formatRequiredProperties(requiredProperties),\n      } : {}),\n      type,\n      ...(type === 'object' ? {\n        properties: formatProperties(propertyValues, options),\n      } : {}),\n      ...(format ? { format } : {}),\n      ...addEnumValues(enumValues),\n      ...addDictionaryAdditionalProperties(typedef),\n      ...(jsonOptions || {}),\n    },\n  };\n};\n\nconst parseComponents = (swaggerObject = {}, components = [], options = {}) => {\n  if (!components || !Array.isArray(components)) return { components: { schemas: {} } };\n  const componentSchema = components.reduce((acum, item) => ({\n    ...acum, ...parseSchema(item, options),\n  }), {});\n  return {\n    ...swaggerObject,\n    components: {\n      ...swaggerObject.components,\n      schemas: componentSchema,\n    },\n  };\n};\n\nmodule.exports = parseComponents;\n"
  },
  {
    "path": "transforms/index.js",
    "content": "const getBasicInfo = require('./basic');\nconst getSecuritySchemes = require('./security');\nconst getPaths = require('./paths');\nconst getComponents = require('./components');\nconst getTags = require('./tags');\n\nmodule.exports = {\n  getBasicInfo,\n  getPaths,\n  getComponents,\n  getTags,\n  getSecuritySchemes,\n};\n"
  },
  {
    "path": "transforms/paths/content.js",
    "content": "const getSchema = require('./schema');\n\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\nconst getContent = entity => (type, contentType, originalValue, examples, extendSchema = {}) => {\n  const schema = getSchema(entity, originalValue)(type);\n  return {\n    [contentType || DEFAULT_CONTENT_TYPE]: {\n      schema: {\n        ...schema,\n        ...extendSchema,\n      },\n      ...(examples ? { examples } : {}),\n    },\n  };\n};\n\nmodule.exports = getContent;\n"
  },
  {
    "path": "transforms/paths/examples.js",
    "content": "const STATUS_CODES = require('./validStatusCodes');\n\nconst errorMessage = require('../utils/errorMessage');\nconst mapDescription = require('../utils/mapDescription');\nconst generator = require('../utils/generator');\n\nconst REQUEST_BODY = 'request';\nconst RESPONSE_BODY = 'response';\n\n// Generates a new object with information on a request body example\nconst parseRequestPayloadExample = (description, content) => {\n  const [summary] = description;\n  return {\n    type: REQUEST_BODY,\n    summary,\n    value: content,\n  };\n};\n\nconst showError = message => {\n  errorMessage(message);\n  return {};\n};\n\n// Generates a new object with information on a response body example\nconst parseResponsePayloadExample = (description, content) => {\n  const [status, summary] = description;\n  if (!STATUS_CODES[status]) {\n    return showError(`${status} is not a valid status for a response`);\n  }\n  return {\n    type: RESPONSE_BODY,\n    status,\n    summary,\n    value: content,\n  };\n};\n\nconst getParsedExample = ({ type, metadata, content }) => {\n  const types = {\n    [REQUEST_BODY]: () => parseRequestPayloadExample(metadata, content),\n    [RESPONSE_BODY]: () => parseResponsePayloadExample(metadata, content),\n    default: () => showError(`Cannot determine where to use example of type ${type}`),\n  };\n  return (types[type] || types.default)();\n};\n\n/**\n *  Parses a single example tag contents. Depending on the type (response or\n * request), the expected data and returned structure will be different.\n *\n *  To prevent compatibility issues between SO, all `\\r\\n` instances (used in\n * Windows by default as end of line sequence) will be replaced by `\\n`.\n *\n * @param {string} exampleTagDescription - Text passed to the example tag.\n *\n * @return {object} Structured information about the example, including the\n * example type (request or response), summary, status code (only applicable to\n * response types) and the example code itself.\n */\nconst parseExample = ({ description: exampleTagDescription }) => {\n  const formattedTagDescription = exampleTagDescription.replace(/\\r\\n/gi, '\\n');\n\n  // The example content starts right after the first end of line character\n  const contentStartIndex = formattedTagDescription.indexOf('\\n');\n  const content = formattedTagDescription.substring(contentStartIndex + 1);\n  const description = formattedTagDescription.substring(0, contentStartIndex);\n\n  const [type, ...metadata] = mapDescription(description);\n\n  return getParsedExample({ type, metadata, content });\n};\n\n/**\n *  This receives a set of values extracted from \"example\" tags, and translates\n * them to objects with the example type (request or response), summary, status\n * code (only applicable to response types) and the example code itself.\n *\n * @param {object[]} exampleTags - Set of example tags, which description are\n *  expected to have the following information in order to be parsed properly:\n *\n *    > For request body examples:\n *\n *      response - [example summary]\n *      [example content]\n *\n *    > For response examples:\n *\n *      response - [http status code] - [example summary]\n *      [example content]\n *\n * @return {object[]} List of objects containing the example type (request or\n *  response), summary, status code (only applicable to response types) and\n *  the example code itself.\n */\nconst exampleGenerator = generator(parseExample, 'type');\n\nmodule.exports = exampleGenerator;\n"
  },
  {
    "path": "transforms/paths/formParams.js",
    "content": "const merge = require('merge');\nconst getContent = require('./content')('@paramFormBody');\nconst mapDescription = require('../utils/mapDescription');\n\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\nconst getRequiredValues = (currentState, contentType, key, isRequired) => {\n  const paramContentType = contentType || DEFAULT_CONTENT_TYPE;\n  if (currentState.content[paramContentType]) {\n    return [\n      ...(currentState.content[paramContentType].schema.required || []),\n      key,\n    ];\n  }\n  return isRequired ? [key] : [];\n};\n\nconst formParams = (currentState, key, body, isRequired, requestExamples) => {\n  const [description, contentType] = mapDescription(body.description);\n  const schema = {\n    properties: {\n      [key]: {\n        type: body.type.name,\n        description,\n      },\n    },\n    required: getRequiredValues(currentState, contentType, key, isRequired),\n  };\n  return {\n    content: {\n      ...merge.recursive(\n        true,\n        currentState.content,\n        getContent({ name: 'object' }, contentType, description, requestExamples, schema),\n      ),\n    },\n  };\n};\n\nmodule.exports = formParams;\n"
  },
  {
    "path": "transforms/paths/index.js",
    "content": "const examplesGenerator = require('./examples');\nconst responsesGenerator = require('./responses');\nconst parametersGenerator = require('./parameters');\nconst requestBodyGenerator = require('./requestBody');\nconst { getTagInfo, getTagsInfo, formatDescriptionTag } = require('../utils/tags');\nconst {\n  validRequestBodyMethods: bodyMethods,\n  validHTTPMethod,\n} = require('../utils/httpMethods');\nconst formatSecurity = require('./security');\n\nconst formatTags = (tags = []) => tags.map(({ description }) => {\n  const { name } = formatDescriptionTag(description);\n  return name;\n});\n\nconst formatSummary = summary => (summary || {}).description || '';\n\nconst formatDescription = description => (description || {}).description || undefined;\n\nconst setRequestBody = (lowerCaseMethod, bodyValues, requestExamples) => {\n  const hasBodyValues = bodyValues.length > 0;\n  const requestBody = requestBodyGenerator(requestExamples, bodyValues);\n  return bodyMethods[lowerCaseMethod] && hasBodyValues ? { requestBody } : {};\n};\n\nconst bodyParams = ({ name }) => name.includes('request.body') || name.includes('.form');\n\nconst getOperationId = operationIdTag => {\n  if (!operationIdTag) return {};\n  return {\n    operationId: operationIdTag.description,\n  };\n};\n\nconst pathValues = tags => {\n  const examplesValues = getTagsInfo(tags, 'example');\n  const examples = examplesGenerator(examplesValues);\n\n  const summary = getTagInfo(tags, 'summary');\n  const description = getTagInfo(tags, 'description');\n  const deprecated = getTagInfo(tags, 'deprecated');\n  const isDeprecated = !!deprecated;\n  /* Response info */\n  const returnValues = [\n    ...getTagsInfo(tags, 'return'),\n    ...getTagsInfo(tags, 'returns'),\n  ];\n  const responseExamples = examples.filter(example => example.type === 'response');\n  const responses = responsesGenerator(returnValues, responseExamples);\n  /* Parameters info */\n  const operationId = getTagsInfo(tags, 'operationId');\n  const paramValues = getTagsInfo(tags, 'param');\n  const parameters = parametersGenerator(paramValues);\n  /* Tags info */\n  const tagsValues = getTagsInfo(tags, 'tags');\n  /* Security info */\n  const securityValues = getTagsInfo(tags, 'security');\n  /* Request body info */\n  const bodyValues = paramValues.filter(bodyParams);\n  return {\n    summary,\n    description,\n    isDeprecated,\n    responses,\n    parameters,\n    tagsValues,\n    bodyValues,\n    securityValues,\n    examples,\n    operationId: operationId[0],\n  };\n};\n\nconst parsePath = (path, state) => {\n  if (!path.description || !path.tags) return {};\n  const [method, endpoint] = path.description.split(' ');\n  // if jsdoc comment does not contain structure <Method> - <Endpoint> is not valid path\n  const lowerCaseMethod = method.toLowerCase();\n  if (!validHTTPMethod(lowerCaseMethod)) return {};\n  const { tags } = path;\n  const {\n    summary,\n    description,\n    bodyValues,\n    isDeprecated,\n    responses,\n    parameters,\n    tagsValues,\n    securityValues,\n    examples,\n    operationId,\n  } = pathValues(tags);\n  const requestExamples = examples.filter(example => example.type === 'request');\n  return {\n    ...state,\n    [endpoint]: {\n      ...state[endpoint],\n      [lowerCaseMethod]: {\n        deprecated: isDeprecated,\n        summary: formatSummary(summary),\n        description: formatDescription(description),\n        security: formatSecurity(securityValues),\n        responses,\n        parameters,\n        tags: formatTags(tagsValues),\n        ...(setRequestBody(lowerCaseMethod, bodyValues, requestExamples)),\n        ...(getOperationId(operationId)),\n      },\n    },\n  };\n};\n\nconst getPathObject = paths => paths.reduce((acum, item) => ({\n  ...acum, ...parsePath(item, acum),\n}), {});\n\nconst parsePaths = (swaggerObject = {}, paths = []) => {\n  if (!paths || !Array.isArray(paths)) return { paths: {} };\n  const pathObject = getPathObject(paths);\n  return {\n    ...swaggerObject,\n    paths: pathObject,\n  };\n};\n\nmodule.exports = parsePaths;\n"
  },
  {
    "path": "transforms/paths/parameters.js",
    "content": "const errorMessage = require('../utils/errorMessage');\nconst setProperty = require('../utils/setProperty')('parameter');\nconst formatDescription = require('../utils/formatDescription');\nconst getSchema = require('./schema');\nconst generator = require('../utils/generator');\n\nconst REQUIRED = 'required';\nconst DEPRECATED = 'deprecated';\nconst EXPLODE = 'explode';\nconst NOEXPLODE = 'noexplode';\nconst BODY_PARAM = 'body';\nconst FORM_TYPE = 'form';\n\nconst defaultParseParameter = {};\n\nconst parameterPayload = (options, schema) => ({\n  name: setProperty(options, 'name', {\n    type: 'string',\n    required: true,\n  }),\n  in: setProperty(options, 'in', {\n    type: 'string',\n    required: true,\n  }),\n  description: setProperty(options, 'description', {\n    type: 'string',\n    defaultValue: '',\n  }),\n  required: setProperty(options, 'required', {\n    type: 'boolean',\n    defaultValue: false,\n  }),\n  deprecated: setProperty(options, 'deprecated', {\n    type: 'boolean',\n    defaultValue: false,\n  }),\n  explode: setProperty(options, 'explode', {\n    type: 'boolean',\n  }),\n  schema,\n});\n\nconst wrongInOption = paramValue => {\n  if (!paramValue.includes('request.body')) {\n    errorMessage(`If you want to add one @param as body you must provide \"request.body\" instead of ${paramValue}`);\n  }\n  return defaultParseParameter;\n};\n\nconst parseParameter = param => {\n  const [name, inOption, ...extraOptions] = param.name.split('.');\n  if (!name || !inOption || inOption === FORM_TYPE) {\n    return defaultParseParameter;\n  }\n  if (inOption === BODY_PARAM) {\n    return wrongInOption(param.name);\n  }\n  const isRequired = extraOptions.includes(REQUIRED);\n  const isDeprecated = extraOptions.includes(DEPRECATED);\n  const shouldExplode = extraOptions.includes(EXPLODE);\n  const shouldNotExplode = extraOptions.includes(NOEXPLODE);\n  const [description, enumValues, jsonOptions] = formatDescription(param.description);\n  const options = {\n    name,\n    in: inOption,\n    required: isRequired,\n    deprecated: isDeprecated,\n    description,\n  };\n  // Used this format because default when undefined is different depending on if it is a query/form or not\n  if (shouldExplode) {\n    options.explode = true;\n  } else if (shouldNotExplode) {\n    options.explode = false;\n  }\n  const schema = getSchema('@param', param.name)(param.type, enumValues, jsonOptions);\n  return parameterPayload(options, schema);\n};\n\nmodule.exports = generator(parseParameter, 'name');\n"
  },
  {
    "path": "transforms/paths/requestBody.js",
    "content": "const setProperty = require('../utils/setProperty')('parameter');\nconst getContent = require('./content')('@paramBody');\nconst mapDescription = require('../utils/mapDescription');\nconst formParams = require('./formParams');\nconst formatExampleValues = require('../utils/formatExamples')('requestBody');\n\nconst REQUIRED = 'required';\nconst FORM_TYPE = 'form';\n\nconst formatExamples = (exampleValues = []) => exampleValues\n  .reduce((exampleMap, example, i) => ({\n    ...exampleMap,\n    [`example${i + 1}`]: {\n      summary: example.summary,\n      value: example.value,\n    },\n  }), {});\n\nconst checkExamples = examples => {\n  const isExample = Array.isArray(examples) && examples.length > 0;\n  return isExample ? formatExamples(examples) : undefined;\n};\n\nconst parseBodyParameter = (currentState, body, examples) => {\n  const [name, ...extraOptions] = body.name.split('.');\n  const isRequired = extraOptions.includes(REQUIRED);\n  const hasForm = extraOptions.includes(FORM_TYPE);\n  const [description, contentType] = mapDescription(body.description);\n  const options = { name, required: isRequired, description };\n\n  const examplesParsed = examples.map(example => (\n    formatExampleValues(example, contentType)\n  ));\n\n  if (hasForm) {\n    return formParams(currentState, name, body, isRequired, checkExamples(examplesParsed));\n  }\n\n  return {\n    ...currentState,\n    description: setProperty(options, 'description', {\n      type: 'string',\n    }),\n    required: setProperty(options, 'required', {\n      type: 'boolean',\n      defaultValue: false,\n    }),\n    content: {\n      ...currentState.content,\n      ...getContent(body.type, contentType, body.description, checkExamples(examplesParsed)),\n    },\n  };\n};\n\nconst INITIAL_STATE = { content: {} };\n\nconst requestBodyGenerator = (examples, params = []) => {\n  if (!params || !Array.isArray(params)) return {};\n\n  return params.reduce((acc, body) => (\n    { ...acc, ...parseBodyParameter(acc, body, examples) }\n  ), INITIAL_STATE);\n};\n\nmodule.exports = requestBodyGenerator;\n"
  },
  {
    "path": "transforms/paths/responses.js",
    "content": "const errorMessage = require('../utils/errorMessage');\nconst STATUS_CODES = require('./validStatusCodes');\nconst mapDescription = require('../utils/mapDescription');\nconst getContent = require('./content')('@return');\nconst formatExampleValues = require('../utils/formatExamples')('responses');\n\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\nconst hasOldContent = (value, status) => (value[status] && value[status].content);\n\nconst formatResponses = (values, examples) => values.reduce((acc, value) => {\n  const [status, description, contentType] = mapDescription(value.description);\n  if (!STATUS_CODES[status]) {\n    errorMessage(`Status ${status} is not valid to create a response`);\n    return {};\n  }\n\n  const exampleList = formatExampleValues(\n    examples[status],\n    contentType || DEFAULT_CONTENT_TYPE,\n    status,\n  );\n\n  return {\n    ...acc,\n    [status]: {\n      description,\n      ...(value.type ? {\n        content: {\n          ...(hasOldContent(acc, status) ? { ...acc[status].content } : {}),\n          ...getContent(value.type, contentType, value.description, exampleList),\n        },\n      } : {}),\n    },\n  };\n}, {});\n\nconst formatExamples = (exampleValues = []) => exampleValues\n  .reduce((exampleMap, example, i) => ({\n    ...exampleMap,\n    [example.status]: {\n      ...exampleMap[example.status],\n      [`example${i + 1}`]: {\n        summary: example.summary,\n        value: example.value,\n      },\n    },\n  }), {});\n\nconst responsesGenerator = (returnValues = [], exampleValues = []) => {\n  if (!returnValues || !Array.isArray(returnValues)) return {};\n  return formatResponses(returnValues, formatExamples(exampleValues));\n};\n\nmodule.exports = responsesGenerator;\n"
  },
  {
    "path": "transforms/paths/schema.js",
    "content": "const errorMessage = require('../utils/errorMessage');\nconst combineSchema = require('../utils/combineSchema');\nconst addEnumValues = require('../utils/enumValues');\nconst { refSchema, formatRefSchema } = require('../utils/refSchema');\n\nconst getSchema = (entity, message) => (type, enumValues = [], jsonOptions = {}) => {\n  if (!type) {\n    return errorMessage(`Entity: ${entity} could not be parsed. Value: \"${message}\" is wrong`);\n  }\n  const nameType = type.name;\n  let schema = {\n    ...refSchema(nameType),\n  };\n\n  schema = {\n    ...schema,\n    ...combineSchema(type.elements),\n    ...addEnumValues(enumValues),\n    ...jsonOptions,\n  };\n  const notPrimitiveType = !nameType;\n  if (notPrimitiveType && !type.elements) {\n    const parseItems = formatRefSchema(type.applications);\n    schema = {\n      ...schema,\n      type: type.expression.name.toLowerCase(),\n      items: parseItems.items ? parseItems.items : parseItems,\n    };\n  }\n  return schema;\n};\n\nmodule.exports = getSchema;\n"
  },
  {
    "path": "transforms/paths/security.js",
    "content": "const { flatArray } = require('../utils/arrays');\n\nconst AND_SEPARATOR = ' & ';\nconst OR_SEPARATOR = ' | ';\n\nconst formatOrValues = ({ description }) => {\n  if (!description) { return []; }\n\n  const securityNames = description.split(OR_SEPARATOR);\n  return securityNames.map(names => ({\n    description: names,\n  }));\n};\n\nconst formatSecurity = (securityValues = []) => (\n  flatArray(securityValues\n    .map(formatOrValues))\n    .map(({ description }) => {\n      const securityNames = description.split(AND_SEPARATOR);\n      return {\n        ...securityNames.reduce((acum, names) => (\n          {\n            ...acum,\n            [names]: [],\n          }\n        ), {}),\n      };\n    })\n);\n\nmodule.exports = formatSecurity;\n"
  },
  {
    "path": "transforms/paths/validStatusCodes.js",
    "content": "const STATUS_CODES = {\n  202: 'Accepted',\n  502: 'Bad Gateway',\n  400: 'Bad Request',\n  409: 'Conflict',\n  100: 'Continue',\n  201: 'Created',\n  417: 'Expectation Failed',\n  424: 'Failed Dependency',\n  403: 'Forbidden',\n  504: 'Gateway Timeout',\n  410: 'Gone',\n  505: 'HTTP Version Not Supported',\n  418: 'I\\'m a teapot',\n  419: 'Insufficient Space on Resource',\n  507: 'Insufficient Storage',\n  500: 'Server Error',\n  411: 'Length Required',\n  423: 'Locked',\n  420: 'Method Failure',\n  405: 'Method Not Allowed',\n  301: 'Moved Permanently',\n  302: 'Moved Temporarily',\n  207: 'Multi-Status',\n  300: 'Multiple Choices',\n  511: 'Network Authentication Required',\n  204: 'No Content',\n  203: 'Non Authoritative Information',\n  406: 'Not Acceptable',\n  404: 'Not Found',\n  501: 'Not Implemented',\n  304: 'Not Modified',\n  200: 'OK',\n  206: 'Partial Content',\n  402: 'Payment Required',\n  308: 'Permanent Redirect',\n  412: 'Precondition Failed',\n  428: 'Precondition Required',\n  102: 'Processing',\n  407: 'Proxy Authentication Required',\n  431: 'Request Header Fields Too Large',\n  408: 'Request Timeout',\n  413: 'Request Entity Too Large',\n  414: 'Request-URI Too Long',\n  416: 'Requested Range Not Satisfiable',\n  205: 'Reset Content',\n  303: 'See Other',\n  503: 'Service Unavailable',\n  101: 'Switching Protocols',\n  307: 'Temporary Redirect',\n  429: 'Too Many Requests',\n  401: 'Unauthorized',\n  422: 'Unprocessable Entity',\n  415: 'Unsupported Media Type',\n  305: 'Use Proxy',\n  '1XX': '1XX Range',\n  '2XX': '2XX Range',\n  '3XX': '3XX Range',\n  '4XX': '4XX Range',\n  '5XX': '5XX Range',\n  default: 'Default response',\n};\n\nmodule.exports = STATUS_CODES;\n"
  },
  {
    "path": "transforms/security/index.js",
    "content": "const formatSecurity = securitySchemes => {\n  const securityTypes = Object.keys(securitySchemes);\n  return securityTypes.map(type => ({ [type]: [] }));\n};\n\nconst parseSecuritySchemas = (swaggerObject = {}) => {\n  const { security } = swaggerObject;\n  return {\n    ...swaggerObject,\n    ...(security ? { security: formatSecurity(security) } : {}),\n    components: {\n      ...swaggerObject.components,\n      ...(security ? { securitySchemes: security } : {}),\n    },\n  };\n};\n\nmodule.exports = parseSecuritySchemas;\n"
  },
  {
    "path": "transforms/tags/index.js",
    "content": "const { getTagsInfo, formatDescriptionTag } = require('../utils/tags');\nconst { flatArray, getIndexBy } = require('../utils/arrays');\n\nconst FILTER_TAG_KEY = 'name';\n\nconst formatTags = ({ tags = [] }) => {\n  const infoTags = getTagsInfo(tags, 'tags');\n  return infoTags.map(({ description: tagDescription }) => {\n    const { name, description = '' } = formatDescriptionTag(tagDescription);\n    return {\n      name,\n      description,\n    };\n  });\n};\n\nconst sortByDescription = tags => [...tags].sort((a, b) => {\n  if (!a.description && b.description) {\n    return 1;\n  }\n  return -1;\n});\n\nconst sortTagsByName = tags => [...tags].sort((a, b) => ((a.name > b.name) ? 1 : -1));\n\nconst filterDuplicateTags = tags => (\n  tags.filter(({ name }, i) => getIndexBy(tags, FILTER_TAG_KEY, name) === i)\n);\n\nconst parseTags = (swaggerObject, data) => {\n  if (!data || !Array.isArray(data)) return { tags: [] };\n  const tags = flatArray(data.map(formatTags));\n  const ordererTags = sortByDescription(tags);\n  const uniqTags = filterDuplicateTags(ordererTags);\n  return {\n    ...swaggerObject,\n    tags: sortTagsByName(uniqTags),\n  };\n};\n\nmodule.exports = parseTags;\n"
  },
  {
    "path": "transforms/utils/arrays.js",
    "content": "const flatArray = elements => (\n  elements.reduce((acc, val) => acc.concat(val), [])\n);\n\nconst getIndexBy = (elements, key, value) => (\n  elements.findIndex(element => element[key] === value)\n);\n\nmodule.exports = {\n  flatArray,\n  getIndexBy,\n};\n"
  },
  {
    "path": "transforms/utils/combineSchema.js",
    "content": "const { refSchema } = require('./refSchema');\n\nconst VALID_TYPES = ['oneOf', 'anyOf', 'allOf'];\n\n/**\n *  This method checks the first item of the data type list to validate if\n * it contains any of the keywords representing the different union types\n * in Swagger: 'oneOf', 'anyOf' or 'allOf'.\n *\n * @param {object[]} elements - List of data types for the property\n * @returns {string|null} Name of the union type (if any)\n */\nconst getUnionType = elements => {\n  const unionType = elements[0].name;\n\n  if (!VALID_TYPES.includes(unionType)) {\n    return null;\n  }\n\n  return unionType;\n};\n\n/**\n *  This method receives an array of data types passed down to the\n * 'property' annotation, for example:\n *\n *    > '{oneOf|string|null}'.\n *\n *  The aim of this method is to process this array and generate\n * the schema for the property, including a list of its types.\n *\n * @param {object[]} elements - List of data types for the property\n * @returns Swagger schema for the property\n */\nconst combineSchema = elements => {\n  let schema = {};\n  if (!elements || elements.length === 0) return schema;\n\n  // Check if 'null' is part of the listed types and remove it from the array\n  const nullIndex = elements.findIndex(el => el.type === 'NullLiteral');\n  if (nullIndex > 0) {\n    elements.splice(nullIndex, 1);\n    schema = { nullable: true };\n  }\n\n  const unionType = getUnionType(elements);\n  const types = !unionType ? elements : elements.slice(1);\n\n  // If there are multiple types in the list, wrap them into a union type\n  // ('oneOf' will be used by default if none is specified)\n  if (types.length > 1 || unionType === 'allOf') {\n    schema = {\n      ...schema,\n      [unionType || 'oneOf']: types.map(type => refSchema(type)),\n    };\n  } else {\n    // If there's only a type in the list, don't wrap it in 'oneOf' or 'anyOf' blocks\n    schema = {\n      ...schema,\n      ...refSchema(types[0]),\n    };\n  }\n\n  return schema;\n};\n\nmodule.exports = combineSchema;\n"
  },
  {
    "path": "transforms/utils/enumValues.js",
    "content": "const addEnumValues = (values = []) => {\n  if (values.length === 0) return {};\n  return { enum: values };\n};\n\nmodule.exports = addEnumValues;\n"
  },
  {
    "path": "transforms/utils/errorMessage.js",
    "content": "const chalk = require('chalk');\n\nconst errorMessage = message => {\n  // eslint-disable-next-line\n  console.warn(chalk.yellow(`[express-jsdoc-swagger] ${message}`));\n};\n\nmodule.exports = errorMessage;\n"
  },
  {
    "path": "transforms/utils/formatDescription.js",
    "content": "const mapDescription = require('./mapDescription');\nconst errorMessage = require('./errorMessage');\n\nconst ENUM_IDENTIFIER = 'enum:';\nconst JSON_IDENTIFIER = 'json:';\nconst DESCRIPTION_DIVIDER = ' - ';\n\nconst formatDescription = description => {\n  const descriptionTypes = mapDescription(description);\n  const descriptionValue = descriptionTypes.filter(value => (\n    !value.includes(ENUM_IDENTIFIER) && !value.includes(JSON_IDENTIFIER)\n  )).join(DESCRIPTION_DIVIDER);\n  const enumOption = descriptionTypes.find(value => value.includes(ENUM_IDENTIFIER));\n  const jsonOption = descriptionTypes.find(value => value.includes(JSON_IDENTIFIER));\n  const res = [descriptionValue];\n  if (enumOption) {\n    const [, enumOptions] = enumOption.split('enum:');\n    const enumValues = enumOptions.split(',');\n    res.push(enumValues);\n  } else {\n    res.push(undefined);\n  }\n  if (jsonOption) {\n    try {\n      const jsonOptions = JSON.parse(jsonOption.slice(JSON_IDENTIFIER.length));\n      if (typeof jsonOptions !== 'object') { throw new Error('options must be object'); }\n      res.push(jsonOptions);\n    } catch (err) {\n      errorMessage(`json options are malformed: ${err.message}`);\n    }\n  }\n  return res;\n};\n\nmodule.exports = formatDescription;\n"
  },
  {
    "path": "transforms/utils/formatExamples.js",
    "content": "const errorMessage = require('./errorMessage');\n\nconst DEFAULT_CONTENT_TYPE = 'application/json';\n\nconst formatJSONExamples = type => (exampleList, contentType, status) => {\n  let cloneExamples = type === 'requestBody' ? { ...exampleList } : undefined;\n  if (exampleList && contentType === DEFAULT_CONTENT_TYPE) {\n    cloneExamples = { ...exampleList };\n    Object.keys(cloneExamples)\n      .filter(k => typeof cloneExamples[k].value === 'string')\n      .forEach(k => {\n        try {\n          cloneExamples[k].value = JSON.parse(cloneExamples[k].value);\n        } catch (err) {\n          const message = type === 'requestBody'\n            ? 'requestBody example malformed'\n            : `response example for status ${status} with content-type ${DEFAULT_CONTENT_TYPE} malformed`;\n          errorMessage(message);\n        }\n      });\n  }\n  return cloneExamples;\n};\n\nmodule.exports = formatJSONExamples;\n"
  },
  {
    "path": "transforms/utils/generator.js",
    "content": "const generator = (parseParameter, filterKey) => paramValues => {\n  if (!paramValues || !Array.isArray(paramValues)) return [];\n  return paramValues.map(parseParameter).filter(param => param[filterKey]);\n};\n\nmodule.exports = generator;\n"
  },
  {
    "path": "transforms/utils/httpMethods.js",
    "content": "const validRequestBodyMethods = {\n  get: false,\n  delete: true,\n  head: false,\n  post: true,\n  put: true,\n  connect: true,\n  options: true,\n  trace: true,\n  patch: true,\n};\n\nconst validHTTPMethod = method => Object.keys(validRequestBodyMethods).includes(method);\n\nmodule.exports = {\n  validRequestBodyMethods,\n  validHTTPMethod,\n};\n"
  },
  {
    "path": "transforms/utils/mapDescription.js",
    "content": "const DECRIPTION_DIVIDER = ' - ';\n\nconst mapDescription = description => (description || '').split(DECRIPTION_DIVIDER);\n\nmodule.exports = mapDescription;\n"
  },
  {
    "path": "transforms/utils/refSchema.js",
    "content": "const validateTypes = require('./validateTypes');\n\nconst REF_ROUTE = '#/components/schemas/';\n\nconst refSchema = value => {\n  // support * @return {array<Song|Album>} 200 - fetch Home Content response\n  if (value && value.type === 'UnionType') {\n    const items = [];\n    value.elements.forEach(el => {\n      const isPrimitiveType = validateTypes(el.name);\n      items.push(isPrimitiveType ? { type: el.name } : { $ref: `${REF_ROUTE}${el.name}` });\n    });\n    return {\n      anyOf: items,\n    };\n  }\n\n  // support * @property {anyOf|Song[]|Album|string|string[]} firstSong\n  if (value && value.expression && value.expression.name.toLowerCase() === 'array' && value.type === 'TypeApplication') {\n    const isPrimitiveType = validateTypes(value.applications[0].name);\n    return isPrimitiveType ? {\n      type: 'array',\n      items: { type: value.applications[0].name },\n    } : {\n      type: 'array',\n      items: { $ref: `${REF_ROUTE}${value.applications[0].name}` },\n    };\n  }\n\n  if (!value) return {};\n\n  const nameValue = value.name || value;\n  // support null\n  if (nameValue.type === 'NullLiteral') return { nullable: true };\n\n  const isPrimitive = validateTypes(nameValue);\n  return isPrimitive ? { type: nameValue } : { $ref: `${REF_ROUTE}${nameValue}` };\n};\n\nconst formatRefSchema = (applications = []) => applications.reduce((itemAcc, itemTypes) => ({\n  ...itemAcc,\n  ...refSchema(itemTypes),\n}), {});\n\nmodule.exports = {\n  refSchema,\n  formatRefSchema,\n};\n"
  },
  {
    "path": "transforms/utils/setProperty.js",
    "content": "const errorMessage = require('./errorMessage');\n\nconst setProperty = entity => {\n  const requiredError = (key, item) => (\n    new Error(`Key ${key} is required in item ${JSON.stringify(item)} for Entity ${entity}`)\n  );\n\n  const warnType = (type, value) => (\n    errorMessage(`${type} is not valid with value ${value} for Entity ${entity}`)\n  );\n\n  return (item, key, options) => {\n    if (!item || !key || !options) {\n      throw (new Error('item, key and options para are required'));\n    }\n    const value = item[key];\n    if (options.required && value === undefined) throw requiredError(key, item);\n    if (value === undefined || value === null) return options.defaultValue;\n    // eslint-disable-next-line\n    if (typeof (value) !== options.type) warnType(options.type, value);\n    return value;\n  };\n};\n\nmodule.exports = setProperty;\n"
  },
  {
    "path": "transforms/utils/tags.js",
    "content": "const mapDescription = require('./mapDescription');\n\nconst getTagInfo = (tags, key) => tags.find(({ title }) => title === key);\n\nconst getTagsInfo = (tags, key) => tags.filter(({ title }) => title === key);\n\nconst formatDescriptionTag = desc => {\n  const [name, description] = mapDescription(desc);\n  return { name, description };\n};\n\nmodule.exports = {\n  getTagInfo,\n  getTagsInfo,\n  formatDescriptionTag,\n};\n"
  },
  {
    "path": "transforms/utils/validateTypes.js",
    "content": "const TYPES = [\n  'integer',\n  'number',\n  'string',\n  'boolean',\n  'object',\n];\n\nconst validateTypes = type => TYPES.includes(type);\n\nmodule.exports = validateTypes;\n"
  }
]