/** * @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(); } }; }