airship-server
Version:
Airship is a framework for Node.JS & TypeScript that helps you to write big, scalable and maintainable API servers.
176 lines • 7.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const SourceCode_1 = require("../domain/SourceCode");
const CustomType_1 = require("../domain/types/CustomType");
const Utils_1 = require("./Utils");
const VectorType_1 = require("../domain/types/VectorType");
const IntBoolType_1 = require("../domain/types/IntBoolType");
const StringType_1 = require("../domain/types/StringType");
const NumberType_1 = require("../domain/types/NumberType");
const AnyType_1 = require("../domain/types/AnyType");
const BooleanType_1 = require("../domain/types/BooleanType");
class JavaScriptCodeGenerator {
generateClass(scheme) {
let code = new SourceCode_1.default();
let imports = this.generateImports(scheme);
let constructor = this.generateClassConstructor(scheme);
let deserializeMethod = this.generateDeserializeMethod(scheme);
let serializeMethod = this.generateSerializeMethod(scheme);
code.append(imports);
code.add('');
code.add(`class ${scheme.name} {`);
code.append(constructor, 1);
code.add('');
code.append(deserializeMethod, 1);
code.add('');
code.append(serializeMethod, 1);
code.add('}');
code.add('');
code.add(`module.exports = ${scheme.name}`);
return code;
}
generateApiMethod(scheme) {
throw new Error('Not implemented');
}
generateApiMethodParamsInterface(scheme) {
throw new Error('Not implemented');
}
generateImports(scheme) {
let code = new SourceCode_1.default();
scheme.fields.forEach((field, index) => {
let customType = this.getCustomType(field.type);
if (customType) {
code.add(`const ${customType.name} = require('./${customType.name}')`);
}
});
return code;
}
generateClassConstructor(scheme) {
let code = new SourceCode_1.default();
let jsdoc = this.generateClassConstructorJSDoc(scheme);
code.append(jsdoc);
code.add('constructor (');
scheme.fields.forEach((field, index) => {
let coma = this.genComa(scheme.fields, index);
code.add(`${Utils_1.toCamelCase(field.name)}${coma}`, 1);
});
code.add(') {');
scheme.fields.forEach((field, index) => {
code.add(`this.${Utils_1.toCamelCase(field.name)} = ${Utils_1.toCamelCase(field.name)}`, 1);
});
code.add('}');
return code;
}
generateClassConstructorJSDoc(scheme) {
let code = new SourceCode_1.default();
code.add('/**');
code.add(' * @class');
scheme.fields.forEach(field => {
code.add(` * @property {${this.renderType(field.type)}} ${Utils_1.toCamelCase(field.name)} ${field.description}`);
});
code.add(' */');
return code;
}
generateDeserializeMethod(scheme) {
let code = new SourceCode_1.default();
code.add('/**');
code.add(' * @param {Object} raw');
code.add(` * @returns {${scheme.name}}`);
code.add(' */');
code.add(`static deserialize(raw) {`);
code.add(`return new ${scheme.name} (`, 1);
scheme.fields.forEach((field, index) => {
let coma = this.genComa(scheme.fields, index);
let fieldVar = `raw['${field.name}']`;
if (field.type instanceof VectorType_1.default)
code.add(this.renderVectorDeserialize(fieldVar, field.type) + coma, 2);
else if (field.type instanceof CustomType_1.default)
code.add(`${fieldVar} ? ${field.type.name}.deserialize(${fieldVar}) : undefined${coma}`, 2);
else if (field.type instanceof IntBoolType_1.default)
code.add(`!!${fieldVar}${coma}`, 2);
else
code.add(fieldVar + coma, 2);
});
code.add(`)`, 1);
code.add('}');
return code;
}
generateSerializeMethod(scheme) {
let code = new SourceCode_1.default();
code.add('/**');
code.add(` * @returns {Object}`);
code.add(' */');
code.add(`serialize() {`);
code.add(`return {`, 1);
scheme.fields.forEach((field, index) => {
let coma = this.genComa(scheme.fields, index);
let fieldVar = `${field.name}: this.${Utils_1.toCamelCase(field.name)}`;
if (field.type instanceof VectorType_1.default)
code.add(`${field.name}: ${this.renderVectorSerialize(`this.${Utils_1.toCamelCase(field.name)}`, field.type) + coma}`, 2);
else if (field.type instanceof CustomType_1.default)
code.add(`${fieldVar} ? this.${Utils_1.toCamelCase(field.name)}.serialize() : undefined${coma}`, 2);
else
code.add(fieldVar + coma, 2);
});
code.add('}', 1);
code.add('}');
return code;
}
renderType(type, withoutUndefined = false) {
if (type instanceof StringType_1.default)
return 'string';
if (type instanceof NumberType_1.default)
return 'number';
if (type instanceof AnyType_1.default)
return 'any';
if (type instanceof BooleanType_1.default)
return 'boolean';
if (type instanceof IntBoolType_1.default)
return 'boolean';
if (type instanceof CustomType_1.default)
return type.name + `${!withoutUndefined ? '|undefined' : ''}`;
if (type instanceof VectorType_1.default) {
return this.renderType(type.item, true) + `[]${!withoutUndefined ? '|undefined' : ''}`;
}
throw new Error('UNSUPPORTED TYPE' + JSON.stringify(type));
}
genComa(list, index) {
return (index == list.length - 1) ? '' : ',';
}
renderVectorDeserialize(value, type) {
let code = '';
if (type instanceof VectorType_1.default)
code += `${value} ? ${value}.map(v => ${this.renderVectorDeserialize('v', type.item)}) : undefined`;
else if (type instanceof CustomType_1.default)
code += `${value} ? ${type.name}.deserialize(${value}) : undefined`;
else
code += value;
return code;
}
renderVectorSerialize(value, type) {
let code = '';
if (type instanceof VectorType_1.default)
code += `${value} ? ${value}.map(v => ${this.renderVectorSerialize('v', type.item)}) : undefined`;
else if (type instanceof CustomType_1.default)
code += `${value}.serialize()`;
else
code += value;
return code;
}
isCustomType(type) {
if (type instanceof CustomType_1.default)
return true;
if (type instanceof VectorType_1.default)
return this.isCustomType(type.item);
return false;
}
getCustomType(type) {
if (type instanceof VectorType_1.default)
return this.getCustomType(type.item);
if (type instanceof CustomType_1.default)
return type;
return null;
}
}
exports.default = JavaScriptCodeGenerator;
//# sourceMappingURL=JavaScriptCodeGenerator.js.map