mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
openapi: implement API handler with openapi-backend
- Tests pass ✅
- Added openapi-backend hook
- Generating OpenAPI v3 definitions for each API version
- Definitions served /api/openapi.json /api/{version}/openapi.json
This commit is contained in:
parent
dbab4ad13a
commit
25e081ac89
6 changed files with 680 additions and 328 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -19,3 +19,5 @@ npm-debug.log
|
||||||
bin/etherpad-1.deb
|
bin/etherpad-1.deb
|
||||||
credentials.json
|
credentials.json
|
||||||
out/
|
out/
|
||||||
|
.nyc_output
|
||||||
|
./package-lock.json
|
||||||
|
|
|
@ -24,6 +24,6 @@
|
||||||
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminsettings:expressCreateServer",
|
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/adminsettings:expressCreateServer",
|
||||||
"socketio": "ep_etherpad-lite/node/hooks/express/adminsettings:socketio" }
|
"socketio": "ep_etherpad-lite/node/hooks/express/adminsettings:socketio" }
|
||||||
},
|
},
|
||||||
{ "name": "swagger", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/swagger:expressCreateServer" } }
|
{ "name": "openapi", "hooks": { "expressCreateServer": "ep_etherpad-lite/node/hooks/express/openapi:expressCreateServer" } }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
255
src/node/hooks/express/openapi.js
Normal file
255
src/node/hooks/express/openapi.js
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
const OpenAPIBackend = require('openapi-backend').default;
|
||||||
|
const formidable = require('formidable');
|
||||||
|
const { promisify } = require('util');
|
||||||
|
|
||||||
|
const apiHandler = require('../../handler/APIHandler');
|
||||||
|
const settings = require('../../utils/Settings');
|
||||||
|
const { API } = require('./swagger');
|
||||||
|
|
||||||
|
const log4js = require('log4js');
|
||||||
|
const apiLogger = log4js.getLogger('API');
|
||||||
|
|
||||||
|
// https://github.com/OAI/OpenAPI-Specification/tree/master/schemas/v3.0
|
||||||
|
const OPENAPI_VERSION = '3.0.2'; // Swagger/OAS version
|
||||||
|
|
||||||
|
// enum for two different styles of API paths used for etherpad
|
||||||
|
const APIPathStyle = {
|
||||||
|
FLAT: 'api', // flat paths e.g. /api/createGroup
|
||||||
|
REST: 'rest', // restful paths e.g. /rest/group/create
|
||||||
|
};
|
||||||
|
exports.APIPathStyle = APIPathStyle;
|
||||||
|
|
||||||
|
// helper to get api root
|
||||||
|
const getApiRootForVersion = (version, style = APIPathStyle.FLAT) => `/${style}/${version}`;
|
||||||
|
|
||||||
|
// helper to generate an OpenAPI server object when serving definitions
|
||||||
|
const generateServerForApiVersion = (apiRoot, req) => ({
|
||||||
|
url: `${settings.ssl ? 'https' : 'http'}://${req.headers.host}${apiRoot}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const defaultResponses = {
|
||||||
|
200: {
|
||||||
|
description: 'ok',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// convert to a flat list of OAS Operation objects
|
||||||
|
const operations = [];
|
||||||
|
for (const resource in API) {
|
||||||
|
for (const action in API[resource]) {
|
||||||
|
const { func: operationId, description, response } = API[resource][action];
|
||||||
|
const operation = {
|
||||||
|
operationId,
|
||||||
|
summary: description,
|
||||||
|
responses: defaultResponses,
|
||||||
|
tags: [resource],
|
||||||
|
_restPath: `/${resource}/${action}`,
|
||||||
|
};
|
||||||
|
operations[operationId] = operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateDefinitionForVersion = (version, style = APIPathStyle.FLAT) => {
|
||||||
|
const definition = {
|
||||||
|
openapi: OPENAPI_VERSION,
|
||||||
|
info: {
|
||||||
|
title: 'Etherpad API',
|
||||||
|
description:
|
||||||
|
'Etherpad is a real-time collaborative editor scalable to thousands of simultaneous real time users. It provides full data export capabilities, and runs on your server, under your control.',
|
||||||
|
version,
|
||||||
|
},
|
||||||
|
paths: {},
|
||||||
|
components: {
|
||||||
|
responses: {},
|
||||||
|
parameters: {},
|
||||||
|
schemas: {
|
||||||
|
SessionInfo: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
authorID: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
groupID: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
validUntil: {
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
UserInfo: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
colorId: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Message: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
text: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
userId: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
userName: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
securitySchemes: {
|
||||||
|
ApiKey: {
|
||||||
|
type: 'apiKey',
|
||||||
|
in: 'query',
|
||||||
|
name: 'apikey',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
security: [{ ApiKey: [] }],
|
||||||
|
};
|
||||||
|
|
||||||
|
// build operations
|
||||||
|
for (const funcName in apiHandler.version[version]) {
|
||||||
|
let operation = {};
|
||||||
|
if (operations[funcName]) {
|
||||||
|
operation = { ...operations[funcName] };
|
||||||
|
} else {
|
||||||
|
// console.warn(`No operation found for function: ${funcName}`);
|
||||||
|
operation = {
|
||||||
|
operationId: funcName,
|
||||||
|
responses: defaultResponses,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// set parameters
|
||||||
|
operation.parameters = operation.parameters || [];
|
||||||
|
for (const paramName of apiHandler.version[version][funcName]) {
|
||||||
|
operation.parameters.push({ $ref: `#/components/parameters/${paramName}` });
|
||||||
|
if (!definition.components.parameters[paramName]) {
|
||||||
|
definition.components.parameters[paramName] = {
|
||||||
|
name: paramName,
|
||||||
|
in: 'query',
|
||||||
|
schema: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set path
|
||||||
|
let path = `/${operation.operationId}`; // APIPathStyle.FLAT
|
||||||
|
if (style === APIPathStyle.REST && operation._restPath) {
|
||||||
|
path = operation._restPath;
|
||||||
|
}
|
||||||
|
delete operation._restPath;
|
||||||
|
|
||||||
|
// add to definition
|
||||||
|
// NOTE: It may be confusing that every operation can be called with both GET and POST
|
||||||
|
definition.paths[path] = {
|
||||||
|
get: {
|
||||||
|
...operation,
|
||||||
|
operationId: `${operation.operationId}UsingGET`,
|
||||||
|
},
|
||||||
|
post: {
|
||||||
|
...operation,
|
||||||
|
operationId: `${operation.operationId}UsingPOST`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return definition;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.expressCreateServer = (_, args) => {
|
||||||
|
const { app } = args;
|
||||||
|
|
||||||
|
for (const version in apiHandler.version) {
|
||||||
|
// create two different styles of api: flat + rest
|
||||||
|
for (const style of [APIPathStyle.FLAT, APIPathStyle.REST]) {
|
||||||
|
const apiRoot = getApiRootForVersion(version, style);
|
||||||
|
|
||||||
|
// generate openapi definition for this API version
|
||||||
|
const definition = generateDefinitionForVersion(version, style);
|
||||||
|
|
||||||
|
// serve openapi definition file
|
||||||
|
app.get(`${apiRoot}/openapi.json`, (req, res) => {
|
||||||
|
res.json({ ...definition, servers: [generateServerForApiVersion(apiRoot, req)] });
|
||||||
|
});
|
||||||
|
|
||||||
|
// serve latest openapi definition file under /api/openapi.json
|
||||||
|
if (version === apiHandler.latestApiVersion) {
|
||||||
|
app.get(`/${style}/openapi.json`, (req, res) => {
|
||||||
|
res.json({ ...definition, servers: [generateServerForApiVersion(apiRoot, req)] });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// build openapi-backend instance for this api version
|
||||||
|
const api = new OpenAPIBackend({
|
||||||
|
apiRoot,
|
||||||
|
definition,
|
||||||
|
strict: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// register default handlers
|
||||||
|
api.register({
|
||||||
|
notFound: (c, req, res) => {
|
||||||
|
res.statusCode = 404;
|
||||||
|
res.send({ code: 3, message: 'no such function', data: null });
|
||||||
|
},
|
||||||
|
notImplemented: (c, req, res) => {
|
||||||
|
res.statusCode = 501;
|
||||||
|
res.send({ code: 3, message: 'not implemented', data: null });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// register operation handlers (calls apiHandler.handle)
|
||||||
|
for (const funcName in apiHandler.version[version]) {
|
||||||
|
const handler = async (c, req, res) => {
|
||||||
|
// parse fields from request
|
||||||
|
const { header, params, query } = c.request;
|
||||||
|
|
||||||
|
let formData = {};
|
||||||
|
if (c.request.method === 'post') {
|
||||||
|
const form = new formidable.IncomingForm();
|
||||||
|
const parseForm = promisify(form.parse).bind(form);
|
||||||
|
formData = await parseForm(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fields = Object.assign({}, header, params, query, formData);
|
||||||
|
|
||||||
|
// log request
|
||||||
|
apiLogger.info(`REQUEST, v${version}:${funcName}, ${JSON.stringify(fields)}`);
|
||||||
|
|
||||||
|
// pass to api handler
|
||||||
|
return apiHandler.handle(version, funcName, fields, req, res);
|
||||||
|
};
|
||||||
|
|
||||||
|
// each operation can be called with either GET or POST
|
||||||
|
api.register(`${funcName}UsingGET`, handler);
|
||||||
|
api.register(`${funcName}UsingPOST`, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start and bind to express
|
||||||
|
api.init();
|
||||||
|
app.use(apiRoot, async (req, res) => api.handleRequest(req, req, res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,62 +1,62 @@
|
||||||
var express = require('express');
|
var express = require('express');
|
||||||
var apiHandler = require('../../handler/APIHandler');
|
var apiHandler = require('../../handler/APIHandler');
|
||||||
var apiCaller = require('./apicalls').apiCaller;
|
var apiCaller = require('./apicalls').apiCaller;
|
||||||
var settings = require("../../utils/Settings");
|
var settings = require('../../utils/Settings');
|
||||||
|
|
||||||
var swaggerModels = {
|
var swaggerModels = {
|
||||||
'models': {
|
models: {
|
||||||
'SessionInfo' : {
|
SessionInfo: {
|
||||||
"id": 'SessionInfo',
|
id: 'SessionInfo',
|
||||||
"properties": {
|
properties: {
|
||||||
"id": {
|
id: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"authorID": {
|
authorID: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"groupID":{
|
groupID: {
|
||||||
"type":"string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"validUntil":{
|
validUntil: {
|
||||||
"type":"long"
|
type: 'integer',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'UserInfo' : {
|
UserInfo: {
|
||||||
"id": 'UserInfo',
|
id: 'UserInfo',
|
||||||
"properties": {
|
properties: {
|
||||||
"id": {
|
id: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"colorId": {
|
colorId: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"name":{
|
name: {
|
||||||
"type":"string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"timestamp":{
|
timestamp: {
|
||||||
"type":"long"
|
type: 'integer',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
'Message' : {
|
Message: {
|
||||||
"id": 'Message',
|
id: 'Message',
|
||||||
"properties": {
|
properties: {
|
||||||
"text": {
|
text: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"userId": {
|
userId: {
|
||||||
"type": "string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"userName":{
|
userName: {
|
||||||
"type":"string"
|
type: 'string',
|
||||||
},
|
},
|
||||||
"time":{
|
time: {
|
||||||
"type":"long"
|
type: 'integer',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function sessionListResponseProcessor(res) {
|
function sessionListResponseProcessor(res) {
|
||||||
|
@ -64,7 +64,7 @@ function sessionListResponseProcessor(res) {
|
||||||
var sessions = [];
|
var sessions = [];
|
||||||
for (var sessionId in res.data) {
|
for (var sessionId in res.data) {
|
||||||
var sessionInfo = res.data[sessionId];
|
var sessionInfo = res.data[sessionId];
|
||||||
sessionId["id"] = sessionId;
|
sessionId['id'] = sessionId;
|
||||||
sessions.push(sessionInfo);
|
sessions.push(sessionInfo);
|
||||||
}
|
}
|
||||||
res.data = sessions;
|
res.data = sessions;
|
||||||
|
@ -75,284 +75,284 @@ function sessionListResponseProcessor(res) {
|
||||||
|
|
||||||
// We'll add some more info to the API methods
|
// We'll add some more info to the API methods
|
||||||
var API = {
|
var API = {
|
||||||
|
|
||||||
// Group
|
// Group
|
||||||
"group": {
|
group: {
|
||||||
"create" : {
|
create: {
|
||||||
"func" : "createGroup",
|
func: 'createGroup',
|
||||||
"description": "creates a new group",
|
description: 'creates a new group',
|
||||||
"response": {"groupID":{"type":"string"}}
|
response: { groupID: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"createIfNotExistsFor" : {
|
createIfNotExistsFor: {
|
||||||
"func": "createGroupIfNotExistsFor",
|
func: 'createGroupIfNotExistsFor',
|
||||||
"description": "this functions helps you to map your application group ids to Etherpad group ids",
|
description: 'this functions helps you to map your application group ids to Etherpad group ids',
|
||||||
"response": {"groupID":{"type":"string"}}
|
response: { groupID: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"delete" : {
|
delete: {
|
||||||
"func": "deleteGroup",
|
func: 'deleteGroup',
|
||||||
"description": "deletes a group"
|
description: 'deletes a group',
|
||||||
},
|
},
|
||||||
"listPads" : {
|
listPads: {
|
||||||
"func": "listPads",
|
func: 'listPads',
|
||||||
"description": "returns all pads of this group",
|
description: 'returns all pads of this group',
|
||||||
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
response: { padIDs: { type: 'List', items: { type: 'string' } } },
|
||||||
},
|
},
|
||||||
"createPad" : {
|
createPad: {
|
||||||
"func": "createGroupPad",
|
func: 'createGroupPad',
|
||||||
"description": "creates a new pad in this group"
|
description: 'creates a new pad in this group',
|
||||||
},
|
},
|
||||||
"listSessions": {
|
listSessions: {
|
||||||
"func": "listSessionsOfGroup",
|
func: 'listSessionsOfGroup',
|
||||||
"responseProcessor": sessionListResponseProcessor,
|
responseProcessor: sessionListResponseProcessor,
|
||||||
"description": "",
|
description: '',
|
||||||
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
response: { sessions: { type: 'List', items: { type: 'SessionInfo' } } },
|
||||||
},
|
},
|
||||||
"list": {
|
list: {
|
||||||
"func": "listAllGroups",
|
func: 'listAllGroups',
|
||||||
"description": "",
|
description: '',
|
||||||
"response": {"groupIDs":{"type":"List", "items":{"type":"string"}}}
|
response: { groupIDs: { type: 'List', items: { type: 'string' } } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Author
|
// Author
|
||||||
"author": {
|
author: {
|
||||||
"create" : {
|
create: {
|
||||||
"func" : "createAuthor",
|
func: 'createAuthor',
|
||||||
"description": "creates a new author",
|
description: 'creates a new author',
|
||||||
"response": {"authorID":{"type":"string"}}
|
response: { authorID: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"createIfNotExistsFor": {
|
createIfNotExistsFor: {
|
||||||
"func": "createAuthorIfNotExistsFor",
|
func: 'createAuthorIfNotExistsFor',
|
||||||
"description": "this functions helps you to map your application author ids to Etherpad author ids",
|
description: 'this functions helps you to map your application author ids to Etherpad author ids',
|
||||||
"response": {"authorID":{"type":"string"}}
|
response: { authorID: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"listPads": {
|
listPads: {
|
||||||
"func": "listPadsOfAuthor",
|
func: 'listPadsOfAuthor',
|
||||||
"description": "returns an array of all pads this author contributed to",
|
description: 'returns an array of all pads this author contributed to',
|
||||||
"response": {"padIDs":{"type":"List", "items":{"type":"string"}}}
|
response: { padIDs: { type: 'List', items: { type: 'string' } } },
|
||||||
},
|
},
|
||||||
"listSessions": {
|
listSessions: {
|
||||||
"func": "listSessionsOfAuthor",
|
func: 'listSessionsOfAuthor',
|
||||||
"responseProcessor": sessionListResponseProcessor,
|
responseProcessor: sessionListResponseProcessor,
|
||||||
"description": "returns all sessions of an author",
|
description: 'returns all sessions of an author',
|
||||||
"response": {"sessions":{"type":"List", "items":{"type":"SessionInfo"}}}
|
response: { sessions: { type: 'List', items: { type: 'SessionInfo' } } },
|
||||||
},
|
},
|
||||||
// We need an operation that return a UserInfo so it can be picked up by the codegen :(
|
// We need an operation that return a UserInfo so it can be picked up by the codegen :(
|
||||||
"getName" : {
|
getName: {
|
||||||
"func": "getAuthorName",
|
func: 'getAuthorName',
|
||||||
"description": "Returns the Author Name of the author",
|
description: 'Returns the Author Name of the author',
|
||||||
"responseProcessor": function(response) {
|
responseProcessor: function(response) {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
response["info"] = {"name": response.data.authorName};
|
response['info'] = { name: response.data.authorName };
|
||||||
delete response["data"];
|
delete response['data'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {"info":{"type":"UserInfo"}}
|
response: { info: { type: 'UserInfo' } },
|
||||||
}
|
|
||||||
},
|
|
||||||
"session": {
|
|
||||||
"create" : {
|
|
||||||
"func": "createSession",
|
|
||||||
"description": "creates a new session. validUntil is an unix timestamp in seconds",
|
|
||||||
"response": {"sessionID":{"type":"string"}}
|
|
||||||
},
|
},
|
||||||
"delete" : {
|
},
|
||||||
"func": "deleteSession",
|
session: {
|
||||||
"description": "deletes a session"
|
create: {
|
||||||
|
func: 'createSession',
|
||||||
|
description: 'creates a new session. validUntil is an unix timestamp in seconds',
|
||||||
|
response: { sessionID: { type: 'string' } },
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
func: 'deleteSession',
|
||||||
|
description: 'deletes a session',
|
||||||
},
|
},
|
||||||
// We need an operation that returns a SessionInfo so it can be picked up by the codegen :(
|
// We need an operation that returns a SessionInfo so it can be picked up by the codegen :(
|
||||||
"info": {
|
info: {
|
||||||
"func": "getSessionInfo",
|
func: 'getSessionInfo',
|
||||||
"description": "returns informations about a session",
|
description: 'returns informations about a session',
|
||||||
"responseProcessor": function(response) {
|
responseProcessor: function(response) {
|
||||||
// move this to info
|
// move this to info
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
response["info"] = response.data;
|
response['info'] = response.data;
|
||||||
delete response["data"];
|
delete response['data'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {"info":{"type":"SessionInfo"}}
|
response: { info: { type: 'SessionInfo' } },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"pad": {
|
pad: {
|
||||||
"listAll" : {
|
listAll: {
|
||||||
"func": "listAllPads",
|
func: 'listAllPads',
|
||||||
"description": "list all the pads",
|
description: 'list all the pads',
|
||||||
"response": {"padIDs":{"type":"List", "items": {"type" : "string"}}}
|
response: { padIDs: { type: 'List', items: { type: 'string' } } },
|
||||||
},
|
},
|
||||||
"createDiffHTML" : {
|
createDiffHTML: {
|
||||||
"func" : "createDiffHTML",
|
func: 'createDiffHTML',
|
||||||
"description": "",
|
description: '',
|
||||||
"response": {}
|
response: {},
|
||||||
},
|
},
|
||||||
"create" : {
|
create: {
|
||||||
"func" : "createPad",
|
func: 'createPad',
|
||||||
"description": "creates a new (non-group) pad. Note that if you need to create a group Pad, you should call createGroupPad"
|
description:
|
||||||
|
'creates a new (non-group) pad. Note that if you need to create a group Pad, you should call createGroupPad',
|
||||||
},
|
},
|
||||||
"getText" : {
|
getText: {
|
||||||
"func" : "getText",
|
func: 'getText',
|
||||||
"description": "returns the text of a pad",
|
description: 'returns the text of a pad',
|
||||||
"response": {"text":{"type":"string"}}
|
response: { text: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"setText" : {
|
setText: {
|
||||||
"func" : "setText",
|
func: 'setText',
|
||||||
"description": "sets the text of a pad"
|
description: 'sets the text of a pad',
|
||||||
},
|
},
|
||||||
"getHTML": {
|
getHTML: {
|
||||||
"func" : "getHTML",
|
func: 'getHTML',
|
||||||
"description": "returns the text of a pad formatted as HTML",
|
description: 'returns the text of a pad formatted as HTML',
|
||||||
"response": {"html":{"type":"string"}}
|
response: { html: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"setHTML": {
|
setHTML: {
|
||||||
"func" : "setHTML",
|
func: 'setHTML',
|
||||||
"description": "sets the text of a pad with HTML"
|
description: 'sets the text of a pad with HTML',
|
||||||
},
|
},
|
||||||
"getRevisionsCount": {
|
getRevisionsCount: {
|
||||||
"func" : "getRevisionsCount",
|
func: 'getRevisionsCount',
|
||||||
"description": "returns the number of revisions of this pad",
|
description: 'returns the number of revisions of this pad',
|
||||||
"response": {"revisions":{"type":"long"}}
|
response: { revisions: { type: 'integer' } },
|
||||||
},
|
},
|
||||||
"getLastEdited": {
|
getLastEdited: {
|
||||||
"func" : "getLastEdited",
|
func: 'getLastEdited',
|
||||||
"description": "returns the timestamp of the last revision of the pad",
|
description: 'returns the timestamp of the last revision of the pad',
|
||||||
"response": {"lastEdited":{"type":"long"}}
|
response: { lastEdited: { type: 'integer' } },
|
||||||
},
|
},
|
||||||
"delete": {
|
delete: {
|
||||||
"func" : "deletePad",
|
func: 'deletePad',
|
||||||
"description": "deletes a pad"
|
description: 'deletes a pad',
|
||||||
},
|
},
|
||||||
"getReadOnlyID": {
|
getReadOnlyID: {
|
||||||
"func" : "getReadOnlyID",
|
func: 'getReadOnlyID',
|
||||||
"description": "returns the read only link of a pad",
|
description: 'returns the read only link of a pad',
|
||||||
"response": {"readOnlyID":{"type":"string"}}
|
response: { readOnlyID: { type: 'string' } },
|
||||||
},
|
},
|
||||||
"setPublicStatus": {
|
setPublicStatus: {
|
||||||
"func": "setPublicStatus",
|
func: 'setPublicStatus',
|
||||||
"description": "sets a boolean for the public status of a pad"
|
description: 'sets a boolean for the public status of a pad',
|
||||||
},
|
},
|
||||||
"getPublicStatus": {
|
getPublicStatus: {
|
||||||
"func": "getPublicStatus",
|
func: 'getPublicStatus',
|
||||||
"description": "return true of false",
|
description: 'return true of false',
|
||||||
"response": {"publicStatus":{"type":"boolean"}}
|
response: { publicStatus: { type: 'boolean' } },
|
||||||
},
|
},
|
||||||
"setPassword": {
|
setPassword: {
|
||||||
"func": "setPassword",
|
func: 'setPassword',
|
||||||
"description": "returns ok or a error message"
|
description: 'returns ok or a error message',
|
||||||
},
|
},
|
||||||
"isPasswordProtected": {
|
isPasswordProtected: {
|
||||||
"func": "isPasswordProtected",
|
func: 'isPasswordProtected',
|
||||||
"description": "returns true or false",
|
description: 'returns true or false',
|
||||||
"response": {"passwordProtection":{"type":"boolean"}}
|
response: { passwordProtection: { type: 'boolean' } },
|
||||||
},
|
},
|
||||||
"authors": {
|
authors: {
|
||||||
"func": "listAuthorsOfPad",
|
func: 'listAuthorsOfPad',
|
||||||
"description": "returns an array of authors who contributed to this pad",
|
description: 'returns an array of authors who contributed to this pad',
|
||||||
"response": {"authorIDs":{"type":"List", "items":{"type" : "string"}}}
|
response: { authorIDs: { type: 'List', items: { type: 'string' } } },
|
||||||
},
|
},
|
||||||
"usersCount": {
|
usersCount: {
|
||||||
"func": "padUsersCount",
|
func: 'padUsersCount',
|
||||||
"description": "returns the number of user that are currently editing this pad",
|
description: 'returns the number of user that are currently editing this pad',
|
||||||
"response": {"padUsersCount":{"type": "long"}}
|
response: { padUsersCount: { type: 'integer' } },
|
||||||
},
|
},
|
||||||
"users": {
|
users: {
|
||||||
"func": "padUsers",
|
func: 'padUsers',
|
||||||
"description": "returns the list of users that are currently editing this pad",
|
description: 'returns the list of users that are currently editing this pad',
|
||||||
"response": {"padUsers":{"type":"List", "items":{"type": "UserInfo"}}}
|
response: { padUsers: { type: 'List', items: { type: 'UserInfo' } } },
|
||||||
},
|
},
|
||||||
"sendClientsMessage": {
|
sendClientsMessage: {
|
||||||
"func": "sendClientsMessage",
|
func: 'sendClientsMessage',
|
||||||
"description": "sends a custom message of type msg to the pad"
|
description: 'sends a custom message of type msg to the pad',
|
||||||
},
|
},
|
||||||
"checkToken" : {
|
checkToken: {
|
||||||
"func": "checkToken",
|
func: 'checkToken',
|
||||||
"description": "returns ok when the current api token is valid"
|
description: 'returns ok when the current api token is valid',
|
||||||
},
|
},
|
||||||
"getChatHistory": {
|
getChatHistory: {
|
||||||
"func": "getChatHistory",
|
func: 'getChatHistory',
|
||||||
"description": "returns the chat history",
|
description: 'returns the chat history',
|
||||||
"response": {"messages":{"type":"List", "items": {"type" : "Message"}}}
|
response: { messages: { type: 'List', items: { type: 'Message' } } },
|
||||||
},
|
},
|
||||||
// We need an operation that returns a Message so it can be picked up by the codegen :(
|
// We need an operation that returns a Message so it can be picked up by the codegen :(
|
||||||
"getChatHead": {
|
getChatHead: {
|
||||||
"func": "getChatHead",
|
func: 'getChatHead',
|
||||||
"description": "returns the chatHead (chat-message) of the pad",
|
description: 'returns the chatHead (chat-message) of the pad',
|
||||||
"responseProcessor": function(response) {
|
responseProcessor: function(response) {
|
||||||
// move this to info
|
// move this to info
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
response["chatHead"] = {"time": response.data["chatHead"]};
|
response['chatHead'] = { time: response.data['chatHead'] };
|
||||||
delete response["data"];
|
delete response['data'];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response": {"chatHead":{"type":"Message"}}
|
response: { chatHead: { type: 'Message' } },
|
||||||
},
|
},
|
||||||
"appendChatMessage": {
|
appendChatMessage: {
|
||||||
"func": "appendChatMessage",
|
func: 'appendChatMessage',
|
||||||
"description": "appends a chat message"
|
description: 'appends a chat message',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function capitalise(string){
|
exports.API = API;
|
||||||
|
|
||||||
|
function capitalise(string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var resource in API) {
|
for (var resource in API) {
|
||||||
for (var func in API[resource]) {
|
for (var func in API[resource]) {
|
||||||
|
|
||||||
// The base response model
|
// The base response model
|
||||||
var responseModel = {
|
var responseModel = {
|
||||||
"properties": {
|
properties: {
|
||||||
"code":{
|
code: {
|
||||||
"type":"int"
|
type: 'int',
|
||||||
},
|
},
|
||||||
"message":{
|
message: {
|
||||||
"type":"string"
|
type: 'string',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var responseModelId = "Response";
|
var responseModelId = 'Response';
|
||||||
|
|
||||||
// Add the data properties (if any) to the response
|
// Add the data properties (if any) to the response
|
||||||
if (API[resource][func]["response"]) {
|
if (API[resource][func]['response']) {
|
||||||
// This is a specific response so let's set a new id
|
// This is a specific response so let's set a new id
|
||||||
responseModelId = capitalise(resource) + capitalise(func) + "Response";
|
responseModelId = capitalise(resource) + capitalise(func) + 'Response';
|
||||||
|
|
||||||
for(var prop in API[resource][func]["response"]) {
|
for (var prop in API[resource][func]['response']) {
|
||||||
var propType = API[resource][func]["response"][prop];
|
var propType = API[resource][func]['response'][prop];
|
||||||
responseModel["properties"][prop] = propType;
|
responseModel['properties'][prop] = propType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the id
|
// Add the id
|
||||||
responseModel["id"] = responseModelId;
|
responseModel['id'] = responseModelId;
|
||||||
|
|
||||||
// Add this to the swagger models
|
// Add this to the swagger models
|
||||||
swaggerModels['models'][responseModelId] = responseModel;
|
swaggerModels['models'][responseModelId] = responseModel;
|
||||||
|
|
||||||
// Store the response model id
|
// Store the response model id
|
||||||
API[resource][func]["responseClass"] = responseModelId;
|
API[resource][func]['responseClass'] = responseModelId;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function newSwagger() {
|
function newSwagger() {
|
||||||
var swagger_module = require.resolve("swagger-node-express");
|
var swagger_module = require.resolve('swagger-node-express');
|
||||||
if (require.cache[swagger_module]) {
|
if (require.cache[swagger_module]) {
|
||||||
// delete the child modules from cache
|
// delete the child modules from cache
|
||||||
require.cache[swagger_module].children.forEach(function(m) {delete require.cache[m.id];});
|
require.cache[swagger_module].children.forEach(function(m) {
|
||||||
|
delete require.cache[m.id];
|
||||||
|
});
|
||||||
// delete the module from cache
|
// delete the module from cache
|
||||||
delete require.cache[swagger_module];
|
delete require.cache[swagger_module];
|
||||||
}
|
}
|
||||||
return require("swagger-node-express");
|
return require('swagger-node-express');
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.expressCreateServer = function (hook_name, args, cb) {
|
exports.expressCreateServer = function(hook_name, args, cb) {
|
||||||
|
|
||||||
for (var version in apiHandler.version) {
|
for (var version in apiHandler.version) {
|
||||||
|
|
||||||
var swagger = newSwagger();
|
var swagger = newSwagger();
|
||||||
var basePath = "/rest/" + version;
|
var basePath = '/rest/' + version;
|
||||||
|
|
||||||
// Let's put this under /rest for now
|
// Let's put this under /rest for now
|
||||||
var subpath = express();
|
var subpath = express();
|
||||||
|
@ -360,52 +360,51 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
args.app.use(basePath, subpath);
|
args.app.use(basePath, subpath);
|
||||||
|
|
||||||
//hack!
|
//hack!
|
||||||
var swagger_temp = swagger
|
var swagger_temp = swagger;
|
||||||
swagger = swagger.createNew(subpath);
|
swagger = swagger.createNew(subpath);
|
||||||
swagger.params = swagger_temp.params
|
swagger.params = swagger_temp.params;
|
||||||
swagger.queryParam = swagger_temp.queryParam
|
swagger.queryParam = swagger_temp.queryParam;
|
||||||
swagger.pathParam = swagger_temp.pathParam
|
swagger.pathParam = swagger_temp.pathParam;
|
||||||
swagger.bodyParam = swagger_temp.bodyParam
|
swagger.bodyParam = swagger_temp.bodyParam;
|
||||||
swagger.formParam = swagger_temp.formParam
|
swagger.formParam = swagger_temp.formParam;
|
||||||
swagger.headerParam = swagger_temp.headerParam
|
swagger.headerParam = swagger_temp.headerParam;
|
||||||
swagger.error = swagger_temp.error
|
swagger.error = swagger_temp.error;
|
||||||
//swagger.setAppHandler(subpath);
|
//swagger.setAppHandler(subpath);
|
||||||
|
|
||||||
swagger.addModels(swaggerModels);
|
swagger.addModels(swaggerModels);
|
||||||
|
|
||||||
for (var resource in API) {
|
for (var resource in API) {
|
||||||
|
|
||||||
for (var funcName in API[resource]) {
|
for (var funcName in API[resource]) {
|
||||||
var func = API[resource][funcName];
|
var func = API[resource][funcName];
|
||||||
|
|
||||||
// get the api function
|
// get the api function
|
||||||
var apiFunc = apiHandler.version[version][func["func"]];
|
var apiFunc = apiHandler.version[version][func['func']];
|
||||||
|
|
||||||
// Skip this one if it does not exist in the version
|
// Skip this one if it does not exist in the version
|
||||||
if(!apiFunc) {
|
if (!apiFunc) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var swaggerFunc = {
|
var swaggerFunc = {
|
||||||
'spec': {
|
spec: {
|
||||||
"description" : func["description"],
|
description: func['description'],
|
||||||
"path" : "/" + resource + "/" + funcName,
|
path: '/' + resource + '/' + funcName,
|
||||||
"summary" : funcName,
|
summary: funcName,
|
||||||
"nickname" : funcName,
|
nickname: funcName,
|
||||||
"method": "GET",
|
method: 'GET',
|
||||||
"params" : apiFunc.map( function(param) {
|
params: apiFunc.map(function(param) {
|
||||||
return swagger.queryParam(param, param, "string");
|
return swagger.queryParam(param, param, 'string');
|
||||||
}),
|
}),
|
||||||
"responseClass" : func["responseClass"]
|
responseClass: func['responseClass'],
|
||||||
},
|
},
|
||||||
'action': (function(func, responseProcessor) {
|
action: (function(func, responseProcessor) {
|
||||||
return function (req,res) {
|
return function(req, res) {
|
||||||
req.params.version = version;
|
req.params.version = version;
|
||||||
req.params.func = func; // call the api function
|
req.params.func = func; // call the api function
|
||||||
|
|
||||||
//wrap the send function so we can process the response
|
//wrap the send function so we can process the response
|
||||||
res.__swagger_send = res.send;
|
res.__swagger_send = res.send;
|
||||||
res.send = function (response) {
|
res.send = function(response) {
|
||||||
// ugly but we need to get this as json
|
// ugly but we need to get this as json
|
||||||
response = JSON.parse(response);
|
response = JSON.parse(response);
|
||||||
// process the response if needed
|
// process the response if needed
|
||||||
|
@ -414,7 +413,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
}
|
}
|
||||||
// Let's move everything out of "data"
|
// Let's move everything out of "data"
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
for(var prop in response.data) {
|
for (var prop in response.data) {
|
||||||
response[prop] = response.data[prop];
|
response[prop] = response.data[prop];
|
||||||
delete response.data;
|
delete response.data;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +424,7 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
|
|
||||||
apiCaller(req, res, req.query);
|
apiCaller(req, res, req.query);
|
||||||
};
|
};
|
||||||
})(func["func"], func["responseProcessor"]) // must use a closure here
|
})(func['func'], func['responseProcessor']), // must use a closure here
|
||||||
};
|
};
|
||||||
|
|
||||||
swagger.addGet(swaggerFunc);
|
swagger.addGet(swaggerFunc);
|
||||||
|
@ -433,11 +432,11 @@ exports.expressCreateServer = function (hook_name, args, cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
swagger.setHeaders = function setHeaders(res) {
|
swagger.setHeaders = function setHeaders(res) {
|
||||||
res.header('Access-Control-Allow-Origin', "*");
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
};
|
};
|
||||||
|
|
||||||
swagger.configureSwaggerPaths("", "/api" , "");
|
swagger.configureSwaggerPaths('', '/api', '');
|
||||||
|
|
||||||
swagger.configure("http://" + settings.ip + ":" + settings.port + basePath, version);
|
swagger.configure('http://' + settings.ip + ':' + settings.port + basePath, version);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
231
src/package-lock.json
generated
231
src/package-lock.json
generated
|
@ -4,6 +4,40 @@
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@apidevtools/json-schema-ref-parser": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-n4YBtwQhdpLto1BaUCyAeflizmIbaloGShsPyRtFf5qdFJxfssj+GgLavczgKJFa3Bq+3St2CKcpRJdjtB4EBw==",
|
||||||
|
"requires": {
|
||||||
|
"@jsdevtools/ono": "^7.1.0",
|
||||||
|
"call-me-maybe": "^1.0.1",
|
||||||
|
"js-yaml": "^3.13.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@apidevtools/openapi-schemas": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-QoPaxGXfgqgGpK1p21FJ400z56hV681a8DOcZt3J5z0WIHgFeaIZ4+6bX5ATqmOoCpRCsH4ITEwKaOyFMz7wOA=="
|
||||||
|
},
|
||||||
|
"@apidevtools/swagger-methods": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-1Vlm18XYW6Yg7uHunroXeunWz5FShPFAdxBbPy8H6niB2Elz9QQsCoYHMbcc11EL1pTxaIr9HXz2An/mHXlX1Q=="
|
||||||
|
},
|
||||||
|
"@apidevtools/swagger-parser": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-Irqybg4dQrcHhZcxJc/UM4vO7Ksoj1Id5e+K94XUOzllqX1n47HEA50EKiXTCQbykxuJ4cYGIivjx/MRSTC5OA==",
|
||||||
|
"requires": {
|
||||||
|
"@apidevtools/json-schema-ref-parser": "^8.0.0",
|
||||||
|
"@apidevtools/openapi-schemas": "^2.0.2",
|
||||||
|
"@apidevtools/swagger-methods": "^3.0.0",
|
||||||
|
"@jsdevtools/ono": "^7.1.0",
|
||||||
|
"call-me-maybe": "^1.0.1",
|
||||||
|
"openapi-types": "^1.3.5",
|
||||||
|
"z-schema": "^4.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@babel/code-frame": {
|
"@babel/code-frame": {
|
||||||
"version": "7.8.3",
|
"version": "7.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
|
||||||
|
@ -46,12 +80,6 @@
|
||||||
"ms": "^2.1.1"
|
"ms": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -87,12 +115,6 @@
|
||||||
"source-map": "^0.5.0"
|
"source-map": "^0.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
|
@ -152,14 +174,6 @@
|
||||||
"@babel/template": "^7.8.6",
|
"@babel/template": "^7.8.6",
|
||||||
"@babel/types": "^7.9.0",
|
"@babel/types": "^7.9.0",
|
||||||
"lodash": "^4.17.13"
|
"lodash": "^4.17.13"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-optimise-call-expression": {
|
"@babel/helper-optimise-call-expression": {
|
||||||
|
@ -304,12 +318,6 @@
|
||||||
"ms": "^2.1.1"
|
"ms": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
@ -327,14 +335,6 @@
|
||||||
"@babel/helper-validator-identifier": "^7.9.0",
|
"@babel/helper-validator-identifier": "^7.9.0",
|
||||||
"lodash": "^4.17.13",
|
"lodash": "^4.17.13",
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@istanbuljs/load-nyc-config": {
|
"@istanbuljs/load-nyc-config": {
|
||||||
|
@ -397,6 +397,11 @@
|
||||||
"integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
|
"integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@jsdevtools/ono": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-pu5fxkbLQWzRbBgfFbZfHXz0KlYojOfVdUhcNfy9lef8ZhBt0pckGr8g7zv4vPX4Out5vBNvqd/az4UaVWzZ9A=="
|
||||||
|
},
|
||||||
"@types/caseless": {
|
"@types/caseless": {
|
||||||
"version": "0.12.2",
|
"version": "0.12.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
|
||||||
|
@ -576,12 +581,6 @@
|
||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
"path-is-absolute": "^1.0.0"
|
"path-is-absolute": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -665,7 +664,6 @@
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
|
@ -750,6 +748,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
|
||||||
"integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
|
"integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
|
||||||
},
|
},
|
||||||
|
"bath-es5": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bath-es5/-/bath-es5-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-PdCioDToH3t84lP40kUFCKWCOCH389Dl1kbC8FGoqOwamxsmqxxnJSXdkTOsPoNHXjem4+sJ+bbNoQm5zeCqxg=="
|
||||||
|
},
|
||||||
"bcrypt-pbkdf": {
|
"bcrypt-pbkdf": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||||
|
@ -893,6 +896,11 @@
|
||||||
"write-file-atomic": "^3.0.0"
|
"write-file-atomic": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"call-me-maybe": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms="
|
||||||
|
},
|
||||||
"callsite": {
|
"callsite": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||||
|
@ -1056,6 +1064,12 @@
|
||||||
"delayed-stream": "~1.0.0"
|
"delayed-stream": "~1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.20.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"commondir": {
|
"commondir": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||||
|
@ -1384,13 +1398,6 @@
|
||||||
"agentkeepalive": "^3.4.1",
|
"agentkeepalive": "^3.4.1",
|
||||||
"chalk": "^1.0.0",
|
"chalk": "^1.0.0",
|
||||||
"lodash": "^4.17.10"
|
"lodash": "^4.17.10"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
|
@ -1533,8 +1540,7 @@
|
||||||
"esprima": {
|
"esprima": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"etag": {
|
"etag": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
|
@ -2260,7 +2266,6 @@
|
||||||
"version": "3.13.1",
|
"version": "3.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^1.0.7",
|
"argparse": "^1.0.7",
|
||||||
"esprima": "^4.0.0"
|
"esprima": "^4.0.0"
|
||||||
|
@ -2306,6 +2311,16 @@
|
||||||
"resolved": "https://registry.npmjs.org/jsonminify/-/jsonminify-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsonminify/-/jsonminify-0.4.1.tgz",
|
||||||
"integrity": "sha1-gF2vuzk5UYjO6atYLIHvlZ1+cQw="
|
"integrity": "sha1-gF2vuzk5UYjO6atYLIHvlZ1+cQw="
|
||||||
},
|
},
|
||||||
|
"jsonschema": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-lz1nOH69GbsVHeVgEdvyavc/33oymY1AZwtePMiMj4HZPMbP5OIKK3zT9INMWjwua/V4Z4yq7wSlBbSG+g4AEw=="
|
||||||
|
},
|
||||||
|
"jsonschema-draft4": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonschema-draft4/-/jsonschema-draft4-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-8K8gBQVPDwrefqIRhhS2ncUS2GU="
|
||||||
|
},
|
||||||
"jsprim": {
|
"jsprim": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||||
|
@ -2393,9 +2408,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "1.3.1",
|
"version": "4.17.15",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||||
"integrity": "sha1-pGY7U2hriV/wdOK6UE37dqjit3A="
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||||
},
|
},
|
||||||
"lodash.assignin": {
|
"lodash.assignin": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
|
@ -2439,6 +2454,16 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
|
||||||
"integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
|
"integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM="
|
||||||
},
|
},
|
||||||
|
"lodash.get": {
|
||||||
|
"version": "4.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||||
|
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
|
||||||
|
},
|
||||||
|
"lodash.isequal": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
|
||||||
|
},
|
||||||
"lodash.isplainobject": {
|
"lodash.isplainobject": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||||
|
@ -2759,6 +2784,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mock-json-schema": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/mock-json-schema/-/mock-json-schema-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-ZqkT1hbATZrL79B/eOoe8oWesX8QaykFOaMb8hnGVeDZy2Iw1JOtObS8nC4UpFbAk1DpXRrj3zjv63hbhAPKiA==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.11",
|
||||||
|
"openapi-types": "^1.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
@ -6277,6 +6311,44 @@
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"openapi-backend": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/openapi-backend/-/openapi-backend-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-j6gDuSg6JCu7mi/MaaGFmmOMJD5lQMuKaFUfbFh6oSVKlqxlLCa9bmtzZxWcii/IYTOGeMVZW/0LLw07WNtddg==",
|
||||||
|
"requires": {
|
||||||
|
"ajv": "^6.10.0",
|
||||||
|
"bath-es5": "^3.0.3",
|
||||||
|
"cookie": "^0.4.0",
|
||||||
|
"lodash": "^4.17.15",
|
||||||
|
"mock-json-schema": "^1.0.5",
|
||||||
|
"openapi-schema-validation": "^0.4.2",
|
||||||
|
"openapi-types": "^1.3.4",
|
||||||
|
"qs": "^6.6.0",
|
||||||
|
"swagger-parser": "^9.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"openapi-schema-validation": {
|
||||||
|
"version": "0.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/openapi-schema-validation/-/openapi-schema-validation-0.4.2.tgz",
|
||||||
|
"integrity": "sha512-K8LqLpkUf2S04p2Nphq9L+3bGFh/kJypxIG2NVGKX0ffzT4NQI9HirhiY6Iurfej9lCu7y4Ndm4tv+lm86Ck7w==",
|
||||||
|
"requires": {
|
||||||
|
"jsonschema": "1.2.4",
|
||||||
|
"jsonschema-draft4": "^1.0.0",
|
||||||
|
"swagger-schema-official": "2.0.0-bab6bed"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"openapi-types": {
|
||||||
|
"version": "1.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-1.3.5.tgz",
|
||||||
|
"integrity": "sha512-11oi4zYorsgvg5yBarZplAqbpev5HkuVNPlZaPTknPDzAynq+lnJdXAmruGWP0s+dNYZS7bjM+xrTpJw7184Fg=="
|
||||||
|
},
|
||||||
"optional-js": {
|
"optional-js": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.1.1.tgz",
|
||||||
|
@ -6960,8 +7032,7 @@
|
||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"sqlstring": {
|
"sqlstring": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
|
@ -7174,8 +7245,28 @@
|
||||||
"integrity": "sha1-Sx/ul24RKE0nZXWRGYCyJY43nas=",
|
"integrity": "sha1-Sx/ul24RKE0nZXWRGYCyJY43nas=",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "1.3.1"
|
"lodash": "1.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-1.3.1.tgz",
|
||||||
|
"integrity": "sha1-pGY7U2hriV/wdOK6UE37dqjit3A="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"swagger-parser": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-oxOHUaeNetO9ChhTJm2fD+48DbGbLD09ZEOwPOWEqcW8J6zmjWxutXtSuOiXsoRgDWvORYlImbwM21Pn+EiuvQ==",
|
||||||
|
"requires": {
|
||||||
|
"@apidevtools/swagger-parser": "9.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"swagger-schema-official": {
|
||||||
|
"version": "2.0.0-bab6bed",
|
||||||
|
"resolved": "https://registry.npmjs.org/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz",
|
||||||
|
"integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0="
|
||||||
|
},
|
||||||
"tar-stream": {
|
"tar-stream": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
|
||||||
|
@ -7407,6 +7498,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
|
||||||
},
|
},
|
||||||
|
"validator": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg=="
|
||||||
|
},
|
||||||
"vargs": {
|
"vargs": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz",
|
||||||
|
@ -7451,12 +7547,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash": "^4.17.14"
|
"lodash": "^4.17.14"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -7650,12 +7740,6 @@
|
||||||
"wrap-ansi": "^5.1.0"
|
"wrap-ansi": "^5.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
|
||||||
"version": "4.17.15",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"string-width": {
|
"string-width": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||||
|
@ -7701,6 +7785,17 @@
|
||||||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||||
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
||||||
},
|
},
|
||||||
|
"z-schema": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/z-schema/-/z-schema-4.2.2.tgz",
|
||||||
|
"integrity": "sha512-7bGR7LohxSdlK1EOdvA/OHksvKGE4jTLSjd8dBj9YKT0S43N9pdMZ0Z7GZt9mHrBFhbNTRh3Ky6Eu2MHsPJe8g==",
|
||||||
|
"requires": {
|
||||||
|
"commander": "^2.7.1",
|
||||||
|
"lodash.get": "^4.4.2",
|
||||||
|
"lodash.isequal": "^4.5.0",
|
||||||
|
"validator": "^11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"zip-stream": {
|
"zip-stream": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz",
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
"nodeify": "^1.0.1",
|
"nodeify": "^1.0.1",
|
||||||
"npm": "6.14.3",
|
"npm": "6.14.3",
|
||||||
"object.values": "^1.0.4",
|
"object.values": "^1.0.4",
|
||||||
|
"openapi-backend": "^2.3.8",
|
||||||
"request": "2.88.0",
|
"request": "2.88.0",
|
||||||
"resolve": "1.1.7",
|
"resolve": "1.1.7",
|
||||||
"security": "1.0.0",
|
"security": "1.0.0",
|
||||||
|
|
Loading…
Reference in a new issue