nope/lib/open-api/startOpenApiBackend.ts
2021-08-04 18:17:23 +02:00

120 lines
3.2 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-11-12 11:21:41
* @modify date 2021-08-04 17:19:12
* @desc [description]
*/
import * as bodyParser from "body-parser";
import * as cors from "cors";
import * as express from "express";
import { initialize } from "express-openapi";
import { readFile } from "fs/promises";
import { ILogger } from "js-logger";
import { assignIn } from "lodash";
import { join } from "path";
import "reflect-metadata";
import { INopeDispatcher } from "../types/nope/nopeDispatcher.interface";
import { getBackendAccesors } from "./getBackendAccessors";
/**
* Function to generate the Base Api Documentation
* @param title The Title of the API
* @param version The Version
* @param basePath A Basepath for the API
*/
function _genApiDoc(title: string, version: string, basePath: string, definitions: any = {}) {
// Default API Doc
const apiDoc = {
swagger: "2.0",
basePath: basePath || "/v1",
info: {
title,
version
},
definitions,
paths: {}
};
return apiDoc;
}
/**
* Function to start a Open-API-Server
* @param _dispatcher The Dispatcher, which should be used.
* @param options Options for the Server
*/
export async function startOpenApiBackend(
_dispatcher: INopeDispatcher,
options: {
port?: number,
backendPort?: number,
basePath?: string,
logger?: ILogger,
} = {}) {
const app: express.Application = (express as any)();
// Define the Default Options
const defaults = {
port: 3001,
backendPort: 3002,
basePath: "/api"
};
// Mix the Options.
const opts = assignIn(defaults, options);
app.use(bodyParser.json());
app.use(cors());
let _definition = {};
try {
// Extract the Elements provided in the API-Document.
_definition = JSON.parse(await readFile(join(__dirname, "apidoc.json"), {
encoding: "utf8"
})).definitions;
} catch (e) {
if (opts.logger) {
opts.logger.error("cant parse apidoc.json");
}
}
initialize({
apiDoc: _genApiDoc("Backend API", "1.0.0", opts.basePath, _definition),
app,
paths: "./dist/open-api",
routesGlob: "**/*.{ts,js}",
routesIndexFileRegExp: /(?:index)?\.[tj]s$/,
dependencies: {
_dispatcher
},
});
app.use(((err, req, res, next) => {
res.status(err.status).json(err);
}) as express.ErrorRequestHandler);
const server = app.listen(opts.port);
const accessor = getBackendAccesors(app);
if (options.logger) {
options.logger.info("Server Running on http://localhost:" + opts.port.toString() + opts.basePath);
options.logger.info("API Documentation available on http://localhost:" + opts.port.toString() + opts.basePath + "/api-docs");
options.logger.debug("Checkout http://localhost:3000/docs");
}
return {
app,
// Accessor for the Server
accessor,
// Function to extract the Definitions.
definitionUri: opts.basePath + "/api-docs",
// Function to Close the Server
close() {
server.close();
}
};
}