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

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

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

function generateModelFile(collection: Collection): FileWrite
{
    const fileName = modelModuleName(collection) + ".ts";
    const definitions: string[] = [
        defineCollection(collection),
        defineEntity(collection.entities),
        definePayload(collection),
        defineFindFunction(collection),
        defineAppendFunction(collection),
        defineRemoveFunction(collection),
    ];
    return {
        location: fileName,
        content: definitions.join("\n\n") + "\n",
    };
}

function defineCollection(collection: Collection): string {
    return `export interface ${collection.name} {
    items: ${collection.entities.name}[];
    nextId: number;
}`;
}

function defineEntity(entity: Entity): string
{
    const propDefinitions = entity.properties.map(p => `\t${p.key}: ${p.type};`).join("\n");
    return `export interface ${entity.name}Input {
${propDefinitions}
}

export interface ${entity.name} extends ${entity.name}Input {
    id: number;
}`;
}

function definePayload(collection: Collection): string {
    const entity = collection.entities;
    return `export interface ${entity.name}Payload extends ${entity.name} {
    ref: string;
}

export function toPayload(item: ${entity.name}): ${entity.name}Payload {
    return {
        ...item,
        ref: \`${collectionRoute(collection)}/\${item.id}\`,
    }
}`;
}

function defineFindFunction(collection: Collection): string {
    return `export function findSingle(collection: ${collection.name}, id: number) {
    return collection.items.find(n => n.id === id);
}`;
}

function defineAppendFunction(collection: Collection): string {
    return `export function append(collection: ${collection.name}, item: ${collection.entities.name}Input): ${collection.entities.name} {
    const newItem: ${collection.entities.name} = {...item, id: collection.nextId};
    collection.nextId++;
    collection.items.push(newItem);
    return newItem;
}`;
}

function defineRemoveFunction(collection: Collection): string {
    return `export function remove(collection: ${collection.name}, id: number): void {
    const index = collection.items.findIndex(i => i.id === id);
    if(index === -1) return;
    collection.items.splice(index, 1);
}`;
}