Added support for TypeScript generation for AngularJS and Node.js

This commit is contained in:
Martin Hardorf
2015-06-16 10:44:05 +02:00
parent eaf5a371ff
commit f87bb12ebb
8 changed files with 404 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
package io.swagger.codegen.languages;
import java.io.File;
import io.swagger.codegen.SupportingFile;
public class TypeScriptAngularClientCodegen extends TypeScriptNodeClientCodegen {
@Override
public String getName() {
return "typescript-angular";
}
public TypeScriptAngularClientCodegen() {
super();
outputFolder = "generated-code/typescript-angular";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-Angular";
apiPackage = "api";
modelPackage = "api";
supportingFiles.add(new SupportingFile("api.d.mustache", apiPackage + File.separator, "api.d.ts"));
}
}

View File

@@ -0,0 +1,169 @@
package io.swagger.codegen.languages;
import io.swagger.codegen.*;
import io.swagger.models.properties.*;
import java.util.*;
import java.io.File;
public class TypeScriptNodeClientCodegen extends DefaultCodegen implements CodegenConfig {
protected String invokerPackage = "io.swagger.client";
protected String groupId = "io.swagger";
protected String artifactId = "swagger-typescript-node-client";
protected String artifactVersion = "1.0.0";
protected String sourceFolder = "src/main/typescript";
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "typescript-node";
}
@Override
public String getHelp() {
return "Generates a TypeScript nodejs client library.";
}
public TypeScriptNodeClientCodegen() {
super();
outputFolder = "generated-code/typescript-node";
modelTemplateFiles.put("model.mustache", ".ts");
apiTemplateFiles.put("api.mustache", ".ts");
templateDir = "TypeScript-node";
apiPackage = "api";
modelPackage = "model";
reservedWords = new HashSet<String>(Arrays.asList("abstract",
"continue", "for", "new", "switch", "assert", "default", "if",
"package", "synchronized", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws", "case", "enum",
"instanceof", "return", "transient", "catch", "extends", "int",
"short", "try", "char", "final", "interface", "static", "void",
"class", "finally", "const", "super", "while"));
additionalProperties.put("invokerPackage", invokerPackage);
additionalProperties.put("groupId", groupId);
additionalProperties.put("artifactId", artifactId);
additionalProperties.put("artifactVersion", artifactVersion);
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float",
"Object"));
instantiationTypes.put("array", "Array");
typeMapping = new HashMap<String, String>();
typeMapping.put("Array", "Array");
typeMapping.put("array", "Array");
typeMapping.put("List", "Array");
typeMapping.put("boolean", "boolean");
typeMapping.put("string", "string");
typeMapping.put("int", "number");
typeMapping.put("float", "number");
typeMapping.put("number", "number");
typeMapping.put("long", "number");
typeMapping.put("short", "number");
typeMapping.put("char", "string");
typeMapping.put("double", "number");
typeMapping.put("object", "any");
typeMapping.put("integer", "number");
}
@Override
public String escapeReservedWord(String name) {
return "_" + name;
}
@Override
public String apiFileFolder() {
return outputFolder + "/" + apiPackage().replace('.', File.separatorChar);
}
public String modelFileFolder() {
return outputFolder + "/" + modelPackage().replace('.', File.separatorChar);
}
@Override
public String toVarName(String name) {
// replace - with _ e.g. created-at => created_at
name = name.replaceAll("-", "_");
// if it's all uppper case, do nothing
if (name.matches("^[A-Z_]*$"))
return name;
// camelize the variable name
// pet_id => PetId
name = camelize(name, true);
// for reserved word or word starting with number, append _
if (reservedWords.contains(name) || name.matches("^\\d.*"))
name = escapeReservedWord(name);
return name;
}
@Override
public String toParamName(String name) {
// should be the same as variable name
return toVarName(name);
}
@Override
public String toModelName(String name) {
// model name cannot use reserved keyword, e.g. return
if (reservedWords.contains(name))
throw new RuntimeException(name
+ " (reserved word) cannot be used as a model name");
// camelize the model name
// phone_number => PhoneNumber
return camelize(name);
}
@Override
public String toModelFilename(String name) {
// should be the same as the model name
return toModelName(name);
}
@Override
public String getTypeDeclaration(Property p) {
if (p instanceof ArrayProperty) {
ArrayProperty ap = (ArrayProperty) p;
Property inner = ap.getItems();
return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">";
} else if (p instanceof MapProperty) {
MapProperty mp = (MapProperty) p;
Property inner = mp.getAdditionalProperties();
return getSwaggerType(p) + "<String, " + getTypeDeclaration(inner)
+ ">";
}
return super.getTypeDeclaration(p);
}
@Override
public String getSwaggerType(Property p) {
String swaggerType = super.getSwaggerType(p);
String type = null;
if (typeMapping.containsKey(swaggerType)) {
type = typeMapping.get(swaggerType);
if (languageSpecificPrimitives.contains(type))
return type;
} else
type = swaggerType;
return type;
}
}

View File

@@ -21,4 +21,6 @@ io.swagger.codegen.languages.SwaggerGenerator
io.swagger.codegen.languages.SwaggerYamlGenerator
io.swagger.codegen.languages.SwiftGenerator
io.swagger.codegen.languages.TizenClientCodegen
io.swagger.codegen.languages.TypeScriptAngularClientCodegen
io.swagger.codegen.languages.TypeScriptNodeClientCodegen
io.swagger.codegen.languages.AkkaScalaClientCodegen

View File

@@ -0,0 +1,13 @@
{{#models}}
{{#model}}
/// <reference path="{{{classname}}}.ts" />
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
/// <reference path="{{classname}}.ts" />
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,68 @@
/// <reference path="api.d.ts" />
/* tslint:disable:no-unused-variable member-ordering */
{{#operations}}
module {{package}} {
'use strict';
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export class {{classname}} {
private basePath = '{{basePath}}';
static $inject: string[] = ['$http'];
constructor(private $http: ng.IHttpService, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}, {{/allParams}} extraHttpRequestParams?: any ) : ng.IHttpPromise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
var path = this.basePath + '{{path}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headers: any = {};
{{#requiredParamCount}}
// verify required params are set
if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) {
throw new Error('Missing required parameter: {{&paramName}}');
}
{{/requiredParamCount}}
{{#queryParams}}if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};{{/headerParams}}
var httpRequestParams: any = {
method: '{{httpMethod}}',
url: path,
json: true,
{{#bodyParam}}data: body,
{{/bodyParam}}
params: queryParameters,
headers: headers
};
if (extraHttpRequestParams) {
for (var k in extraHttpRequestParams){
if (extraHttpRequestParams.hasOwnProperty(k)) {
httpRequestParams[k] = extraHttpRequestParams[k];
}
}
}
return this.$http(httpRequestParams);
}
{{/operation}}
}
angular.module('{{package}}_{{classname}}', ['$http'])
.service('{{classname}}', {{classname}});
}
{{/operations}}

View File

@@ -0,0 +1,30 @@
/// <reference path="api.d.ts" />
module {{package}} {
'use strict';
{{#models}}
{{#model}}
{{#description}}/**
* {{{description}}}
*/{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}
{{#description}}/**
* {{{description}}}
*/{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};
{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}
}

View File

@@ -0,0 +1,73 @@
/* tslint:disable:no-unused-variable */
{{#operations}}
{{#description}}
/**
* {{&description}}
*/
{{/description}}
export class {{classname}} {
private basePath = '{{basePath}}';
constructor(private url: string, private username: string, private password: string, basePath?: string) {
if (basePath) {
this.basePath = basePath;
}
}
{{#operation}}
public {{nickname}} ({{#allParams}}{{paramName}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}} ) : Promise<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }> {
var path = this.url + this.basePath + '{{path}}';
{{#pathParams}}
path = path.replace('{' + '{{paramName}}' + '}', String({{paramName}}));
{{/pathParams}}
var queryParameters: any = {};
var headers: any = {};
{{#requiredParamCount}}
// verify required params are set
if ({{/requiredParamCount}}{{#requiredParams}} !{{paramName}} {{#hasMore}}|| {{/hasMore}}{{/requiredParams}}{{#requiredParamCount}}) {
throw new Error('Missing required parameter: {{&paramName}}');
}
{{/requiredParamCount}}
{{#queryParams}}if ({{paramName}} !== undefined) {
queryParameters['{{paramName}}'] = {{paramName}};
}
{{/queryParams}}
{{#headerParams}}headerParams['{{paramName}}'] = {{paramName}};
{{/headerParams}}
var deferred = promise.defer<{ response: http.ClientResponse; {{#returnType}}body: {{{returnType}}}; {{/returnType}} }>();
request({
method: '{{httpMethod}}',
qs: queryParameters,
uri: path,
json: true,
{{#bodyParam}}body: body,
{{/bodyParam}}
auth: {
username: this.username, password: this.password
}
}, (error, response, body) => {
if (error) {
deferred.reject(error);
} else {
if (response.statusCode >= 200 && response.statusCode <= 299) {
deferred.resolve({ response: response, body: body });
} else {
deferred.reject({ response: response, body: body });
}
}
});
return deferred.promise;
}
{{/operation}}
}
{{/operations}}

View File

@@ -0,0 +1,24 @@
{{#models}}
{{#model}}
{{#description}}/**
* {{{description}}}
*/{{/description}}
export class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
{{#vars}}{{#description}}/**
* {{{description}}}
*/
{{/description}}
{{name}}: {{#isEnum}}{{classname}}.{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{/isEnum}};{{/vars}}
}
{{#hasEnums}}
export module {{classname}} {
{{#vars}}
{{#isEnum}}export enum {{datatypeWithEnum}} { {{#allowableValues}}{{#values}}
{{.}} = <any> '{{.}}',{{/values}}{{/allowableValues}}
}{{/isEnum}}
{{/vars}}
}
{{/hasEnums}}
{{/model}}
{{/models}}