Newer
Older
ServerGenerator / src / ExampleOutput / DataAccess.ts
@peter peter on 12 Sep 2020 2 KB Added create operation.
import { Graph, GraphNode } from "./Model";
import * as fs from "fs";

type GraphStorage = Graph & { $schema: string; };


export function save(fileName: string, graph: Graph): void {
    const content = JSON.stringify(prepareForWrite(graph));
    fs.writeFileSync(fileName, content);
}

function prepareForWrite(graph: Graph): GraphStorage {
    return { ...graph, $schema: "./graph.schema.json" }
}

function parseGraph(data: any): Graph {
    return {
        nextId: parsePrimitiveProperty<Graph, number>("number", "nextId", 1, data),
        nodes: parseArrayProperty<Graph, GraphNode>("nodes", parseGraphNode, data),
    };
}

function parseGraphNode(data: any): GraphNode
{
    return {
        id: parsePrimitiveProperty<GraphNode, number>("number", "id", 0, data),
        name: parsePrimitiveProperty<GraphNode, string>("string", "name", "", data),
        description: parsePrimitiveProperty<GraphNode, string>("string", "description", "", data),
    };
}

function parseArrayProperty<O, T>(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[]
{
    if(fieldName in data)
    {
        const valueList = data[fieldName];
        if(Array.isArray(valueList))
        {
            return valueList.map(itemParser);
        }
    }
    return [];
}

export function parsePrimitiveProperty<O, T = string | number>(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T
{
    if(fieldName in obj)
    {
        const fieldValue = obj[fieldName];
        if(typeof fieldValue === type)
        {
            return fieldValue;
        }
    }
    return defaultValue;
}



function canReadFile(path: string): boolean {
    try {
        fs.accessSync(path, fs.constants.R_OK);
        return true;
    } catch (error) {
        return false;
    }
}

const emptyGraph: () => Graph = () =>
    ({
        nodes: [],
        nextId: 1,
    });

export function load(fileName: string): Graph {
    if (!canReadFile(fileName)) {
        return emptyGraph();
    }
    const content = fs.readFileSync(fileName).toString();
    const data = JSON.parse(content);
    return parseGraph(data);
}