forked from loafle/openapi-generator-original
Sttp4 generator (#15834)
* implementation of sttp4 generator * rebased with master * running scripts --------- Co-authored-by: Adam Fish Rybicki <adamrybicki@adams-macbook-pro.home> Co-authored-by: William Cheng <wing328hk@gmail.com>
This commit is contained in:
parent
debf92fd7d
commit
faa5da51e5
6
bin/configs/scala-sttp4-petstore-new.yaml
Normal file
6
bin/configs/scala-sttp4-petstore-new.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
generatorName: scala-sttp4
|
||||
outputDir: samples/client/petstore/scala/sttp4
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/scala-sttp4
|
||||
additionalProperties:
|
||||
hideGenerationTimestamp: "true"
|
@ -58,6 +58,7 @@ The following generators are available:
|
||||
* [scala-akka](generators/scala-akka.md)
|
||||
* [scala-gatling](generators/scala-gatling.md)
|
||||
* [scala-sttp](generators/scala-sttp.md)
|
||||
* [scala-sttp4 (beta)](generators/scala-sttp4.md)
|
||||
* [scalaz](generators/scalaz.md)
|
||||
* [swift-combine](generators/swift-combine.md)
|
||||
* [swift5](generators/swift5.md)
|
||||
|
252
docs/generators/scala-sttp4.md
Normal file
252
docs/generators/scala-sttp4.md
Normal file
@ -0,0 +1,252 @@
|
||||
---
|
||||
title: Documentation for the scala-sttp4 Generator
|
||||
---
|
||||
|
||||
## METADATA
|
||||
|
||||
| Property | Value | Notes |
|
||||
| -------- | ----- | ----- |
|
||||
| generator name | scala-sttp4 | pass this to the generate command after -g |
|
||||
| generator stability | BETA | |
|
||||
| generator type | CLIENT | |
|
||||
| generator language | Scala | |
|
||||
| generator default templating engine | mustache | |
|
||||
| helpTxt | Generates a Scala client library (beta) based on Sttp4. | |
|
||||
|
||||
## CONFIG OPTIONS
|
||||
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
|
||||
|
||||
| Option | Description | Values | Default |
|
||||
| ------ | ----------- | ------ | ------- |
|
||||
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|
||||
|apiPackage|package for generated api classes| |null|
|
||||
|dateLibrary|Option. Date library to use|<dl><dt>**joda**</dt><dd>Joda (for legacy app)</dd><dt>**java8**</dt><dd>Java 8 native JSR310 (preferred for JDK 1.8+)</dd></dl>|java8|
|
||||
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|
||||
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|
||||
|enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|<dl><dt>**false**</dt><dd>No changes to the enum's are made, this is the default option.</dd><dt>**true**</dt><dd>With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.</dd></dl>|false|
|
||||
|jodaTimeVersion|The version of joda-time library| |2.10.13|
|
||||
|json4sVersion|The version of json4s library| |4.0.6|
|
||||
|jsonLibrary|Json library to use. Possible values are: json4s and circe.| |json4s|
|
||||
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C# have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|
||||
|mainPackage|Top-level package name, which defines 'apiPackage', 'modelPackage', 'invokerPackage'| |org.openapitools.client|
|
||||
|modelPackage|package for generated models| |null|
|
||||
|modelPropertyNaming|Naming convention for the property: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
|
||||
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|
||||
|separateErrorChannel|Whether to return response as F[Either[ResponseError[ErrorType], ReturnType]]] or to flatten response's error raising them through enclosing monad (F[ReturnType]).| |true|
|
||||
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|
||||
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|
||||
|sourceFolder|source folder for generated code| |null|
|
||||
|sttpClientVersion|The version of sttp client| |4.0.0-M1|
|
||||
|
||||
## IMPORT MAPPING
|
||||
|
||||
| Type/Alias | Imports |
|
||||
| ---------- | ------- |
|
||||
|Array|java.util.List|
|
||||
|ArrayList|java.util.ArrayList|
|
||||
|Date|java.util.Date|
|
||||
|DateTime|org.joda.time.*|
|
||||
|File|java.io.File|
|
||||
|HashMap|java.util.HashMap|
|
||||
|ListBuffer|scala.collection.mutable.ListBuffer|
|
||||
|ListSet|scala.collection.immutable.ListSet|
|
||||
|LocalDate|org.joda.time.*|
|
||||
|LocalDateTime|org.joda.time.*|
|
||||
|LocalTime|org.joda.time.*|
|
||||
|Seq|scala.collection.immutable.Seq|
|
||||
|Set|scala.collection.immutable.Set|
|
||||
|Timestamp|java.sql.Timestamp|
|
||||
|URI|java.net.URI|
|
||||
|UUID|java.util.UUID|
|
||||
|
||||
|
||||
## INSTANTIATION TYPES
|
||||
|
||||
| Type/Alias | Instantiated By |
|
||||
| ---------- | --------------- |
|
||||
|array|ListBuffer|
|
||||
|map|Map|
|
||||
|set|Set|
|
||||
|
||||
|
||||
## LANGUAGE PRIMITIVES
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>Any</li>
|
||||
<li>Array</li>
|
||||
<li>Boolean</li>
|
||||
<li>Byte</li>
|
||||
<li>Double</li>
|
||||
<li>Float</li>
|
||||
<li>Int</li>
|
||||
<li>List</li>
|
||||
<li>Long</li>
|
||||
<li>Map</li>
|
||||
<li>Object</li>
|
||||
<li>Seq</li>
|
||||
<li>String</li>
|
||||
<li>boolean</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
<ul class="column-ul">
|
||||
<li>abstract</li>
|
||||
<li>case</li>
|
||||
<li>catch</li>
|
||||
<li>class</li>
|
||||
<li>clone</li>
|
||||
<li>def</li>
|
||||
<li>do</li>
|
||||
<li>else</li>
|
||||
<li>extends</li>
|
||||
<li>false</li>
|
||||
<li>final</li>
|
||||
<li>finally</li>
|
||||
<li>for</li>
|
||||
<li>forSome</li>
|
||||
<li>if</li>
|
||||
<li>implicit</li>
|
||||
<li>import</li>
|
||||
<li>lazy</li>
|
||||
<li>match</li>
|
||||
<li>new</li>
|
||||
<li>null</li>
|
||||
<li>object</li>
|
||||
<li>override</li>
|
||||
<li>package</li>
|
||||
<li>private</li>
|
||||
<li>protected</li>
|
||||
<li>return</li>
|
||||
<li>sealed</li>
|
||||
<li>super</li>
|
||||
<li>this</li>
|
||||
<li>throw</li>
|
||||
<li>trait</li>
|
||||
<li>true</li>
|
||||
<li>try</li>
|
||||
<li>type</li>
|
||||
<li>val</li>
|
||||
<li>var</li>
|
||||
<li>while</li>
|
||||
<li>with</li>
|
||||
<li>yield</li>
|
||||
</ul>
|
||||
|
||||
## FEATURE SET
|
||||
|
||||
|
||||
### Client Modification Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasePath|✓|ToolingExtension
|
||||
|Authorizations|✗|ToolingExtension
|
||||
|UserAgent|✓|ToolingExtension
|
||||
|MockServer|✗|ToolingExtension
|
||||
|
||||
### Data Type Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Custom|✗|OAS2,OAS3
|
||||
|Int32|✓|OAS2,OAS3
|
||||
|Int64|✓|OAS2,OAS3
|
||||
|Float|✓|OAS2,OAS3
|
||||
|Double|✓|OAS2,OAS3
|
||||
|Decimal|✓|ToolingExtension
|
||||
|String|✓|OAS2,OAS3
|
||||
|Byte|✓|OAS2,OAS3
|
||||
|Binary|✓|OAS2,OAS3
|
||||
|Boolean|✓|OAS2,OAS3
|
||||
|Date|✓|OAS2,OAS3
|
||||
|DateTime|✓|OAS2,OAS3
|
||||
|Password|✓|OAS2,OAS3
|
||||
|File|✓|OAS2
|
||||
|Uuid|✗|
|
||||
|Array|✓|OAS2,OAS3
|
||||
|Null|✗|OAS3
|
||||
|AnyType|✗|OAS2,OAS3
|
||||
|Object|✓|OAS2,OAS3
|
||||
|Maps|✓|ToolingExtension
|
||||
|CollectionFormat|✓|OAS2
|
||||
|CollectionFormatMulti|✓|OAS2
|
||||
|Enum|✓|OAS2,OAS3
|
||||
|ArrayOfEnum|✓|ToolingExtension
|
||||
|ArrayOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfModel|✓|ToolingExtension
|
||||
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|
||||
|MapOfEnum|✓|ToolingExtension
|
||||
|MapOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|
||||
|MapOfCollectionOfModel|✓|ToolingExtension
|
||||
|MapOfCollectionOfEnum|✓|ToolingExtension
|
||||
|
||||
### Documentation Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Readme|✓|ToolingExtension
|
||||
|Model|✓|ToolingExtension
|
||||
|Api|✓|ToolingExtension
|
||||
|
||||
### Global Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Host|✓|OAS2,OAS3
|
||||
|BasePath|✓|OAS2,OAS3
|
||||
|Info|✓|OAS2,OAS3
|
||||
|Schemes|✗|OAS2,OAS3
|
||||
|PartialSchemes|✓|OAS2,OAS3
|
||||
|Consumes|✓|OAS2
|
||||
|Produces|✓|OAS2
|
||||
|ExternalDocumentation|✓|OAS2,OAS3
|
||||
|Examples|✓|OAS2,OAS3
|
||||
|XMLStructureDefinitions|✗|OAS2,OAS3
|
||||
|MultiServer|✗|OAS3
|
||||
|ParameterizedServer|✗|OAS3
|
||||
|ParameterStyling|✗|OAS3
|
||||
|Callbacks|✗|OAS3
|
||||
|LinkObjects|✗|OAS3
|
||||
|
||||
### Parameter Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Path|✓|OAS2,OAS3
|
||||
|Query|✓|OAS2,OAS3
|
||||
|Header|✓|OAS2,OAS3
|
||||
|Body|✓|OAS2
|
||||
|FormUnencoded|✓|OAS2
|
||||
|FormMultipart|✓|OAS2
|
||||
|Cookie|✗|OAS3
|
||||
|
||||
### Schema Support Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|Simple|✓|OAS2,OAS3
|
||||
|Composite|✓|OAS2,OAS3
|
||||
|Polymorphism|✗|OAS2,OAS3
|
||||
|Union|✗|OAS3
|
||||
|allOf|✗|OAS2,OAS3
|
||||
|anyOf|✗|OAS3
|
||||
|oneOf|✗|OAS3
|
||||
|not|✗|OAS3
|
||||
|
||||
### Security Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|BasicAuth|✓|OAS2,OAS3
|
||||
|ApiKey|✓|OAS2,OAS3
|
||||
|OpenIDConnect|✗|OAS3
|
||||
|BearerToken|✓|OAS3
|
||||
|OAuth2_Implicit|✗|OAS2,OAS3
|
||||
|OAuth2_Password|✗|OAS2,OAS3
|
||||
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|
||||
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
|
||||
|SignatureAuth|✗|OAS3
|
||||
|
||||
### Wire Format Feature
|
||||
| Name | Supported | Defined By |
|
||||
| ---- | --------- | ---------- |
|
||||
|JSON|✓|OAS2,OAS3
|
||||
|XML|✓|OAS2,OAS3
|
||||
|PROTOBUF|✗|ToolingExtension
|
||||
|Custom|✓|OAS2,OAS3
|
@ -0,0 +1,605 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import io.swagger.v3.oas.models.servers.Server;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.meta.GeneratorMetadata;
|
||||
import org.openapitools.codegen.meta.Stability;
|
||||
import org.openapitools.codegen.meta.features.*;
|
||||
import org.openapitools.codegen.model.ModelMap;
|
||||
import org.openapitools.codegen.model.ModelsMap;
|
||||
import org.openapitools.codegen.model.OperationMap;
|
||||
import org.openapitools.codegen.model.OperationsMap;
|
||||
import org.openapitools.codegen.utils.CamelizeOption;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.openapitools.codegen.utils.CamelizeOption.*;
|
||||
import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER;
|
||||
import static org.openapitools.codegen.utils.StringUtils.camelize;
|
||||
|
||||
public class ScalaSttp4ClientCodegen extends AbstractScalaCodegen implements CodegenConfig {
|
||||
private static final StringProperty STTP_CLIENT_VERSION = new StringProperty("sttpClientVersion", "The version of " +
|
||||
"sttp client", "4.0.0-M1");
|
||||
private static final BooleanProperty USE_SEPARATE_ERROR_CHANNEL = new BooleanProperty("separateErrorChannel",
|
||||
"Whether to return response as " +
|
||||
"F[Either[ResponseError[ErrorType], ReturnType]]] or to flatten " +
|
||||
"response's error raising them through enclosing monad (F[ReturnType]).", true);
|
||||
private static final StringProperty JODA_TIME_VERSION = new StringProperty("jodaTimeVersion", "The version of " +
|
||||
"joda-time library", "2.10.13");
|
||||
private static final StringProperty JSON4S_VERSION = new StringProperty("json4sVersion", "The version of json4s " +
|
||||
"library", "4.0.6");
|
||||
|
||||
private static final JsonLibraryProperty JSON_LIBRARY_PROPERTY = new JsonLibraryProperty();
|
||||
|
||||
public static final String DEFAULT_PACKAGE_NAME = "org.openapitools.client";
|
||||
private static final PackageProperty PACKAGE_PROPERTY = new PackageProperty();
|
||||
|
||||
private static final List<Property<?>> properties = Arrays.asList(
|
||||
STTP_CLIENT_VERSION, USE_SEPARATE_ERROR_CHANNEL, JODA_TIME_VERSION,
|
||||
JSON4S_VERSION, JSON_LIBRARY_PROPERTY, PACKAGE_PROPERTY);
|
||||
|
||||
private final Logger LOGGER = LoggerFactory.getLogger(ScalaSttp4ClientCodegen.class);
|
||||
|
||||
protected String groupId = "org.openapitools";
|
||||
protected String artifactId = "openapi-client";
|
||||
protected String artifactVersion = "1.0.0";
|
||||
protected boolean registerNonStandardStatusCodes = true;
|
||||
protected boolean renderJavadoc = true;
|
||||
protected boolean removeOAuthSecurities = true;
|
||||
|
||||
Map<String, ModelsMap> enumRefs = new HashMap<>();
|
||||
|
||||
public ScalaSttp4ClientCodegen() {
|
||||
super();
|
||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||
.stability(Stability.BETA)
|
||||
.build();
|
||||
|
||||
modifyFeatureSet(features -> features
|
||||
.includeDocumentationFeatures(DocumentationFeature.Readme)
|
||||
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom))
|
||||
.securityFeatures(EnumSet.of(
|
||||
SecurityFeature.BasicAuth,
|
||||
SecurityFeature.ApiKey,
|
||||
SecurityFeature.BearerToken
|
||||
))
|
||||
.excludeGlobalFeatures(
|
||||
GlobalFeature.XMLStructureDefinitions,
|
||||
GlobalFeature.Callbacks,
|
||||
GlobalFeature.LinkObjects,
|
||||
GlobalFeature.ParameterStyling
|
||||
)
|
||||
.excludeSchemaSupportFeatures(
|
||||
SchemaSupportFeature.Polymorphism
|
||||
)
|
||||
.excludeParameterFeatures(
|
||||
ParameterFeature.Cookie
|
||||
)
|
||||
.includeClientModificationFeatures(
|
||||
ClientModificationFeature.BasePath,
|
||||
ClientModificationFeature.UserAgent
|
||||
)
|
||||
);
|
||||
|
||||
outputFolder = "generated-code/scala-sttp4";
|
||||
modelTemplateFiles.put("model.mustache", ".scala");
|
||||
apiTemplateFiles.put("api.mustache", ".scala");
|
||||
embeddedTemplateDir = templateDir = "scala-sttp4";
|
||||
|
||||
String jsonLibrary = JSON_LIBRARY_PROPERTY.getValue(additionalProperties);
|
||||
|
||||
String jsonValueClass = "circe".equals(jsonLibrary) ? "io.circe.Json" : "org.json4s.JValue";
|
||||
|
||||
additionalProperties.put(CodegenConstants.GROUP_ID, groupId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId);
|
||||
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
|
||||
if (renderJavadoc) {
|
||||
additionalProperties.put("javadocRenderer", new JavadocLambda());
|
||||
}
|
||||
additionalProperties.put("fnCapitalize", new CapitalizeLambda());
|
||||
additionalProperties.put("fnCamelize", new CamelizeLambda(false));
|
||||
additionalProperties.put("fnEnumEntry", new EnumEntryLambda());
|
||||
|
||||
// importMapping.remove("Seq");
|
||||
// importMapping.remove("List");
|
||||
// importMapping.remove("Set");
|
||||
// importMapping.remove("Map");
|
||||
|
||||
// TODO: there is no specific sttp mapping. All Scala Type mappings should be in AbstractScala
|
||||
typeMapping = new HashMap<>();
|
||||
typeMapping.put("array", "Seq");
|
||||
typeMapping.put("set", "Set");
|
||||
typeMapping.put("boolean", "Boolean");
|
||||
typeMapping.put("string", "String");
|
||||
typeMapping.put("int", "Int");
|
||||
typeMapping.put("integer", "Int");
|
||||
typeMapping.put("long", "Long");
|
||||
typeMapping.put("float", "Float");
|
||||
typeMapping.put("byte", "Byte");
|
||||
typeMapping.put("short", "Short");
|
||||
typeMapping.put("char", "Char");
|
||||
typeMapping.put("double", "Double");
|
||||
typeMapping.put("object", "Any");
|
||||
typeMapping.put("file", "File");
|
||||
typeMapping.put("binary", "File");
|
||||
typeMapping.put("number", "Double");
|
||||
typeMapping.put("decimal", "BigDecimal");
|
||||
typeMapping.put("ByteArray", "Array[Byte]");
|
||||
typeMapping.put("AnyType", jsonValueClass);
|
||||
|
||||
instantiationTypes.put("array", "ListBuffer");
|
||||
instantiationTypes.put("map", "Map");
|
||||
|
||||
properties.stream()
|
||||
.map(Property::toCliOptions)
|
||||
.flatMap(Collection::stream)
|
||||
.forEach(option -> cliOptions.add(option));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
properties.forEach(p -> p.updateAdditionalProperties(additionalProperties));
|
||||
invokerPackage = PACKAGE_PROPERTY.getInvokerPackage(additionalProperties);
|
||||
apiPackage = PACKAGE_PROPERTY.getApiPackage(additionalProperties);
|
||||
modelPackage = PACKAGE_PROPERTY.getModelPackage(additionalProperties);
|
||||
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
|
||||
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
|
||||
supportingFiles.add(new SupportingFile("jsonSupport.mustache", invokerFolder, "JsonSupport.scala"));
|
||||
supportingFiles.add(new SupportingFile("additionalTypeSerializers.mustache", invokerFolder, "AdditionalTypeSerializers.scala"));
|
||||
supportingFiles.add(new SupportingFile("project/build.properties.mustache", "project", "build.properties"));
|
||||
supportingFiles.add(new SupportingFile("dateSerializers.mustache", invokerFolder, "DateSerializers.scala"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "scala-sttp4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a Scala client library (beta) based on Sttp4.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encodePath(String input) {
|
||||
String path = super.encodePath(input);
|
||||
|
||||
// The parameter names in the URI must be converted to the same case as
|
||||
// the method parameter.
|
||||
StringBuffer buf = new StringBuffer(path.length());
|
||||
Matcher matcher = Pattern.compile("[{](.*?)[}]").matcher(path);
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(buf, "\\${" + toParamName(matcher.group(0)) + "}");
|
||||
}
|
||||
matcher.appendTail(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path,
|
||||
String httpMethod,
|
||||
Operation operation,
|
||||
List<Server> servers) {
|
||||
CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
|
||||
op.path = encodePath(path);
|
||||
return op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.CLIENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
if (this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
return "`" + name + "`";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelsMap postProcessModels(ModelsMap objs) {
|
||||
return objs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked by {@link DefaultGenerator} after all models have been post-processed,
|
||||
* allowing for a last pass of codegen-specific model cleanup.
|
||||
*
|
||||
* @param objs Current state of codegen object model.
|
||||
* @return An in-place modified state of the codegen object model.
|
||||
*/
|
||||
@Override
|
||||
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
|
||||
final Map<String, ModelsMap> processed = super.postProcessAllModels(objs);
|
||||
postProcessUpdateImports(processed);
|
||||
return processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update/clean up model imports
|
||||
*
|
||||
* append '._" if the import is a Enum class, otherwise
|
||||
* remove model imports to avoid warnings for importing class in the same package in Scala
|
||||
*
|
||||
* @param models processed models to be further processed
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void postProcessUpdateImports(final Map<String, ModelsMap> models) {
|
||||
final String prefix = modelPackage() + ".";
|
||||
|
||||
enumRefs = getEnumRefs(models);
|
||||
|
||||
for (String openAPIName : models.keySet()) {
|
||||
CodegenModel model = ModelUtils.getModelByName(openAPIName, models);
|
||||
if (model == null) {
|
||||
LOGGER.warn("Expected to retrieve model {} by name, but no model was found. Check your -Dmodels inclusions.", openAPIName);
|
||||
continue;
|
||||
}
|
||||
|
||||
ModelsMap objs = models.get(openAPIName);
|
||||
List<Map<String, String>> imports = objs.getImports();
|
||||
if (imports == null || imports.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<Map<String, String>> newImports = new ArrayList<>();
|
||||
Iterator<Map<String, String>> iterator = imports.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String importPath = iterator.next().get("import");
|
||||
Map<String, String> item = new HashMap<>();
|
||||
if (importPath.startsWith(prefix)) {
|
||||
if (isEnumClass(importPath, enumRefs)) {
|
||||
item.put("import", importPath.concat("._"));
|
||||
newImports.add(item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
item.put("import", importPath);
|
||||
newImports.add(item);
|
||||
}
|
||||
}
|
||||
// reset imports
|
||||
objs.setImports(newImports);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, ModelsMap> getEnumRefs(final Map<String, ModelsMap> models) {
|
||||
Map<String, ModelsMap> enums = new HashMap<>();
|
||||
for (String key : models.keySet()) {
|
||||
CodegenModel model = ModelUtils.getModelByName(key, models);
|
||||
if (model.isEnum) {
|
||||
ModelsMap objs = models.get(key);
|
||||
enums.put(key, objs);
|
||||
}
|
||||
}
|
||||
return enums;
|
||||
}
|
||||
|
||||
private boolean isEnumClass(final String importPath, final Map<String, ModelsMap> enumModels) {
|
||||
if (enumModels == null || enumModels.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
for (ModelsMap objs : enumModels.values()) {
|
||||
List<ModelMap> models = objs.getModels();
|
||||
if (models == null || models.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
for (final Map<String, Object> model : models) {
|
||||
String enumImportPath = (String) model.get("importPath");
|
||||
if (enumImportPath != null && enumImportPath.equals(importPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
|
||||
if (registerNonStandardStatusCodes) {
|
||||
try {
|
||||
OperationMap opsMap = objs.getOperations();
|
||||
HashSet<Integer> unknownCodes = new HashSet<>();
|
||||
for (CodegenOperation operation : opsMap.getOperation()) {
|
||||
for (CodegenResponse response : operation.responses) {
|
||||
if ("default".equals(response.code)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
int code = Integer.parseInt(response.code);
|
||||
if (code >= 600) {
|
||||
unknownCodes.add(code);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
LOGGER.error("Status code is not an integer : response.code", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!unknownCodes.isEmpty()) {
|
||||
additionalProperties.put("unknownStatusCodes", unknownCodes);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Unable to find operations List", e);
|
||||
}
|
||||
}
|
||||
|
||||
// update imports for enum class
|
||||
List<Map<String, String>> newImports = new ArrayList<>();
|
||||
List<Map<String, String>> imports = objs.getImports();
|
||||
if (imports != null && !imports.isEmpty()) {
|
||||
Iterator<Map<String, String>> iterator = imports.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String importPath = iterator.next().get("import");
|
||||
Map<String, String> item = new HashMap<>();
|
||||
if (isEnumClass(importPath, enumRefs)) {
|
||||
item.put("import", importPath.concat("._"));
|
||||
}
|
||||
else {
|
||||
item.put("import", importPath);
|
||||
}
|
||||
newImports.add(item);
|
||||
}
|
||||
}
|
||||
objs.setImports(newImports);
|
||||
|
||||
return super.postProcessOperationsWithModels(objs, allModels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CodegenSecurity> fromSecurity(Map<String, SecurityScheme> schemes) {
|
||||
final List<CodegenSecurity> codegenSecurities = super.fromSecurity(schemes);
|
||||
if (!removeOAuthSecurities) {
|
||||
return codegenSecurities;
|
||||
}
|
||||
|
||||
// Remove OAuth securities
|
||||
codegenSecurities.removeIf(security -> security.isOAuth);
|
||||
if (codegenSecurities.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return codegenSecurities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
return formatIdentifier(name, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumName(CodegenProperty property) {
|
||||
return formatIdentifier(property.baseName, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDefaultValue(Schema p) {
|
||||
if (p.getRequired() != null && p.getRequired().contains(p.getName())) {
|
||||
return "None";
|
||||
}
|
||||
|
||||
if (ModelUtils.isBooleanSchema(p)) {
|
||||
return null;
|
||||
} else if (ModelUtils.isDateSchema(p)) {
|
||||
return null;
|
||||
} else if (ModelUtils.isDateTimeSchema(p)) {
|
||||
return null;
|
||||
} else if (ModelUtils.isNumberSchema(p)) {
|
||||
return null;
|
||||
} else if (ModelUtils.isIntegerSchema(p)) {
|
||||
return null;
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
String inner = getSchemaType(getAdditionalProperties(p));
|
||||
return "Map[String, " + inner + "].empty ";
|
||||
} else if (ModelUtils.isArraySchema(p)) {
|
||||
ArraySchema ap = (ArraySchema) p;
|
||||
String inner = getSchemaType(ap.getItems());
|
||||
if (ModelUtils.isSet(ap)) {
|
||||
return "Set[" + inner + "].empty ";
|
||||
}
|
||||
return "Seq[" + inner + "].empty ";
|
||||
} else if (ModelUtils.isStringSchema(p)) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update datatypeWithEnum for array container
|
||||
*
|
||||
* @param property Codegen property
|
||||
*/
|
||||
@Override
|
||||
protected void updateDataTypeWithEnumForArray(CodegenProperty property) {
|
||||
CodegenProperty baseItem = property.items;
|
||||
while (baseItem != null && (Boolean.TRUE.equals(baseItem.isMap)
|
||||
|| Boolean.TRUE.equals(baseItem.isArray))) {
|
||||
baseItem = baseItem.items;
|
||||
}
|
||||
if (baseItem != null) {
|
||||
// set datetypeWithEnum as only the inner type is enum
|
||||
property.datatypeWithEnum = toEnumName(baseItem);
|
||||
// naming the enum with respect to the language enum naming convention
|
||||
// e.g. remove [], {} from array/map of enum
|
||||
property.enumName = toEnumName(property);
|
||||
property._enum = baseItem._enum;
|
||||
|
||||
updateCodegenPropertyEnum(property);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Property<T> {
|
||||
final String name;
|
||||
final String description;
|
||||
final T defaultValue;
|
||||
|
||||
public Property(String name, String description, T defaultValue) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public abstract List<CliOption> toCliOptions();
|
||||
|
||||
public abstract void updateAdditionalProperties(Map<String, Object> additionalProperties);
|
||||
|
||||
public abstract T getValue(Map<String, Object> additionalProperties);
|
||||
|
||||
public void setValue(Map<String, Object> additionalProperties, T value) {
|
||||
additionalProperties.put(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringProperty extends Property<String> {
|
||||
public StringProperty(String name, String description, String defaultValue) {
|
||||
super(name, description, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CliOption> toCliOptions() {
|
||||
return Collections.singletonList(CliOption.newString(name, description).defaultValue(defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdditionalProperties(Map<String, Object> additionalProperties) {
|
||||
if (!additionalProperties.containsKey(name)) {
|
||||
additionalProperties.put(name, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(Map<String, Object> additionalProperties) {
|
||||
return additionalProperties.getOrDefault(name, defaultValue).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BooleanProperty extends Property<Boolean> {
|
||||
public BooleanProperty(String name, String description, Boolean defaultValue) {
|
||||
super(name, description, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CliOption> toCliOptions() {
|
||||
return Collections.singletonList(CliOption.newBoolean(name, description, defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdditionalProperties(Map<String, Object> additionalProperties) {
|
||||
Boolean value = getValue(additionalProperties);
|
||||
additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue(Map<String, Object> additionalProperties) {
|
||||
return Boolean.valueOf(additionalProperties.getOrDefault(name, defaultValue.toString()).toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static class JsonLibraryProperty extends StringProperty {
|
||||
private static final String JSON4S = "json4s";
|
||||
private static final String CIRCE = "circe";
|
||||
|
||||
public JsonLibraryProperty() {
|
||||
super("jsonLibrary", "Json library to use. Possible values are: json4s and circe.", JSON4S);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdditionalProperties(Map<String, Object> additionalProperties) {
|
||||
String value = getValue(additionalProperties);
|
||||
if (CIRCE.equals(value) || JSON4S.equals(value)) {
|
||||
additionalProperties.put(CIRCE, CIRCE.equals(value));
|
||||
additionalProperties.put(JSON4S, JSON4S.equals(value));
|
||||
} else {
|
||||
IllegalArgumentException exception =
|
||||
new IllegalArgumentException("Invalid json library: " + value + ". Must be " + CIRCE + " " +
|
||||
"or " + JSON4S);
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PackageProperty extends StringProperty {
|
||||
|
||||
public PackageProperty() {
|
||||
super("mainPackage", "Top-level package name, which defines 'apiPackage', 'modelPackage', " +
|
||||
"'invokerPackage'", DEFAULT_PACKAGE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAdditionalProperties(Map<String, Object> additionalProperties) {
|
||||
String mainPackage = getValue(additionalProperties);
|
||||
if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
String apiPackage = mainPackage + ".api";
|
||||
additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
|
||||
}
|
||||
if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
|
||||
String modelPackage = mainPackage + ".model";
|
||||
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
|
||||
}
|
||||
if (!additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
String invokerPackage = mainPackage + ".core";
|
||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||
}
|
||||
}
|
||||
|
||||
public String getApiPackage(Map<String, Object> additionalProperties) {
|
||||
return additionalProperties.getOrDefault(CodegenConstants.API_PACKAGE, DEFAULT_PACKAGE_NAME + ".api").toString();
|
||||
}
|
||||
|
||||
public String getModelPackage(Map<String, Object> additionalProperties) {
|
||||
return additionalProperties.getOrDefault(CodegenConstants.MODEL_PACKAGE, DEFAULT_PACKAGE_NAME + ".model").toString();
|
||||
}
|
||||
|
||||
public String getInvokerPackage(Map<String, Object> additionalProperties) {
|
||||
return additionalProperties.getOrDefault(CodegenConstants.INVOKER_PACKAGE, DEFAULT_PACKAGE_NAME + ".core").toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class JavadocLambda extends CustomLambda {
|
||||
@Override
|
||||
public String formatFragment(String fragment) {
|
||||
final String[] lines = fragment.split("\\r?\\n");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(" /**\n");
|
||||
for (String line : lines) {
|
||||
sb.append(" * ").append(line).append("\n");
|
||||
}
|
||||
sb.append(" */\n");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class CapitalizeLambda extends CustomLambda {
|
||||
@Override
|
||||
public String formatFragment(String fragment) {
|
||||
return StringUtils.capitalize(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
private class EnumEntryLambda extends CustomLambda {
|
||||
@Override
|
||||
public String formatFragment(String fragment) {
|
||||
return formatIdentifier(fragment, true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -138,4 +138,5 @@ org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen
|
||||
org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen
|
||||
org.openapitools.codegen.languages.WsdlSchemaCodegen
|
||||
org.openapitools.codegen.languages.XojoClientCodegen
|
||||
org.openapitools.codegen.languages.ScalaSttp4ClientCodegen
|
||||
org.openapitools.codegen.languages.SwiftCombineClientCodegen
|
||||
|
114
modules/openapi-generator/src/main/resources/scala-sttp4/README.mustache
vendored
Normal file
114
modules/openapi-generator/src/main/resources/scala-sttp4/README.mustache
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
# {{artifactId}}
|
||||
|
||||
{{appName}}
|
||||
- API version: {{appVersion}}
|
||||
{{^hideGenerationTimestamp}}
|
||||
- Build date: {{generatedDate}}
|
||||
{{/hideGenerationTimestamp}}
|
||||
|
||||
{{{appDescriptionWithNewLines}}}
|
||||
|
||||
{{#infoUrl}}
|
||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||
{{/infoUrl}}
|
||||
|
||||
*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)*
|
||||
|
||||
## Requirements
|
||||
|
||||
Building the API client library requires:
|
||||
1. Java 1.7+
|
||||
2. Maven/Gradle/SBT
|
||||
|
||||
## Installation
|
||||
|
||||
To install the API client library to your local Maven repository, simply execute:
|
||||
|
||||
```shell
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
|
||||
|
||||
```shell
|
||||
mvn clean deploy
|
||||
```
|
||||
|
||||
Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
|
||||
|
||||
### Maven users
|
||||
|
||||
Add this dependency to your project's POM:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>{{{groupId}}}</groupId>
|
||||
<artifactId>{{{artifactId}}}</artifactId>
|
||||
<version>{{{artifactVersion}}}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Gradle users
|
||||
|
||||
Add this dependency to your project's build file:
|
||||
|
||||
```groovy
|
||||
compile "{{{groupId}}}:{{{artifactId}}}:{{{artifactVersion}}}"
|
||||
```
|
||||
|
||||
### SBT users
|
||||
|
||||
```scala
|
||||
libraryDependencies += "{{{groupId}}}" % "{{{artifactId}}}" % "{{{artifactVersion}}}"
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *{{basePath}}*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | **{{operationId}}** | **{{httpMethod}}** {{path}} | {{summary}}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
## Documentation for Models
|
||||
|
||||
{{#models}}{{#model}} - [{{classname}}]({{modelDocPath}}{{classname}}.md)
|
||||
{{/model}}{{/models}}
|
||||
|
||||
<a id="documentation-for-authorization"></a>
|
||||
## Documentation for Authorization
|
||||
|
||||
{{^authMethods}}Endpoints do not require authorization.{{/authMethods}}
|
||||
{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}}
|
||||
{{#authMethods}}
|
||||
<a id="{{name}}"></a>
|
||||
### {{name}}
|
||||
|
||||
{{#isApiKey}}- **Type**: API key
|
||||
- **API key parameter name**: {{keyParamName}}
|
||||
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasicBasic}}- **Type**: HTTP basic authentication
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}
|
||||
{{/isBasicBearer}}
|
||||
{{#isHttpSignature}}- **Type**: HTTP signature authentication
|
||||
{{/isHttpSignature}}
|
||||
{{#isOAuth}}- **Type**: OAuth
|
||||
- **Flow**: {{flow}}
|
||||
- **Authorization URL**: {{authorizationUrl}}
|
||||
- **Scopes**: {{^scopes}}N/A{{/scopes}}
|
||||
{{#scopes}} - {{scope}}: {{description}}
|
||||
{{/scopes}}
|
||||
{{/isOAuth}}
|
||||
|
||||
{{/authMethods}}
|
||||
|
||||
## Author
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#-last}}{{infoEmail}}
|
||||
{{/-last}}{{/apis}}{{/apiInfo}}
|
45
modules/openapi-generator/src/main/resources/scala-sttp4/additionalTypeSerializers.mustache
vendored
Normal file
45
modules/openapi-generator/src/main/resources/scala-sttp4/additionalTypeSerializers.mustache
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package {{invokerPackage}}
|
||||
|
||||
import java.net.{ URI, URISyntaxException }
|
||||
|
||||
{{#json4s}}
|
||||
object AdditionalTypeSerializers {
|
||||
import org.json4s.{Serializer, CustomSerializer, JNull, MappingException}
|
||||
import org.json4s.JsonAST.JString
|
||||
case object URISerializer extends CustomSerializer[URI]( _ => ( {
|
||||
case JString(s) =>
|
||||
try new URI(s)
|
||||
catch {
|
||||
case _: URISyntaxException =>
|
||||
throw new MappingException("String could not be parsed as a URI reference, it violates RFC 2396.")
|
||||
case _: NullPointerException =>
|
||||
throw new MappingException("String is null.")
|
||||
}
|
||||
case JNull => null
|
||||
}, {
|
||||
case uri: URI =>
|
||||
JString(uri.toString())
|
||||
}))
|
||||
|
||||
def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ URISerializer
|
||||
}
|
||||
{{/json4s}}
|
||||
{{#circe}}
|
||||
trait AdditionalTypeSerializers {
|
||||
import io.circe._
|
||||
|
||||
implicit final lazy val URIDecoder: Decoder[URI] = Decoder.decodeString.emap(string =>
|
||||
try Right(new URI(string))
|
||||
catch {
|
||||
case _: URISyntaxException =>
|
||||
Left("String could not be parsed as a URI reference, it violates RFC 2396.")
|
||||
case _: NullPointerException =>
|
||||
Left("String is null.")
|
||||
}
|
||||
)
|
||||
|
||||
implicit final lazy val URIEncoder: Encoder[URI] = new Encoder[URI] {
|
||||
final def apply(a: URI): Json = Json.fromString(a.toString)
|
||||
}
|
||||
}
|
||||
{{/circe}}
|
43
modules/openapi-generator/src/main/resources/scala-sttp4/api.mustache
vendored
Normal file
43
modules/openapi-generator/src/main/resources/scala-sttp4/api.mustache
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
{{>licenseInfo}}
|
||||
package {{package}}
|
||||
|
||||
{{#imports}}
|
||||
import {{import}}
|
||||
{{/imports}}
|
||||
import {{invokerPackage}}.JsonSupport._
|
||||
import sttp.client4._
|
||||
import sttp.model.Method
|
||||
|
||||
{{#operations}}
|
||||
object {{classname}} {
|
||||
|
||||
def apply(baseUrl: String = "{{{basePath}}}") = new {{classname}}(baseUrl)
|
||||
}
|
||||
|
||||
class {{classname}}(baseUrl: String) {
|
||||
|
||||
{{#operation}}
|
||||
{{#javadocRenderer}}
|
||||
{{>javadoc}}
|
||||
{{/javadocRenderer}}
|
||||
def {{operationId}}({{>methodParameters}}): Request[{{#defaultReturnType}}Either[Either[String, String], Unit]{{/defaultReturnType}}{{^defaultReturnType}}{{#separateErrorChannel}}Either[ResponseException[String, Exception], {{>operationReturnType}}]{{/separateErrorChannel}}{{^separateErrorChannel}}{{>operationReturnType}}{{/separateErrorChannel}}{{/defaultReturnType}}] =
|
||||
basicRequest
|
||||
.method(Method.{{httpMethod.toUpperCase}}, uri"$baseUrl{{{path}}}{{#queryParams.0}}?{{#queryParams}}{{baseName}}=${ {{{paramName}}} }{{^-last}}&{{/-last}}{{/queryParams}}{{/queryParams.0}}{{#isApiKey}}{{#isKeyInQuery}}{{^queryParams.0}}?{{/queryParams.0}}{{#queryParams.0}}&{{/queryParams.0}}{{keyParamName}}=${apiKey.value}&{{/isKeyInQuery}}{{/isApiKey}}")
|
||||
.contentType({{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}}){{#headerParams}}
|
||||
.header({{>paramCreation}}){{/headerParams}}{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
|
||||
.auth.basic(username, password){{/isBasicBasic}}{{#isBasicBearer}}
|
||||
.auth.bearer(bearerToken){{/isBasicBearer}}{{/isBasic}}{{#isApiKey}}{{#isKeyInHeader}}
|
||||
.header("{{keyParamName}}", apiKey){{/isKeyInHeader}}{{#isKeyInCookie}}
|
||||
.cookie("{{keyParamName}}", apiKey){{/isKeyInCookie}}{{/isApiKey}}{{/authMethods}}{{#formParams.0}}{{^isMultipart}}
|
||||
.body(Map({{#formParams}}
|
||||
{{>paramFormCreation}}{{^-last}},{{/-last}}{{/formParams}}
|
||||
)){{/isMultipart}}{{#isMultipart}}
|
||||
.multipartBody(Seq({{#formParams}}
|
||||
{{>paramMultipartCreation}}{{^-last}}, {{/-last}}{{/formParams}}
|
||||
).flatten){{/isMultipart}}{{/formParams.0}}{{#bodyParam}}
|
||||
.body({{paramName}}){{/bodyParam}}
|
||||
.response({{#defaultReturnType}}asEither(asString, ignore){{/defaultReturnType}}{{^defaultReturnType}}{{#separateErrorChannel}}asJson{{/separateErrorChannel}}{{^separateErrorChannel}}asJsonAlwaysUnsafe{{/separateErrorChannel}}[{{>operationReturnType}}]{{/defaultReturnType}})
|
||||
|
||||
{{/operation}}
|
||||
}
|
||||
{{/operations}}
|
26
modules/openapi-generator/src/main/resources/scala-sttp4/build.sbt.mustache
vendored
Normal file
26
modules/openapi-generator/src/main/resources/scala-sttp4/build.sbt.mustache
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
version := "{{artifactVersion}}"
|
||||
name := "{{artifactId}}"
|
||||
organization := "{{groupId}}"
|
||||
|
||||
scalaVersion := "2.13.10"
|
||||
crossScalaVersions := Seq(scalaVersion.value, "2.12.17")
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.softwaremill.sttp.client4" %% "core" % "{{sttpClientVersion}}",
|
||||
{{#joda}}
|
||||
"joda-time" % "joda-time" % "{{jodaTimeVersion}}",
|
||||
{{/joda}}
|
||||
{{#json4s}}
|
||||
"com.softwaremill.sttp.client4" %% "json4s" % "{{sttpClientVersion}}",
|
||||
"org.json4s" %% "json4s-jackson" % "{{json4sVersion}}"
|
||||
{{/json4s}}
|
||||
{{#circe}}
|
||||
"com.softwaremill.sttp.client4" %% "circe" % "{{sttpClientVersion}}"
|
||||
{{/circe}}
|
||||
)
|
||||
|
||||
scalacOptions := Seq(
|
||||
"-unchecked",
|
||||
"-deprecation",
|
||||
"-feature"
|
||||
)
|
78
modules/openapi-generator/src/main/resources/scala-sttp4/dateSerializers.mustache
vendored
Normal file
78
modules/openapi-generator/src/main/resources/scala-sttp4/dateSerializers.mustache
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
package {{invokerPackage}}
|
||||
|
||||
{{#java8}}
|
||||
import java.time.{LocalDate, OffsetDateTime}
|
||||
import java.time.format.DateTimeFormatter
|
||||
{{/java8}}
|
||||
{{#joda}}
|
||||
import org.joda.time.DateTime
|
||||
import org.joda.time.format.ISODateTimeFormat
|
||||
{{/joda}}
|
||||
|
||||
{{#json4s}}
|
||||
object DateSerializers {
|
||||
import org.json4s.{Serializer, CustomSerializer, JNull}
|
||||
import org.json4s.JsonAST.JString
|
||||
{{#java8}}
|
||||
import scala.util.Try
|
||||
import java.time.{LocalDateTime, ZoneId}
|
||||
|
||||
case object DateTimeSerializer extends CustomSerializer[OffsetDateTime](_ => ( {
|
||||
case JString(s) =>
|
||||
Try(OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME)) orElse
|
||||
Try(LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toOffsetDateTime) getOrElse (null)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: OffsetDateTime =>
|
||||
JString(d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
|
||||
}))
|
||||
|
||||
case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( {
|
||||
case JString(s) => LocalDate.parse(s)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: LocalDate =>
|
||||
JString(d.format(DateTimeFormatter.ISO_LOCAL_DATE))
|
||||
}))
|
||||
{{/java8}}
|
||||
{{#joda}}
|
||||
case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( {
|
||||
case JString(s) =>
|
||||
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: org.joda.time.DateTime =>
|
||||
JString(ISODateTimeFormat.dateTime().print(d))
|
||||
})
|
||||
)
|
||||
|
||||
case object LocalDateSerializer extends CustomSerializer[org.joda.time.LocalDate](_ => ( {
|
||||
case JString(s) => org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd").parseLocalDate(s)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: org.joda.time.LocalDate => JString(d.toString("yyyy-MM-dd"))
|
||||
}))
|
||||
{{/joda}}
|
||||
|
||||
def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ LocalDateSerializer :+ DateTimeSerializer
|
||||
}
|
||||
{{/json4s}}
|
||||
{{#circe}}
|
||||
trait DateSerializers {
|
||||
import io.circe.{Decoder, Encoder}
|
||||
{{#java8}}
|
||||
implicit val isoOffsetDateTimeDecoder: Decoder[OffsetDateTime] = Decoder.decodeOffsetDateTimeWithFormatter(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
|
||||
implicit val isoOffsetDateTimeEncoder: Encoder[OffsetDateTime] = Encoder.encodeOffsetDateTimeWithFormatter(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
|
||||
|
||||
implicit val localDateDecoder: Decoder[LocalDate] = Decoder.decodeLocalDateWithFormatter(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
implicit val localDateEncoder: Encoder[LocalDate] = Encoder.encodeLocalDateWithFormatter(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
{{/java8}}
|
||||
{{#joda}}
|
||||
implicit val dateTimeDecoder: Decoder[DateTime] = Decoder.decodeString.map(ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(_))
|
||||
implicit val dateTimeEncoder: Encoder[DateTime] = Encoder.encodeString.contramap(ISODateTimeFormat.dateTime().print(_))
|
||||
|
||||
implicit val localDateDecoder: Decoder[org.joda.time.LocalDate] = Decoder.decodeString.map(org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd").parseLocalDate(_))
|
||||
implicit val localDateEncoder: Encoder[org.joda.time.LocalDate] = Encoder.encodeString.contramap(_.toString("yyyy-MM-dd"))
|
||||
{{/joda}}
|
||||
}
|
||||
{{/circe}}
|
25
modules/openapi-generator/src/main/resources/scala-sttp4/javadoc.mustache
vendored
Normal file
25
modules/openapi-generator/src/main/resources/scala-sttp4/javadoc.mustache
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{{#notes}}
|
||||
{{{.}}}
|
||||
|
||||
{{/notes}}
|
||||
Expected answers:
|
||||
{{#responses}}
|
||||
code {{code}} : {{{dataType}}} {{#message}}({{{.}}}){{/message}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
Headers :
|
||||
{{/-first}}
|
||||
{{{baseName}}} - {{{description}}}
|
||||
{{/headers}}
|
||||
{{/responses}}
|
||||
{{#authMethods.0}}
|
||||
|
||||
Available security schemes:
|
||||
{{#authMethods}}
|
||||
{{name}} ({{type}})
|
||||
{{/authMethods}}
|
||||
{{/authMethods.0}}
|
||||
|
||||
{{#allParams}}
|
||||
@param {{{paramName}}} {{{description}}}
|
||||
{{/allParams}}
|
58
modules/openapi-generator/src/main/resources/scala-sttp4/jsonSupport.mustache
vendored
Normal file
58
modules/openapi-generator/src/main/resources/scala-sttp4/jsonSupport.mustache
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
{{>licenseInfo}}
|
||||
package {{invokerPackage}}
|
||||
|
||||
{{#models.0}}
|
||||
import {{modelPackage}}._
|
||||
{{/models.0}}
|
||||
{{#json4s}}
|
||||
import org.json4s._
|
||||
import sttp.client4.json4s.SttpJson4sApi
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
object JsonSupport extends SttpJson4sApi {
|
||||
def enumSerializers: Seq[Serializer[_]] = Seq[Serializer[_]](){{#models}}{{#model}}{{#isEnum}} :+
|
||||
new EnumNameSerializer({{classname}}){{/isEnum}}{{/model}}{{/models}}
|
||||
|
||||
private class EnumNameSerializer[E <: Enumeration: ClassTag](enumeration: E) extends Serializer[E#Value] {
|
||||
import JsonDSL._
|
||||
val EnumerationClass: Class[E#Value] = classOf[E#Value]
|
||||
|
||||
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), E#Value] = {
|
||||
case (t @ TypeInfo(EnumerationClass, _), json) if isValid(json) =>
|
||||
json match {
|
||||
case JString(value) => enumeration.withName(value)
|
||||
case value => throw new MappingException(s"Can't convert $value to $EnumerationClass")
|
||||
}
|
||||
}
|
||||
|
||||
private[this] def isValid(json: JValue) = json match {
|
||||
case JString(value) if enumeration.values.exists(_.toString == value) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
|
||||
case i: E#Value => i.toString
|
||||
}
|
||||
}
|
||||
|
||||
implicit val format: Formats = DefaultFormats ++ enumSerializers ++ DateSerializers.all ++ AdditionalTypeSerializers.all
|
||||
implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization
|
||||
}
|
||||
{{/json4s}}
|
||||
{{#circe}}
|
||||
import io.circe.{Decoder, Encoder}
|
||||
import io.circe.generic.AutoDerivation
|
||||
import sttp.client3.circe.SttpCirceApi
|
||||
|
||||
object JsonSupport extends SttpCirceApi with AutoDerivation with DateSerializers with AdditionalTypeSerializers {
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#isEnum}}
|
||||
implicit val {{classname}}Decoder: Decoder[{{classname}}.{{classname}}] = Decoder.decodeEnumeration({{classname}})
|
||||
implicit val {{classname}}Encoder: Encoder[{{classname}}.{{classname}}] = Encoder.encodeEnumeration({{classname}})
|
||||
{{/isEnum}}
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
}
|
||||
{{/circe}}
|
11
modules/openapi-generator/src/main/resources/scala-sttp4/licenseInfo.mustache
vendored
Normal file
11
modules/openapi-generator/src/main/resources/scala-sttp4/licenseInfo.mustache
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* {{{appName}}}
|
||||
* {{{appDescription}}}
|
||||
*
|
||||
* {{#version}}The version of the OpenAPI document: {{{.}}}{{/version}}
|
||||
* {{#infoEmail}}Contact: {{{.}}}{{/infoEmail}}
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/methodParameters.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/methodParameters.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
{{#authMethods.0}}{{#authMethods}}{{#isApiKey}}apiKey: String{{/isApiKey}}{{#isBasic}}{{#isBasicBasic}}username: String, password: String{{/isBasicBasic}}{{#isBasicBearer}}bearerToken: String{{/isBasicBearer}}{{/isBasic}}{{^-last}}, {{/-last}}{{/authMethods}})({{/authMethods.0}}{{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{/required}}{{^required}}{{#isContainer}}{{dataType}}{{/isContainer}}{{^isContainer}}Option[{{dataType}}]{{/isContainer}}{{/required}}{{^defaultValue}}{{^required}}{{^isContainer}} = None{{/isContainer}}{{/required}}{{/defaultValue}}{{^-last}}, {{/-last}}{{/allParams}}
|
60
modules/openapi-generator/src/main/resources/scala-sttp4/model.mustache
vendored
Normal file
60
modules/openapi-generator/src/main/resources/scala-sttp4/model.mustache
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
{{>licenseInfo}}
|
||||
package {{package}}
|
||||
|
||||
{{#imports}}
|
||||
import {{import}}
|
||||
{{/imports}}
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#description}}
|
||||
{{#javadocRenderer}}
|
||||
{{#title}}
|
||||
{{{.}}}
|
||||
{{/title}}
|
||||
{{{description}}}
|
||||
{{/javadocRenderer}}
|
||||
{{/description}}
|
||||
{{^isEnum}}
|
||||
case class {{classname}}(
|
||||
{{#vars}}
|
||||
{{#description}}
|
||||
/* {{{.}}} */
|
||||
{{/description}}
|
||||
{{{name}}}: {{^required}}Option[{{/required}}{{^isEnum}}{{dataType}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}Enums.{{datatypeWithEnum}}{{/isArray}}{{#isArray}}Seq[{{classname}}Enums.{{datatypeWithEnum}}]{{/isArray}}{{/isEnum}}{{^required}}] = None{{/required}}{{^-last}},{{/-last}}
|
||||
{{/vars}}
|
||||
)
|
||||
{{/isEnum}}
|
||||
|
||||
{{#isEnum}}
|
||||
object {{classname}} extends Enumeration {
|
||||
type {{classname}} = {{classname}}.Value
|
||||
{{#allowableValues}}
|
||||
{{#values}}
|
||||
val {{#fnEnumEntry}}{{.}}{{/fnEnumEntry}} = Value("{{.}}")
|
||||
{{/values}}
|
||||
{{/allowableValues}}
|
||||
}
|
||||
{{/isEnum}}
|
||||
{{#hasEnums}}
|
||||
object {{classname}}Enums {
|
||||
|
||||
{{#vars}}
|
||||
{{#isEnum}}
|
||||
type {{datatypeWithEnum}} = {{datatypeWithEnum}}.Value
|
||||
{{/isEnum}}
|
||||
{{/vars}}
|
||||
{{#vars}}
|
||||
{{#isEnum}}
|
||||
object {{datatypeWithEnum}} extends Enumeration {
|
||||
{{#_enum}}
|
||||
val {{#fnEnumEntry}}{{.}}{{/fnEnumEntry}} = Value("{{.}}")
|
||||
{{/_enum}}
|
||||
}
|
||||
|
||||
{{/isEnum}}
|
||||
{{/vars}}
|
||||
}
|
||||
{{/hasEnums}}
|
||||
{{/model}}
|
||||
{{/models}}
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/operationReturnType.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/operationReturnType.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
{{{returnType}}}{{^returnType}}Unit{{/returnType}}
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/paramCreation.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/paramCreation.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
"{{baseName}}", {{#isContainer}}ArrayValues({{{paramName}}}{{#collectionFormat}}, {{collectionFormat.toUpperCase}}{{/collectionFormat}}){{/isContainer}}{{^isContainer}}{{{paramName}}}{{/isContainer}}.toString
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/paramFormCreation.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/paramFormCreation.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
"{{baseName}}" -> {{#isContainer}}ArrayValues({{{paramName}}}{{#collectionFormat}}, {{collectionFormat.toUpperCase}}{{/collectionFormat}}){{/isContainer}}{{^isContainer}}{{{paramName}}}{{/isContainer}}
|
16
modules/openapi-generator/src/main/resources/scala-sttp4/paramMultipartCreation.mustache
vendored
Normal file
16
modules/openapi-generator/src/main/resources/scala-sttp4/paramMultipartCreation.mustache
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{{#required}}
|
||||
{{#isFile}}
|
||||
multipartFile("{{baseName}}", {{#isContainer}}ArrayValues({{{paramName}}}{{#collectionFormat}}, {{collectionFormat.toUpperCase}}{{/collectionFormat}}){{/isContainer}}{{^isContainer}}{{{paramName}}}{{/isContainer}})
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
multipart("{{baseName}}", {{paramName}})
|
||||
{{/isFile}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
{{#isFile}}
|
||||
{{paramName}}.map(multipartFile("{{baseName}}", _))
|
||||
{{/isFile}}
|
||||
{{^isFile}}
|
||||
{{paramName}}.map(multipart("{{baseName}}", {{#isContainer}}ArrayValues(_{{#collectionFormat}}, {{collectionFormat.toUpperCase}}{{/collectionFormat}}){{/isContainer}}{{^isContainer}}_{{/isContainer}}))
|
||||
{{/isFile}}
|
||||
{{/required}}
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/project/build.properties.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/project/build.properties.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
sbt.version=1.9.0
|
1
modules/openapi-generator/src/main/resources/scala-sttp4/responseState.mustache
vendored
Normal file
1
modules/openapi-generator/src/main/resources/scala-sttp4/responseState.mustache
vendored
Normal file
@ -0,0 +1 @@
|
||||
{{#isDefault}}Success{{/isDefault}}{{^isDefault}}Error{{/isDefault}}
|
@ -0,0 +1,23 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
15
samples/client/petstore/scala/sttp4/.openapi-generator/FILES
Normal file
15
samples/client/petstore/scala/sttp4/.openapi-generator/FILES
Normal file
@ -0,0 +1,15 @@
|
||||
README.md
|
||||
build.sbt
|
||||
project/build.properties
|
||||
src/main/scala/org/openapitools/client/api/PetApi.scala
|
||||
src/main/scala/org/openapitools/client/api/StoreApi.scala
|
||||
src/main/scala/org/openapitools/client/api/UserApi.scala
|
||||
src/main/scala/org/openapitools/client/core/AdditionalTypeSerializers.scala
|
||||
src/main/scala/org/openapitools/client/core/DateSerializers.scala
|
||||
src/main/scala/org/openapitools/client/core/JsonSupport.scala
|
||||
src/main/scala/org/openapitools/client/model/ApiResponse.scala
|
||||
src/main/scala/org/openapitools/client/model/Category.scala
|
||||
src/main/scala/org/openapitools/client/model/Order.scala
|
||||
src/main/scala/org/openapitools/client/model/Pet.scala
|
||||
src/main/scala/org/openapitools/client/model/Tag.scala
|
||||
src/main/scala/org/openapitools/client/model/User.scala
|
@ -0,0 +1 @@
|
||||
7.0.0-SNAPSHOT
|
116
samples/client/petstore/scala/sttp4/README.md
Normal file
116
samples/client/petstore/scala/sttp4/README.md
Normal file
@ -0,0 +1,116 @@
|
||||
# openapi-client
|
||||
|
||||
OpenAPI Petstore
|
||||
- API version: 1.0.0
|
||||
|
||||
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
|
||||
|
||||
*Automatically generated by the [OpenAPI Generator](https://openapi-generator.tech)*
|
||||
|
||||
## Requirements
|
||||
|
||||
Building the API client library requires:
|
||||
1. Java 1.7+
|
||||
2. Maven/Gradle/SBT
|
||||
|
||||
## Installation
|
||||
|
||||
To install the API client library to your local Maven repository, simply execute:
|
||||
|
||||
```shell
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
To deploy it to a remote Maven repository instead, configure the settings of the repository and execute:
|
||||
|
||||
```shell
|
||||
mvn clean deploy
|
||||
```
|
||||
|
||||
Refer to the [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) for more information.
|
||||
|
||||
### Maven users
|
||||
|
||||
Add this dependency to your project's POM:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-client</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Gradle users
|
||||
|
||||
Add this dependency to your project's build file:
|
||||
|
||||
```groovy
|
||||
compile "org.openapitools:openapi-client:1.0.0"
|
||||
```
|
||||
|
||||
### SBT users
|
||||
|
||||
```scala
|
||||
libraryDependencies += "org.openapitools" % "openapi-client" % "1.0.0"
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *http://petstore.swagger.io/v2*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*PetApi* | **addPet** | **POST** /pet | Add a new pet to the store
|
||||
*PetApi* | **deletePet** | **DELETE** /pet/${petId} | Deletes a pet
|
||||
*PetApi* | **findPetsByStatus** | **GET** /pet/findByStatus | Finds Pets by status
|
||||
*PetApi* | **findPetsByTags** | **GET** /pet/findByTags | Finds Pets by tags
|
||||
*PetApi* | **getPetById** | **GET** /pet/${petId} | Find pet by ID
|
||||
*PetApi* | **updatePet** | **PUT** /pet | Update an existing pet
|
||||
*PetApi* | **updatePetWithForm** | **POST** /pet/${petId} | Updates a pet in the store with form data
|
||||
*PetApi* | **uploadFile** | **POST** /pet/${petId}/uploadImage | uploads an image
|
||||
*StoreApi* | **deleteOrder** | **DELETE** /store/order/${orderId} | Delete purchase order by ID
|
||||
*StoreApi* | **getInventory** | **GET** /store/inventory | Returns pet inventories by status
|
||||
*StoreApi* | **getOrderById** | **GET** /store/order/${orderId} | Find purchase order by ID
|
||||
*StoreApi* | **placeOrder** | **POST** /store/order | Place an order for a pet
|
||||
*UserApi* | **createUser** | **POST** /user | Create user
|
||||
*UserApi* | **createUsersWithArrayInput** | **POST** /user/createWithArray | Creates list of users with given input array
|
||||
*UserApi* | **createUsersWithListInput** | **POST** /user/createWithList | Creates list of users with given input array
|
||||
*UserApi* | **deleteUser** | **DELETE** /user/${username} | Delete user
|
||||
*UserApi* | **getUserByName** | **GET** /user/${username} | Get user by user name
|
||||
*UserApi* | **loginUser** | **GET** /user/login | Logs user into the system
|
||||
*UserApi* | **logoutUser** | **GET** /user/logout | Logs out current logged in user session
|
||||
*UserApi* | **updateUser** | **PUT** /user/${username} | Updated user
|
||||
|
||||
|
||||
## Documentation for Models
|
||||
|
||||
- [ApiResponse](ApiResponse.md)
|
||||
- [Category](Category.md)
|
||||
- [Order](Order.md)
|
||||
- [Pet](Pet.md)
|
||||
- [Tag](Tag.md)
|
||||
- [User](User.md)
|
||||
|
||||
|
||||
<a id="documentation-for-authorization"></a>
|
||||
## Documentation for Authorization
|
||||
|
||||
|
||||
Authentication schemes defined for the API:
|
||||
<a id="api_key"></a>
|
||||
### api_key
|
||||
|
||||
- **Type**: API key
|
||||
- **API key parameter name**: api_key
|
||||
- **Location**: HTTP header
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
|
18
samples/client/petstore/scala/sttp4/build.sbt
Normal file
18
samples/client/petstore/scala/sttp4/build.sbt
Normal file
@ -0,0 +1,18 @@
|
||||
version := "1.0.0"
|
||||
name := "openapi-client"
|
||||
organization := "org.openapitools"
|
||||
|
||||
scalaVersion := "2.13.10"
|
||||
crossScalaVersions := Seq(scalaVersion.value, "2.12.17")
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.softwaremill.sttp.client4" %% "core" % "4.0.0-M1",
|
||||
"com.softwaremill.sttp.client4" %% "json4s" % "4.0.0-M1",
|
||||
"org.json4s" %% "json4s-jackson" % "4.0.6"
|
||||
)
|
||||
|
||||
scalacOptions := Seq(
|
||||
"-unchecked",
|
||||
"-deprecation",
|
||||
"-feature"
|
||||
)
|
@ -0,0 +1 @@
|
||||
sbt.version=1.9.0
|
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.api
|
||||
|
||||
import org.openapitools.client.model.ApiResponse
|
||||
import java.io.File
|
||||
import org.openapitools.client.model.Pet
|
||||
import org.openapitools.client.core.JsonSupport._
|
||||
import sttp.client4._
|
||||
import sttp.model.Method
|
||||
|
||||
object PetApi {
|
||||
|
||||
def apply(baseUrl: String = "http://petstore.swagger.io/v2") = new PetApi(baseUrl)
|
||||
}
|
||||
|
||||
class PetApi(baseUrl: String) {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Pet (successful operation)
|
||||
* code 405 : (Invalid input)
|
||||
*
|
||||
* @param pet Pet object that needs to be added to the store
|
||||
*/
|
||||
def addPet(pet: Pet
|
||||
): Request[Either[ResponseException[String, Exception], Pet]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/pet")
|
||||
.contentType("application/json")
|
||||
.body(pet)
|
||||
.response(asJson[Pet])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid pet value)
|
||||
*
|
||||
* @param petId Pet id to delete
|
||||
* @param apiKey
|
||||
*/
|
||||
def deletePet(petId: Long, apiKey: Option[String] = None
|
||||
): Request[Either[ResponseException[String, Exception], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.DELETE, uri"$baseUrl/pet/${petId}")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey.toString)
|
||||
.response(asJson[Unit])
|
||||
|
||||
/**
|
||||
* Multiple status values can be provided with comma separated strings
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Seq[Pet] (successful operation)
|
||||
* code 400 : (Invalid status value)
|
||||
*
|
||||
* @param status Status values that need to be considered for filter
|
||||
*/
|
||||
def findPetsByStatus(status: Seq[String]
|
||||
): Request[Either[ResponseException[String, Exception], Seq[Pet]]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/pet/findByStatus?status=${ status }")
|
||||
.contentType("application/json")
|
||||
.response(asJson[Seq[Pet]])
|
||||
|
||||
/**
|
||||
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Seq[Pet] (successful operation)
|
||||
* code 400 : (Invalid tag value)
|
||||
*
|
||||
* @param tags Tags to filter by
|
||||
*/
|
||||
def findPetsByTags(tags: Seq[String]
|
||||
): Request[Either[ResponseException[String, Exception], Seq[Pet]]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/pet/findByTags?tags=${ tags }")
|
||||
.contentType("application/json")
|
||||
.response(asJson[Seq[Pet]])
|
||||
|
||||
/**
|
||||
* Returns a single pet
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Pet (successful operation)
|
||||
* code 400 : (Invalid ID supplied)
|
||||
* code 404 : (Pet not found)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param petId ID of pet to return
|
||||
*/
|
||||
def getPetById(apiKey: String)(petId: Long
|
||||
): Request[Either[ResponseException[String, Exception], Pet]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/pet/${petId}")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.response(asJson[Pet])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Pet (successful operation)
|
||||
* code 400 : (Invalid ID supplied)
|
||||
* code 404 : (Pet not found)
|
||||
* code 405 : (Validation exception)
|
||||
*
|
||||
* @param pet Pet object that needs to be added to the store
|
||||
*/
|
||||
def updatePet(pet: Pet
|
||||
): Request[Either[ResponseException[String, Exception], Pet]] =
|
||||
basicRequest
|
||||
.method(Method.PUT, uri"$baseUrl/pet")
|
||||
.contentType("application/json")
|
||||
.body(pet)
|
||||
.response(asJson[Pet])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 405 : (Invalid input)
|
||||
*
|
||||
* @param petId ID of pet that needs to be updated
|
||||
* @param name Updated name of the pet
|
||||
* @param status Updated status of the pet
|
||||
*/
|
||||
def updatePetWithForm(petId: Long, name: Option[String] = None, status: Option[String] = None
|
||||
): Request[Either[ResponseException[String, Exception], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/pet/${petId}")
|
||||
.contentType("application/x-www-form-urlencoded")
|
||||
.body(Map(
|
||||
"name" -> name,
|
||||
"status" -> status
|
||||
))
|
||||
.response(asJson[Unit])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : ApiResponse (successful operation)
|
||||
*
|
||||
* @param petId ID of pet to update
|
||||
* @param additionalMetadata Additional data to pass to server
|
||||
* @param file file to upload
|
||||
*/
|
||||
def uploadFile(petId: Long, additionalMetadata: Option[String] = None, file: Option[File] = None
|
||||
): Request[Either[ResponseException[String, Exception], ApiResponse]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/pet/${petId}/uploadImage")
|
||||
.contentType("multipart/form-data")
|
||||
.multipartBody(Seq(
|
||||
additionalMetadata.map(multipart("additionalMetadata", _))
|
||||
,
|
||||
file.map(multipartFile("file", _))
|
||||
|
||||
).flatten)
|
||||
.response(asJson[ApiResponse])
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.api
|
||||
|
||||
import org.openapitools.client.model.Order
|
||||
import org.openapitools.client.core.JsonSupport._
|
||||
import sttp.client4._
|
||||
import sttp.model.Method
|
||||
|
||||
object StoreApi {
|
||||
|
||||
def apply(baseUrl: String = "http://petstore.swagger.io/v2") = new StoreApi(baseUrl)
|
||||
}
|
||||
|
||||
class StoreApi(baseUrl: String) {
|
||||
|
||||
/**
|
||||
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
|
||||
*
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid ID supplied)
|
||||
* code 404 : (Order not found)
|
||||
*
|
||||
* @param orderId ID of the order that needs to be deleted
|
||||
*/
|
||||
def deleteOrder(orderId: String
|
||||
): Request[Either[ResponseException[String, Exception], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.DELETE, uri"$baseUrl/store/order/${orderId}")
|
||||
.contentType("application/json")
|
||||
.response(asJson[Unit])
|
||||
|
||||
/**
|
||||
* Returns a map of status codes to quantities
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Map[String, Int] (successful operation)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*/
|
||||
def getInventory(apiKey: String)(
|
||||
): Request[Either[ResponseException[String, Exception], Map[String, Int]]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/store/inventory")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.response(asJson[Map[String, Int]])
|
||||
|
||||
/**
|
||||
* For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Order (successful operation)
|
||||
* code 400 : (Invalid ID supplied)
|
||||
* code 404 : (Order not found)
|
||||
*
|
||||
* @param orderId ID of pet that needs to be fetched
|
||||
*/
|
||||
def getOrderById(orderId: Long
|
||||
): Request[Either[ResponseException[String, Exception], Order]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/store/order/${orderId}")
|
||||
.contentType("application/json")
|
||||
.response(asJson[Order])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : Order (successful operation)
|
||||
* code 400 : (Invalid Order)
|
||||
*
|
||||
* @param order order placed for purchasing the pet
|
||||
*/
|
||||
def placeOrder(order: Order
|
||||
): Request[Either[ResponseException[String, Exception], Order]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/store/order")
|
||||
.contentType("application/json")
|
||||
.body(order)
|
||||
.response(asJson[Order])
|
||||
|
||||
}
|
@ -0,0 +1,184 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.api
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
import org.openapitools.client.model.User
|
||||
import org.openapitools.client.core.JsonSupport._
|
||||
import sttp.client4._
|
||||
import sttp.model.Method
|
||||
|
||||
object UserApi {
|
||||
|
||||
def apply(baseUrl: String = "http://petstore.swagger.io/v2") = new UserApi(baseUrl)
|
||||
}
|
||||
|
||||
class UserApi(baseUrl: String) {
|
||||
|
||||
/**
|
||||
* This can only be done by the logged in user.
|
||||
*
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param user Created user object
|
||||
*/
|
||||
def createUser(apiKey: String)(user: User
|
||||
): Request[Either[Either[String, String], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/user")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.body(user)
|
||||
.response(asEither(asString, ignore))
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param user List of user object
|
||||
*/
|
||||
def createUsersWithArrayInput(apiKey: String)(user: Seq[User]
|
||||
): Request[Either[Either[String, String], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/user/createWithArray")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.body(user)
|
||||
.response(asEither(asString, ignore))
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param user List of user object
|
||||
*/
|
||||
def createUsersWithListInput(apiKey: String)(user: Seq[User]
|
||||
): Request[Either[Either[String, String], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.POST, uri"$baseUrl/user/createWithList")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.body(user)
|
||||
.response(asEither(asString, ignore))
|
||||
|
||||
/**
|
||||
* This can only be done by the logged in user.
|
||||
*
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid username supplied)
|
||||
* code 404 : (User not found)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param username The name that needs to be deleted
|
||||
*/
|
||||
def deleteUser(apiKey: String)(username: String
|
||||
): Request[Either[ResponseException[String, Exception], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.DELETE, uri"$baseUrl/user/${username}")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.response(asJson[Unit])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : User (successful operation)
|
||||
* code 400 : (Invalid username supplied)
|
||||
* code 404 : (User not found)
|
||||
*
|
||||
* @param username The name that needs to be fetched. Use user1 for testing.
|
||||
*/
|
||||
def getUserByName(username: String
|
||||
): Request[Either[ResponseException[String, Exception], User]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/user/${username}")
|
||||
.contentType("application/json")
|
||||
.response(asJson[User])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 200 : String (successful operation)
|
||||
* Headers :
|
||||
* Set-Cookie - Cookie authentication key for use with the `api_key` apiKey authentication.
|
||||
* X-Rate-Limit - calls per hour allowed by the user
|
||||
* X-Expires-After - date in UTC when token expires
|
||||
* code 400 : (Invalid username/password supplied)
|
||||
*
|
||||
* @param username The user name for login
|
||||
* @param password The password for login in clear text
|
||||
*/
|
||||
def loginUser(username: String, password: String
|
||||
): Request[Either[ResponseException[String, Exception], String]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/user/login?username=${ username }&password=${ password }")
|
||||
.contentType("application/json")
|
||||
.response(asJson[String])
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*/
|
||||
def logoutUser(apiKey: String)(
|
||||
): Request[Either[Either[String, String], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.GET, uri"$baseUrl/user/logout")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.response(asEither(asString, ignore))
|
||||
|
||||
/**
|
||||
* This can only be done by the logged in user.
|
||||
*
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid user supplied)
|
||||
* code 404 : (User not found)
|
||||
*
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*
|
||||
* @param username name that need to be deleted
|
||||
* @param user Updated user object
|
||||
*/
|
||||
def updateUser(apiKey: String)(username: String, user: User
|
||||
): Request[Either[ResponseException[String, Exception], Unit]] =
|
||||
basicRequest
|
||||
.method(Method.PUT, uri"$baseUrl/user/${username}")
|
||||
.contentType("application/json")
|
||||
.header("api_key", apiKey)
|
||||
.body(user)
|
||||
.response(asJson[Unit])
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package org.openapitools.client.core
|
||||
|
||||
import java.net.{ URI, URISyntaxException }
|
||||
|
||||
object AdditionalTypeSerializers {
|
||||
import org.json4s.{Serializer, CustomSerializer, JNull, MappingException}
|
||||
import org.json4s.JsonAST.JString
|
||||
case object URISerializer extends CustomSerializer[URI]( _ => ( {
|
||||
case JString(s) =>
|
||||
try new URI(s)
|
||||
catch {
|
||||
case _: URISyntaxException =>
|
||||
throw new MappingException("String could not be parsed as a URI reference, it violates RFC 2396.")
|
||||
case _: NullPointerException =>
|
||||
throw new MappingException("String is null.")
|
||||
}
|
||||
case JNull => null
|
||||
}, {
|
||||
case uri: URI =>
|
||||
JString(uri.toString())
|
||||
}))
|
||||
|
||||
def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ URISerializer
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package org.openapitools.client.core
|
||||
|
||||
import java.time.{LocalDate, OffsetDateTime}
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object DateSerializers {
|
||||
import org.json4s.{Serializer, CustomSerializer, JNull}
|
||||
import org.json4s.JsonAST.JString
|
||||
import scala.util.Try
|
||||
import java.time.{LocalDateTime, ZoneId}
|
||||
|
||||
case object DateTimeSerializer extends CustomSerializer[OffsetDateTime](_ => ( {
|
||||
case JString(s) =>
|
||||
Try(OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME)) orElse
|
||||
Try(LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toOffsetDateTime) getOrElse (null)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: OffsetDateTime =>
|
||||
JString(d.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
|
||||
}))
|
||||
|
||||
case object LocalDateSerializer extends CustomSerializer[LocalDate]( _ => ( {
|
||||
case JString(s) => LocalDate.parse(s)
|
||||
case JNull => null
|
||||
}, {
|
||||
case d: LocalDate =>
|
||||
JString(d.format(DateTimeFormatter.ISO_LOCAL_DATE))
|
||||
}))
|
||||
|
||||
def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+ LocalDateSerializer :+ DateTimeSerializer
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.core
|
||||
|
||||
import org.openapitools.client.model._
|
||||
import org.json4s._
|
||||
import sttp.client4.json4s.SttpJson4sApi
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
object JsonSupport extends SttpJson4sApi {
|
||||
def enumSerializers: Seq[Serializer[_]] = Seq[Serializer[_]]()
|
||||
|
||||
private class EnumNameSerializer[E <: Enumeration: ClassTag](enumeration: E) extends Serializer[E#Value] {
|
||||
import JsonDSL._
|
||||
val EnumerationClass: Class[E#Value] = classOf[E#Value]
|
||||
|
||||
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), E#Value] = {
|
||||
case (t @ TypeInfo(EnumerationClass, _), json) if isValid(json) =>
|
||||
json match {
|
||||
case JString(value) => enumeration.withName(value)
|
||||
case value => throw new MappingException(s"Can't convert $value to $EnumerationClass")
|
||||
}
|
||||
}
|
||||
|
||||
private[this] def isValid(json: JValue) = json match {
|
||||
case JString(value) if enumeration.values.exists(_.toString == value) => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
|
||||
case i: E#Value => i.toString
|
||||
}
|
||||
}
|
||||
|
||||
implicit val format: Formats = DefaultFormats ++ enumSerializers ++ DateSerializers.all ++ AdditionalTypeSerializers.all
|
||||
implicit val serialization: org.json4s.Serialization = org.json4s.jackson.Serialization
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
|
||||
/**
|
||||
* An uploaded response
|
||||
* Describes the result of uploading an image resource
|
||||
*/
|
||||
case class ApiResponse(
|
||||
code: Option[Int] = None,
|
||||
`type`: Option[String] = None,
|
||||
message: Option[String] = None
|
||||
)
|
||||
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
|
||||
/**
|
||||
* Pet category
|
||||
* A category for a pet
|
||||
*/
|
||||
case class Category(
|
||||
id: Option[Long] = None,
|
||||
name: Option[String] = None
|
||||
)
|
||||
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
/**
|
||||
* Pet Order
|
||||
* An order for a pets from the pet store
|
||||
*/
|
||||
case class Order(
|
||||
id: Option[Long] = None,
|
||||
petId: Option[Long] = None,
|
||||
quantity: Option[Int] = None,
|
||||
shipDate: Option[OffsetDateTime] = None,
|
||||
/* Order Status */
|
||||
status: Option[OrderEnums.Status] = None,
|
||||
complete: Option[Boolean] = None
|
||||
)
|
||||
|
||||
object OrderEnums {
|
||||
|
||||
type Status = Status.Value
|
||||
object Status extends Enumeration {
|
||||
val Placed = Value("placed")
|
||||
val Approved = Value("approved")
|
||||
val Delivered = Value("delivered")
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
|
||||
/**
|
||||
* a Pet
|
||||
* A pet for sale in the pet store
|
||||
*/
|
||||
case class Pet(
|
||||
id: Option[Long] = None,
|
||||
category: Option[Category] = None,
|
||||
name: String,
|
||||
photoUrls: Seq[String],
|
||||
tags: Option[Seq[Tag]] = None,
|
||||
/* pet status in the store */
|
||||
status: Option[PetEnums.Status] = None
|
||||
)
|
||||
|
||||
object PetEnums {
|
||||
|
||||
type Status = Status.Value
|
||||
object Status extends Enumeration {
|
||||
val Available = Value("available")
|
||||
val Pending = Value("pending")
|
||||
val Sold = Value("sold")
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
|
||||
/**
|
||||
* Pet Tag
|
||||
* A tag for a pet
|
||||
*/
|
||||
case class Tag(
|
||||
id: Option[Long] = None,
|
||||
name: Option[String] = None
|
||||
)
|
||||
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* OpenAPI Petstore
|
||||
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
*
|
||||
* The version of the OpenAPI document: 1.0.0
|
||||
*
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package org.openapitools.client.model
|
||||
|
||||
|
||||
/**
|
||||
* a User
|
||||
* A User who is purchasing from the pet store
|
||||
*/
|
||||
case class User(
|
||||
id: Option[Long] = None,
|
||||
username: Option[String] = None,
|
||||
firstName: Option[String] = None,
|
||||
lastName: Option[String] = None,
|
||||
email: Option[String] = None,
|
||||
password: Option[String] = None,
|
||||
phone: Option[String] = None,
|
||||
/* User Status */
|
||||
userStatus: Option[Int] = None
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user