1919import java .math .BigDecimal ;
2020import java .util .*;
2121import java .util .Map .Entry ;
22+ import java .util .regex .Pattern ;
2223
2324public 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 });
0 commit comments