diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularJsClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularJsClientCodegen.java new file mode 100644 index 00000000000..a2c464d12bc --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAngularJsClientCodegen.java @@ -0,0 +1,101 @@ +package org.openapitools.codegen.languages; + +import java.io.File; + +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.CliOption; +import org.openapitools.codegen.CodegenModel; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.utils.SemVer; + +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.PathItem.HttpMethod; +import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.oas.models.info.*; + +public class TypeScriptAngularJsClientCodegen extends AbstractTypeScriptClientCodegen { + + public TypeScriptAngularJsClientCodegen() { + super(); + outputFolder = "generated-code/typescript-angularjs"; + modelTemplateFiles.put("model.mustache", ".ts"); + apiTemplateFiles.put("api.mustache", ".ts"); + embeddedTemplateDir = templateDir = "typescript-angularjs"; + apiPackage = "api"; + modelPackage = "model"; + } + + @Override + public String getName() { + return "typescript-angularjs"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript AngularJS client library."; + } + + @Override + public void processOpts() { + super.processOpts(); + supportingFiles.add(new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts")); + supportingFiles.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts")); + supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts")); + supportingFiles.add(new SupportingFile("api.module.mustache", getIndexDirectory(), "api.module.ts")); + supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); + supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); + + } + + @Override + public String getSchemaType(Schema p) { + String openAPIType = super.getSchemaType(p); + if (isLanguagePrimitive(openAPIType) || isLanguageGenericType(openAPIType)) { + return openAPIType; + } + return addModelPrefix(openAPIType); + } + + @Override + public void postProcessParameter(CodegenParameter parameter) { + super.postProcessParameter(parameter); + parameter.dataType = addModelPrefix(parameter.dataType); + } + + private String getIndexDirectory() { + String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.'))); + return indexPackage.replace('.', File.separatorChar); + } + + private String addModelPrefix(String openAPIType) { + String type = null; + if (typeMapping.containsKey(openAPIType)) { + type = typeMapping.get(openAPIType); + } else { + type = openAPIType; + } + + if (!isLanguagePrimitive(type) && !isLanguageGenericType(type)) { + type = "models." + openAPIType; + } + return type; + } + + private boolean isLanguagePrimitive(String type) { + return languageSpecificPrimitives.contains(type); + } + + private boolean isLanguageGenericType(String type) { + for (String genericType : languageGenericTypes) { + if (type.startsWith(genericType + "<")) { + return true; + } + } + return false; + } +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAureliaClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAureliaClientCodegen.java new file mode 100644 index 00000000000..c71af8bc98f --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAureliaClientCodegen.java @@ -0,0 +1,140 @@ +package org.openapitools.codegen.languages; + +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.*; + +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.PathItem.HttpMethod; +import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.oas.models.info.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +public class TypeScriptAureliaClientCodegen extends AbstractTypeScriptClientCodegen { + + public static final String NPM_NAME = "npmName"; + public static final String NPM_VERSION = "npmVersion"; + + protected String npmName = null; + protected String npmVersion = "1.0.0"; + + public TypeScriptAureliaClientCodegen() { + super(); + + apiTemplateFiles.put("api.mustache", ".ts"); + + // clear import mapping (from default generator) as TS does not use it + // at the moment + importMapping.clear(); + + outputFolder = "generated-code/typescript-aurelia"; + embeddedTemplateDir = templateDir = "typescript-aurelia"; + this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package")); + this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package")); + } + + @Override + public String getName() { + return "typescript-aurelia"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript client library for the Aurelia framework (beta)."; + } + + public String getNpmName() { + return npmName; + } + + public void setNpmName(String npmName) { + this.npmName = npmName; + } + + public String getNpmVersion() { + return npmVersion; + } + + public void setNpmVersion(String npmVersion) { + this.npmVersion = npmVersion; + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey(NPM_NAME)) { + this.setNpmName(additionalProperties.get(NPM_NAME).toString()); + } + + if (additionalProperties.containsKey(NPM_VERSION)) { + this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString()); + } + + // Set supporting files + supportingFiles.add(new SupportingFile("models.mustache", "", "models.ts")); + supportingFiles.add(new SupportingFile("index.ts.mustache", "", "index.ts")); + supportingFiles.add(new SupportingFile("Api.ts.mustache", "", "Api.ts")); + supportingFiles.add(new SupportingFile("AuthStorage.ts.mustache", "", "AuthStorage.ts")); + supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); + supportingFiles.add(new SupportingFile("README.md", "", "README.md")); + supportingFiles.add(new SupportingFile("package.json.mustache", "", "package.json")); + supportingFiles.add(new SupportingFile("tsconfig.json.mustache", "", "tsconfig.json")); + supportingFiles.add(new SupportingFile("tslint.json.mustache", "", "tslint.json")); + supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); + } + + @Override + public Map postProcessOperations(Map objs) { + objs = super.postProcessOperations(objs); + + HashSet modelImports = new HashSet<>(); + Map operations = (Map) objs.get("operations"); + List operationList = (List) operations.get("operation"); + for (CodegenOperation op : operationList) { + // Aurelia uses "asGet", "asPost", ... methods; change the method format + op.httpMethod = initialCaps(op.httpMethod.toLowerCase()); + + // Collect models to be imported + for (CodegenParameter param : op.allParams) { + if (!param.isPrimitiveType && !param.isListContainer && !param.dataType.equals("any")) { + modelImports.add(param.dataType); + } + } + if (op.returnBaseType != null && !op.returnTypeIsPrimitive) { + modelImports.add(op.returnBaseType); + } + } + + objs.put("modelImports", modelImports); + + return objs; + } + + @Override + public Map postProcessModels(Map objs) { + // process enum in models + List models = (List) postProcessModelsEnum(objs).get("models"); + for (Object _mo : models) { + Map mo = (Map) _mo; + CodegenModel cm = (CodegenModel) mo.get("model"); + cm.imports = new TreeSet(cm.imports); + for (CodegenProperty var : cm.vars) { + // name enum with model name, e.g. StatuEnum => PetStatusEnum + if (Boolean.TRUE.equals(var.isEnum)) { + var.datatypeWithEnum = var.datatypeWithEnum.replace(var.enumName, cm.classname + var.enumName); + var.enumName = cm.classname + var.enumName; + } + } + } + + return objs; + } + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java new file mode 100644 index 00000000000..2e4eff4e388 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptFetchClientCodegen.java @@ -0,0 +1,147 @@ +package org.openapitools.codegen.languages; + +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.*; + +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.PathItem.HttpMethod; +import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.oas.models.info.*; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.*; + +public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodegen { + private static final SimpleDateFormat SNAPSHOT_SUFFIX_FORMAT = new SimpleDateFormat("yyyyMMddHHmm"); + + public static final String NPM_NAME = "npmName"; + public static final String NPM_VERSION = "npmVersion"; + public static final String NPM_REPOSITORY = "npmRepository"; + public static final String SNAPSHOT = "snapshot"; + public static final String WITH_INTERFACES = "withInterfaces"; + + protected String npmName = null; + protected String npmVersion = "1.0.0"; + protected String npmRepository = null; + + public TypeScriptFetchClientCodegen() { + super(); + + // clear import mapping (from default generator) as TS does not use it + // at the moment + importMapping.clear(); + + outputFolder = "generated-code/typescript-fetch"; + embeddedTemplateDir = templateDir = "typescript-fetch"; + + this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package")); + this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package")); + this.cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json")); + this.cliOptions.add(new CliOption(SNAPSHOT, "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + } + + @Override + public String getName() { + return "typescript-fetch"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript client library using Fetch API (beta)."; + } + + public String getNpmName() { + return npmName; + } + + public void setNpmName(String npmName) { + this.npmName = npmName; + } + + public String getNpmVersion() { + return npmVersion; + } + + public void setNpmVersion(String npmVersion) { + this.npmVersion = npmVersion; + } + + public String getNpmRepository() { + return npmRepository; + } + + public void setNpmRepository(String npmRepository) { + this.npmRepository = npmRepository; + } + + @Override + public void processOpts() { + super.processOpts(); + supportingFiles.add(new SupportingFile("index.mustache", "", "index.ts")); + supportingFiles.add(new SupportingFile("api.mustache", "", "api.ts")); + supportingFiles.add(new SupportingFile("configuration.mustache", "", "configuration.ts")); + supportingFiles.add(new SupportingFile("custom.d.mustache", "", "custom.d.ts")); + supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); + supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); + + if (additionalProperties.containsKey(NPM_NAME)) { + addNpmPackageGeneration(); + } + } + + @Override + public String getTypeDeclaration(Schema p) { + Schema inner; + if (p instanceof ArraySchema) { + inner = ((ArraySchema) p).getItems(); + return this.getSchemaType(p) + "<" + this.getTypeDeclaration(inner) + ">"; + } else if (p instanceof MapSchema) { + inner = (Schema) p.getAdditionalProperties(); + return "{ [key: string]: " + this.getTypeDeclaration(inner) + "; }"; + } else if (p instanceof FileSchema) { + return "any"; + } else if (p instanceof BinarySchema) { + return "any"; + } else if (!StringUtils.isEmpty(p.get$ref())) { // model + return "any"; + } else { + return super.getTypeDeclaration(p); + } + } + + @Override + protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) { + codegenModel.additionalPropertiesType = getTypeDeclaration((Schema) schema.getAdditionalProperties()); + addImport(codegenModel, codegenModel.additionalPropertiesType); + } + + private void addNpmPackageGeneration() { + if (additionalProperties.containsKey(NPM_NAME)) { + this.setNpmName(additionalProperties.get(NPM_NAME).toString()); + } + + if (additionalProperties.containsKey(NPM_VERSION)) { + this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString()); + } + + if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) { + this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date())); + } + additionalProperties.put(NPM_VERSION, npmVersion); + + if (additionalProperties.containsKey(NPM_REPOSITORY)) { + this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); + } + + //Files for building our lib + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("package.mustache", "", "package.json")); + supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json")); + } + +} diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptJqueryClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptJqueryClientCodegen.java new file mode 100644 index 00000000000..117f6a3c1cf --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptJqueryClientCodegen.java @@ -0,0 +1,195 @@ +package org.openapitools.codegen.languages; + +import io.swagger.v3.parser.util.SchemaTypeUtil; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.openapitools.codegen.*; + +import io.swagger.v3.oas.models.media.*; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.PathItem.HttpMethod; +import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.oas.models.info.*; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class TypeScriptJqueryClientCodegen extends AbstractTypeScriptClientCodegen { + private static final Logger LOGGER = LoggerFactory.getLogger(TypeScriptJqueryClientCodegen.class); + private static final SimpleDateFormat SNAPSHOT_SUFFIX_FORMAT = new SimpleDateFormat("yyyyMMddHHmm"); + + public static final String NPM_NAME = "npmName"; + public static final String NPM_VERSION = "npmVersion"; + public static final String NPM_REPOSITORY = "npmRepository"; + public static final String SNAPSHOT = "snapshot"; + public static final String JQUERY_ALREADY_IMPORTED = "jqueryAlreadyImported"; + + protected String npmName = null; + protected String npmVersion = "1.0.0"; + protected String npmRepository = null; + + public TypeScriptJqueryClientCodegen() { + super(); + + modelTemplateFiles.put("model.mustache", ".ts"); + apiTemplateFiles.put("api.mustache", ".ts"); + typeMapping.put("Date", "Date"); + apiPackage = "api"; + modelPackage = "model"; + + outputFolder = "generated-code/typescript-jquery"; + embeddedTemplateDir = templateDir = "typescript-jquery"; + + this.cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package")); + this.cliOptions.add(new CliOption(NPM_VERSION, "The version of your npm package")); + this.cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json")); + this.cliOptions.add(new CliOption(SNAPSHOT, + "When setting this property to true the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm", + SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + this.cliOptions.add(new CliOption(JQUERY_ALREADY_IMPORTED, + "When using this in legacy app using mix of typescript and javascript, this will only declare jquery and not import it", + SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString())); + } + + @Override + public String getName() { + return "typescript-jquery"; + } + + @Override + public String getHelp() { + return "Generates a TypeScript jquery client library."; + } + + public void setNpmName(String npmName) { + this.npmName = npmName; + } + + public void setNpmVersion(String npmVersion) { + this.npmVersion = npmVersion; + } + + public String getNpmVersion() { + return npmVersion; + } + + public String getNpmRepository() { + return npmRepository; + } + + public void setNpmRepository(String npmRepository) { + this.npmRepository = npmRepository; + } + + @Override + public void processOpts() { + super.processOpts(); + + supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); + supportingFiles.add(new SupportingFile("models.mustache", modelPackage().replace('.', File.separatorChar), "models.ts")); + supportingFiles.add(new SupportingFile("apis.mustache", apiPackage().replace('.', File.separatorChar), "api.ts")); + supportingFiles.add(new SupportingFile("configuration.mustache", getIndexDirectory(), "configuration.ts")); + supportingFiles.add(new SupportingFile("index.mustache", getIndexDirectory(), "index.ts")); + supportingFiles.add(new SupportingFile("variables.mustache", getIndexDirectory(), "variables.ts")); + + //LOGGER.warn("check additionals: " + additionalProperties.get(NPM_NAME)); + if (additionalProperties.containsKey(NPM_NAME)) { + addNpmPackageGeneration(); + } + } + + @Override + public String getSchemaType(Schema p) { + String openAPIType = super.getSchemaType(p); + if (p instanceof StringSchema) { + if (p.getEnum() != null) { + return openAPIType; + } + } + if (isLanguagePrimitive(openAPIType) || isLanguageGenericType(openAPIType)) { + return openAPIType; + } + return addModelPrefix(openAPIType); + } + + @Override + public void postProcessParameter(CodegenParameter parameter) { + super.postProcessParameter(parameter); + + if (!parameter.isEnum) { + parameter.dataType = addModelPrefix(parameter.dataType); + } + } + + @Override + protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) { + codegenModel.additionalPropertiesType = getSchemaType((Schema) schema.getAdditionalProperties()); + addImport(codegenModel, codegenModel.additionalPropertiesType); + } + + private String addModelPrefix(String openAPIType) { + String type = null; + if (typeMapping.containsKey(openAPIType)) { + type = typeMapping.get(openAPIType); + } else { + type = openAPIType; + } + + if (!isLanguagePrimitive(type) && !isLanguageGenericType(type)) { + type = "models." + openAPIType; + } + return type; + } + + private boolean isLanguagePrimitive(String type) { + return languageSpecificPrimitives.contains(type); + } + + private boolean isLanguageGenericType(String type) { + for (String genericType : languageGenericTypes) { + if (type.startsWith(genericType + "<")) { + return true; + } + } + return false; + } + + private String getPackageRootDirectory() { + String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.'))); + return indexPackage.replace('.', File.separatorChar); + } + + private void addNpmPackageGeneration() { + if (additionalProperties.containsKey(NPM_NAME)) { + this.setNpmName(additionalProperties.get(NPM_NAME).toString()); + } + + if (additionalProperties.containsKey(NPM_VERSION)) { + this.setNpmVersion(additionalProperties.get(NPM_VERSION).toString()); + } + + if (additionalProperties.containsKey(SNAPSHOT) && Boolean.valueOf(additionalProperties.get(SNAPSHOT).toString())) { + this.setNpmVersion(npmVersion + "-SNAPSHOT." + SNAPSHOT_SUFFIX_FORMAT.format(new Date())); + } + additionalProperties.put(NPM_VERSION, npmVersion); + + if (additionalProperties.containsKey(NPM_REPOSITORY)) { + this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); + } + + //Files for building our lib + supportingFiles.add(new SupportingFile("README.mustache", getPackageRootDirectory(), "README.md")); + supportingFiles.add(new SupportingFile("package.mustache", getPackageRootDirectory(), "package.json")); + supportingFiles.add(new SupportingFile("typings.mustache", getPackageRootDirectory(), "typings.json")); + supportingFiles.add(new SupportingFile("tsconfig.mustache", getPackageRootDirectory(), "tsconfig.json")); + } + + private String getIndexDirectory() { + String indexPackage = modelPackage.substring(0, Math.max(0, modelPackage.lastIndexOf('.'))); + return indexPackage.replace('.', File.separatorChar); + } + +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 6eade1cd694..e7285806685 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -31,3 +31,7 @@ org.openapitools.codegen.languages.ScalaClientCodegen org.openapitools.codegen.languages.SinatraServerCodegen org.openapitools.codegen.languages.TizenClientCodegen org.openapitools.codegen.languages.TypeScriptAngularClientCodegen +org.openapitools.codegen.languages.TypeScriptAngularJsClientCodegen +org.openapitools.codegen.languages.TypeScriptAureliaClientCodegen +org.openapitools.codegen.languages.TypeScriptFetchClientCodegen +org.openapitools.codegen.languages.TypeScriptJqueryClientCodegen