Newer
Older
ServerGenerator / src / UtilGenerator.ts
export const UtilCode = `export interface Ok<T> {
    isSuccessful: true;
    value: T;
}

export interface Err {
    isSuccessful: false;
    errorMessage: string;
}

export type Result<T> = Ok<T> | Err;

export const andThen = <T, R>(fn: (a: T) => Result<R>) => (result: Result<T>) => {
    if (result.isSuccessful) {
        return fn(result.value);
    }
    else {
        return result;
    }
}

export function parseNotNull(data: any): Result<any> {
    if (data == null) return { isSuccessful: false, errorMessage: "Input is null." };
    else return { isSuccessful: true, value: data };
}

export function parseObject(data: any): Result<object> {
    if (typeof data === "object") return { isSuccessful: true, value: data };
    else return { isSuccessful: false, errorMessage: "Input is not an object." };
}

export const parseRequiredMember = <T>(fieldName: keyof T) => (data: any): Result<any> => {
    if (fieldName in data) {
        return { isSuccessful: true, value: data[fieldName] };
    }
    else {
        return { isSuccessful: false, errorMessage: \`Required member "\${fieldName}" could not be found.\` };
    }
}

export const parseNullableMember = <T>(fieldName: keyof T) => (data: any): Result<any> => {
    if (fieldName in data) {
        return { isSuccessful: true, value: data[fieldName] };
    }
    else {
        return { isSuccessful: true, value: null };
    }
}

export function parseString(data: any): Result<string> {
    if (data == null || typeof data === "string") return { isSuccessful: true, value: data };
    else return { isSuccessful: false, errorMessage: "Value is not a string." };
}

export type ParseObject<T extends {}> = {
    [P in keyof T]: Result<T[P]>
};

export function compose<R, S, T>(first: (obj:R) => Result<S>, second: (obj: S) => Result<T>): (obj:R) => Result<T> {
    return (obj:R): Result<T> => {
        const firstResult = first(obj);
        if(!firstResult.isSuccessful) return firstResult;
        return second(firstResult.value);
    };
}

export function resolve<T extends {}>(members: ParseObject<T>): Result<T> {
    const obj: Partial<T> = {};
    for (const key in members) {
        if (Object.prototype.hasOwnProperty.call(members, key)) {
            const member: Result<T[Extract<keyof T, string>]> = members[key];
            if (!member.isSuccessful) {
                return member;
            }
            obj[key] = member.value;
        }
    }
    return { isSuccessful: true, value: (obj as T) };
}
`;