[TypescriptAngular] gets package npm version from API specification (#2810)

This commit is contained in:
Vincent Devos 2019-05-07 12:50:36 +02:00 committed by William Cheng
parent 31734c2717
commit a4f2e15bb7
5 changed files with 78 additions and 72 deletions

View File

@ -14,15 +14,15 @@ sidebar_label: typescript-angular
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase| |modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|supportsES6|Generate code that conforms to ES6.| |false| |supportsES6|Generate code that conforms to ES6.| |false|
|npmName|The name under which you want to publish generated npm package. Required to generate a full angular package| |null| |npmName|The name under which you want to publish generated npm package. Required to generate a full angular package| |null|
|npmVersion|The version of your npm package. Default is '1.0.0'| |null| |npmVersion|The version of your npm package. If not provided, using the version from the OpenAPI specification file.| |1.0.0|
|npmRepository|Use this property to set an url your private npmRepo in the package.json| |null| |npmRepository|Use this property to set an url your private npmRepo in the package.json| |null|
|snapshot|When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false| |snapshot|When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false| |withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|taggedUnions|Use discriminators to create tagged unions instead of extending interfaces.| |false| |taggedUnions|Use discriminators to create tagged unions instead of extending interfaces.| |false|
|providedInRoot|Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).| |false| |providedInRoot|Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).| |false|
|ngVersion|The version of Angular. Default is '7.0.0'| |null| |ngVersion|The version of Angular.| |7.0.0|
|serviceSuffix|The suffix of the generated service. Default is 'Service'.| |null| |serviceSuffix|The suffix of the generated service.| |Service|
|serviceFileSuffix|The suffix of the file of the generated service (service<suffix>.ts). Default is '.service'.| |null| |serviceFileSuffix|The suffix of the file of the generated service (service<suffix>.ts).| |.service|
|modelSuffix|The suffix of the generated model. Default is ''.| |null| |modelSuffix|The suffix of the generated model.| |null|
|modelFileSuffix|The suffix of the file of the generated model (model<suffix>.ts). Default is ''.| |null| |modelFileSuffix|The suffix of the file of the generated model (model<suffix>.ts).| |null|
|fileNaming|Naming convention for the output files: 'camelCase', 'kebab-case'. Default is 'camelCase'.| |null| |fileNaming|Naming convention for the output files: 'camelCase', 'kebab-case'.| |camelCase|

View File

@ -45,7 +45,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
private static final String UNDEFINED_VALUE = "undefined"; private static final String UNDEFINED_VALUE = "undefined";
protected String modelPropertyNaming = "camelCase"; protected String modelPropertyNaming = "camelCase";
protected Boolean supportsES6 = true; protected Boolean supportsES6 = false;
protected HashSet<String> languageGenericTypes; protected HashSet<String> languageGenericTypes;
public AbstractTypeScriptClientCodegen() { public AbstractTypeScriptClientCodegen() {
@ -120,7 +120,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
typeMapping.put("Error", "Error"); typeMapping.put("Error", "Error");
cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase")); cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase"));
cliOptions.add(new CliOption(CodegenConstants.SUPPORTS_ES6, CodegenConstants.SUPPORTS_ES6_DESC).defaultValue("false")); cliOptions.add(new CliOption(CodegenConstants.SUPPORTS_ES6, CodegenConstants.SUPPORTS_ES6_DESC).defaultValue(String.valueOf(this.getSupportsES6())));
} }

View File

@ -17,6 +17,7 @@
package org.openapitools.codegen.languages; package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.util.SchemaTypeUtil; import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*; import org.openapitools.codegen.*;
@ -53,6 +54,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
protected String npmName = null; protected String npmName = null;
protected String npmVersion = "1.0.0"; protected String npmVersion = "1.0.0";
protected String ngVersion = "7.0.0";
protected String npmRepository = null; protected String npmRepository = null;
protected String serviceSuffix = "Service"; protected String serviceSuffix = "Service";
protected String serviceFileSuffix = ".service"; protected String serviceFileSuffix = ".service";
@ -76,27 +78,27 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." + this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." +
" Required to generate a full angular package")); " Required to generate a full angular package"));
this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. Default is '1.0.0'")); this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package. If not provided, using the version from the OpenAPI specification file.").defaultValue(this.getNpmVersion()));
this.cliOptions.add(new CliOption(NPM_REPOSITORY, this.cliOptions.add(new CliOption(NPM_REPOSITORY,
"Use this property to set an url your private npmRepo in the package.json")); "Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(new CliOption(SNAPSHOT, this.cliOptions.add(CliOption.newBoolean(SNAPSHOT,
"When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm",
SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); false));
this.cliOptions.add(new CliOption(WITH_INTERFACES, this.cliOptions.add(CliOption.newBoolean(WITH_INTERFACES,
"Setting this property to true will generate interfaces next to the default class implementations.", "Setting this property to true will generate interfaces next to the default class implementations.",
SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); false));
this.cliOptions.add(new CliOption(TAGGED_UNIONS, this.cliOptions.add(CliOption.newBoolean(TAGGED_UNIONS,
"Use discriminators to create tagged unions instead of extending interfaces.", "Use discriminators to create tagged unions instead of extending interfaces.",
SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); this.taggedUnions));
this.cliOptions.add(new CliOption(PROVIDED_IN_ROOT, this.cliOptions.add(CliOption.newBoolean(PROVIDED_IN_ROOT,
"Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).", "Use this property to provide Injectables in root (it is only valid in angular version greater or equal to 6.0.0).",
SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); false));
this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular. Default is '7.0.0'")); this.cliOptions.add(new CliOption(NG_VERSION, "The version of Angular.").defaultValue(this.ngVersion));
this.cliOptions.add(new CliOption(SERVICE_SUFFIX, "The suffix of the generated service. Default is 'Service'.")); this.cliOptions.add(new CliOption(SERVICE_SUFFIX, "The suffix of the generated service.").defaultValue(this.serviceSuffix));
this.cliOptions.add(new CliOption(SERVICE_FILE_SUFFIX, "The suffix of the file of the generated service (service<suffix>.ts). Default is '.service'.")); this.cliOptions.add(new CliOption(SERVICE_FILE_SUFFIX, "The suffix of the file of the generated service (service<suffix>.ts).").defaultValue(this.serviceFileSuffix));
this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model. Default is ''.")); this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model."));
this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model<suffix>.ts). Default is ''.")); this.cliOptions.add(new CliOption(MODEL_FILE_SUFFIX, "The suffix of the file of the generated model (model<suffix>.ts)."));
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'. Default is 'camelCase'.")); this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
} }
@Override @Override
@ -136,7 +138,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
if (additionalProperties.containsKey(NG_VERSION)) { if (additionalProperties.containsKey(NG_VERSION)) {
ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString()); ngVersion = new SemVer(additionalProperties.get(NG_VERSION).toString());
} else { } else {
ngVersion = new SemVer("7.0.0"); ngVersion = new SemVer(this.ngVersion);
LOGGER.info("generating code for Angular {} ...", ngVersion); LOGGER.info("generating code for Angular {} ...", ngVersion);
LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)"); LOGGER.info(" (you can select the angular version by setting the additionalProperty ngVersion)");
} }
@ -202,22 +204,6 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.setNpmName(additionalProperties.get(NPM_NAME).toString()); this.setNpmName(additionalProperties.get(NPM_NAME).toString());
} }
if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
} else if (this.getVersionFromApi() != null) {
this.setNpmVersion(this.getVersionFromApi());
}
if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) {
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
}
else {
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
}
}
additionalProperties.put(NPM_VERSION, npmVersion);
if (additionalProperties.containsKey(NPM_REPOSITORY)) { if (additionalProperties.containsKey(NPM_REPOSITORY)) {
this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
} }
@ -296,6 +282,32 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json")); supportingFiles.add(new SupportingFile("tsconfig.mustache", getIndexDirectory(), "tsconfig.json"));
} }
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
if (additionalProperties.containsKey(NPM_NAME)) {
// If no npmVersion is provided in additional properties, version from API specification is used.
// If none of them is provided then fallbacks to default version
if (additionalProperties.containsKey(NPM_VERSION)) {
this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
} else if (openAPI.getInfo() != null && openAPI.getInfo().getVersion() != null) {
this.setNpmVersion(openAPI.getInfo().getVersion());
}
if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) {
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
} else {
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date()));
}
}
additionalProperties.put(NPM_VERSION, npmVersion);
}
}
private String getIndexDirectory() { private String getIndexDirectory() {
String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.'))); String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.')));
return indexPackage.replace('.', File.separatorChar); return indexPackage.replace('.', File.separatorChar);
@ -654,16 +666,4 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
return name; return name;
} }
/**
* Returns version from OpenAPI info.
*
* @return version
*/
private String getVersionFromApi() {
if (this.openAPI != null && this.openAPI.getInfo() != null) {
return this.openAPI.getInfo().getVersion();
} else {
return null;
}
}
} }

View File

@ -38,11 +38,14 @@ public class TypeScriptAngularClientCodegenTest {
@Test @Test
public void testSnapshotVersion() { public void testSnapshotVersion() {
OpenAPI openAPI = TestUtils.createOpenAPI();
TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen(); TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore"); codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
codegen.additionalProperties().put("snapshot", true); codegen.additionalProperties().put("snapshot", true);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT"); codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT.[0-9]{12}$")); Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT.[0-9]{12}$"));
@ -51,6 +54,7 @@ public class TypeScriptAngularClientCodegenTest {
codegen.additionalProperties().put("snapshot", true); codegen.additionalProperties().put("snapshot", true);
codegen.additionalProperties().put("npmVersion", "3.0.0-M1"); codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1-SNAPSHOT.[0-9]{12}$")); Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1-SNAPSHOT.[0-9]{12}$"));
@ -58,11 +62,14 @@ public class TypeScriptAngularClientCodegenTest {
@Test @Test
public void testWithoutSnapshotVersion() { public void testWithoutSnapshotVersion() {
OpenAPI openAPI = TestUtils.createOpenAPI();
TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen(); TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore"); codegen.additionalProperties().put("npmName", "@openapi/typescript-angular-petstore");
codegen.additionalProperties().put("snapshot", false); codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT"); codegen.additionalProperties().put("npmVersion", "1.0.0-SNAPSHOT");
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT$")); Assert.assertTrue(codegen.getNpmVersion().matches("^1.0.0-SNAPSHOT$"));
@ -71,6 +78,7 @@ public class TypeScriptAngularClientCodegenTest {
codegen.additionalProperties().put("snapshot", false); codegen.additionalProperties().put("snapshot", false);
codegen.additionalProperties().put("npmVersion", "3.0.0-M1"); codegen.additionalProperties().put("npmVersion", "3.0.0-M1");
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(openAPI);
Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1$")); Assert.assertTrue(codegen.getNpmVersion().matches("^3.0.0-M1$"));

View File

@ -8,34 +8,20 @@ import org.testng.annotations.Test;
public class TypescriptAngularApiVersionTest { public class TypescriptAngularApiVersionTest {
@Test @Test(description = "tests if API version specification is used if no version is provided in additional properties")
public void testWithApiVersion() { public void testWithApiVersion() {
final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen(); final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "just-a-test"); codegen.additionalProperties().put("npmName", "just-a-test");
OpenAPI api = TestUtils.createOpenAPI(); OpenAPI api = TestUtils.createOpenAPI();
codegen.setOpenAPI(api);
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "1.0.7"); Assert.assertEquals(codegen.getNpmVersion(), "1.0.7");
} }
@Test @Test(description = "tests if npmVersion additional property is used")
public void testWithoutNpmName() {
final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
OpenAPI api = TestUtils.createOpenAPI();
codegen.setOpenAPI(api);
codegen.processOpts();
Assert.assertEquals(codegen.getNpmVersion(), "1.0.0");
}
@Test
public void testWithNpmVersion() { public void testWithNpmVersion() {
final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen(); final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
@ -43,12 +29,24 @@ public class TypescriptAngularApiVersionTest {
codegen.additionalProperties().put("npmVersion", "2.0.0"); codegen.additionalProperties().put("npmVersion", "2.0.0");
OpenAPI api = TestUtils.createOpenAPI(); OpenAPI api = TestUtils.createOpenAPI();
codegen.setOpenAPI(api);
codegen.processOpts(); codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "2.0.0"); Assert.assertEquals(codegen.getNpmVersion(), "2.0.0");
} }
@Test(description = "tests if default version is used when neither OpenAPI version nor npmVersion additional property has been provided")
public void testWithoutApiVersion() {
final TypeScriptAngularClientCodegen codegen = new TypeScriptAngularClientCodegen();
codegen.additionalProperties().put("npmName", "just-a-test");
OpenAPI api = TestUtils.createOpenAPI();
api.getInfo().setVersion(null);
codegen.processOpts();
codegen.preprocessOpenAPI(api);
Assert.assertEquals(codegen.getNpmVersion(), "1.0.0");
}
} }