diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java new file mode 100644 index 000000000000..a31e15878cff --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptAngularClientCodegen.java @@ -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")); + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java new file mode 100644 index 000000000000..19b8514f8e3c --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/TypeScriptNodeClientCodegen.java @@ -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(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(Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float", + "Object")); + instantiationTypes.put("array", "Array"); + + typeMapping = new HashMap(); + 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) + ""; + } + 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; + } +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 8bbdbc8d140f..2a0372049762 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -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 diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache new file mode 100644 index 000000000000..a8bf1c582670 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.d.mustache @@ -0,0 +1,13 @@ +{{#models}} +{{#model}} +/// +{{/model}} +{{/models}} + +{{#apiInfo}} +{{#apis}} +{{#operations}} +/// +{{/operations}} +{{/apis}} +{{/apiInfo}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache new file mode 100644 index 000000000000..3b53e816891e --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/api.mustache @@ -0,0 +1,68 @@ +/// + +/* 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: {{¶mName}}'); + } + {{/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}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache new file mode 100644 index 000000000000..bbda64b37daf --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-Angular/model.mustache @@ -0,0 +1,30 @@ +/// + +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}} + {{.}} = '{{.}}',{{/values}}{{/allowableValues}} + }{{/isEnum}} +{{/vars}} + } +{{/hasEnums}} +{{/model}} +{{/models}} +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache new file mode 100644 index 000000000000..4b329799ad51 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/api.mustache @@ -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: {{¶mName}}'); + } + {{/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}} diff --git a/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache new file mode 100644 index 000000000000..f187ac3e40f8 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/TypeScript-node/model.mustache @@ -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}} + {{.}} = '{{.}}',{{/values}}{{/allowableValues}} + }{{/isEnum}} +{{/vars}} +} +{{/hasEnums}} +{{/model}} +{{/models}}