Skip to content

Commit 15a0bf5

Browse files
fehguywing328
authored andcommitted
Refactor nodejs generated code structure (#4909)
* read directly from templates * refactor nodejs structure * dont inject into global scope * move to 2 spaces consistently
1 parent 7aebcfa commit 15a0bf5

File tree

17 files changed

+765
-544
lines changed

17 files changed

+765
-544
lines changed

bin/nodejs-petstore-server.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ fi
2626

2727
# if you've executed sbt assembly previously it will use that instead.
2828
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
29-
ags="$@ generate -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l nodejs-server -o samples/server/petstore/nodejs"
29+
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"
3030

3131
java $JAVA_OPTS -Dservice -jar $executable $ags

modules/swagger-codegen/XhhGitIgnore/sdk_unit_testing_binary.json

Lines changed: 0 additions & 67 deletions
This file was deleted.

modules/swagger-codegen/XhhGitIgnore/sdk_unit_testing_file_downloading.json

Lines changed: 0 additions & 30 deletions
This file was deleted.

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/NodeJSServerCodegen.java

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
import java.math.BigDecimal;
2020
import java.util.*;
2121
import java.util.Map.Entry;
22+
import java.util.regex.Pattern;
2223

2324
public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig {
2425

2526
private static final Logger LOGGER = LoggerFactory.getLogger(NodeJSServerCodegen.class);
26-
27+
protected String implFolder = "service";
2728
public static final String GOOGLE_CLOUD_FUNCTIONS = "googleCloudFunctions";
2829
public static final String EXPORTED_NAME = "exportedName";
2930

@@ -81,16 +82,19 @@ public NodeJSServerCodegen() {
8182
*/
8283
additionalProperties.put("apiVersion", apiVersion);
8384
additionalProperties.put("serverPort", serverPort);
85+
additionalProperties.put("implFolder", implFolder);
86+
87+
supportingFiles.add(new SupportingFile("writer.mustache", ("utils").replace(".", "/"), "writer.js"));
8488

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

96100
@Override
@@ -145,15 +149,35 @@ public String toApiFilename(String name) {
145149
return toApiName(name);
146150
}
147151

152+
153+
@Override
154+
public String apiFilename(String templateName, String tag) {
155+
String result = super.apiFilename(templateName, tag);
156+
157+
if ( templateName.equals("service.mustache") ) {
158+
String stringToMatch = File.separator + "controllers" + File.separator;
159+
String replacement = File.separator + implFolder + File.separator;
160+
result = result.replaceAll(Pattern.quote(stringToMatch), replacement);
161+
}
162+
return result;
163+
}
164+
165+
private String implFileFolder(String output) {
166+
return outputFolder + "/" + output + "/" + apiPackage().replace('.', '/');
167+
}
168+
148169
/**
149170
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
150-
* those terms here. This logic is only called if a variable matches the reseved words
171+
* those terms here. This logic is only called if a variable matches the reserved words
151172
*
152173
* @return the escaped term
153174
*/
154175
@Override
155176
public String escapeReservedWord(String name) {
156-
return "_" + name; // add an underscore to the name
177+
if(this.reservedWords().contains(name)) {
178+
name = "_" + name;
179+
}
180+
return name;
157181
}
158182

159183
/**
@@ -256,7 +280,7 @@ public void processOpts() {
256280

257281
if (additionalProperties.containsKey(GOOGLE_CLOUD_FUNCTIONS)) {
258282
setGoogleCloudFunctions(
259-
Boolean.valueOf(additionalProperties.get(GOOGLE_CLOUD_FUNCTIONS).toString()));
283+
Boolean.valueOf(additionalProperties.get(GOOGLE_CLOUD_FUNCTIONS).toString()));
260284
}
261285

262286
if (additionalProperties.containsKey(EXPORTED_NAME)) {
@@ -273,8 +297,8 @@ public void processOpts() {
273297
// "controller.js")
274298
// );
275299
supportingFiles.add(new SupportingFile("swagger.mustache",
276-
"api",
277-
"swagger.yaml")
300+
"api",
301+
"swagger.yaml")
278302
);
279303
if (getGoogleCloudFunctions()) {
280304
writeOptional(outputFolder, new SupportingFile("index-gcf.mustache", "", "index.js"));
@@ -307,7 +331,12 @@ public void preprocessSwagger(Swagger swagger) {
307331
if (info.getTitle() != null) {
308332
// when info.title is defined, use it for projectName
309333
// used in package.json
310-
projectName = dashize(info.getTitle());
334+
projectName = info.getTitle()
335+
.replaceAll("[^a-zA-Z0-9]", "-")
336+
.replaceAll("^[-]*", "")
337+
.replaceAll("[-]*$", "")
338+
.replaceAll("[-]{2,}", "-")
339+
.toLowerCase();
311340
this.additionalProperties.put("projectName", projectName);
312341
}
313342
}
@@ -318,14 +347,14 @@ public void preprocessSwagger(Swagger swagger) {
318347
if (!host.endsWith(".cloudfunctions.net")) {
319348
LOGGER.warn("Host " + host + " seems not matching with cloudfunctions.net URL.");
320349
}
321-
if (!additionalProperties.containsKey(EXPORTED_NAME)) {
350+
if (!additionalProperties.containsKey(EXPORTED_NAME)) {
322351
String basePath = swagger.getBasePath();
323352
if (basePath == null || basePath.equals("/")) {
324353
LOGGER.warn("Cannot find the exported name properly. Using 'openapi' as the exported name");
325354
basePath = "/openapi";
326355
}
327356
additionalProperties.put(EXPORTED_NAME, basePath.substring(1));
328-
}
357+
}
329358
}
330359

331360
// need vendor extensions for x-swagger-router-controller
@@ -353,7 +382,7 @@ public void preprocessSwagger(Swagger swagger) {
353382
}
354383
}
355384

356-
@Override
385+
@Override
357386
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
358387
Swagger swagger = (Swagger)objs.get("swagger");
359388
if(swagger != null) {
@@ -362,7 +391,7 @@ public Map<String, Object> postProcessSupportingFileData(Map<String, Object> obj
362391
module.addSerializer(Double.class, new JsonSerializer<Double>() {
363392
@Override
364393
public void serialize(Double val, JsonGenerator jgen,
365-
SerializerProvider provider) throws IOException, JsonProcessingException {
394+
SerializerProvider provider) throws IOException, JsonProcessingException {
366395
jgen.writeNumber(new BigDecimal(val));
367396
}
368397
});
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
'use strict';
22

3-
var url = require('url');
3+
var utils = require('../utils/writer.js');
44
{{#operations}}
5-
6-
var {{classname}} = require('./{{classname}}Service');
5+
var {{classname}} = require('../{{implFolder}}/{{classname}}Service');
76
{{#operation}}
87

98
module.exports.{{nickname}} = function {{nickname}} (req, res, next) {
10-
{{classname}}.{{nickname}}(req.swagger.params, res, next);
9+
{{#allParams}}
10+
var {{paramName}} = req.swagger.params['{{baseName}}'].value;
11+
{{/allParams}}
12+
{{classname}}.{{nickname}}({{#allParams}}{{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}})
13+
.then(function (response) {
14+
utils.writeJson(res, response);
15+
})
16+
.catch(function (response) {
17+
utils.writeJson(res, response);
18+
});
1119
};
1220
{{/operation}}
1321
{{/operations}}

modules/swagger-codegen/src/main/resources/nodejs/service.mustache

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,42 @@
22

33
{{#operations}}
44
{{#operation}}
5-
exports.{{{operationId}}} = function(args, res, next) {
6-
/**
7-
{{#summary}}
8-
* {{{summary}}}
9-
{{/summary}}
10-
{{#notes}}
11-
* {{{notes}}}
12-
{{/notes}}
13-
*
14-
{{#allParams}}
15-
* {{paramName}} {{{dataType}}} {{{description}}}{{^required}} (optional){{/required}}
16-
{{/allParams}}
17-
{{^returnType}}
18-
* no response value expected for this operation
19-
{{/returnType}}
20-
{{#returnType}}
21-
* returns {{{returnType}}}
22-
{{/returnType}}
23-
**/
5+
6+
/**
7+
{{#summary}}
8+
* {{{summary}}}
9+
{{/summary}}
10+
{{#notes}}
11+
* {{{notes}}}
12+
{{/notes}}
13+
*
14+
{{#allParams}}
15+
* {{paramName}} {{{dataType}}} {{{description}}}{{^required}} (optional){{/required}}
16+
{{/allParams}}
17+
{{^returnType}}
18+
* no response value expected for this operation
19+
{{/returnType}}
20+
{{#returnType}}
21+
* returns {{{returnType}}}
22+
{{/returnType}}
23+
**/
24+
exports.{{{operationId}}} = function({{#allParams}}{{paramName}}{{#hasMore}},{{/hasMore}}{{/allParams}}) {
25+
return new Promise(function(resolve, reject) {
2426
{{#returnType}}
25-
var examples = {};
26-
{{#examples}}
27-
examples['{{contentType}}'] = {{{example}}};
28-
{{/examples}}
29-
if (Object.keys(examples).length > 0) {
30-
res.setHeader('Content-Type', 'application/json');
31-
res.end(JSON.stringify(examples[Object.keys(examples)[0]] || {}, null, 2));
32-
} else {
33-
res.end();
34-
}
35-
{{/returnType}}
36-
{{^returnType}}
37-
res.end();
38-
{{/returnType}}
27+
var examples = {};
28+
{{#examples}}
29+
examples['{{contentType}}'] = {{{example}}};
30+
{{/examples}}
31+
if (Object.keys(examples).length > 0) {
32+
resolve(examples[Object.keys(examples)[0]]);
33+
} else {
34+
resolve();
35+
}
36+
{{/returnType}}
37+
{{^returnType}}
38+
resolve();
39+
{{/returnType}}
40+
});
3941
}
4042

4143
{{/operation}}

0 commit comments

Comments
 (0)