All files / generator compiler.ts

100% Statements 49/49
96.15% Branches 25/26
100% Functions 8/8
100% Lines 48/48

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116    1x 1x   1x   1x 15x               15x 7x         7x   8x         8x 8x 4x         15x     1x 57x 57x 104x   104x 67x     104x 16x 16x 88x 14x 14x 14x 10x     74x         1x   74x             74x 74x     74x     1x 16x       16x 14x           16x     1x 14x               1x 104x 104x 32x 18x   14x     72x     1x
import { AbstractSyntaxTreeModel } from './models/abstract-syntax-tree.model';
import { Draf7SchemaModel } from './models/schema.model';
import { ValueTypeEnum } from './enums/value-type.enum';
import { Utils } from './utils';
 
export class Compiler {
 
    public static compile(tree: AbstractSyntaxTreeModel): Draf7SchemaModel {
        let schema = <Draf7SchemaModel>{
            '$id': 'http://example.com/example.json',
            '$schema': 'http://json-schema.org/draft-07/schema#',
            type: tree.type,
            definitions: {},
            description: 'root of schema'
        };
 
        if (tree.type === ValueTypeEnum.OBJECT) {
            schema = {
                ...schema,
                properties: {},
                required: []
            };
            Compiler.compileChild(tree, schema.properties, schema);
        } else {
            schema = {
                ...schema,
                uniqueItems: tree.uniqueItems,
                items: []
            };
            Compiler.compileChild(tree, schema.items, schema);
            if (Object.keys(schema.items).length === 1) {
                schema.items = schema.items[0];
            }
        }
 
 
        return schema;
    }
 
    public static compileChild(tree: any, properties: any, parentSchema: Draf7SchemaModel) {
        const keys = Object.keys(tree.children);
        keys.forEach((k) => {
            const child = tree.children[k];
 
            if (child.required && parentSchema.required) {
                parentSchema.required.push(k);
            }
 
            if (child.type === ValueTypeEnum.OBJECT) {
                properties[k] = Compiler.getObjectPart(Compiler.getId(parentSchema, k, keys.length), child);
                Compiler.compileChild(child, properties[k].properties, properties[k]);
            } else if (child.type === ValueTypeEnum.ARRAY) {
                properties[k] = Compiler.getArrayPart(Compiler.getId(parentSchema, k, keys.length), child);
                Compiler.compileChild(child, properties[k].items, properties[k]);
                if (Object.keys(properties[k].items).length === 1) {
                    properties[k].items = properties[k].items[0];
                }
            } else {
                properties[k] = Compiler.getPimitivePart(Compiler.getId(parentSchema, k, keys.length), child, k);
            }
        })
    }
 
    private static getPimitivePart(id: string, child: AbstractSyntaxTreeModel, k: string): Draf7SchemaModel {
        // TODO : Manage all options
        const result = <Draf7SchemaModel> {
            '$id': id,
            type: child.type,
            title: `The ${k} Schema `,
            default: Utils.getDefaultValue(child.type)
        };
 
        Eif (child.values && child.values.length > 0) {
            result.examples = [...child.values];
        }
 
        return result;
    }
 
    private static getObjectPart(id: string, child: AbstractSyntaxTreeModel): Draf7SchemaModel {
        let schema = <Draf7SchemaModel> {
            '$id': id,
            type: child.type
        };
        if (Object.keys(child.children).length > 0) {
            schema = {
                ...schema,
                properties: {},
                required: []
            };
        }
        return schema;
    }
 
    private static getArrayPart(id: string, child: AbstractSyntaxTreeModel): Draf7SchemaModel {
        return <Draf7SchemaModel> {
            '$id': id,
            type: child.type,
            uniqueItems: child.uniqueItems,
            items: []
        };
    }
 
    private static getId(parentSchema: Draf7SchemaModel, key: string, length: number): string {
        const parentId = parentSchema.$id[0] === '/' ? parentSchema.$id : '';
        if (parentSchema.type === ValueTypeEnum.ARRAY) {
            if (length > 1) {
                return `${parentId}/items/${key}`;
            }else {
                return`${parentId}/items`;
            }
        } else {
            return `${parentId}/properties/${key}`;
        }
    }
}