Skip to content

Commit

Permalink
Refactor nodejs generated code structure (#4909)
Browse files Browse the repository at this point in the history
* read directly from templates

* refactor nodejs structure

* dont inject into global scope

* move to 2 spaces consistently
  • Loading branch information
fehguy authored and wing328 committed Mar 5, 2017
1 parent 7aebcfa commit 15a0bf5
Show file tree
Hide file tree
Showing 17 changed files with 765 additions and 544 deletions.
2 changes: 1 addition & 1 deletion bin/nodejs-petstore-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ fi

# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nodejs-server -o samples/server/petstore/nodejs"
ags="$@ generate -t modules/swagger-codegen/src/main/resources/nodejs -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nodejs-server -o samples/server/petstore/nodejs"

java $JAVA_OPTS -Dservice -jar $executable $ags
67 changes: 0 additions & 67 deletions modules/swagger-codegen/XhhGitIgnore/sdk_unit_testing_binary.json

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;

public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSServerCodegen.class);

protected String implFolder = "service";
public static final String GOOGLE_CLOUD_FUNCTIONS = "googleCloudFunctions";
public static final String EXPORTED_NAME = "exportedName";

Expand Down Expand Up @@ -81,16 +82,19 @@ public NodeJSServerCodegen() {
*/
additionalProperties.put("apiVersion", apiVersion);
additionalProperties.put("serverPort", serverPort);
additionalProperties.put("implFolder", implFolder);

supportingFiles.add(new SupportingFile("writer.mustache", ("utils").replace(".", "/"), "writer.js"));

cliOptions.add(CliOption.newBoolean(GOOGLE_CLOUD_FUNCTIONS,
"When specified, it will generate the code which runs within Google Cloud Functions "
+ "instead of standalone Node.JS server. See "
+ "https://cloud.google.com/functions/docs/quickstart for the details of how to "
+ "deploy the generated code."));
"When specified, it will generate the code which runs within Google Cloud Functions "
+ "instead of standalone Node.JS server. See "
+ "https://cloud.google.com/functions/docs/quickstart for the details of how to "
+ "deploy the generated code."));
cliOptions.add(new CliOption(EXPORTED_NAME,
"When the generated code will be deployed to Google Cloud Functions, this option can be "
+ "used to update the name of the exported function. By default, it refers to the "
+ "basePath. This does not affect normal standalone nodejs server code."));
"When the generated code will be deployed to Google Cloud Functions, this option can be "
+ "used to update the name of the exported function. By default, it refers to the "
+ "basePath. This does not affect normal standalone nodejs server code."));
}

@Override
Expand Down Expand Up @@ -145,15 +149,35 @@ public String toApiFilename(String name) {
return toApiName(name);
}


@Override
public String apiFilename(String templateName, String tag) {
String result = super.apiFilename(templateName, tag);

if ( templateName.equals("service.mustache") ) {
String stringToMatch = File.separator + "controllers" + File.separator;
String replacement = File.separator + implFolder + File.separator;
result = result.replaceAll(Pattern.quote(stringToMatch), replacement);
}
return result;
}

private String implFileFolder(String output) {
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
}

/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reseved words
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
if(this.reservedWords().contains(name)) {
name = "_" + name;
}
return name;
}

/**
Expand Down Expand Up @@ -256,7 +280,7 @@ public void processOpts() {

if (additionalProperties.containsKey(GOOGLE_CLOUD_FUNCTIONS)) {
setGoogleCloudFunctions(
Boolean.valueOf(additionalProperties.get(GOOGLE_CLOUD_FUNCTIONS).toString()));
Boolean.valueOf(additionalProperties.get(GOOGLE_CLOUD_FUNCTIONS).toString()));
}

if (additionalProperties.containsKey(EXPORTED_NAME)) {
Expand All @@ -273,8 +297,8 @@ public void processOpts() {
// "controller.js")
// );
supportingFiles.add(new SupportingFile("swagger.mustache",
"api",
"swagger.yaml")
"api",
"swagger.yaml")
);
if (getGoogleCloudFunctions()) {
writeOptional(outputFolder, new SupportingFile("index-gcf.mustache", "", "index.js"));
Expand Down Expand Up @@ -307,7 +331,12 @@ public void preprocessSwagger(Swagger swagger) {
if (info.getTitle() != null) {
// when info.title is defined, use it for projectName
// used in package.json
projectName = dashize(info.getTitle());
projectName = info.getTitle()
.replaceAll("[^a-zA-Z0-9]", "-")
.replaceAll("^[-]*", "")
.replaceAll("[-]*$", "")
.replaceAll("[-]{2,}", "-")
.toLowerCase();
this.additionalProperties.put("projectName", projectName);
}
}
Expand All @@ -318,14 +347,14 @@ public void preprocessSwagger(Swagger swagger) {
if (!host.endsWith(".cloudfunctions.net")) {
LOGGER.warn("Host " + host + " seems not matching with cloudfunctions.net URL.");
}
if (!additionalProperties.containsKey(EXPORTED_NAME)) {
if (!additionalProperties.containsKey(EXPORTED_NAME)) {
String basePath = swagger.getBasePath();
if (basePath == null || basePath.equals("/")) {
LOGGER.warn("Cannot find the exported name properly. Using 'openapi' as the exported name");
basePath = "/openapi";
}
additionalProperties.put(EXPORTED_NAME, basePath.substring(1));
}
}
}

// need vendor extensions for x-swagger-router-controller
Expand Down Expand Up @@ -353,7 +382,7 @@ public void preprocessSwagger(Swagger swagger) {
}
}

@Override
@Override
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
Swagger swagger = (Swagger)objs.get("swagger");
if(swagger != null) {
Expand All @@ -362,7 +391,7 @@ public Map<String, Object> postProcessSupportingFileData(Map<String, Object> obj
module.addSerializer(Double.class, new JsonSerializer<Double>() {
@Override
public void serialize(Double val, JsonGenerator jgen,
SerializerProvider provider) throws IOException, JsonProcessingException {
SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeNumber(new BigDecimal(val));
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
'use strict';

var url = require('url');
var utils = require('../utils/writer.js');
{{#operations}}

var {{classname}} = require('./{{classname}}Service');
var {{classname}} = require('../{{implFolder}}/{{classname}}Service');
{{#operation}}

module.exports.{{nickname}} = function {{nickname}} (req, res, next) {
{{classname}}.{{nickname}}(req.swagger.params, res, next);
{{#allParams}}
var {{paramName}} = req.swagger.params['{{baseName}}'].value;
{{/allParams}}
{{classname}}.{{nickname}}({{#allParams}}{{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}})
.then(function (response) {
utils.writeJson(res, response);
})
.catch(function (response) {
utils.writeJson(res, response);
});
};
{{/operation}}
{{/operations}}
68 changes: 35 additions & 33 deletions modules/swagger-codegen/src/main/resources/nodejs/service.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,42 @@

{{#operations}}
{{#operation}}
exports.{{{operationId}}} = function(args, res, next) {
/**
{{#summary}}
* {{{summary}}}
{{/summary}}
{{#notes}}
* {{{notes}}}
{{/notes}}
*
{{#allParams}}
* {{paramName}} {{{dataType}}} {{{description}}}{{^required}} (optional){{/required}}
{{/allParams}}
{{^returnType}}
* no response value expected for this operation
{{/returnType}}
{{#returnType}}
* returns {{{returnType}}}
{{/returnType}}
**/

/**
{{#summary}}
* {{{summary}}}
{{/summary}}
{{#notes}}
* {{{notes}}}
{{/notes}}
*
{{#allParams}}
* {{paramName}} {{{dataType}}} {{{description}}}{{^required}} (optional){{/required}}
{{/allParams}}
{{^returnType}}
* no response value expected for this operation
{{/returnType}}
{{#returnType}}
* returns {{{returnType}}}
{{/returnType}}
**/
exports.{{{operationId}}} = function({{#allParams}}{{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
return new Promise(function(resolve, reject) {
{{#returnType}}
var examples = {};
{{#examples}}
examples['{{contentType}}'] = {{{example}}};
{{/examples}}
if (Object.keys(examples).length > 0) {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2));
} else {
res.end();
}
{{/returnType}}
{{^returnType}}
res.end();
{{/returnType}}
var examples = {};
{{#examples}}
examples['{{contentType}}'] = {{{example}}};
{{/examples}}
if (Object.keys(examples).length > 0) {
resolve(examples[Object.keys(examples)[0]]);
} else {
resolve();
}
{{/returnType}}
{{^returnType}}
resolve();
{{/returnType}}
});
}

{{/operation}}
Expand Down
Loading

0 comments on commit 15a0bf5

Please sign in to comment.