Newer
Older
ServerGenerator / src / ExampleOutput / Middleware.ts
@peter peter on 19 Sep 2020 3 KB Updated code to satisfy eslint.
import express from "express";
import * as DataAccess from "./DataAccess";
import { append, findSingle, GraphNodeInput, remove, toPayload } from "./Model";
import { andThen, compose, parseNotNull, ParseObject, parseObject, parseRequiredMember, parseString, resolve, Result } from "./util";


const parseName = andThen(compose(parseRequiredMember<GraphNodeInput>("name"), parseString));
const parseDescription = andThen(compose(parseRequiredMember<GraphNodeInput>("description"), parseString));

function parseGraphNodeInput(data: unknown): Result<GraphNodeInput> {
    const obj = andThen(parseObject)(parseNotNull(data));
    const members: ParseObject<GraphNodeInput> = {
        name: parseName(obj),
        description: parseDescription(obj),
    };
    return resolve(members);
}

export function graphMiddleware({ fileName }: { fileName: string }) {
    const graph = DataAccess.load(fileName);

    const route = express.Router();

    // TODO post/delete single entity
    route.get("/nodes/:id(\\d+)", (req, res) => {
        const id = Number.parseInt(req.params.id, undefined);
        const node = findSingle(graph, id);
        if (node == null) {
            res.status(404).send("not found");
            return;
        }
        res.send(toPayload(node));
    });

    route.post("/nodes/:id(\\d+)", (req, res) => {
        const id = Number.parseInt(req.params.id, undefined);
        const existingItem = findSingle(graph, id);
        const parsed = parseGraphNodeInput(req.body);
        if(!parsed.isSuccessful) {
            res.status(400).send(parsed.errorMessage);
            return;
        }
        const inputItem = parsed.value;
        if(existingItem == null) {
            res.status(404).send("Not found");
            return;
        }
        else {
            // update
            existingItem.name = inputItem.name;
            existingItem.description = inputItem.description;
            DataAccess.save(fileName, graph);
            const payload = toPayload(existingItem);
            res.status(200).send(payload);
            return;
        }
    });

    route.delete("/nodes/:id(\\d+)", (req, res) => {
        const id = Number.parseInt(req.params.id, undefined);
        remove(graph, id);
        DataAccess.save(fileName, graph);
        res.status(204).send();
    });

    route.get("/nodes", (req, res) => {
        const nodes = graph.nodes;
        res.send(nodes.map(toPayload));
    });

    route.post("/nodes", (req, res) => {
        try {
            const parsed = parseGraphNodeInput(req.body);
            if(!parsed.isSuccessful) {
                res.status(400).send(parsed.errorMessage);
                return;
            }
            const item = parsed.value;
            const added = append(graph, item);
            DataAccess.save(fileName, graph);
            const payload = toPayload(added);
            res.status(201).send(payload);
        } catch (error) {
            console.error(error);
            res.status(500).send("Internal Server Error.");
            return;
        }
    });

    return route;
}