Kaynağa Gözat

Merge branch 'master' into feat/tag-list-page-for-master-merge

yusuketk 7 yıl önce
ebeveyn
işleme
56eb700f9e

+ 1 - 0
CHANGES.md

@@ -5,6 +5,7 @@
 * Improvement: Show display name when mouse hover to user image
 * Improvement: Show display name when mouse hover to user image
 * Fix: URL in slack message is broken on Safari
 * Fix: URL in slack message is broken on Safari
 * Fix: Registration does not work when basic auth is enabled
 * Fix: Registration does not work when basic auth is enabled
+* Support: Publish API docs with swagger-jsdoc and ReDoc
 * Support: Upgrade libs
 * Support: Upgrade libs
     * cmd-env
     * cmd-env
     * elasticsearch
     * elasticsearch

+ 1 - 0
README.md

@@ -171,6 +171,7 @@ Environment Variables
     * MAX_FILE_SIZE: The maximum file size limit for uploads (bytes). default: `Infinity`
     * MAX_FILE_SIZE: The maximum file size limit for uploads (bytes). default: `Infinity`
     * MONGO_GRIDFS_TOTAL_LIMIT: Total capacity limit of MongoDB GridFS (bytes). default: `Infinity`
     * MONGO_GRIDFS_TOTAL_LIMIT: Total capacity limit of MongoDB GridFS (bytes). default: `Infinity`
     * SAML_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS: If `true`, the system uses only the value of the environment variable as the value of the SAML option that can be set via the environment variable.
     * SAML_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS: If `true`, the system uses only the value of the environment variable as the value of the SAML option that can be set via the environment variable.
+    * PUBLISH_OPEN_API: Publish GROWI OpenAPI resources with [ReDoc](https://github.com/Rebilly/ReDoc). Visit `/api-docs`.
 * **Option to integrate with external systems**
 * **Option to integrate with external systems**
     * HACKMD_URI: URI to connect to [HackMD(CodiMD)](https://hackmd.io/) server.
     * HACKMD_URI: URI to connect to [HackMD(CodiMD)](https://hackmd.io/) server.
         * **This server must load the GROWI agent. [Here's how to prepare it](https://docs.growi.org/guide/admin-cookbook/integrate-with-hackmd.html).**
         * **This server must load the GROWI agent. [Here's how to prepare it](https://docs.growi.org/guide/admin-cookbook/integrate-with-hackmd.html).**

+ 1 - 0
config/env.dev.js

@@ -10,6 +10,7 @@ module.exports = {
     // 'growi-plugin-lsx',
     // 'growi-plugin-lsx',
     // 'growi-plugin-pukiwiki-like-linker',
     // 'growi-plugin-pukiwiki-like-linker',
   ],
   ],
+  // PUBLISH_OPEN_API: true,
   // USER_UPPER_LIMIT: 0,
   // USER_UPPER_LIMIT: 0,
   // DEV_HTTPS: true,
   // DEV_HTTPS: true,
   // PUBLIC_WIKI_ONLY: true,
   // PUBLIC_WIKI_ONLY: true,

+ 12 - 0
config/swagger-definition.js

@@ -0,0 +1,12 @@
+module.exports = {
+  openapi: '3.0.1',
+  info: {
+    title: 'GROWI API v3',
+    version: '3.0.0',
+  },
+  externalDocs: {
+    description: 'GROWI Docs',
+    url: 'https://docs.growi.org',
+  },
+  basePath: '/api/v3/',
+};

+ 1 - 0
package.json

@@ -211,6 +211,7 @@
     "socket.io-client": "^2.0.3",
     "socket.io-client": "^2.0.3",
     "style-loader": "^0.23.0",
     "style-loader": "^0.23.0",
     "stylelint-config-recess-order": "^2.0.1",
     "stylelint-config-recess-order": "^2.0.1",
+    "swagger-jsdoc": "^3.2.9",
     "terser-webpack-plugin": "^1.2.2",
     "terser-webpack-plugin": "^1.2.2",
     "throttle-debounce": "^2.0.0",
     "throttle-debounce": "^2.0.0",
     "toastr": "^2.1.2",
     "toastr": "^2.1.2",

+ 7 - 0
resource/cdn-manifests.js

@@ -70,6 +70,13 @@ module.exports = {
         integrity: '',
         integrity: '',
       },
       },
     },
     },
+    {
+      name: 'redoc-standalone',
+      url: 'https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js',
+      args: {
+        integrity: '',
+      },
+    },
   ],
   ],
   style: [
   style: [
     {
     {

+ 0 - 1
src/server/crowi/dev.js

@@ -5,7 +5,6 @@ const path = require('path');
 const swig = require('swig-templates');
 const swig = require('swig-templates');
 const onHeaders = require('on-headers');
 const onHeaders = require('on-headers');
 
 
-
 class CrowiDev {
 class CrowiDev {
 
 
   /**
   /**

+ 1 - 0
src/server/crowi/index.js

@@ -6,6 +6,7 @@ const pkg = require('@root/package.json');
 const InterceptorManager = require('@commons/service/interceptor-manager');
 const InterceptorManager = require('@commons/service/interceptor-manager');
 const CdnResourcesService = require('@commons/service/cdn-resources-service');
 const CdnResourcesService = require('@commons/service/cdn-resources-service');
 const Xss = require('@commons/service/xss');
 const Xss = require('@commons/service/xss');
+
 const path = require('path');
 const path = require('path');
 
 
 const sep = path.sep;
 const sep = path.sep;

+ 43 - 0
src/server/routes/apiv3/docs.js

@@ -0,0 +1,43 @@
+const loggerFactory = require('@alias/logger');
+
+const logger = loggerFactory('growi:routes:apiv3:docs'); // eslint-disable-line no-unused-vars
+
+const express = require('express');
+
+const router = express.Router();
+
+// paths to scan
+const APIS = [
+  'src/server/routes/apiv3/**/*.js',
+];
+
+module.exports = (crowi) => {
+
+  // skip if disabled
+  if (!crowi.configManager.getConfig('crowi', 'app:publishOpenAPI')) {
+    return router;
+  }
+
+  const swaggerJSDoc = require('swagger-jsdoc');
+  const swaggerDefinition = require('@root/config/swagger-definition');
+
+  // generate swagger spec
+  const options = {
+    swaggerDefinition,
+    apis: APIS,
+  };
+  const swaggerSpec = swaggerJSDoc(options);
+
+  // publish swagger spec
+  router.get('/swagger-spec.json', (req, res) => {
+    res.setHeader('Content-Type', 'application/json');
+    res.send(swaggerSpec);
+  });
+
+  // publish redoc
+  router.get('/', (req, res) => {
+    res.render('redoc');
+  });
+
+  return router;
+};

+ 35 - 0
src/server/routes/apiv3/healthcheck.js

@@ -8,7 +8,42 @@ const router = express.Router();
 
 
 const helmet = require('helmet');
 const helmet = require('helmet');
 
 
+/**
+ * @swagger
+ *  tags:
+ *    name: Healthcheck
+ */
+
 module.exports = (crowi) => {
 module.exports = (crowi) => {
+  /**
+   * @swagger
+   *
+   *  /healthcheck:
+   *    get:
+   *      tags: [Healthcheck]
+   *      description: Check whether the server is healthy or not
+   *      produces:
+   *        - application/json
+   *      parameters:
+   *        - name: connectToMiddlewares
+   *          in: query
+   *          description: Check also MongoDB and Elasticsearch
+   *          schema:
+   *            type: boolean
+   *      responses:
+   *        200:
+   *          description: Resources are available
+   *          content:
+   *            application/json:
+   *              schema:
+   *                properties:
+   *                  mongo:
+   *                    type: string
+   *                    description: 'OK'
+   *                  esInfo:
+   *                    type: object
+   *                    description: A result of `client.info()` of Elasticsearch Info API
+   */
   router.get('/', helmet.noCache(), async(req, res) => {
   router.get('/', helmet.noCache(), async(req, res) => {
     const connectToMiddlewares = req.query.connectToMiddlewares;
     const connectToMiddlewares = req.query.connectToMiddlewares;
 
 

+ 1 - 0
src/server/routes/index.js

@@ -234,6 +234,7 @@ module.exports = function(crowi, app) {
   app.post('/_api/hackmd.saveOnHackmd' , accessTokenParser , loginRequired(crowi, app) , csrf, hackmd.validateForApi, hackmd.saveOnHackmd);
   app.post('/_api/hackmd.saveOnHackmd' , accessTokenParser , loginRequired(crowi, app) , csrf, hackmd.validateForApi, hackmd.saveOnHackmd);
 
 
   // API v3
   // API v3
+  app.use('/api-docs', require('./apiv3/docs')(crowi));
   app.use('/_api/v3', require('./apiv3')(crowi));
   app.use('/_api/v3', require('./apiv3')(crowi));
 
 
   app.get('/*/$'                   , loginRequired(crowi, app, false) , page.showPageWithEndOfSlash, page.notFound);
   app.get('/*/$'                   , loginRequired(crowi, app, false) , page.showPageWithEndOfSlash, page.notFound);

+ 6 - 0
src/server/service/config-loader.js

@@ -116,6 +116,12 @@ const ENV_VAR_NAME_TO_CONFIG_INFO = {
     type:    TYPES.STRING,
     type:    TYPES.STRING,
     default: null,
     default: null,
   },
   },
+  PUBLISH_OPEN_API: {
+    ns:      'crowi',
+    key:     'app:publishOpenAPI',
+    type:    TYPES.BOOLEAN,
+    default: false,
+  },
   MAX_FILE_SIZE: {
   MAX_FILE_SIZE: {
     ns:      'crowi',
     ns:      'crowi',
     key:     'app:maxFileSize',
     key:     'app:maxFileSize',

+ 24 - 0
src/server/views/redoc.html

@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>GROWI API v3</title>
+    <!-- needed for adaptive design -->
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
+
+    <!--
+    ReDoc doesn't change outer page styles
+    -->
+    <style>
+      body {
+        margin: 0;
+        padding: 0;
+      }
+    </style>
+  </head>
+  <body>
+    <redoc spec-url='/api-docs/swagger-spec.json'></redoc>
+    {{ cdnScriptTag('redoc-standalone') }}
+  </body>
+</html>

+ 119 - 8
yarn.lock

@@ -1914,6 +1914,11 @@ cache-base@^1.0.1:
     union-value "^1.0.0"
     union-value "^1.0.0"
     unset-value "^1.0.0"
     unset-value "^1.0.0"
 
 
+call-me-maybe@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
+  integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
+
 callsite@1.0.0:
 callsite@1.0.0:
   version "1.0.0"
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
   resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
@@ -2348,6 +2353,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
   dependencies:
   dependencies:
     delayed-stream "~1.0.0"
     delayed-stream "~1.0.0"
 
 
+commander@2.17.1, commander@~2.17.1:
+  version "2.17.1"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
+
 commander@2.19.0:
 commander@2.19.0:
   version "2.19.0"
   version "2.19.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
@@ -2364,15 +2373,11 @@ commander@^2.2.0:
   version "2.15.1"
   version "2.15.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
 
 
-commander@^2.20.0:
+commander@^2.20.0, commander@^2.7.1:
   version "2.20.0"
   version "2.20.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
   integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
   integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
 
 
-commander@~2.17.1:
-  version "2.17.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
-
 commondir@^1.0.1:
 commondir@^1.0.1:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -2557,6 +2562,11 @@ core-js@^2.4.0, core-js@^2.5.0:
   version "2.5.3"
   version "2.5.3"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
 
 
+core-js@^2.5.7:
+  version "2.6.5"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895"
+  integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==
+
 core-util-is@1.0.2, core-util-is@~1.0.0:
 core-util-is@1.0.2, core-util-is@~1.0.0:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -3118,7 +3128,7 @@ doctrine@1.5.0:
     esutils "^2.0.2"
     esutils "^2.0.2"
     isarray "^1.0.0"
     isarray "^1.0.0"
 
 
-doctrine@^2.1.0:
+doctrine@2.1.0, doctrine@^2.1.0:
   version "2.1.0"
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
   resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
   dependencies:
   dependencies:
@@ -4306,6 +4316,11 @@ form-data@~2.3.2:
     combined-stream "^1.0.6"
     combined-stream "^1.0.6"
     mime-types "^2.1.12"
     mime-types "^2.1.12"
 
 
+format-util@^1.0.3:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.3.tgz#032dca4a116262a12c43f4c3ec8566416c5b2d95"
+  integrity sha1-Ay3KShFiYqEsQ/TD7IVmQWxbLZU=
+
 formidable@~1.0.14:
 formidable@~1.0.14:
   version "1.0.17"
   version "1.0.17"
   resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.0.17.tgz#ef5491490f9433b705faa77249c99029ae348559"
   resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.0.17.tgz#ef5491490f9433b705faa77249c99029ae348559"
@@ -5713,6 +5728,14 @@ js-yaml@3.12.0, js-yaml@^3.9.0:
     argparse "^1.0.7"
     argparse "^1.0.7"
     esprima "^4.0.0"
     esprima "^4.0.0"
 
 
+js-yaml@3.13.1:
+  version "3.13.1"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
+  integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
+  dependencies:
+    argparse "^1.0.7"
+    esprima "^4.0.0"
+
 js-yaml@^3.11.0:
 js-yaml@^3.11.0:
   version "3.11.0"
   version "3.11.0"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
@@ -5764,6 +5787,16 @@ json-parse-better-errors@^1.0.2:
   version "1.0.2"
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
   resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
 
 
+json-schema-ref-parser@^5.1.3:
+  version "5.1.3"
+  resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-5.1.3.tgz#f86c5868f40898e69169e1bbc854725a4fd0e1ad"
+  integrity sha512-CpDFlBwz/6la78hZxyB9FECVKGYjIIl3Ms3KLqFj99W7IIb7D00/RDgc++IGB4BBALl0QRhh5m4q5WNSopvLtQ==
+  dependencies:
+    call-me-maybe "^1.0.1"
+    debug "^3.1.0"
+    js-yaml "^3.12.0"
+    ono "^4.0.6"
+
 json-schema-traverse@^0.3.0:
 json-schema-traverse@^0.3.0:
   version "0.3.1"
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
   resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
@@ -5817,6 +5850,16 @@ jsonify@~0.0.0:
   version "0.0.0"
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
 
 
+jsonschema-draft4@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/jsonschema-draft4/-/jsonschema-draft4-1.0.0.tgz#f0af2005054f0f0ade7ea2118614b69dc512d865"
+  integrity sha1-8K8gBQVPDwrefqIRhhS2ncUS2GU=
+
+jsonschema@1.2.4:
+  version "1.2.4"
+  resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.4.tgz#a46bac5d3506a254465bc548876e267c6d0d6464"
+  integrity sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw==
+
 jsprim@^1.2.2:
 jsprim@^1.2.2:
   version "1.4.1"
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
   resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@@ -6080,7 +6123,7 @@ lodash.foreach@^4.1.0:
   version "4.5.0"
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
   resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
 
 
-lodash.get@^4.0, lodash.get@^4.0.2, lodash.get@^4.4.2:
+lodash.get@^4.0, lodash.get@^4.0.0, lodash.get@^4.0.2, lodash.get@^4.4.2:
   version "4.4.2"
   version "4.4.2"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
   resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
 
 
@@ -6088,6 +6131,11 @@ lodash.has@^4.0, lodash.has@^4.5.2:
   version "4.5.2"
   version "4.5.2"
   resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
   resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862"
 
 
+lodash.isequal@^4.0.0:
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
+  integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
+
 lodash.isfinite@^3.3.2:
 lodash.isfinite@^3.3.2:
   version "3.3.2"
   version "3.3.2"
   resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
   resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3"
@@ -7340,6 +7388,22 @@ onetime@^2.0.0:
   dependencies:
   dependencies:
     mimic-fn "^1.0.0"
     mimic-fn "^1.0.0"
 
 
+ono@^4.0.6:
+  version "4.0.11"
+  resolved "https://registry.yarnpkg.com/ono/-/ono-4.0.11.tgz#c7f4209b3e396e8a44ef43b9cedc7f5d791d221d"
+  integrity sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==
+  dependencies:
+    format-util "^1.0.3"
+
+openapi-schema-validation@^0.4.2:
+  version "0.4.2"
+  resolved "https://registry.yarnpkg.com/openapi-schema-validation/-/openapi-schema-validation-0.4.2.tgz#895c29021be02e000f71c51f859da52118eb1e21"
+  integrity sha512-K8LqLpkUf2S04p2Nphq9L+3bGFh/kJypxIG2NVGKX0ffzT4NQI9HirhiY6Iurfej9lCu7y4Ndm4tv+lm86Ck7w==
+  dependencies:
+    jsonschema "1.2.4"
+    jsonschema-draft4 "^1.0.0"
+    swagger-schema-official "2.0.0-bab6bed"
+
 opener@^1.5.1:
 opener@^1.5.1:
   version "1.5.1"
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
@@ -10228,6 +10292,41 @@ svgo@^1.0.0:
     unquote "~1.1.1"
     unquote "~1.1.1"
     util.promisify "~1.0.0"
     util.promisify "~1.0.0"
 
 
+swagger-jsdoc@^3.2.9:
+  version "3.2.9"
+  resolved "https://registry.yarnpkg.com/swagger-jsdoc/-/swagger-jsdoc-3.2.9.tgz#9fe2f10c480e06f62d207c00396b0a759fa569c5"
+  integrity sha512-yEGoqnIA5Owb15266x8JyQQM054kyhqkqz/zGxCEsrcx/fq/gf14alEp3qqLpknGOxTr3cqxQr3LrgOxXVm5vg==
+  dependencies:
+    commander "2.17.1"
+    doctrine "2.1.0"
+    glob "7.1.3"
+    js-yaml "3.13.1"
+    swagger-parser "5.0.5"
+
+swagger-methods@^1.0.4:
+  version "1.0.8"
+  resolved "https://registry.yarnpkg.com/swagger-methods/-/swagger-methods-1.0.8.tgz#8baf37ee861d3c72ff7b2faad6d74c60b336e2ed"
+  integrity sha512-G6baCwuHA+C5jf4FNOrosE4XlmGsdjbOjdBK4yuiDDj/ro9uR4Srj3OR84oQMT8F3qKp00tYNv0YN730oTHPZA==
+
+swagger-parser@5.0.5:
+  version "5.0.5"
+  resolved "https://registry.yarnpkg.com/swagger-parser/-/swagger-parser-5.0.5.tgz#52cf173dcb1f3189fa30da4d18f293887e79707d"
+  integrity sha512-6UiaUT9nH5nEzvxDvwZpTfhCs2VOwxrP9neZ83QpsTA3mMGHdun4x8vSXiqjaGQzLh2LG8ND5TRhmVNG1hRUqA==
+  dependencies:
+    call-me-maybe "^1.0.1"
+    debug "^3.1.0"
+    json-schema-ref-parser "^5.1.3"
+    ono "^4.0.6"
+    openapi-schema-validation "^0.4.2"
+    swagger-methods "^1.0.4"
+    swagger-schema-official "2.0.0-bab6bed"
+    z-schema "^3.23.0"
+
+swagger-schema-official@2.0.0-bab6bed:
+  version "2.0.0-bab6bed"
+  resolved "https://registry.yarnpkg.com/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz#70070468d6d2977ca5237b2e519ca7d06a2ea3fd"
+  integrity sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0=
+
 swig-templates@^2.0.2:
 swig-templates@^2.0.2:
   version "2.0.2"
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/swig-templates/-/swig-templates-2.0.2.tgz#d2502a7303019356f4ea76ea9065d4f58af6ab75"
   resolved "https://registry.yarnpkg.com/swig-templates/-/swig-templates-2.0.2.tgz#d2502a7303019356f4ea76ea9065d4f58af6ab75"
@@ -10841,7 +10940,7 @@ validate-npm-package-license@^3.0.1:
     spdx-correct "~1.0.0"
     spdx-correct "~1.0.0"
     spdx-expression-parse "~1.0.0"
     spdx-expression-parse "~1.0.0"
 
 
-validator@>=10.11.0:
+validator@>=10.11.0, validator@^10.0.0:
   version "10.11.0"
   version "10.11.0"
   resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228"
   resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228"
   integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
   integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==
@@ -11370,3 +11469,15 @@ yargs@~3.10.0:
 yeast@0.1.2:
 yeast@0.1.2:
   version "0.1.2"
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
   resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
+
+z-schema@^3.23.0:
+  version "3.25.1"
+  resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.25.1.tgz#7e14663be2b96003d938a56f644fb8561643fb7e"
+  integrity sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==
+  dependencies:
+    core-js "^2.5.7"
+    lodash.get "^4.0.0"
+    lodash.isequal "^4.0.0"
+    validator "^10.0.0"
+  optionalDependencies:
+    commander "^2.7.1"