|
|
|
|
@@ -17,17 +17,12 @@
|
|
|
|
|
|
|
|
|
|
package org.openapitools.codegen.languages;
|
|
|
|
|
|
|
|
|
|
import com.github.curiousoddman.rgxgen.RgxGen;
|
|
|
|
|
import com.google.common.collect.Sets;
|
|
|
|
|
|
|
|
|
|
import io.swagger.v3.core.util.Json;
|
|
|
|
|
import io.swagger.v3.oas.models.media.*;
|
|
|
|
|
import io.swagger.v3.oas.models.media.MediaType;
|
|
|
|
|
import io.swagger.v3.oas.models.parameters.RequestBody;
|
|
|
|
|
import io.swagger.v3.oas.models.OpenAPI;
|
|
|
|
|
import io.swagger.v3.oas.models.media.ArraySchema;
|
|
|
|
|
import io.swagger.v3.oas.models.media.ComposedSchema;
|
|
|
|
|
import io.swagger.v3.oas.models.media.Schema;
|
|
|
|
|
import io.swagger.v3.oas.models.parameters.Parameter;
|
|
|
|
|
import io.swagger.v3.oas.models.parameters.RequestBody;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
import org.openapitools.codegen.*;
|
|
|
|
|
import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
|
|
|
|
|
@@ -40,42 +35,30 @@ import org.openapitools.codegen.model.OperationsMap;
|
|
|
|
|
import org.openapitools.codegen.utils.ModelUtils;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import com.github.curiousoddman.rgxgen.RgxGen;
|
|
|
|
|
import com.github.curiousoddman.rgxgen.config.RgxGenOption;
|
|
|
|
|
import com.github.curiousoddman.rgxgen.config.RgxGenProperties;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.time.OffsetDateTime;
|
|
|
|
|
import java.time.ZoneOffset;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
|
|
|
|
|
import static org.openapitools.codegen.utils.StringUtils.camelize;
|
|
|
|
|
import static org.openapitools.codegen.utils.StringUtils.underscore;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
import static org.openapitools.codegen.utils.OnceLogger.once;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenConfig {
|
|
|
|
|
public class TypeScriptClientCodegen extends AbstractTypeScriptClientCodegen implements CodegenConfig {
|
|
|
|
|
private final Logger LOGGER = LoggerFactory.getLogger(TypeScriptClientCodegen.class);
|
|
|
|
|
|
|
|
|
|
private static final String X_DISCRIMINATOR_TYPE = "x-discriminator-value";
|
|
|
|
|
private static final String UNDEFINED_VALUE = "undefined";
|
|
|
|
|
|
|
|
|
|
private static final String FRAMEWORK_SWITCH = "framework";
|
|
|
|
|
private static final String FRAMEWORK_SWITCH_DESC = "Specify the framework which should be used in the client code.";
|
|
|
|
|
private static final String[] FRAMEWORKS = { "fetch-api", "jquery" };
|
|
|
|
|
private static final String[] FRAMEWORKS = {"fetch-api", "jquery"};
|
|
|
|
|
private static final String PLATFORM_SWITCH = "platform";
|
|
|
|
|
private static final String PLATFORM_SWITCH_DESC = "Specifies the platform the code should run on. The default is 'node' for the 'request' framework and 'browser' otherwise.";
|
|
|
|
|
private static final String[] PLATFORMS = { "browser", "node", "deno" };
|
|
|
|
|
private static final String[] PLATFORMS = {"browser", "node", "deno"};
|
|
|
|
|
private static final String IMPORT_FILE_EXTENSION_SWITCH = "importFileExtension";
|
|
|
|
|
private static final String IMPORT_FILE_EXTENSION_SWITCH_DESC = "File extension to use with relative imports. Set it to '.js' or '.mjs' when using [ESM](https://nodejs.org/api/esm.html). Defaults to '.ts' when 'platform' is set to 'deno'.";
|
|
|
|
|
private static final String FILE_CONTENT_DATA_TYPE= "fileContentDataType";
|
|
|
|
|
private static final String FILE_CONTENT_DATA_TYPE = "fileContentDataType";
|
|
|
|
|
private static final String FILE_CONTENT_DATA_TYPE_DESC = "Specifies the type to use for the content of a file - i.e. Blob (Browser, Deno) / Buffer (node)";
|
|
|
|
|
private static final String USE_RXJS_SWITCH = "useRxJS";
|
|
|
|
|
private static final String USE_RXJS_SWITCH_DESC = "Enable this to internally use rxjs observables. If disabled, a stub is used instead. This is required for the 'angular' framework.";
|
|
|
|
|
@@ -85,27 +68,17 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
private static final String USE_OBJECT_PARAMS_SWITCH = "useObjectParameters";
|
|
|
|
|
private static final String USE_OBJECT_PARAMS_DESC = "Use aggregate parameter objects as function arguments for api operations instead of passing each parameter as a separate function argument.";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Map<String, String> frameworkToHttpLibMap;
|
|
|
|
|
|
|
|
|
|
// NPM Options
|
|
|
|
|
private static final String SNAPSHOT = "snapshot";
|
|
|
|
|
@SuppressWarnings("squid:S5164")
|
|
|
|
|
protected static final ThreadLocal<SimpleDateFormat> SNAPSHOT_SUFFIX_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT));
|
|
|
|
|
private static final String NPM_REPOSITORY = "npmRepository";
|
|
|
|
|
private static final String NPM_NAME = "npmName";
|
|
|
|
|
private static final String NPM_VERSION = "npmVersion";
|
|
|
|
|
|
|
|
|
|
// NPM Option Values
|
|
|
|
|
protected String npmRepository = null;
|
|
|
|
|
protected String snapshot = null;
|
|
|
|
|
protected String npmName = null;
|
|
|
|
|
protected String npmVersion = "1.0.0";
|
|
|
|
|
protected String modelPropertyNaming = "camelCase";
|
|
|
|
|
protected HashSet<String> languageGenericTypes;
|
|
|
|
|
|
|
|
|
|
private DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
|
|
|
|
|
private DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
|
|
|
|
|
private final DateTimeFormatter iso8601Date = DateTimeFormatter.ISO_DATE;
|
|
|
|
|
private final DateTimeFormatter iso8601DateTime = DateTimeFormatter.ISO_DATE_TIME;
|
|
|
|
|
|
|
|
|
|
public TypeScriptClientCodegen() {
|
|
|
|
|
super();
|
|
|
|
|
@@ -114,88 +87,23 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
this.frameworkToHttpLibMap.put("fetch-api", "isomorphic-fetch");
|
|
|
|
|
this.frameworkToHttpLibMap.put("jquery", "jquery");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.EXPERIMENTAL).build();
|
|
|
|
|
|
|
|
|
|
outputFolder = "generated-code" + File.separator + "typescript";
|
|
|
|
|
embeddedTemplateDir = templateDir = "typescript";
|
|
|
|
|
|
|
|
|
|
supportsInheritance = true;
|
|
|
|
|
|
|
|
|
|
// NOTE: TypeScript uses camel cased reserved words, while models are title cased. We don't want lowercase comparisons.
|
|
|
|
|
reservedWords.addAll(Arrays.asList(
|
|
|
|
|
// local variable names used in API methods (endpoints)
|
|
|
|
|
"varLocalPath", "queryParameters", "headerParams", "formParams", "useFormData", "varLocalDeferred",
|
|
|
|
|
"requestOptions", "from",
|
|
|
|
|
"from",
|
|
|
|
|
// Typescript reserved words
|
|
|
|
|
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "constructor", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
|
|
|
|
|
"constructor"));
|
|
|
|
|
|
|
|
|
|
languageSpecificPrimitives = new HashSet<>(Arrays.asList(
|
|
|
|
|
"string",
|
|
|
|
|
"String",
|
|
|
|
|
"boolean",
|
|
|
|
|
"Boolean",
|
|
|
|
|
"Double",
|
|
|
|
|
"Integer",
|
|
|
|
|
"Long",
|
|
|
|
|
"Float",
|
|
|
|
|
"Object",
|
|
|
|
|
"Array",
|
|
|
|
|
"Date",
|
|
|
|
|
"number",
|
|
|
|
|
"any",
|
|
|
|
|
"File",
|
|
|
|
|
"Error",
|
|
|
|
|
"Map",
|
|
|
|
|
"Set"
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
languageGenericTypes = new HashSet<>(Arrays.asList(
|
|
|
|
|
"Array"
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
instantiationTypes.put("array", "Array");
|
|
|
|
|
|
|
|
|
|
typeMapping = new HashMap<>();
|
|
|
|
|
typeMapping.put("Array", "Array");
|
|
|
|
|
typeMapping.put("array", "Array");
|
|
|
|
|
typeMapping.put("List", "Array");
|
|
|
|
|
typeMapping.put("boolean", "boolean");
|
|
|
|
|
typeMapping.put("string", "string");
|
|
|
|
|
typeMapping.put("int", "number");
|
|
|
|
|
typeMapping.put("float", "number");
|
|
|
|
|
typeMapping.put("number", "number");
|
|
|
|
|
typeMapping.put("long", "number");
|
|
|
|
|
typeMapping.put("short", "number");
|
|
|
|
|
typeMapping.put("char", "string");
|
|
|
|
|
typeMapping.put("double", "number");
|
|
|
|
|
typeMapping.put("object", "any");
|
|
|
|
|
typeMapping.put("integer", "number");
|
|
|
|
|
typeMapping.put("Map", "any");
|
|
|
|
|
typeMapping.put("map", "any");
|
|
|
|
|
typeMapping.put("Set", "Set");
|
|
|
|
|
typeMapping.put("set", "Set");
|
|
|
|
|
typeMapping.put("date", "string");
|
|
|
|
|
typeMapping.put("DateTime", "Date");
|
|
|
|
|
typeMapping.put("binary", "any");
|
|
|
|
|
typeMapping.put("File", "any");
|
|
|
|
|
typeMapping.put("file", "any");
|
|
|
|
|
typeMapping.put("ByteArray", "string");
|
|
|
|
|
typeMapping.put("UUID", "string");
|
|
|
|
|
typeMapping.put("Error", "Error");
|
|
|
|
|
typeMapping.put("AnyType", "any");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." +
|
|
|
|
|
" Required to generate a full package"));
|
|
|
|
|
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()));
|
|
|
|
|
cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json"));
|
|
|
|
|
cliOptions.add(CliOption.newBoolean(SNAPSHOT,
|
|
|
|
|
"When setting this property to true, the version will be suffixed with -SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.get().toPattern(),
|
|
|
|
|
false));
|
|
|
|
|
|
|
|
|
|
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(TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE, TypeScriptClientCodegen.FILE_CONTENT_DATA_TYPE_DESC).defaultValue("Buffer"));
|
|
|
|
|
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_RXJS_SWITCH, TypeScriptClientCodegen.USE_RXJS_SWITCH_DESC).defaultValue("false"));
|
|
|
|
|
cliOptions.add(new CliOption(TypeScriptClientCodegen.USE_OBJECT_PARAMS_SWITCH, TypeScriptClientCodegen.USE_OBJECT_PARAMS_DESC).defaultValue("false"));
|
|
|
|
|
@@ -203,20 +111,23 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
cliOptions.add(new CliOption(TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH, TypeScriptClientCodegen.IMPORT_FILE_EXTENSION_SWITCH_DESC));
|
|
|
|
|
|
|
|
|
|
CliOption frameworkOption = new CliOption(TypeScriptClientCodegen.FRAMEWORK_SWITCH, TypeScriptClientCodegen.FRAMEWORK_SWITCH_DESC);
|
|
|
|
|
for (String option: TypeScriptClientCodegen.FRAMEWORKS) {
|
|
|
|
|
for (String option : TypeScriptClientCodegen.FRAMEWORKS) {
|
|
|
|
|
frameworkOption.addEnum(option, option);
|
|
|
|
|
}
|
|
|
|
|
frameworkOption.defaultValue(FRAMEWORKS[0]);
|
|
|
|
|
cliOptions.add(frameworkOption);
|
|
|
|
|
|
|
|
|
|
CliOption platformOption = new CliOption(TypeScriptClientCodegen.PLATFORM_SWITCH, TypeScriptClientCodegen.PLATFORM_SWITCH_DESC);
|
|
|
|
|
for (String option: TypeScriptClientCodegen.PLATFORMS) {
|
|
|
|
|
for (String option : TypeScriptClientCodegen.PLATFORMS) {
|
|
|
|
|
platformOption.addEnum(option, option);
|
|
|
|
|
}
|
|
|
|
|
platformOption.defaultValue(PLATFORMS[0]);
|
|
|
|
|
|
|
|
|
|
cliOptions.add(platformOption);
|
|
|
|
|
|
|
|
|
|
// Set property naming to camelCase
|
|
|
|
|
supportModelPropertyNaming(CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.camelCase);
|
|
|
|
|
|
|
|
|
|
// Git
|
|
|
|
|
supportingFiles.add(new SupportingFile(".gitignore.mustache", "", ".gitignore"));
|
|
|
|
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
|
|
|
|
@@ -274,42 +185,12 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
this.npmVersion = npmVersion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public CodegenType getTag() {
|
|
|
|
|
return CodegenType.CLIENT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@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.parseBoolean(additionalProperties.get(SNAPSHOT).toString())) {
|
|
|
|
|
if (npmVersion.toUpperCase(Locale.ROOT).matches("^.*-SNAPSHOT$")) {
|
|
|
|
|
this.setNpmVersion(npmVersion + "." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
|
|
|
|
|
} else {
|
|
|
|
|
this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.get().format(new Date()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
additionalProperties.put(NPM_VERSION, npmVersion);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
|
|
|
|
final Object propFramework = additionalProperties.get(FRAMEWORK_SWITCH);
|
|
|
|
|
|
|
|
|
|
Map<String, Boolean> frameworks = new HashMap<>();
|
|
|
|
|
for (String framework: FRAMEWORKS) {
|
|
|
|
|
for (String framework : FRAMEWORKS) {
|
|
|
|
|
frameworks.put(framework, framework.equals(propFramework));
|
|
|
|
|
}
|
|
|
|
|
objs.put("framework", propFramework);
|
|
|
|
|
@@ -331,7 +212,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
|
|
|
|
|
OperationMap operationsMap = operations.getOperations();
|
|
|
|
|
List<CodegenOperation> operationList = operationsMap.getOperation();
|
|
|
|
|
for (CodegenOperation operation: operationList) {
|
|
|
|
|
for (CodegenOperation operation : operationList) {
|
|
|
|
|
List<CodegenResponse> responses = operation.responses;
|
|
|
|
|
operation.returnType = this.getReturnType(responses);
|
|
|
|
|
}
|
|
|
|
|
@@ -340,12 +221,13 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the correct return type based on all 2xx HTTP responses defined for an operation.
|
|
|
|
|
*
|
|
|
|
|
* @param responses all CodegenResponses defined for one operation
|
|
|
|
|
* @return TypeScript return type
|
|
|
|
|
*/
|
|
|
|
|
private String getReturnType(List<CodegenResponse> responses) {
|
|
|
|
|
Set<String> returnTypes = new HashSet<>();
|
|
|
|
|
for (CodegenResponse response: responses) {
|
|
|
|
|
for (CodegenResponse response : responses) {
|
|
|
|
|
if (response.is2xx) {
|
|
|
|
|
if (response.dataType != null) {
|
|
|
|
|
returnTypes.add(response.dataType);
|
|
|
|
|
@@ -362,18 +244,21 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return String.join(" | ", returnTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String escapeReservedWord(String name) {
|
|
|
|
|
if (this.reservedWordsMappings().containsKey(name)) {
|
|
|
|
|
return this.reservedWordsMappings().get(name);
|
|
|
|
|
}
|
|
|
|
|
return "_" + name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toParamName(String name) {
|
|
|
|
|
// should be the same as variable name
|
|
|
|
|
return toVarName(name);
|
|
|
|
|
// sanitize name
|
|
|
|
|
name = sanitizeName(name);
|
|
|
|
|
|
|
|
|
|
if ("_".equals(name)) {
|
|
|
|
|
name = "_u";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if it's all upper case, do nothing
|
|
|
|
|
if (name.matches("^[A-Z_]*$")) {
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return super.toParamName(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -390,22 +275,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
name = getNameUsingModelPropertyNaming(name);
|
|
|
|
|
|
|
|
|
|
// for reserved word or word starting with number, append _
|
|
|
|
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
|
|
|
|
name = escapeReservedWord(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toModelName(final String name) {
|
|
|
|
|
String fullModelName = name;
|
|
|
|
|
fullModelName = addPrefix(fullModelName, modelNamePrefix);
|
|
|
|
|
fullModelName = addSuffix(fullModelName, modelNameSuffix);
|
|
|
|
|
return toTypescriptTypeName(fullModelName, "Model");
|
|
|
|
|
return super.toVarName(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -414,283 +284,12 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return "../" + modelPackage() + "/" + toModelName(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String addPrefix(String name, String prefix) {
|
|
|
|
|
if (!StringUtils.isEmpty(prefix)) {
|
|
|
|
|
name = prefix + "_" + name;
|
|
|
|
|
}
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String addSuffix(String name, String suffix) {
|
|
|
|
|
if (!StringUtils.isEmpty(suffix)) {
|
|
|
|
|
name = name + "_" + suffix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String toTypescriptTypeName(final String name, String safePrefix) {
|
|
|
|
|
ArrayList<String> exceptions = new ArrayList<>(Arrays.asList("\\|", " "));
|
|
|
|
|
String sanName = sanitizeName(name, "(?![| ])\\W", exceptions);
|
|
|
|
|
|
|
|
|
|
sanName = camelize(sanName);
|
|
|
|
|
|
|
|
|
|
// model name cannot use reserved keyword, e.g. return
|
|
|
|
|
// this is unlikely to happen, because we have just camelized the name, while reserved words are usually all lowercase
|
|
|
|
|
if (isReservedWord(sanName)) {
|
|
|
|
|
String modelName = safePrefix + sanName;
|
|
|
|
|
LOGGER.warn("{} (reserved word) cannot be used as model name. Renamed to {}", sanName, modelName);
|
|
|
|
|
return modelName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// model name starts with number
|
|
|
|
|
if (sanName.matches("^\\d.*")) {
|
|
|
|
|
String modelName = safePrefix + sanName; // e.g. 200Response => Model200Response
|
|
|
|
|
LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", sanName,
|
|
|
|
|
modelName);
|
|
|
|
|
return modelName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (languageSpecificPrimitives.contains(sanName)) {
|
|
|
|
|
String modelName = safePrefix + sanName;
|
|
|
|
|
LOGGER.warn("{} (model name matches existing language type) cannot be used as a model name. Renamed to {}",
|
|
|
|
|
sanName, modelName);
|
|
|
|
|
return modelName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return sanName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toModelFilename(String name) {
|
|
|
|
|
// should be the same as the model name
|
|
|
|
|
return toModelName(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected String getParameterDataType(Parameter parameter, Schema p) {
|
|
|
|
|
// handle enums of various data types
|
|
|
|
|
Schema inner;
|
|
|
|
|
if (ModelUtils.isArraySchema(p)) {
|
|
|
|
|
ArraySchema mp1 = (ArraySchema) p;
|
|
|
|
|
inner = mp1.getItems();
|
|
|
|
|
return this.getSchemaType(p) + "<" + this.getParameterDataType(parameter, inner) + ">";
|
|
|
|
|
} else if (ModelUtils.isMapSchema(p)) {
|
|
|
|
|
inner = (Schema) p.getAdditionalProperties();
|
|
|
|
|
return "{ [key: string]: " + this.getParameterDataType(parameter, inner) + "; }";
|
|
|
|
|
} else if (ModelUtils.isStringSchema(p)) {
|
|
|
|
|
// Handle string enums
|
|
|
|
|
if (p.getEnum() != null) {
|
|
|
|
|
return enumValuesToEnumTypeUnion(p.getEnum(), "string");
|
|
|
|
|
}
|
|
|
|
|
} else if (ModelUtils.isIntegerSchema(p)) {
|
|
|
|
|
// Handle integer enums
|
|
|
|
|
if (p.getEnum() != null) {
|
|
|
|
|
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
|
|
|
|
|
}
|
|
|
|
|
} else if (ModelUtils.isNumberSchema(p)) {
|
|
|
|
|
// Handle double enums
|
|
|
|
|
if (p.getEnum() != null) {
|
|
|
|
|
return numericEnumValuesToEnumTypeUnion(new ArrayList<Number>(p.getEnum()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return this.getTypeDeclaration(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a list of strings to a literal union for representing enum values as a type.
|
|
|
|
|
* Example output: 'available' | 'pending' | 'sold'
|
|
|
|
|
*
|
|
|
|
|
* @param values list of allowed enum values
|
|
|
|
|
* @param dataType either "string" or "number"
|
|
|
|
|
* @return a literal union for representing enum values as a type
|
|
|
|
|
*/
|
|
|
|
|
protected String enumValuesToEnumTypeUnion(List<String> values, String dataType) {
|
|
|
|
|
StringBuilder b = new StringBuilder();
|
|
|
|
|
boolean isFirst = true;
|
|
|
|
|
for (String value : values) {
|
|
|
|
|
if (!isFirst) {
|
|
|
|
|
b.append(" | ");
|
|
|
|
|
}
|
|
|
|
|
b.append(toEnumValue(value, dataType));
|
|
|
|
|
isFirst = false;
|
|
|
|
|
}
|
|
|
|
|
return b.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Converts a list of numbers to a literal union for representing enum values as a type.
|
|
|
|
|
* Example output: 3 | 9 | 55
|
|
|
|
|
*
|
|
|
|
|
* @param values a list of numbers
|
|
|
|
|
* @return a literal union for representing enum values as a type
|
|
|
|
|
*/
|
|
|
|
|
protected String numericEnumValuesToEnumTypeUnion(List<Number> values) {
|
|
|
|
|
List<String> stringValues = new ArrayList<>();
|
|
|
|
|
for (Number value : values) {
|
|
|
|
|
stringValues.add(value.toString());
|
|
|
|
|
}
|
|
|
|
|
return enumValuesToEnumTypeUnion(stringValues, "number");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toDefaultValue(Schema p) {
|
|
|
|
|
if (ModelUtils.isBooleanSchema(p)) {
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else if (ModelUtils.isDateSchema(p)) {
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else if (ModelUtils.isDateTimeSchema(p)) {
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else if (ModelUtils.isNumberSchema(p)) {
|
|
|
|
|
if (p.getDefault() != null) {
|
|
|
|
|
return p.getDefault().toString();
|
|
|
|
|
}
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else if (ModelUtils.isIntegerSchema(p)) {
|
|
|
|
|
if (p.getDefault() != null) {
|
|
|
|
|
return p.getDefault().toString();
|
|
|
|
|
}
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else if (ModelUtils.isStringSchema(p)) {
|
|
|
|
|
if (p.getDefault() != null) {
|
|
|
|
|
return "'" + (String) p.getDefault() + "'";
|
|
|
|
|
}
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
} else {
|
|
|
|
|
return UNDEFINED_VALUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected boolean isReservedWord(String word) {
|
|
|
|
|
// NOTE: This differs from super's implementation in that TypeScript does _not_ want case insensitive matching.
|
|
|
|
|
return reservedWords.contains(word);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getSchemaType(Schema p) {
|
|
|
|
|
String openAPIType = super.getSchemaType(p);
|
|
|
|
|
String type = null;
|
|
|
|
|
if (ModelUtils.isComposedSchema(p)) {
|
|
|
|
|
return openAPIType;
|
|
|
|
|
} else if (typeMapping.containsKey(openAPIType)) {
|
|
|
|
|
type = typeMapping.get(openAPIType);
|
|
|
|
|
if (languageSpecificPrimitives.contains(type))
|
|
|
|
|
return type;
|
|
|
|
|
} else
|
|
|
|
|
type = openAPIType;
|
|
|
|
|
return toModelName(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toOperationId(String operationId) {
|
|
|
|
|
// throw exception if method name is empty
|
|
|
|
|
if (StringUtils.isEmpty(operationId)) {
|
|
|
|
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// method name cannot use reserved keyword, e.g. return
|
|
|
|
|
// append _ at the beginning, e.g. _return
|
|
|
|
|
if (isReservedWord(operationId)) {
|
|
|
|
|
return escapeReservedWord(camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return camelize(sanitizeName(operationId), LOWERCASE_FIRST_LETTER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setModelPropertyNaming(String naming) {
|
|
|
|
|
if ("original".equals(naming) || "camelCase".equals(naming) ||
|
|
|
|
|
"PascalCase".equals(naming) || "snake_case".equals(naming)) {
|
|
|
|
|
this.modelPropertyNaming = naming;
|
|
|
|
|
} else {
|
|
|
|
|
throw new IllegalArgumentException("Invalid model property naming '" +
|
|
|
|
|
naming + "'. Must be 'original', 'camelCase', " +
|
|
|
|
|
"'PascalCase' or 'snake_case'");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getModelPropertyNaming() {
|
|
|
|
|
return this.modelPropertyNaming;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getNameUsingModelPropertyNaming(String name) {
|
|
|
|
|
switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) {
|
|
|
|
|
case original:
|
|
|
|
|
return name;
|
|
|
|
|
case camelCase:
|
|
|
|
|
return camelize(name, LOWERCASE_FIRST_LETTER);
|
|
|
|
|
case PascalCase:
|
|
|
|
|
return camelize(name);
|
|
|
|
|
case snake_case:
|
|
|
|
|
return underscore(name);
|
|
|
|
|
default:
|
|
|
|
|
throw new IllegalArgumentException("Invalid model property naming '" +
|
|
|
|
|
name + "'. Must be 'original', 'camelCase', " +
|
|
|
|
|
"'PascalCase' or 'snake_case'");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toEnumValue(String value, String datatype) {
|
|
|
|
|
if ("number".equals(datatype)) {
|
|
|
|
|
return value;
|
|
|
|
|
} else {
|
|
|
|
|
return "\'" + escapeText(value) + "\'";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toEnumDefaultValue(String value, String datatype) {
|
|
|
|
|
return datatype + "_" + value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toEnumVarName(String name, String datatype) {
|
|
|
|
|
if (name.length() == 0) {
|
|
|
|
|
return "Empty";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for symbol, e.g. $, #
|
|
|
|
|
if (getSymbolName(name) != null) {
|
|
|
|
|
return camelize(getSymbolName(name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// number
|
|
|
|
|
if ("number".equals(datatype)) {
|
|
|
|
|
String varName = "NUMBER_" + name;
|
|
|
|
|
|
|
|
|
|
varName = varName.replaceAll("-", "MINUS_");
|
|
|
|
|
varName = varName.replaceAll("\\+", "PLUS_");
|
|
|
|
|
varName = varName.replaceAll("\\.", "_DOT_");
|
|
|
|
|
return varName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// string
|
|
|
|
|
String enumName = sanitizeName(name);
|
|
|
|
|
enumName = enumName.replaceFirst("^_", "");
|
|
|
|
|
enumName = enumName.replaceFirst("_$", "");
|
|
|
|
|
|
|
|
|
|
// camelize the enum variable name
|
|
|
|
|
// ref: https://basarat.gitbooks.io/typescript/content/docs/enums.html
|
|
|
|
|
enumName = camelize(enumName);
|
|
|
|
|
|
|
|
|
|
if (enumName.matches("\\d.*")) { // starts with number
|
|
|
|
|
return "_" + enumName;
|
|
|
|
|
} else {
|
|
|
|
|
return enumName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toEnumName(CodegenProperty property) {
|
|
|
|
|
String enumName = toModelName(property.name) + "Enum";
|
|
|
|
|
|
|
|
|
|
if (enumName.matches("\\d.*")) { // starts with number
|
|
|
|
|
return "_" + enumName;
|
|
|
|
|
} else {
|
|
|
|
|
return enumName;
|
|
|
|
|
return "'" + escapeText(value) + "'";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -738,53 +337,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return tsImports;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
|
|
|
|
|
Map<String, ModelsMap> result = super.postProcessAllModels(objs);
|
|
|
|
|
|
|
|
|
|
for (ModelsMap entry : result.values()) {
|
|
|
|
|
for (ModelMap mo : entry.getModels()) {
|
|
|
|
|
CodegenModel cm = mo.getModel();
|
|
|
|
|
if (cm.discriminator != null && cm.children != null) {
|
|
|
|
|
for (CodegenModel child : cm.children) {
|
|
|
|
|
this.setDiscriminatorValue(child, cm.discriminator.getPropertyName(), this.getDiscriminatorValue(child));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setDiscriminatorValue(CodegenModel model, String baseName, String value) {
|
|
|
|
|
for (CodegenProperty prop : model.allVars) {
|
|
|
|
|
if (prop.baseName.equals(baseName)) {
|
|
|
|
|
prop.discriminatorValue = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (model.children != null) {
|
|
|
|
|
final boolean newDiscriminator = model.discriminator != null;
|
|
|
|
|
for (CodegenModel child : model.children) {
|
|
|
|
|
this.setDiscriminatorValue(child, baseName, newDiscriminator ? value : this.getDiscriminatorValue(child));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getDiscriminatorValue(CodegenModel model) {
|
|
|
|
|
return model.vendorExtensions.containsKey(X_DISCRIMINATOR_TYPE) ?
|
|
|
|
|
(String) model.vendorExtensions.get(X_DISCRIMINATOR_TYPE) : model.classname;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String escapeQuotationMark(String input) {
|
|
|
|
|
// remove ', " to avoid code injection
|
|
|
|
|
return input.replace("\"", "").replace("'", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String escapeUnsafeCharacters(String input) {
|
|
|
|
|
return input.replace("*/", "*_/").replace("/*", "/_*");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getName() {
|
|
|
|
|
return "typescript";
|
|
|
|
|
@@ -795,17 +347,10 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return "Generates a TypeScript client library using Fetch API (beta).";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void processOpts() {
|
|
|
|
|
super.processOpts();
|
|
|
|
|
|
|
|
|
|
if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) {
|
|
|
|
|
setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
convertPropertyToBooleanAndWriteBack(CodegenConstants.SUPPORTS_ES6);
|
|
|
|
|
|
|
|
|
|
// change package names
|
|
|
|
|
apiPackage = this.apiPackage + ".apis";
|
|
|
|
|
testPackage = this.testPackage + ".tests";
|
|
|
|
|
@@ -815,8 +360,8 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
|
|
|
|
|
String httpLibName = this.getHttpLibForFramework(additionalProperties.get(FRAMEWORK_SWITCH).toString());
|
|
|
|
|
supportingFiles.add(new SupportingFile(
|
|
|
|
|
"http" + File.separator + httpLibName + ".mustache",
|
|
|
|
|
"http", httpLibName + ".ts"
|
|
|
|
|
"http" + File.separator + httpLibName + ".mustache",
|
|
|
|
|
"http", httpLibName + ".ts"
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
Object propPlatform = additionalProperties.get(PLATFORM_SWITCH);
|
|
|
|
|
@@ -826,7 +371,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, Boolean> platforms = new HashMap<>();
|
|
|
|
|
for (String platform: PLATFORMS) {
|
|
|
|
|
for (String platform : PLATFORMS) {
|
|
|
|
|
platforms.put(platform, platform.equals(propPlatform));
|
|
|
|
|
}
|
|
|
|
|
additionalProperties.put("platforms", platforms);
|
|
|
|
|
@@ -861,14 +406,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NPM Settings
|
|
|
|
|
if (additionalProperties.containsKey(NPM_NAME)) {
|
|
|
|
|
setNpmName(additionalProperties.get(NPM_NAME).toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (additionalProperties.containsKey(NPM_VERSION)) {
|
|
|
|
|
setNpmVersion(additionalProperties.get(NPM_VERSION).toString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (additionalProperties.containsKey(NPM_REPOSITORY)) {
|
|
|
|
|
setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
|
|
|
|
|
}
|
|
|
|
|
@@ -1396,9 +933,7 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return example;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/***
|
|
|
|
|
*
|
|
|
|
|
* Set the codegenParameter example value
|
|
|
|
|
* We have a custom version of this function so we can invoke toExampleValue
|
|
|
|
|
*
|
|
|
|
|
@@ -1489,64 +1024,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
return cp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toAnyOfName(List<String> names, ComposedSchema composedSchema) {
|
|
|
|
|
List<String> types = getTypesFromSchemas(composedSchema.getAnyOf());
|
|
|
|
|
|
|
|
|
|
return String.join(" | ", types);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toOneOfName(List<String> names, ComposedSchema composedSchema) {
|
|
|
|
|
List<String> types = getTypesFromSchemas(composedSchema.getOneOf());
|
|
|
|
|
|
|
|
|
|
return String.join(" | ", types);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String toAllOfName(List<String> names, ComposedSchema composedSchema) {
|
|
|
|
|
List<String> types = getTypesFromSchemas(composedSchema.getAllOf());
|
|
|
|
|
|
|
|
|
|
return String.join(" & ", types);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extracts the list of type names from a list of schemas.
|
|
|
|
|
* Excludes `AnyType` if there are other valid types extracted.
|
|
|
|
|
*
|
|
|
|
|
* @param schemas list of schemas
|
|
|
|
|
* @return list of types
|
|
|
|
|
*/
|
|
|
|
|
protected List<String> getTypesFromSchemas(List<Schema> schemas) {
|
|
|
|
|
List<Schema> filteredSchemas = schemas.size() > 1
|
|
|
|
|
? schemas.stream().filter(schema -> !"AnyType".equals(super.getSchemaType(schema))).collect(Collectors.toList())
|
|
|
|
|
: schemas;
|
|
|
|
|
|
|
|
|
|
return filteredSchemas.stream().map(schema -> {
|
|
|
|
|
String schemaType = getSchemaType(schema);
|
|
|
|
|
if (ModelUtils.isArraySchema(schema)) {
|
|
|
|
|
ArraySchema ap = (ArraySchema) schema;
|
|
|
|
|
Schema inner = ap.getItems();
|
|
|
|
|
schemaType = schemaType + "<" + getSchemaType(inner) + ">";
|
|
|
|
|
}
|
|
|
|
|
return schemaType;
|
|
|
|
|
}).distinct().collect(Collectors.toList());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void addImport(CodegenModel m, String type) {
|
|
|
|
|
if (type == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String[] parts = splitComposedType(type);
|
|
|
|
|
for (String s : parts) {
|
|
|
|
|
if (needToImport(s)) {
|
|
|
|
|
m.imports.add(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void addImport(Set<String> importsToBeAddedTo, String type) {
|
|
|
|
|
if (type == null) {
|
|
|
|
|
@@ -1567,9 +1044,6 @@ public class TypeScriptClientCodegen extends DefaultCodegen implements CodegenCo
|
|
|
|
|
* @return list of types
|
|
|
|
|
*/
|
|
|
|
|
protected String[] splitComposedType(String type) {
|
|
|
|
|
return type.replace(" ","").split("[|&<>]");
|
|
|
|
|
return type.replace(" ", "").split("[|&<>]");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.TYPESCRIPT; }
|
|
|
|
|
}
|
|
|
|
|
|