UNPKG

airship-server

Version:

Airship is a framework for Node.JS & TypeScript that helps you to write big, scalable and maintainable API servers.

215 lines 9.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const SourceCode_1 = require("../domain/SourceCode"); 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"); const CustomType_1 = require("../domain/types/CustomType"); const VectorType_1 = require("../domain/types/VectorType"); const Utils_1 = require("./Utils"); const IntBoolType_1 = require("../domain/types/IntBoolType"); class TypescriptCodeGenerator { generateClass(scheme) { let code = new SourceCode_1.default(); let constructor = this.generateClassConstructor(scheme); let deserializeMethod = this.generateDeserializeMethod(scheme); let serializeMethod = this.generateSerializeMethod(scheme); code.add(`export class ${scheme.name} {`); code.append(constructor, 1); code.add(''); code.append(deserializeMethod, 1); code.add(''); code.append(serializeMethod, 1); code.add('}'); return code; } generateApiMethod(scheme) { let code = new SourceCode_1.default(); let methodName = Utils_1.toCamelCase(scheme.name, false, '.'); let propsName = `MethodsProps.${Utils_1.toCamelCase(scheme.name, true, '.')}Params`; let responseName = this.renderType(scheme.responseType, true); /** * Returns detailed information on users. * * * @param {{ * subview:string, * el:(number|Element) * }} params */ code.add(`/**`); code.add(` * ${scheme.description}`); code.add(' *'); code.add(' * @param {{'); scheme.params.forEach((param, index) => { let coma = this.genComa(scheme.params, index); code.add(` * ${Utils_1.toCamelCase(param.name)}: (${this.renderType(param.type, true)}${param.required ? '' : '|undefined'})${coma}`); }); code.add(' * }} params'); code.add(' *'); code.add(` * @returns {Promise<${responseName}>}`); code.add(` */`); code.add(`public async ${methodName}(params: ${propsName}): Promise<Responses.${responseName}> {`); code.add('return this.call(', 1); code.add(`'${scheme.name}',`, 2); code.add(`{`, 2); scheme.params.forEach((param, index) => { let coma = this.genComa(scheme.params, index); let fieldVar = `${param.name}: params.${param.name}`; if (param.type instanceof VectorType_1.default) code.add(`${param.name}: ${this.renderVectorSerialize(`params.${param.name}`, param.type) + coma}`, 3); else if (param.type instanceof CustomType_1.default) code.add(`${fieldVar} ? params.${param.name}.serialize() : undefined${coma}`, 3); else code.add(fieldVar + coma, 3); //code.add(`${param.name}: params.${toCamelCase(param.name)}${coma}`, 3) }); code.add(`},`, 2); code.add(`Responses.${responseName}`, 2); code.add(')', 1); code.add('}'); return code; } generateApiMethodParamsInterface(scheme) { let code = new SourceCode_1.default(); code.add(`export interface ${Utils_1.toCamelCase(scheme.name, true, '.')}Params {`); scheme.params.forEach((prop, index) => { let coma = this.genComa(scheme.params, index); let isCustom = this.isCustomType(prop.type); // code.add(`/**`, 1) // code.add(` * ${prop.description}`, 1) // code.add(` */`, 1) code.add(`${Utils_1.toCamelCase(prop.name)}${prop.required ? '' : '?'}: ${isCustom ? 'Models.' : ''}${this.renderType(prop.type, true)}${coma}`, 1); }); code.add('}'); 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(`readonly ${Utils_1.toCamelCase(field.name)}: ${this.renderType(field.type)}${coma}`, 1); }); code.add(') {'); code.add(''); code.add('}'); return code; } generateClassConstructorJSDoc(scheme) { let code = new SourceCode_1.default(); code.add('/**'); code.add(' * @class'); scheme.fields.forEach(field => { let type = this.removeNamespaceFromCustomType(field.type); code.add(` * @property {${this.renderType(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: any): ${scheme.name} {`); 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(`public serialize(): Object {`); code.add(`return {`, 1); scheme.fields.forEach((field, index) => { let coma = this.genComa(scheme.fields, index); let fieldVar = `${field.name}: this.${field.name}`; if (field.type instanceof VectorType_1.default) code.add(`${field.name}: ${this.renderVectorSerialize(`this.${field.name}`, field.type) + coma}`, 2); else if (field.type instanceof CustomType_1.default) code.add(`${fieldVar} ? this.${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: any) => ${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: any) => ${this.renderVectorSerialize('v', type.item)}) : undefined`; else if (type instanceof CustomType_1.default) code += `${value} ? ${value}.serialize() : undefined`; 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; } removeNamespaceFromCustomType(type) { if (type instanceof CustomType_1.default) return new CustomType_1.default(type.name.replace('Models.', '')); if (type instanceof VectorType_1.default) return new VectorType_1.default(this.removeNamespaceFromCustomType(type.item)); return type; } } exports.default = TypescriptCodeGenerator; //# sourceMappingURL=TypescriptCodeGenerator.js.map