feat(typescript-angular): add flag for using string enums (#3464)

* feat(typescript): add flag for using string enums

* fix: adjust templates

* fix: repair logic

* fix: remove sample

* fix: add to v7 sample

* fix: remove unneeded lines
This commit is contained in:
Erik Seliger 2019-07-31 21:16:49 +02:00 committed by Esteban Gehring
parent 8b054e6f8e
commit 0e621dcc29
34 changed files with 102 additions and 26 deletions

View File

@ -1,6 +1,7 @@
{ {
"npmName": "@openapitools/typescript-angular-petstore", "npmName": "@openapitools/typescript-angular-petstore",
"npmVersion": "1.0.0", "npmVersion": "1.0.0",
"npmRepository" : "https://skimdb.npmjs.com/registry", "stringEnums": true,
"snapshot" : false "npmRepository": "https://skimdb.npmjs.com/registry",
"snapshot": false
} }

View File

@ -26,3 +26,4 @@ sidebar_label: typescript-angular
|modelSuffix|The suffix of the generated model.| |null| |modelSuffix|The suffix of the generated model.| |null|
|modelFileSuffix|The suffix of the file of the generated model (model<suffix>.ts).| |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'.| |camelCase| |fileNaming|Naming convention for the output files: 'camelCase', 'kebab-case'.| |camelCase|
|stringEnums|Generate string enums instead of objects for enum values.| |false|

View File

@ -55,6 +55,9 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
protected String npmName = null; protected String npmName = null;
protected String npmVersion = "1.0.0"; protected String npmVersion = "1.0.0";
protected String enumSuffix = "Enum";
protected String classEnumSeparator = ".";
public AbstractTypeScriptClientCodegen() { public AbstractTypeScriptClientCodegen() {
super(); super();
@ -551,8 +554,7 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
@Override @Override
public String toEnumName(CodegenProperty property) { public String toEnumName(CodegenProperty property) {
String enumName = toModelName(property.name) + "Enum"; String enumName = toModelName(property.name) + enumSuffix;
if (enumName.matches("\\d.*")) { // starts with number if (enumName.matches("\\d.*")) { // starts with number
return "_" + enumName; return "_" + enumName;
} else { } else {
@ -571,14 +573,14 @@ public abstract class AbstractTypeScriptClientCodegen extends DefaultCodegen imp
// name enum with model name, e.g. StatusEnum => Pet.StatusEnum // name enum with model name, e.g. StatusEnum => Pet.StatusEnum
for (CodegenProperty var : cm.vars) { for (CodegenProperty var : cm.vars) {
if (Boolean.TRUE.equals(var.isEnum)) { if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + "." + var.enumName); var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + classEnumSeparator + var.enumName);
} }
} }
if (cm.parent != null) { if (cm.parent != null) {
for (CodegenProperty var : cm.allVars) { for (CodegenProperty var : cm.allVars) {
if (Boolean.TRUE.equals(var.isEnum)) { if (Boolean.TRUE.equals(var.isEnum)) {
var.datatypeWithEnum = var.datatypeWithEnum var.datatypeWithEnum = var.datatypeWithEnum
.replace(var.enumName, cm.classname + "." + var.enumName); .replace(var.enumName, cm.classname + classEnumSeparator + var.enumName);
} }
} }
} }

View File

@ -49,6 +49,8 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
public static final String MODEL_SUFFIX = "modelSuffix"; public static final String MODEL_SUFFIX = "modelSuffix";
public static final String MODEL_FILE_SUFFIX = "modelFileSuffix"; public static final String MODEL_FILE_SUFFIX = "modelFileSuffix";
public static final String FILE_NAMING = "fileNaming"; public static final String FILE_NAMING = "fileNaming";
public static final String STRING_ENUMS = "stringEnums";
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
protected String ngVersion = "7.0.0"; protected String ngVersion = "7.0.0";
protected String npmRepository = null; protected String npmRepository = null;
@ -57,6 +59,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
protected String modelSuffix = ""; protected String modelSuffix = "";
protected String modelFileSuffix = ""; protected String modelFileSuffix = "";
protected String fileNaming = "camelCase"; protected String fileNaming = "camelCase";
protected Boolean stringEnums = false;
private boolean taggedUnions = false; private boolean taggedUnions = false;
@ -89,6 +92,7 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
this.cliOptions.add(new CliOption(MODEL_SUFFIX, "The suffix of the generated model.")); 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).")); 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'.").defaultValue(this.fileNaming)); this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
} }
@Override @Override
@ -137,6 +141,15 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
addNpmPackageGeneration(ngVersion); addNpmPackageGeneration(ngVersion);
} }
if (additionalProperties.containsKey(STRING_ENUMS)) {
setStringEnums(Boolean.valueOf(additionalProperties.get(STRING_ENUMS).toString()));
additionalProperties.put("stringEnums", getStringEnums());
if (getStringEnums()) {
enumSuffix = "";
classEnumSeparator = "";
}
}
if (additionalProperties.containsKey(WITH_INTERFACES)) { if (additionalProperties.containsKey(WITH_INTERFACES)) {
boolean withInterfaces = Boolean.parseBoolean(additionalProperties.get(WITH_INTERFACES).toString()); boolean withInterfaces = Boolean.parseBoolean(additionalProperties.get(WITH_INTERFACES).toString());
if (withInterfaces) { if (withInterfaces) {
@ -272,6 +285,14 @@ public class TypeScriptAngularClientCodegen extends AbstractTypeScriptClientCode
return indexPackage.replace('.', File.separatorChar); return indexPackage.replace('.', File.separatorChar);
} }
public void setStringEnums(boolean value) {
stringEnums = value;
}
public Boolean getStringEnums() {
return stringEnums;
}
@Override @Override
public boolean isDataTypeFile(final String dataType) { public boolean isDataTypeFile(final String dataType) {
return dataType != null && dataType.equals("Blob"); return dataType != null && dataType.equals("Blob");

View File

@ -1,3 +1,13 @@
{{#stringEnums}}
export enum {{classname}} {
{{#allowableValues}}
{{#enumVars}}
{{name}} = {{{value}}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
{{/stringEnums}}
{{^stringEnums}}
export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; export type {{classname}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{classname}} = { export const {{classname}} = {
@ -6,4 +16,5 @@ export const {{classname}} = {
{{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}} {{name}}: {{{value}}} as {{classname}}{{^-last}},{{/-last}}
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
}; };
{{/stringEnums}}

View File

@ -1,8 +1,20 @@
{{#hasEnums}} {{#hasEnums}}
{{^stringEnums}}
export namespace {{classname}} { export namespace {{classname}} {
{{/stringEnums}}
{{#vars}} {{#vars}}
{{#isEnum}} {{#isEnum}}
{{#stringEnums}}
export enum {{classname}}{{enumName}} {
{{#allowableValues}}
{{#enumVars}}
{{name}} = {{{value}}}{{^-last}},{{/-last}}
{{/enumVars}}
{{/allowableValues}}
};
{{/stringEnums}}
{{^stringEnums}}
export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}}; export type {{enumName}} = {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}} | {{/-last}}{{/enumVars}}{{/allowableValues}};
export const {{enumName}} = { export const {{enumName}} = {
{{#allowableValues}} {{#allowableValues}}
@ -11,6 +23,8 @@ export namespace {{classname}} {
{{/enumVars}} {{/enumVars}}
{{/allowableValues}} {{/allowableValues}}
}; };
{{/stringEnums}}
{{/isEnum}} {{/isEnum}}
{{/vars}} {{/vars}}
}{{/hasEnums}} {{^stringEnums}}}{{/stringEnums}}
{{/hasEnums}}

View File

@ -25,6 +25,7 @@ import java.util.Map;
public class TypeScriptAngularClientOptionsProvider implements OptionsProvider { public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
public static final String SUPPORTS_ES6_VALUE = "false"; public static final String SUPPORTS_ES6_VALUE = "false";
public static final String STRING_ENUMS_VALUE = "false";
public static final String SORT_PARAMS_VALUE = "false"; public static final String SORT_PARAMS_VALUE = "false";
public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true"; public static final String ENSURE_UNIQUE_PARAMS_VALUE = "true";
public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase"; public static final String MODEL_PROPERTY_NAMING_VALUE = "camelCase";
@ -52,6 +53,7 @@ public class TypeScriptAngularClientOptionsProvider implements OptionsProvider {
.put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE) .put(CodegenConstants.ENSURE_UNIQUE_PARAMS, ENSURE_UNIQUE_PARAMS_VALUE)
.put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE) .put(CodegenConstants.MODEL_PROPERTY_NAMING, MODEL_PROPERTY_NAMING_VALUE)
.put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE) .put(CodegenConstants.SUPPORTS_ES6, SUPPORTS_ES6_VALUE)
.put(TypeScriptAngularClientCodegen.STRING_ENUMS, STRING_ENUMS_VALUE)
.put(TypeScriptAngularClientCodegen.NPM_NAME, NMP_NAME) .put(TypeScriptAngularClientCodegen.NPM_NAME, NMP_NAME)
.put(TypeScriptAngularClientCodegen.NPM_VERSION, NMP_VERSION) .put(TypeScriptAngularClientCodegen.NPM_VERSION, NMP_VERSION)
.put(TypeScriptAngularClientCodegen.SNAPSHOT, Boolean.FALSE.toString()) .put(TypeScriptAngularClientCodegen.SNAPSHOT, Boolean.FALSE.toString())

View File

@ -48,6 +48,8 @@ public class TypeScriptAngularClientOptionsTest extends AbstractOptionsTest {
times = 1; times = 1;
clientCodegen.setSupportsES6(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.SUPPORTS_ES6_VALUE)); clientCodegen.setSupportsES6(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.SUPPORTS_ES6_VALUE));
times = 1; times = 1;
clientCodegen.setStringEnums(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.STRING_ENUMS_VALUE));
times = 1;
clientCodegen.setPrependFormOrBodyParameters(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)); clientCodegen.setPrependFormOrBodyParameters(Boolean.valueOf(TypeScriptAngularClientOptionsProvider.PREPEND_FORM_OR_BODY_PARAMETERS_VALUE));
times = 1; times = 1;
}}; }};

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -22,15 +22,14 @@ export interface Order {
/** /**
* Order Status * Order Status
*/ */
status?: Order.StatusEnum; status?: OrderStatus;
complete?: boolean; complete?: boolean;
} }
export namespace Order { export enum OrderStatus {
export type StatusEnum = 'placed' | 'approved' | 'delivered'; Placed = 'placed',
export const StatusEnum = { Approved = 'approved',
Placed: 'placed' as StatusEnum, Delivered = 'delivered'
Approved: 'approved' as StatusEnum, };
Delivered: 'delivered' as StatusEnum
};
}

View File

@ -25,14 +25,13 @@ export interface Pet {
/** /**
* pet status in the store * pet status in the store
*/ */
status?: Pet.StatusEnum; status?: PetStatus;
}
export namespace Pet {
export type StatusEnum = 'available' | 'pending' | 'sold';
export const StatusEnum = {
Available: 'available' as StatusEnum,
Pending: 'pending' as StatusEnum,
Sold: 'sold' as StatusEnum
};
} }
export enum PetStatus {
Available = 'available',
Pending = 'pending',
Sold = 'sold'
};

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }

View File

@ -34,3 +34,4 @@ export namespace Order {
}; };
} }

View File

@ -36,3 +36,4 @@ export namespace Pet {
}; };
} }