one-schema
Version:
one-schema object validator
119 lines (107 loc) • 4.46 kB
text/typescript
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);
}