fix(core): update
This commit is contained in:
1
ts/index.ts
Normal file
1
ts/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './smartswagger.classes.smartswagger';
|
231
ts/smartswagger.classes.smartswagger.ts
Normal file
231
ts/smartswagger.classes.smartswagger.ts
Normal file
@ -0,0 +1,231 @@
|
||||
import path from 'path';
|
||||
import * as plugins from './smartswagger.plugins';
|
||||
|
||||
interface RedocProps {
|
||||
'x-tagGroups': any;
|
||||
}
|
||||
type IExtendedApiDoc = plugins.openapiTypes.OpenAPIV3.Document & RedocProps;
|
||||
|
||||
export class Smartswagger {
|
||||
// STATIC
|
||||
/**
|
||||
*
|
||||
* @param urlArg a url arg that contains an original swagger.json in the response
|
||||
* @returns an instance of
|
||||
*/
|
||||
public static async createFromUrl(urlArg: string) {
|
||||
const jsonResponse = await plugins.nodeFetch(urlArg, {
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
});
|
||||
const apiDoc = await jsonResponse.json();
|
||||
const newSMartswaggerInstance = new Smartswagger(apiDoc);
|
||||
return newSMartswaggerInstance;
|
||||
}
|
||||
|
||||
// INSTANCE
|
||||
/**
|
||||
* the basic info of the api doc
|
||||
*/
|
||||
public baseInfo: plugins.openapiTypes.OpenAPIV3.InfoObject;
|
||||
|
||||
public apiDoc: IExtendedApiDoc;
|
||||
|
||||
constructor(apiDocArg: IExtendedApiDoc) {
|
||||
this.apiDoc = apiDocArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* dereferences the document at hand
|
||||
*/
|
||||
public async deref() {
|
||||
this.apiDoc = (await plugins.swaggerParser.dereference(
|
||||
this.apiDoc
|
||||
)) as IExtendedApiDoc;
|
||||
}
|
||||
|
||||
public async addServer(serverArg: plugins.openapiTypes.OpenAPIV3.ServerObject) {
|
||||
await this.deref();
|
||||
this.apiDoc.servers = this.apiDoc.servers || [];
|
||||
this.apiDoc.servers.push(serverArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* merge a document from url
|
||||
* @param documentToMergeArg
|
||||
* @param basePathArg
|
||||
*/
|
||||
public async mergeDocument(
|
||||
documentToMergeArg: IExtendedApiDoc,
|
||||
basePathArg: string
|
||||
) {
|
||||
console.log(`merging document with name ${documentToMergeArg.info?.title}`);
|
||||
await this.deref();
|
||||
// lets get a dereferenced version of the document we want to merge
|
||||
const documentToMerge = (await plugins.swaggerParser.dereference(
|
||||
documentToMergeArg
|
||||
)) as IExtendedApiDoc;
|
||||
for (const path of Object.keys(documentToMerge.paths)) {
|
||||
const pathToMerge = plugins.path.join(basePathArg, path);
|
||||
this.apiDoc.paths = this.apiDoc.paths || {};
|
||||
this.apiDoc.paths[pathToMerge] = documentToMerge.paths[path];
|
||||
}
|
||||
|
||||
// merge tag groups
|
||||
this.apiDoc['x-tagGroups'] = this.apiDoc['x-tagGroups'] || [];
|
||||
if (documentToMerge['x-tagGroups']) {
|
||||
for (const xTagGroup of documentToMerge['x-tagGroups']) {
|
||||
this.apiDoc['x-tagGroups'].push(xTagGroup);
|
||||
}
|
||||
}
|
||||
console.log('merged!');
|
||||
}
|
||||
|
||||
/**
|
||||
* merges a document from url
|
||||
*/
|
||||
public async mergeDocumentFromUrl(documentUrlArg: string, basePathArg: string) {
|
||||
console.log(`getting document at ${documentUrlArg} for merging...`)
|
||||
const documentResponse = await plugins.nodeFetch(documentUrlArg, {
|
||||
headers: {
|
||||
'accept-encoding': 'application/json',
|
||||
},
|
||||
});
|
||||
const documentString = await documentResponse.text();
|
||||
const apiDoc: IExtendedApiDoc = JSON.parse(documentString);
|
||||
console.log(`document successfully fetched!`);
|
||||
await this.mergeDocument(apiDoc, basePathArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* merges a component to routes based on regex
|
||||
*/
|
||||
public mergeComponentToRoutes(
|
||||
routeDescriptor: {
|
||||
includeRegexpArray: RegExp[];
|
||||
excludeRegexpArray: RegExp[];
|
||||
},
|
||||
componentArg: plugins.openapiTypes.OpenAPIV3.ComponentsObject
|
||||
) {
|
||||
for (const pathCandidateRoute of Object.keys(this.apiDoc.paths)) {
|
||||
let included: boolean = false;
|
||||
let excluded: boolean = false;
|
||||
for (const regExp of routeDescriptor.includeRegexpArray) {
|
||||
if (regExp.test(pathCandidateRoute)) {
|
||||
included = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (included) {
|
||||
for (const regExp of routeDescriptor.excludeRegexpArray) {
|
||||
if (regExp.test(pathCandidateRoute)) {
|
||||
excluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (included && !excluded) {
|
||||
// lets do the actual component inclusion
|
||||
const pathCandidate = this.apiDoc.paths[pathCandidateRoute];
|
||||
const instrumentMethod = (methodArg: typeof pathCandidate.get) => {
|
||||
if (!methodArg) {
|
||||
return;
|
||||
}
|
||||
if (componentArg.securitySchemes) {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private cacheResult: string = '';
|
||||
private cacheCreationUnixTimestamp: number;
|
||||
|
||||
/**
|
||||
* returns an express middleware using 'swagger-ui-express'
|
||||
*/
|
||||
public getSlashApiUiMiddleware() {
|
||||
return (req: plugins.smartexpress.Request, res: plugins.smartexpress.Response) => {
|
||||
res.setHeader('content-type', 'text/html');
|
||||
res.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>${this.apiDoc.info?.title || 'no name set'} - SwaggerUI</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui.css">
|
||||
<style>
|
||||
body {
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
</body>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui-standalone-preset.js"></script>
|
||||
<script src="https://unpkg.com/swagger-ui-dist@3.12.1/swagger-ui-bundle.js"></script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Build a system
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/apischema",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
})
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
`);
|
||||
res.end();
|
||||
};
|
||||
}
|
||||
|
||||
public getSlashRedocMiddleware() {
|
||||
return (req: plugins.smartexpress.Request, res: plugins.smartexpress.Response) => {
|
||||
res.setHeader('content-type', 'text/html');
|
||||
res.write(`
|
||||
<html>
|
||||
<head>
|
||||
<title>${this.apiDoc.info?.title || 'no name set'} - Redoc </title>
|
||||
<!-- needed for adaptive design -->
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||
|
||||
<!--
|
||||
Redoc doesn't change outer page styles
|
||||
-->
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<redoc spec-url='/apischema'></redoc>
|
||||
<script src="https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
res.end();
|
||||
};
|
||||
}
|
||||
|
||||
public getSlashApiSchemaMiddleware() {
|
||||
return async (req: plugins.smartexpress.Request, res: plugins.smartexpress.Response) => {
|
||||
res.header('content-type', 'application/json');
|
||||
res.write(JSON.stringify(this.apiDoc));
|
||||
res.end();
|
||||
};
|
||||
}
|
||||
}
|
26
ts/smartswagger.plugins.ts
Normal file
26
ts/smartswagger.plugins.ts
Normal file
@ -0,0 +1,26 @@
|
||||
// node native
|
||||
import * as path from 'path';
|
||||
|
||||
export {
|
||||
path
|
||||
}
|
||||
|
||||
// @pushrocks scope
|
||||
import * as smartexpress from '@pushrocks/smartexpress';
|
||||
import * as smartpromise from '@pushrocks/smartpromise';
|
||||
|
||||
export {
|
||||
smartexpress,
|
||||
smartpromise
|
||||
}
|
||||
|
||||
// third party
|
||||
import * as openapiTypes from 'openapi-types';
|
||||
import swaggerParser from '@apidevtools/swagger-parser';
|
||||
import nodeFetch from 'node-fetch';
|
||||
|
||||
export {
|
||||
openapiTypes,
|
||||
swaggerParser,
|
||||
nodeFetch
|
||||
}
|
Reference in New Issue
Block a user