[JavaScript] index.js and ApiClient.js generated to incorrect location
Created by: demonfiddler
Description
Prior to the swagger-codegen -> openapi-generator fork, JavaScriptClientCodegen had already been broken, and remains so. The breakage is that two of the supporting files, ApiClient.js and index.js, are now generated to the hard-coded ${output}/src directory, ignoring the sourceFolder configuration parameter. This can break their module references to the api and model modules if either a sourceFolder other than src is specified or if an invokerPackage is specified. The two files need to be moved back into ${sourceFolder}/${invokerPackage}, otherwise nothing will work! The sample in swagger-codegen/samples/client/petstore/javascript does not override sourceFolder nor does it specify an invokerPackage, so it looks like this, which does work:
src/
api/
PetApi.js
...
model/
Animal.js
....
ApiClient.js
index.js (requires api/*, model/*)
As things currently stand it is no longer possible to generate a project with this structure if you override sourceFolder and/or invokerPackage. Instead, you'll end up with:
${sourceFolder}/
${invokerPackage}/
api/
PetApi.js
...
model/
Animal.js
....
src/
ApiClient.js
index.js (requires unresolvable api/*, model/*)
I am quite familiar with this code, as a couple of years ago I submitted several PRs, including one to get proper JSDoc comments that can be parsed by both JSDoc and Tern.js.
In addition, the test specification files are generated to ${outputFolder}/test/api/*ApiTest.spec.js and ${outputFolder}/test/model/*.spec.js and contain define() / require() calls that expect the index file to be at (hard-coded) ../../src/index. Given that the proposed fix entails moving index.js and ApiClient.js back to ${sourceFolder}/${invokerPackage} where they belong, the test spec files will have to account for the possbility that the generator configuration might specify an invokerPackage, in which case the index file would be located at ../../${sourceFolder}/${invokerPackage}/index. Furthermore, the output location of the test specification files does not itself currently include ${invokerPackage} and as a consequence when performing multiple YAML generations to the same output folder there is the possibilility of name collisions between identically named APIs or models from different YAMLs. To guard against this possibility the spec files should instead be generated to test/${invokerPackage}/api/*ApiTest.spec.js and test/${invokerPackage}/model/*.spec.js, and the relative location of the index files adjusted to suit.
openapi-generator version
3.2.1-SNAPSHOT
OpenAPI declaration file content or url
I am not permitted to post the proprietary YAMLs for which this effect is observed but it should be observable with any YAML (e.g., PetStore).
Command line used for generation
Generated using openapi-generator-maven-plugin:
<configuration>
<generatorName>${language}</generatorName>
<inputSpec>${openapi.yaml.directory}/ae.yaml</inputSpec>
<output>${openapi.output.directory}/ae</output>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<artifactVersion>${project.version}</artifactVersion>
<apiPackage>${api.package.ae}</apiPackage>
<modelPackage>${model.package.ae}</modelPackage>
<invokerPackage>ae</invokerPackage>
<configOptions>
<sourceFolder></sourceFolder>
<artifactName>XXX AE Microservice</artifactName>
</configOptions>
</configuration>
Steps to reproduce
Generate the JavaScript then attempt to load the generated index.js or ApiClient.js using AMD or CommonJS - this will fail because src/index.js and ApiClient.js refer to modules under ${invokerPackage}.
Related issues/PRs
Possibly #1046
Suggest a fix/enhancement
Revert the swagger-generator change that moved the output location of these two files:
final String[][] JAVASCRIPT_SUPPORTING_FILES = new String[][]{
...
new String[]{"index.mustache", "src/index.js"},
new String[]{"ApiClient.mustache", "src/ApiClient.js"},
...
};
which used to be configured like this in the preprocessSwagger(Swagger) method:
supportingFiles.add(new SupportingFile("index.mustache", createPath(sourceFolder, invokerPackage), "index.js"));
supportingFiles.add(new SupportingFile("ApiClient.mustache", createPath(sourceFolder, invokerPackage), "ApiClient.js"));
I forgot to mention: the current state of affairs prevents you from generating multiple YAMLs to different invokerPackages then aggregating the results, since the index.js and ApiClient.js files are now shared between all executions and thus can only relate to the first of these (subsequent generations skip these files).