mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-07-04 22:50:53 +00:00
Add a Javascript (Closure) Angular generator.
This commit is contained in:
parent
564fa04f7c
commit
b950271940
@ -0,0 +1,206 @@
|
|||||||
|
package io.swagger.codegen.languages;
|
||||||
|
|
||||||
|
import io.swagger.codegen.CodegenModel;
|
||||||
|
import io.swagger.codegen.*;
|
||||||
|
import io.swagger.models.properties.*;
|
||||||
|
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class JavascriptClosureAngularClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
public JavascriptClosureAngularClientCodegen() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
supportsInheritance = false;
|
||||||
|
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"));
|
||||||
|
|
||||||
|
languageSpecificPrimitives = new HashSet<String>(Arrays.asList(
|
||||||
|
"string",
|
||||||
|
"boolean",
|
||||||
|
"number",
|
||||||
|
"Object",
|
||||||
|
"Blob",
|
||||||
|
"Date"));
|
||||||
|
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", "Object");
|
||||||
|
typeMapping.put("Object", "Object");
|
||||||
|
typeMapping.put("File", "Blob");
|
||||||
|
typeMapping.put("file", "Blob");
|
||||||
|
typeMapping.put("integer", "number");
|
||||||
|
typeMapping.put("Map", "Object");
|
||||||
|
typeMapping.put("map", "Object");
|
||||||
|
typeMapping.put("DateTime", "Date");
|
||||||
|
|
||||||
|
outputFolder = "generated-code/javascript-closure-angular";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".js");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".js");
|
||||||
|
embeddedTemplateDir = templateDir = "Javascript-Closure-Angular";
|
||||||
|
apiPackage = "API.Client";
|
||||||
|
modelPackage = "API.Client";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "javascript-closure-angular";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a Javascript AngularJS client library annotated with Google Closure Compiler annotations" +
|
||||||
|
"(https://developers.google.com/closure/compiler/docs/js-for-compiler?hl=en)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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 "Object<!string, "+ getTypeDeclaration(inner) + ">";
|
||||||
|
} else if (p instanceof FileProperty) {
|
||||||
|
return "Object";
|
||||||
|
}
|
||||||
|
String type = super.getTypeDeclaration(p);
|
||||||
|
if (type.equals("boolean") ||
|
||||||
|
type.equals("Date") ||
|
||||||
|
type.equals("number") ||
|
||||||
|
type.equals("string")) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
return apiPackage + "." + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
|
||||||
|
List<Object> models = (List<Object>) objs.get("models");
|
||||||
|
for (Object _mo : models) {
|
||||||
|
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||||
|
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||||
|
cm.imports = new TreeSet(cm.imports);
|
||||||
|
for (CodegenProperty var : cm.vars) {
|
||||||
|
// handle default value for enum, e.g. available => StatusEnum.available
|
||||||
|
if (var.isEnum && var.defaultValue != null && !"null".equals(var.defaultValue)) {
|
||||||
|
var.defaultValue = var.datatypeWithEnum + "." + var.defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||||
|
if (objs.get("imports") instanceof List) {
|
||||||
|
List<Map<String, String>> imports = (ArrayList<Map<String, String>>)objs.get("imports");
|
||||||
|
Collections.sort(imports, new Comparator<Map<String, String>>() {
|
||||||
|
public int compare(Map<String, String> o1, Map<String, String> o2) {
|
||||||
|
return o1.get("import").compareTo(o2.get("import"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
objs.put("imports", imports);
|
||||||
|
}
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* @fileoverview AUTOMATICALLY GENERATED service for {{package}}.{{classname}}.
|
||||||
|
* Do not edit this file by hand or your changes will be lost next time it is
|
||||||
|
* generated.{{#appDescription}}
|
||||||
|
*
|
||||||
|
* {{ appDescription }}{{/appDescription}}{{#version}}
|
||||||
|
* Version: {{version}}{{/version}}{{#appContact}}
|
||||||
|
* Contact: {{appContact}}{{/appContact}}
|
||||||
|
* Generated at: {{generatedDate}}
|
||||||
|
* Generated by: {{generatorClass}}
|
||||||
|
*/{{#licenseInfo}}
|
||||||
|
/**
|
||||||
|
* @license {{licenseInfo}}{{#licenseUrl}}
|
||||||
|
* {{licenseUrl}}{{/licenseUrl}}
|
||||||
|
*/
|
||||||
|
{{/licenseInfo}}
|
||||||
|
|
||||||
|
goog.provide('{{package}}.{{classname}}');
|
||||||
|
|
||||||
|
{{#imports}}
|
||||||
|
goog.require('{{import}}');
|
||||||
|
{{/imports}}
|
||||||
|
{{#operations}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
{{#description}}
|
||||||
|
* {{&description}}
|
||||||
|
{{/description}}
|
||||||
|
* @constructor
|
||||||
|
* @param {!angular.$http} $http
|
||||||
|
* @param {!angular.$injector} $injector
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
{{package}}.{{classname}} = function($http, $injector) {
|
||||||
|
/** @private {!string} */
|
||||||
|
this.basePath_ = $injector.has('{{classname}}BasePath') ?
|
||||||
|
/** @type {!string} */ ($injector.get('{{classname}}BasePath')) :
|
||||||
|
'{{basePath}}';
|
||||||
|
|
||||||
|
/** @private {!Object<string, string>} */
|
||||||
|
this.defaultHeaders_ = $injector.has('{{classname}}DefaultHeaders') ?
|
||||||
|
/** @type {!Object<string, string>} */ (
|
||||||
|
$injector.get('{{classname}}DefaultHeaders')) :
|
||||||
|
{};
|
||||||
|
|
||||||
|
/** @private {!angular.$http} */
|
||||||
|
this.http_ = $http;
|
||||||
|
}
|
||||||
|
{{package}}.{{classname}}.$inject = ['$http', '$injector'];
|
||||||
|
{{#operation}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {{summary}}
|
||||||
|
* {{notes}}{{#allParams}}
|
||||||
|
* @param {!{{{dataType}}}{{^required}}={{/required}}} {{^required}}opt_{{/required}}{{paramName}} {{description}}{{/allParams}}
|
||||||
|
* @param {!angular.$http.Config=} opt_extraHttpRequestParams Extra HTTP parameters to send.
|
||||||
|
* @return {!angular.$q.Promise{{#returnType}}<!{{{returnType}}}>{{/returnType}}}
|
||||||
|
*/
|
||||||
|
{{package}}.{{classname}}.prototype.{{nickname}} = function({{#allParams}}{{^required}}opt_{{/required}}{{paramName}}, {{/allParams}}opt_extraHttpRequestParams) {
|
||||||
|
/** @const {!string} */
|
||||||
|
var path = this.basePath_ + '{{path}}'{{#pathParams}}
|
||||||
|
.replace('{' + '{{baseName}}' + '}', String({{^required}}opt_{{/required}}{{paramName}})){{/pathParams}};
|
||||||
|
{{#required}}
|
||||||
|
|
||||||
|
// verify required parameter '{{paramName}}' is set
|
||||||
|
if (!{{paramName}}) {
|
||||||
|
throw new Error('Missing required parameter {{paramName}} when calling {{nickname}}');
|
||||||
|
}
|
||||||
|
{{/required}}
|
||||||
|
|
||||||
|
/** @type {!Object<string,string>} */
|
||||||
|
var queryParameters = {};
|
||||||
|
{{#queryParams}}
|
||||||
|
if ({{^required}}opt_{{/required}}{{paramName}} !== undefined) {
|
||||||
|
queryParameters['{{baseName}}'] = String({{^required}}opt_{{/required}}{{paramName}});
|
||||||
|
}
|
||||||
|
{{/queryParams}}
|
||||||
|
|
||||||
|
/** @type {!Object<string,string>} */
|
||||||
|
var headerParams = angular.copy(this.defaultHeaders_);
|
||||||
|
{{#headerParams}}
|
||||||
|
if ({{^required}}opt_{{/required}}{{paramName}} !== undefined) {
|
||||||
|
headerParams['{{baseName}}'] = {{^required}}opt_{{/required}}{{paramName}};
|
||||||
|
}
|
||||||
|
{{/headerParams}}
|
||||||
|
{{#hasFormParams}}
|
||||||
|
|
||||||
|
/** @type {!FormData} */
|
||||||
|
var formParams = new FormData();
|
||||||
|
{{/hasFormParams}}
|
||||||
|
{{#formParams}}
|
||||||
|
if ({{^required}}opt_{{/required}}{{paramName}} !== undefined) {
|
||||||
|
var {{paramName}}_ = /** @type {?} */ ({{^required}}opt_{{/required}}{{paramName}});
|
||||||
|
if ({{paramName}}_ instanceof Blob) {
|
||||||
|
formParams.append('{{baseName}}', {{paramName}}_);
|
||||||
|
} else if (typeof {{paramName}}_ === 'string') {
|
||||||
|
formParams.append('{{baseName}}', {{paramName}}_);
|
||||||
|
} else {
|
||||||
|
throw new Error('Forms parameter {{^required}}opt_{{/required}}{{paramName}} is required to be a string or a Blob (https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/formParams}}
|
||||||
|
{{#allParams}}
|
||||||
|
{{/allParams}}
|
||||||
|
|
||||||
|
/** @type {!angular.$http.Config} */
|
||||||
|
var httpRequestConfig = /** @type {!angular.$http.Config} */ ({
|
||||||
|
url: path,
|
||||||
|
json: {{#hasFormParams}}false{{/hasFormParams}}{{^hasFormParams}}true{{/hasFormParams}},{{#bodyParam}}
|
||||||
|
data: {{paramName}},{{/bodyParam}}{{#hasFormParams}}
|
||||||
|
data: formParams,{{/hasFormParams}}
|
||||||
|
params: queryParameters,
|
||||||
|
headers: headerParams
|
||||||
|
});
|
||||||
|
|
||||||
|
if (opt_extraHttpRequestParams) {
|
||||||
|
// If an opt_extraHttpRequestParams object is passed in, override values
|
||||||
|
// set the generated config with the passed in values.
|
||||||
|
httpRequestConfig = angular.merge(httpRequestConfig, opt_extraHttpRequestParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This whole block is to work around a limitation in closure compiler. It
|
||||||
|
// would be better to call the $http service directly as a function, but that
|
||||||
|
// isn't permitted since it has methods attached to it. Manually confirmed to
|
||||||
|
// compile down to just a single method even with only SIMPLE optimization on.
|
||||||
|
// https://github.com/google/closure-compiler/blob/90769b826df65eabfb0211517b0d6d85c0c1c60b/contrib/externs/angular-1.4.js#L1393
|
||||||
|
switch ('{{httpMethod}}') {
|
||||||
|
case 'GET':
|
||||||
|
return this.http_.get(path, httpRequestConfig);
|
||||||
|
case 'HEAD':
|
||||||
|
return this.http_.head(path, httpRequestConfig);
|
||||||
|
case 'POST':
|
||||||
|
return this.http_.post(path, {}, httpRequestConfig);
|
||||||
|
case 'PUT':
|
||||||
|
return this.http_.put(path, {}, httpRequestConfig);
|
||||||
|
case 'DELETE':
|
||||||
|
return this.http_.delete(path, httpRequestConfig);
|
||||||
|
case 'PATCH':
|
||||||
|
return this.http_.patch(path, {}, httpRequestConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/operation}}
|
||||||
|
{{/operations}}
|
@ -0,0 +1,40 @@
|
|||||||
|
{{#models}}
|
||||||
|
{{#model}}
|
||||||
|
goog.provide('{{package}}.{{name}}');
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
||||||
|
|
||||||
|
{{#models}}
|
||||||
|
{{#model}}
|
||||||
|
/**
|
||||||
|
{{#description}}
|
||||||
|
* {{{description}}}
|
||||||
|
{{/description}}
|
||||||
|
* @record
|
||||||
|
*/
|
||||||
|
{{package}}.{{classname}} = function() {}
|
||||||
|
{{#vars}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
{{#description}}
|
||||||
|
* {{{description}}}
|
||||||
|
{{/description}}
|
||||||
|
{{! Explicitly force types to be non-nullable using !. This is redundant but valid }}
|
||||||
|
* @type {!{{{datatype}}}}
|
||||||
|
* @export
|
||||||
|
*/
|
||||||
|
{{package}}.{{classname}}.prototype.{{name}};
|
||||||
|
{{/vars}}
|
||||||
|
|
||||||
|
{{#hasEnums}}
|
||||||
|
{{#vars}}
|
||||||
|
{{#isEnum}}
|
||||||
|
/** @enum {string} */
|
||||||
|
{{package}}.{{classname}}.{{datatypeWithEnum}} = { {{#allowableValues}}{{#values}}
|
||||||
|
{{.}}: '{{.}}',{{/values}}{{/allowableValues}}
|
||||||
|
}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/vars}}
|
||||||
|
{{/hasEnums}}
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
@ -10,6 +10,7 @@ io.swagger.codegen.languages.JavaJerseyServerCodegen
|
|||||||
io.swagger.codegen.languages.JavaCXFServerCodegen
|
io.swagger.codegen.languages.JavaCXFServerCodegen
|
||||||
io.swagger.codegen.languages.JavaInflectorServerCodegen
|
io.swagger.codegen.languages.JavaInflectorServerCodegen
|
||||||
io.swagger.codegen.languages.JavascriptClientCodegen
|
io.swagger.codegen.languages.JavascriptClientCodegen
|
||||||
|
io.swagger.codegen.languages.JavascriptClosureAngularClientCodegen
|
||||||
io.swagger.codegen.languages.JMeterCodegen
|
io.swagger.codegen.languages.JMeterCodegen
|
||||||
io.swagger.codegen.languages.NodeJSServerCodegen
|
io.swagger.codegen.languages.NodeJSServerCodegen
|
||||||
io.swagger.codegen.languages.ObjcClientCodegen
|
io.swagger.codegen.languages.ObjcClientCodegen
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package io.swagger.codegen.options;
|
||||||
|
|
||||||
|
import io.swagger.codegen.CodegenConstants;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class JavascriptClosureAnularClientOptionsProvider implements OptionsProvider {
|
||||||
|
public static final String SORT_PARAMS_VALUE = "false";
|
||||||
|
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLanguage() {
|
||||||
|
return "javascript-closure-angular";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> createOptions() {
|
||||||
|
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
|
||||||
|
return builder.put(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG, SORT_PARAMS_VALUE)
|
||||||
|
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isServer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user