UNPKG

one-schema

Version:
119 lines (107 loc) 4.46 kB
import { IFieldValidatorSerialized } from "../../types/core"; const PRIMITIVE_TYPE_MAP_REQUIRED: {[key: string]: string} = { string: 'string', int32: 'int32', float64: 'double', bool: 'bool', }; const PRIMITIVE_TYPE_MAP_NOT_REQUIRED: {[key: string]: string} = { string: 'google.protobuf.StringValue', int32: 'google.protobuf.Int32Value', float64: 'google.protobuf.DoubleValue', bool: 'google.protobuf.BoolValue', }; const INDENT_TAB = ' '; function primitiveFVToProtobuf(fieldValidator: IFieldValidatorSerialized, fieldName: string) { const isFVRequired = fieldValidator.settings.required; const fvType = fieldValidator.settings.type; if(!fvType){ throw new Error("Field Validator is missing type!"); } if (isFVRequired) { if (PRIMITIVE_TYPE_MAP_REQUIRED.hasOwnProperty(fvType)) { return `${PRIMITIVE_TYPE_MAP_REQUIRED[fvType]} ${fieldName}`; } } else if (PRIMITIVE_TYPE_MAP_NOT_REQUIRED.hasOwnProperty(fvType)) { return `${PRIMITIVE_TYPE_MAP_NOT_REQUIRED[fvType]} ${fieldName}`; } throw new Error(`Unsupported primitive type ${fieldValidator.settings.type}!`); } function fvObjectToProtobuf(fieldValidator: IFieldValidatorSerialized, objectTypeName: string, indentAmount: string) { const outerIndent = indentAmount || ''; const defs: string[] = []; if (fieldValidator.settings.type !== 'object') { throw new Error('Must be object to be schema!'); } const { schema } = fieldValidator.settings; if(!schema){ throw new Error("Object field validator must have a schema to convert it to a protobuf!"); } const innerIndent = outerIndent + INDENT_TAB; Object.keys(schema).forEach((k, ind) => { const fld = schema[k]; if (fld.settings.type === 'object') { const nObjName = `${objectTypeName}_${k}`; defs.push(fvObjectToProtobuf(fld, nObjName, outerIndent + INDENT_TAB)); defs.push(`${innerIndent}${nObjName} ${k} = ${ind + 1};`); } else if (fld.settings.type === 'array') { if(!fld.settings.arrayOf){ throw new Error("Array fields must have an arrayOf schema defined!"); } if (!fld.settings.required) { throw new Error("Array fields must be 'required()' in order to convert them into protobufs!"); } if (fld.settings.arrayOf.settings.type === 'object') { const arrObjName = `${objectTypeName}_${k}`; defs.push(fvObjectToProtobuf(fld.settings.arrayOf, arrObjName, outerIndent + INDENT_TAB)); defs.push(`${innerIndent}repeated ${arrObjName} ${k} = ${ind + 1};`); } else if (fld.settings.arrayOf.settings.type === 'array') { throw new Error('Arrays of arrays are not allowed in protobufs!'); } else { defs.push(`${innerIndent}repeated ${primitiveFVToProtobuf(fld.settings.arrayOf, k)} = ${ind + 1};`); } } else { defs.push(`${innerIndent}${primitiveFVToProtobuf(fld, k)} = ${ind + 1};`); } }); return `${indentAmount}message ${objectTypeName} {\n${defs.join('\n')}\n${indentAmount}}`; } interface ISchemaToProtobufOutput { definitions: string; typeString: string; } function fvSchemaToProtobuf(fieldValidator: IFieldValidatorSerialized, objectTypeName: string): ISchemaToProtobufOutput { if (fieldValidator.settings.type === 'object') { return { definitions: fvObjectToProtobuf(fieldValidator, objectTypeName, ''), typeString: objectTypeName, }; } else if (fieldValidator.settings.type === 'array') { if(!fieldValidator.settings.arrayOf){ throw new Error("") } const childType = fieldValidator.settings.arrayOf.settings.type; if (childType === 'array') { throw new Error('Arrays of arrays are not allowed in protobufs!'); } else if (childType === 'object') { const childPbResult = fvSchemaToProtobuf(fieldValidator.settings.arrayOf, objectTypeName); return { definitions: childPbResult.definitions, typeString: `repeated ${objectTypeName}`, }; } else { return { definitions: '', typeString: `repeated ${primitiveFVToProtobuf(fieldValidator.settings.arrayOf, '').trim()}`, }; } } else { return { definitions: '', typeString: primitiveFVToProtobuf(fieldValidator, '').trim(), }; } } export function generateProtobuf(fieldValidator: IFieldValidatorSerialized, objectTypeName: string): ISchemaToProtobufOutput { return fvSchemaToProtobuf(fieldValidator, objectTypeName); }