Newer
Older
ServerGenerator / src / server-generator.ts
#!/usr/bin/env node
import { Description } from "./types";
import { join } from "path";
import * as fs from "fs";
import { generateModel } from "./ModelGenerator";
import { generateDataAccess } from "./DataAccessGenerator";
import { generateOpenAPI } from "./OpenApiGenerator";
import { generateMiddlewares } from "./MiddlewareGenerator";
import { UtilCode } from "./UtilGenerator";
import { parseDescription } from "./input-parser";
import * as yargs from "yargs";

interface Options {
    typeScriptOutputFolder: string;
    openapiOutput: string;
}
export interface FileWrite {
    location: string;
    content: string;
}

/**
 * Central function, that contains all the (pure) logic.
 * @param options parameters for the generators
 * @param description The supplied data model description
 */
function generate(options: Options, description: Description): FileWrite[] {
    // generate model files
    const modelWrites = generateModel(description.collections);
    modelWrites.forEach(w => { w.location = join(options.typeScriptOutputFolder, w.location) });

    // generate data access files
    const dataAccessWrites = generateDataAccess(description.collections);
    dataAccessWrites.forEach(w => { w.location = join(options.typeScriptOutputFolder, w.location) });

    // generate openapi file
    const openapiDoc = generateOpenAPI(description);
    const openapiWrites: FileWrite = { location: options.openapiOutput, content: JSON.stringify(openapiDoc, null, "\t") };

    // generate middleware file
    const middlewareWrites = generateMiddlewares(description);
    middlewareWrites.forEach(w => { w.location = join(options.typeScriptOutputFolder, w.location) });

    const utilWrite: FileWrite = {
        location: join(options.typeScriptOutputFolder, "util.ts"),
        content: UtilCode,
    };

    // TODO create json schema file for the storage

    return [
        ...modelWrites,
        ...dataAccessWrites,
        ...middlewareWrites,
        openapiWrites,
        utilWrite,
    ];
}

function execute(options: Options, modelFile: string) {
    const modelContent = fs.readFileSync(join(__dirname, "..", "src", "characters.model.json")).toString();
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const rawModelObject = JSON.parse(modelContent);
    const modelResult = parseDescription(rawModelObject);
    if (!modelResult.isSuccessful) {
        console.error(modelResult.errorMessage);
        return;
    }
    const model: Description = modelResult.value;
    // const options: Options = {
    //     openapiOutput: join(__dirname, "..", "src", "TestOutput", "openapi.json"),
    //     typeScriptOutputFolder: join(__dirname, "..", "src", "TestOutput")
    // };
    const writes = generate(options, model);
    for (const write of writes) {
        fs.writeFileSync(write.location, write.content);
        console.log(`Written file '${write.location}'`)
    }
}

const inputArguments = yargs.option("typescript-output-folder", {
    type: "string",
    description: "Output folder for the generated server code.",
    demandOption: true,
}).option("openapi-output", {
    type: "string",
    description: "File name of the generated OpenAPI description.",
    demandOption: true,
}).argv;

const inputOptions: Options = {
    openapiOutput: inputArguments["openapi-output"],
    typeScriptOutputFolder: inputArguments["typescript-output-folder"],
};

execute(inputOptions, inputArguments._[0]);