Newer
Older
ServerGenerator / src / DataAccessGenerator.ts
import { Collection, Entity, Property } from "./types";
import { FileWrite } from "./server-generator";
import { modelModuleName } from "./ModelGenerator";

export function generateDataAccess(collections: Collection[]): FileWrite[] {
    return collections.map(generateDataAccessFile);
}

export function dataAccessModuleName(collection: Collection): string {
    return `${collection.name}DataAccess`;
}

function generateDataAccessFile(collection: Collection): FileWrite {
    const definitions: string[] = [
        defineImports(collection),
        defineSave(collection),
        defineParseEntity(collection.entities),
        defineParseCollection(collection),
        defineLoad(collection),
    ];

    return {
        location: dataAccessModuleName(collection) + ".ts",
        content: definitions.join("\n\n") + "\n",
    };
}

function defineImports(collection: Collection): string {
    const entity = collection.entities;
    return `/* eslint-disable @typescript-eslint/no-explicit-any */
import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}";
import * as fs from "fs";
import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`;
}

function defineSave(collection: Collection): string {
    return `export function save(fileName: string, collection: ${collection.name}): void {
    const content = JSON.stringify({ ...collection, $schema: "./${collection.name.toLowerCase()}.schema.json" });
    fs.writeFileSync(fileName, content);
}`;
}

function defineParseEntity(entity: Entity): string {
    const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n");
    return `function parse${entity.name}(data: any): ${entity.name}
{
    return {
        id: parsePrimitiveProperty<${entity.name}, number>("number", "id", 0, data),
${propParser}
    };
}`;
}

function parseStringProperty(entityName: string, property: Property): string {
    return `\t\t${property.key}: parsePrimitiveProperty<${entityName}, string>("string", "${property.key}", "", data),`;
}

function defineParseCollection(collection: Collection): string {
    return `function parse${collection.name}(data: any): ${collection.name} {
    return {
        nextId: parsePrimitiveProperty<${collection.name}, number>("number", "nextId", 1, data),
        items: parseArrayProperty<${collection.name}, ${collection.entities.name}>("items", parse${collection.entities.name}, data),
    };
}`;
}

function defineLoad(collection: Collection): string {
    return `export function load(fileName: string): ${collection.name} {
    if (!canReadFile(fileName)) {
        return {
            items: [],
            nextId: 1,
        };
    }
    const content = fs.readFileSync(fileName).toString();
    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const data = JSON.parse(content);
    return parse${collection.name}(data);
}`;
}