Adding OpenAPI documentation for the pusher.

The pusher now exposes a "/openapi" endpoint and a "/swagger-ui/" endpoint.
This commit is contained in:
David Négrier 2022-02-21 19:05:56 +01:00
parent 80761804a7
commit 3b4f06d659
10 changed files with 547 additions and 6 deletions

View File

@ -86,6 +86,7 @@ services:
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
ENABLE_OPENAPI_ENDPOINT: "true"
volumes: volumes:
- ./pusher:/usr/src/app - ./pusher:/usr/src/app
labels: labels:

View File

@ -16,3 +16,8 @@ Check out the [contributing guide](../../CONTRIBUTING.md)
- [How to add translations](how-to-translate.md) - [How to add translations](how-to-translate.md)
- [How to add new functions in the scripting API](contributing-to-scripting-api.md) - [How to add new functions in the scripting API](contributing-to-scripting-api.md)
- [About Wokas](wokas.md) - [About Wokas](wokas.md)
## Pusher documentation
The Pusher is exposing its HTTP API as "OpenAPI" endpoint.
You can browse this API at `http://pusher.workadventure.localhost/swagger-ui/`.

View File

@ -62,13 +62,17 @@
"@types/jasmine": "^3.5.10", "@types/jasmine": "^3.5.10",
"@types/jsonwebtoken": "^8.3.8", "@types/jsonwebtoken": "^8.3.8",
"@types/mkdirp": "^1.0.1", "@types/mkdirp": "^1.0.1",
"@types/swagger-jsdoc": "^6.0.1",
"@types/uuidv4": "^5.0.0", "@types/uuidv4": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^2.26.0", "@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0", "@typescript-eslint/parser": "^2.26.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"jasmine": "^3.5.0", "jasmine": "^3.5.0",
"lint-staged": "^11.0.0", "lint-staged": "^11.0.0",
"live-directory": "^2.3.2",
"prettier": "^2.3.1", "prettier": "^2.3.1",
"swagger-jsdoc": "^6.1.0",
"swagger-ui-dist": "^4.5.1",
"ts-node-dev": "^1.1.8", "ts-node-dev": "^1.1.8",
"typescript": "^4.5.2" "typescript": "^4.5.2"
}, },

View File

@ -7,8 +7,10 @@ import { DebugController } from "./Controller/DebugController";
import { AdminController } from "./Controller/AdminController"; import { AdminController } from "./Controller/AdminController";
import { OpenIdProfileController } from "./Controller/OpenIdProfileController"; import { OpenIdProfileController } from "./Controller/OpenIdProfileController";
import { WokaListController } from "./Controller/WokaListController"; import { WokaListController } from "./Controller/WokaListController";
import { SwaggerController } from "./Controller/SwaggerController";
import HyperExpress from "hyper-express"; import HyperExpress from "hyper-express";
import { cors } from "./Middleware/Cors"; import { cors } from "./Middleware/Cors";
import { ENABLE_OPENAPI_ENDPOINT } from "./Enum/EnvironmentVariable";
class App { class App {
public app: HyperExpress.compressors.TemplatedApp; public app: HyperExpress.compressors.TemplatedApp;
@ -31,6 +33,9 @@ class App {
new AdminController(webserver); new AdminController(webserver);
new OpenIdProfileController(webserver); new OpenIdProfileController(webserver);
new WokaListController(webserver); new WokaListController(webserver);
if (ENABLE_OPENAPI_ENDPOINT) {
new SwaggerController(webserver);
}
} }
} }

View File

@ -13,6 +13,27 @@ export class AdminController extends BaseHttpController {
this.receiveRoomEditionPrompt(); this.receiveRoomEditionPrompt();
} }
/**
* @openapi
* /room/refresh:
* post:
* description: Forces anyone out of the room. The request must be authenticated with the "admin-token" header.
* parameters:
* - name: "admin-token"
* in: "header"
* required: true
* type: "string"
* description: TODO - move this to a classic "Authorization" header!
* - name: "roomId"
* in: "body"
* description: "The ID (full URL) to the room"
* required: true
* type: "string"
* responses:
* 200:
* description: Will always return "ok".
* example: "ok"
*/
receiveRoomEditionPrompt() { receiveRoomEditionPrompt() {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.post("/room/refresh", { middlewares: [adminToken] }, async (req, res) => { this.app.post("/room/refresh", { middlewares: [adminToken] }, async (req, res) => {
@ -43,6 +64,40 @@ export class AdminController extends BaseHttpController {
}); });
} }
/**
* @openapi
* /message:
* post:
* description: Sends a message (or a world full message) to a number of rooms.
* parameters:
* - name: "admin-token"
* in: "header"
* required: true
* type: "string"
* description: TODO - move this to a classic "Authorization" header!
* - name: "text"
* in: "body"
* description: "The text of the message"
* required: true
* type: "string"
* - name: "type"
* in: "body"
* description: Either "capacity" or "message
* required: true
* type: "string"
* - name: "targets"
* in: "body"
* description: The list of room IDs to target
* required: true
* type: array
* items:
* type: string
* example: "https://play.workadventu.re/@/foo/bar/baz"
* responses:
* 200:
* description: Will always return "ok".
* example: "ok"
*/
receiveGlobalMessagePrompt() { receiveGlobalMessagePrompt() {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.post("/message", { middlewares: [adminToken] }, async (req, res) => { this.app.post("/message", { middlewares: [adminToken] }, async (req, res) => {

View File

@ -21,6 +21,37 @@ export class AuthenticateController extends BaseHttpController {
} }
openIDLogin() { openIDLogin() {
/**
* @openapi
* /login-screen:
* get:
* description: Redirects the user to the OpenID login screen
* parameters:
* - name: "nonce"
* in: "query"
* description: "todo"
* required: true
* type: "string"
* - name: "state"
* in: "query"
* description: "todo"
* required: true
* type: "string"
* - name: "playUri"
* in: "query"
* description: "todo"
* required: false
* type: "string"
* - name: "redirect"
* in: "query"
* description: "todo"
* required: false
* type: "string"
* responses:
* 302:
* description: Redirects the user to the OpenID login screen
*
*/
//eslint-disable-next-line @typescript-eslint/no-misused-promises //eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.get("/login-screen", async (req, res) => { this.app.get("/login-screen", async (req, res) => {
try { try {
@ -47,6 +78,37 @@ export class AuthenticateController extends BaseHttpController {
} }
openIDCallback() { openIDCallback() {
/**
* @openapi
* /login-callback:
* get:
* description: TODO
* parameters:
* - name: "nonce"
* in: "query"
* description: "todo"
* required: true
* type: "string"
* - name: "state"
* in: "query"
* description: "todo"
* required: true
* type: "string"
* - name: "playUri"
* in: "query"
* description: "todo"
* required: false
* type: "string"
* - name: "redirect"
* in: "query"
* description: "todo"
* required: false
* type: "string"
* responses:
* 200:
* description: TODO
*
*/
//eslint-disable-next-line @typescript-eslint/no-misused-promises //eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.get("/login-callback", async (req, res) => { this.app.get("/login-callback", async (req, res) => {
const IPAddress = req.header("x-forwarded-for"); const IPAddress = req.header("x-forwarded-for");
@ -112,6 +174,22 @@ export class AuthenticateController extends BaseHttpController {
} }
}); });
/**
* @openapi
* /logout-callback:
* get:
* description: TODO
* parameters:
* - name: "token"
* in: "query"
* description: "todo"
* required: false
* type: "string"
* responses:
* 200:
* description: TODO
*
*/
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.get("/logout-callback", async (req, res) => { this.app.get("/logout-callback", async (req, res) => {
const { token } = parse(req.path_query); const { token } = parse(req.path_query);
@ -130,7 +208,56 @@ export class AuthenticateController extends BaseHttpController {
}); });
} }
//Try to login with an admin token /**
* @openapi
* /register:
* post:
* description: Try to login with an admin token
* parameters:
* - name: "organizationMemberToken"
* in: "body"
* description: "A token allowing a user to connect to a given world"
* required: true
* type: "string"
* responses:
* 200:
* description: The details of the logged user
* content:
* application/json:
* schema:
* type: object
* properties:
* authToken:
* type: string
* description: A unique identification JWT token
* userUuid:
* type: string
* description: Unique user ID
* email:
* type: string|null
* description: The email of the user
* example: john.doe@example.com
* roomUrl:
* type: string
* description: The room URL to connect to
* example: https://play.workadventu.re/@/foo/bar/baz
* organizationMemberToken:
* type: string|null
* description: TODO- unclear. It seems to be sent back from the request?
* example: ???
* mapUrlStart:
* type: string
* description: TODO- unclear. I cannot find any use of this
* example: ???
* textures:
* type: string
* description: TODO - document this is still needed
* example: ???
* messages:
* type: array
* description: The list of messages to be displayed when the user logs?
* example: ???
*/
private register() { private register() {
this.app.post("/register", (req, res) => { this.app.post("/register", (req, res) => {
(async () => { (async () => {
@ -166,7 +293,28 @@ export class AuthenticateController extends BaseHttpController {
}); });
} }
//permit to login on application. Return token to connect on Websocket IO. /**
* @openapi
* /anonymLogin:
* post:
* description: Generates an "anonymous" JWT token allowing to connect to WorkAdventure anonymously.
* responses:
* 200:
* description: The details of the logged user
* content:
* application/json:
* schema:
* type: object
* properties:
* authToken:
* type: string
* description: A unique identification JWT token
* userUuid:
* type: string
* description: Unique user ID
* 403:
* description: Anonymous login is disabled at the configuration level (environment variable DISABLE_ANONYMOUS = true)
*/
private anonymLogin() { private anonymLogin() {
this.app.post("/anonymLogin", (req, res) => { this.app.post("/anonymLogin", (req, res) => {
if (DISABLE_ANONYMOUS) { if (DISABLE_ANONYMOUS) {
@ -183,6 +331,21 @@ export class AuthenticateController extends BaseHttpController {
}); });
} }
/**
* @openapi
* /profile-callback:
* get:
* description: ???
* parameters:
* - name: "token"
* in: "query"
* description: "A JWT authentication token ???"
* required: true
* type: "string"
* responses:
* 302:
* description: Redirects the user to the profile screen of the admin
*/
profileCallback() { profileCallback() {
// eslint-disable-next-line @typescript-eslint/no-misused-promises // eslint-disable-next-line @typescript-eslint/no-misused-promises
this.app.get("/profile-callback", async (req, res) => { this.app.get("/profile-callback", async (req, res) => {

View File

@ -10,6 +10,94 @@ import { BaseHttpController } from "./BaseHttpController";
export class MapController extends BaseHttpController { export class MapController extends BaseHttpController {
// Returns a map mapping map name to file name of the map // Returns a map mapping map name to file name of the map
routes() { routes() {
/**
* @openapi
* /map:
* get:
* description: Returns a map mapping map name to file name of the map
* produces:
* - "application/json"
* parameters:
* - name: "playUri"
* in: "query"
* description: "The full URL of WorkAdventure to load this map"
* required: true
* type: "string"
* - name: "authToken"
* in: "query"
* description: "The authentication token"
* required: true
* type: "string"
* responses:
* 200:
* description: The details of the map
* content:
* application/json:
* schema:
* type: object
* required:
* - mapUrl
* - policy_type
* - tags
* - textures
* - authenticationMandatory
* - roomSlug
* - contactPage
* - group
* properties:
* mapUrl:
* type: string
* description: The full URL to the JSON map file
* example: https://myuser.github.io/myrepo/map.json
* policy_type:
* type: integer
* description: ANONYMOUS_POLICY = 1, MEMBERS_ONLY_POLICY = 2, USE_TAGS_POLICY= 3
* example: 1
* tags:
* type: array
* description: The list of tags required to enter this room
* items:
* type: string
* example: speaker
* textures:
* type: array
* description: The list of public textures for this map (TODO remove this)
* items:
* type: object
* properties:
* todo:
* type: string
* authenticationMandatory:
* type: boolean|null
* description: Whether the authentication is mandatory or not for this map.
* example: true
* roomSlug:
* type: string
* description: The slug of the room
* deprecated: true
* example: foo
* contactPage:
* type: string|null
* description: The URL to the contact page
* example: https://mycompany.com/contact-us
* group:
* type: string|null
* description: The group this room is part of (maps the notion of "world" in WorkAdventure SAAS)
* example: myorg/myworld
* iframeAuthentication:
* type: string|null
* description: The URL of the authentication Iframe
* example: https://mycompany.com/authc
* expireOn:
* type: string|undefined
* description: The date (in ISO 8601 format) at which the room will expire
* example: 2022-11-05T08:15:30-05:00
* canReport:
* type: boolean|undefined
* description: Whether the "report" feature is enabled or not on this room
* example: true
*
*/
this.app.get("/map", (req, res) => { this.app.get("/map", (req, res) => {
const query = parse(req.path_query); const query = parse(req.path_query);
if (typeof query.playUri !== "string") { if (typeof query.playUri !== "string") {

View File

@ -0,0 +1,63 @@
import swaggerJsdoc from "swagger-jsdoc";
import { BaseHttpController } from "./BaseHttpController";
// @ts-ignore
import LiveDirectory from "live-directory";
import * as fs from "fs";
export class SwaggerController extends BaseHttpController {
routes() {
this.app.get("/openapi", (req, res) => {
const options = {
swaggerDefinition: {
openapi: "3.0.0",
info: {
title: "WorkAdventure Pusher",
version: "1.0.0",
},
},
apis: ["./src/Controller/*.ts"],
};
res.json(swaggerJsdoc(options));
});
// Create a LiveDirectory instance to virtualize directory with our assets
const LiveAssets = new LiveDirectory({
path: __dirname + "/../../node_modules/swagger-ui-dist", // We want to provide the system path to the folder. Avoid using relative paths.
keep: {
extensions: [".css", ".js", ".json", ".png", ".jpg", ".jpeg", ".html"], // We only want to serve files with these extensions
},
ignore: (path: string) => {
return path.startsWith("."); // We want to ignore dotfiles for safety
},
});
// Create static serve route to serve index.html
this.app.get("/swagger-ui/", (request, response) => {
fs.readFile(__dirname + "/../../node_modules/swagger-ui-dist/index.html", "utf8", function (err, data) {
if (err) {
return response.status(500).send(err.message);
}
const result = data.replace(/https:\/\/petstore.swagger.io\/v2\/swagger.json/g, "/openapi");
response.send(result);
return;
});
});
// Create static serve route to serve frontend assets
this.app.get("/swagger-ui/*", (request, response) => {
// Strip away '/assets' from the request path to get asset relative path
// Lookup LiveFile instance from our LiveDirectory instance.
const path = request.path.replace("/swagger-ui", "");
const file = LiveAssets.get(path);
// Return a 404 if no asset/file exists on the derived path
if (file === undefined) return response.status(404).send("");
// Set appropriate mime-type and serve file buffer as response body
return response.type(file.extension).send(file.buffer);
});
}
}

View File

@ -20,6 +20,9 @@ export const OPID_CLIENT_REDIRECT_URL = process.env.OPID_CLIENT_REDIRECT_URL ||
export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile"; export const OPID_PROFILE_SCREEN_PROVIDER = process.env.OPID_PROFILE_SCREEN_PROVIDER || ADMIN_URL + "/profile";
export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true"; export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true";
// If set to the string "true", the /openapi route will return the OpenAPI definition and the swagger-ui/ route will display the documentation
export const ENABLE_OPENAPI_ENDPOINT = process.env.ENABLE_OPENAPI_ENDPOINT === "true";
export { export {
SECRET_KEY, SECRET_KEY,
API_URL, API_URL,

View File

@ -2,6 +2,38 @@
# yarn lockfile v1 # yarn lockfile v1
"@apidevtools/json-schema-ref-parser@^9.0.6":
version "9.0.9"
resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b"
integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==
dependencies:
"@jsdevtools/ono" "^7.1.3"
"@types/json-schema" "^7.0.6"
call-me-maybe "^1.0.1"
js-yaml "^4.1.0"
"@apidevtools/openapi-schemas@^2.0.4":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz#9fa08017fb59d80538812f03fc7cac5992caaa17"
integrity sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==
"@apidevtools/swagger-methods@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz#b789a362e055b0340d04712eafe7027ddc1ac267"
integrity sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==
"@apidevtools/swagger-parser@10.0.2":
version "10.0.2"
resolved "https://registry.yarnpkg.com/@apidevtools/swagger-parser/-/swagger-parser-10.0.2.tgz#f4145afb7c3a3bafe0376f003b5c3bdeae17a952"
integrity sha512-JFxcEyp8RlNHgBCE98nwuTkZT6eNFPc1aosWV6wPcQph72TSEEu1k3baJD4/x1qznU+JiDdz8F5pTwabZh+Dhg==
dependencies:
"@apidevtools/json-schema-ref-parser" "^9.0.6"
"@apidevtools/openapi-schemas" "^2.0.4"
"@apidevtools/swagger-methods" "^3.0.2"
"@jsdevtools/ono" "^7.1.3"
call-me-maybe "^1.0.1"
z-schema "^4.2.3"
"@babel/code-frame@^7.0.0": "@babel/code-frame@^7.0.0":
version "7.16.7" version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@ -23,6 +55,11 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@jsdevtools/ono@^7.1.3":
version "7.1.3"
resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
"@mapbox/node-pre-gyp@^1.0.4": "@mapbox/node-pre-gyp@^1.0.4":
version "1.0.8" version "1.0.8"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58"
@ -153,7 +190,7 @@
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.10.3.tgz#a89798b3d5a8bd23ca56e855a9aee3e5a93bdaaa" resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.10.3.tgz#a89798b3d5a8bd23ca56e855a9aee3e5a93bdaaa"
integrity sha512-SWyMrjgdAUHNQmutvDcKablrJhkDLy4wunTme8oYLjKp41GnHGxMRXr2MQMvy/qy8H3LdzwQk9gH4hZ6T++H8g== integrity sha512-SWyMrjgdAUHNQmutvDcKablrJhkDLy4wunTme8oYLjKp41GnHGxMRXr2MQMvy/qy8H3LdzwQk9gH4hZ6T++H8g==
"@types/json-schema@^7.0.3": "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.6":
version "7.0.9" version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
@ -244,6 +281,11 @@
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
"@types/swagger-jsdoc@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/@types/swagger-jsdoc/-/swagger-jsdoc-6.0.1.tgz#94a99aca0356cb64ad2a6eb903ed034703453801"
integrity sha512-+MUpcbyxD528dECUBCEVm6abNuORdbuGjbrUdHDeAQ+rkPuo2a+L4N02WJHF3bonSSE6SJ3dUJwF2V6+cHnf0w==
"@types/uuid@8.3.1": "@types/uuid@8.3.1":
version "8.3.1" version "8.3.1"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f"
@ -421,6 +463,11 @@ argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
ascli@~1: ascli@~1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc"
@ -518,6 +565,11 @@ cacheable-request@^7.0.2:
normalize-url "^6.0.1" normalize-url "^6.0.1"
responselike "^2.0.0" responselike "^2.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=
callsites@^3.0.0: callsites@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@ -550,7 +602,7 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
chokidar@^3.5.1: chokidar@^3.5.1, chokidar@^3.5.2:
version "3.5.3" version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@ -665,6 +717,16 @@ colour@~0.7.1:
resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778"
integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=
commander@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.0.tgz#b990bfb8ac030aedc6d11bc04d1488ffef56db75"
integrity sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==
commander@^2.7.1:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^8.2.0: commander@^8.2.0:
version "8.3.0" version "8.3.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
@ -775,7 +837,7 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
doctrine@^3.0.0: doctrine@3.0.0, doctrine@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
@ -945,6 +1007,11 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
etag@^1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
execa@^5.1.1: execa@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
@ -1100,6 +1167,18 @@ glob-parent@^5.0.0, glob-parent@~5.1.2:
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"
glob@7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.5, glob@^7.1.3, glob@^7.1.6: glob@^7.0.5, glob@^7.1.3, glob@^7.1.6:
version "7.2.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
@ -1398,6 +1477,13 @@ js-yaml@^3.13.1:
argparse "^1.0.7" argparse "^1.0.7"
esprima "^4.0.0" esprima "^4.0.0"
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
json-buffer@3.0.1: json-buffer@3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
@ -1512,6 +1598,14 @@ listr2@^3.12.2:
through "^2.3.8" through "^2.3.8"
wrap-ansi "^7.0.0" wrap-ansi "^7.0.0"
live-directory@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/live-directory/-/live-directory-2.3.2.tgz#17945a1386ed439af24228c802f6546c0fa85a9b"
integrity sha512-s/QBuRkngjzUU8kVkrklqT/2/je4GYE45HiVZ8WwFNTvswXknlsC5vdgv4ycOrL/76CBMjrG7rySFpX8nX80gg==
dependencies:
chokidar "^3.5.2"
etag "^1.8.1"
lodash.camelcase@^4.3.0: lodash.camelcase@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@ -1522,6 +1616,11 @@ lodash.clone@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
lodash.includes@^4.3.0: lodash.includes@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@ -1532,6 +1631,11 @@ lodash.isboolean@^3.0.3:
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
lodash.isinteger@^4.0.4: lodash.isinteger@^4.0.4:
version "4.0.4" version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
@ -1552,6 +1656,11 @@ lodash.isstring@^4.0.1:
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.mergewith@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
lodash.once@^4.0.0: lodash.once@^4.0.0:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
@ -2329,6 +2438,30 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
swagger-jsdoc@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/swagger-jsdoc/-/swagger-jsdoc-6.1.0.tgz#c2b86321f2c4dde8947b418fe8a4bc94431d5522"
integrity sha512-xgep5M8Gq31MxpCbQLvJZpNqHfGPfI+sILCzujZbEXIQp2COtkZgoGASs0gacRs4xHmLDH+GuMGdorPITSG4tA==
dependencies:
commander "6.2.0"
doctrine "3.0.0"
glob "7.1.6"
lodash.mergewith "^4.6.2"
swagger-parser "10.0.2"
yaml "2.0.0-1"
swagger-parser@10.0.2:
version "10.0.2"
resolved "https://registry.yarnpkg.com/swagger-parser/-/swagger-parser-10.0.2.tgz#d7f18faa09c9c145e938977c9bd6c3435998b667"
integrity sha512-9jHkHM+QXyLGFLk1DkXBwV+4HyNm0Za3b8/zk/+mjr8jgOSiqm3FOTHBSDsBjtn9scdL+8eWcHdupp2NLM8tDw==
dependencies:
"@apidevtools/swagger-parser" "10.0.2"
swagger-ui-dist@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.5.1.tgz#3a71f053784ad3b781e7454743064ce3fa7522b4"
integrity sha512-52iaT+VRsT4EnE2PHrAdccRYd25Vllt9WQLH8ijkQzXAHUe6lgoEEweTGdE63utFlqaJt8JEPUcRc8x04vUyPg==
table@^5.2.3: table@^5.2.3:
version "5.4.6" version "5.4.6"
resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
@ -2518,6 +2651,11 @@ v8-compile-cache@^2.0.3:
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
validator@^13.6.0:
version "13.7.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857"
integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==
webidl-conversions@^3.0.0: webidl-conversions@^3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@ -2615,6 +2753,11 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@2.0.0-1:
version "2.0.0-1"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.0.0-1.tgz#8c3029b3ee2028306d5bcf396980623115ff8d18"
integrity sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==
yaml@^1.10.0: yaml@^1.10.0:
version "1.10.2" version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
@ -2637,3 +2780,14 @@ yn@3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
z-schema@^4.2.3:
version "4.2.4"
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-4.2.4.tgz#73102a49512179b12a8ec50b1daa676b984da6e4"
integrity sha512-YvBeW5RGNeNzKOUJs3rTL4+9rpcvHXt5I051FJbOcitV8bl40pEfcG0Q+dWSwS0/BIYrMZ/9HHoqLllMkFhD0w==
dependencies:
lodash.get "^4.4.2"
lodash.isequal "^4.5.0"
validator "^13.6.0"
optionalDependencies:
commander "^2.7.1"