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; }